ZlibDecompressor.c
上传用户:quxuerui
上传日期:2018-01-08
资源大小:41811k
文件大小:10k
源码类别:

网格计算

开发平台:

Java

  1. /*
  2.  * Licensed to the Apache Software Foundation (ASF) under one
  3.  * or more contributor license agreements.  See the NOTICE file
  4.  * distributed with this work for additional information
  5.  * regarding copyright ownership.  The ASF licenses this file
  6.  * to you under the Apache License, Version 2.0 (the
  7.  * "License"); you may not use this file except in compliance
  8.  * with the License.  You may obtain a copy of the License at
  9.  *
  10.  *     http://www.apache.org/licenses/LICENSE-2.0
  11.  *
  12.  * Unless required by applicable law or agreed to in writing, software
  13.  * distributed under the License is distributed on an "AS IS" BASIS,
  14.  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
  15.  * See the License for the specific language governing permissions and
  16.  * limitations under the License.
  17.  */
  18. #if defined HAVE_CONFIG_H
  19.   #include <config.h>
  20. #endif
  21. #if defined HAVE_STDIO_H
  22.   #include <stdio.h>
  23. #else
  24.   #error 'stdio.h not found'
  25. #endif  
  26. #if defined HAVE_STDLIB_H
  27.   #include <stdlib.h>
  28. #else
  29.   #error 'stdlib.h not found'
  30. #endif  
  31. #if defined HAVE_STRING_H
  32.   #include <string.h>
  33. #else
  34.   #error 'string.h not found'
  35. #endif  
  36. #if defined HAVE_DLFCN_H
  37.   #include <dlfcn.h>
  38. #else
  39.   #error 'dlfcn.h not found'
  40. #endif  
  41. #include "org_apache_hadoop_io_compress_zlib.h"
  42. #include "org_apache_hadoop_io_compress_zlib_ZlibDecompressor.h"
  43. static jfieldID ZlibDecompressor_clazz;
  44. static jfieldID ZlibDecompressor_stream;
  45. static jfieldID ZlibDecompressor_compressedDirectBuf;
  46. static jfieldID ZlibDecompressor_compressedDirectBufOff;
  47. static jfieldID ZlibDecompressor_compressedDirectBufLen;
  48. static jfieldID ZlibDecompressor_uncompressedDirectBuf;
  49. static jfieldID ZlibDecompressor_directBufferSize;
  50. static jfieldID ZlibDecompressor_needDict;
  51. static jfieldID ZlibDecompressor_finished;
  52. static int (*dlsym_inflateInit2_)(z_streamp, int, const char *, int);
  53. static int (*dlsym_inflate)(z_streamp, int);
  54. static int (*dlsym_inflateSetDictionary)(z_streamp, const Bytef *, uInt);
  55. static int (*dlsym_inflateReset)(z_streamp);
  56. static int (*dlsym_inflateEnd)(z_streamp);
  57. JNIEXPORT void JNICALL
  58. Java_org_apache_hadoop_io_compress_zlib_ZlibDecompressor_initIDs(
  59. JNIEnv *env, jclass class
  60. ) {
  61. // Load libz.so
  62.     void *libz = dlopen(HADOOP_ZLIB_LIBRARY, RTLD_LAZY | RTLD_GLOBAL);
  63. if (!libz) {
  64.   THROW(env, "java/lang/UnsatisfiedLinkError", "Cannot load libz.so");
  65.   return;
  66. // Locate the requisite symbols from libz.so
  67. dlerror();                                 // Clear any existing error
  68. LOAD_DYNAMIC_SYMBOL(dlsym_inflateInit2_, env, libz, "inflateInit2_");
  69. LOAD_DYNAMIC_SYMBOL(dlsym_inflate, env, libz, "inflate");
  70. LOAD_DYNAMIC_SYMBOL(dlsym_inflateSetDictionary, env, libz, "inflateSetDictionary");
  71. LOAD_DYNAMIC_SYMBOL(dlsym_inflateReset, env, libz, "inflateReset");
  72. LOAD_DYNAMIC_SYMBOL(dlsym_inflateEnd, env, libz, "inflateEnd");
  73. // Initialize the requisite fieldIds
  74.     ZlibDecompressor_clazz = (*env)->GetStaticFieldID(env, class, "clazz", 
  75.                                                       "Ljava/lang/Class;");
  76.     ZlibDecompressor_stream = (*env)->GetFieldID(env, class, "stream", "J");
  77.     ZlibDecompressor_needDict = (*env)->GetFieldID(env, class, "needDict", "Z");
  78.     ZlibDecompressor_finished = (*env)->GetFieldID(env, class, "finished", "Z");
  79.     ZlibDecompressor_compressedDirectBuf = (*env)->GetFieldID(env, class, 
  80.      "compressedDirectBuf", 
  81.      "Ljava/nio/Buffer;");
  82.     ZlibDecompressor_compressedDirectBufOff = (*env)->GetFieldID(env, class, 
  83.      "compressedDirectBufOff", "I");
  84.     ZlibDecompressor_compressedDirectBufLen = (*env)->GetFieldID(env, class, 
  85.      "compressedDirectBufLen", "I");
  86.     ZlibDecompressor_uncompressedDirectBuf = (*env)->GetFieldID(env, class, 
  87.      "uncompressedDirectBuf", 
  88.      "Ljava/nio/Buffer;");
  89.     ZlibDecompressor_directBufferSize = (*env)->GetFieldID(env, class, 
  90.      "directBufferSize", "I");
  91. }
  92. JNIEXPORT jlong JNICALL
  93. Java_org_apache_hadoop_io_compress_zlib_ZlibDecompressor_init(
  94. JNIEnv *env, jclass cls, jint windowBits
  95. ) {
  96.     z_stream *stream = malloc(sizeof(z_stream));
  97.     memset((void*)stream, 0, sizeof(z_stream));
  98.     if (stream == 0) {
  99. THROW(env, "java/lang/OutOfMemoryError", NULL);
  100. return (jlong)0;
  101.     } 
  102.     
  103.     int rv = dlsym_inflateInit2_(stream, windowBits, ZLIB_VERSION, sizeof(z_stream));
  104. if (rv != Z_OK) {
  105.     // Contingency - Report error by throwing appropriate exceptions
  106. free(stream);
  107. stream = NULL;
  108. switch (rv) {
  109.   case Z_MEM_ERROR:
  110.   {
  111.      THROW(env, "java/lang/OutOfMemoryError", NULL);
  112.   }
  113.   break;
  114.    default:
  115.    {
  116.     THROW(env, "java/lang/InternalError", NULL);
  117.    }
  118.    break;
  119. }
  120. }
  121. return JLONG(stream);
  122. }
  123. JNIEXPORT void JNICALL
  124. Java_org_apache_hadoop_io_compress_zlib_ZlibDecompressor_setDictionary(
  125. JNIEnv *env, jclass cls, jlong stream,
  126. jarray b, jint off, jint len
  127. ) {
  128.     Bytef *buf = (*env)->GetPrimitiveArrayCritical(env, b, 0);
  129.     if (!buf) {
  130. THROW(env, "java/lang/InternalError", NULL);
  131.         return;
  132.     }
  133.     int rv = dlsym_inflateSetDictionary(ZSTREAM(stream), buf + off, len);
  134.     (*env)->ReleasePrimitiveArrayCritical(env, b, buf, 0);
  135.     
  136.     if (rv != Z_OK) {
  137.     // Contingency - Report error by throwing appropriate exceptions
  138. switch (rv) {
  139.     case Z_STREAM_ERROR:
  140.      case Z_DATA_ERROR:
  141. {
  142. THROW(env, "java/lang/IllegalArgumentException", 
  143. (ZSTREAM(stream))->msg);
  144. }
  145. break;
  146.      default:
  147.      {
  148. THROW(env, "java/lang/InternalError", (ZSTREAM(stream))->msg);
  149.      }
  150. break;
  151. }
  152. }
  153. }
  154. JNIEXPORT jint JNICALL
  155. Java_org_apache_hadoop_io_compress_zlib_ZlibDecompressor_inflateBytesDirect(
  156. JNIEnv *env, jobject this
  157. ) {
  158. // Get members of ZlibDecompressor
  159.     z_stream *stream = ZSTREAM(
  160.      (*env)->GetLongField(env, this, 
  161.      ZlibDecompressor_stream)
  162.      );
  163.     if (!stream) {
  164. THROW(env, "java/lang/NullPointerException", NULL);
  165. return (jint)0;
  166.     } 
  167.     // Get members of ZlibDecompressor
  168.     jobject clazz = (*env)->GetStaticObjectField(env, this, 
  169.                                                  ZlibDecompressor_clazz);
  170. jarray compressed_direct_buf = (jarray)(*env)->GetObjectField(env, this, 
  171. ZlibDecompressor_compressedDirectBuf);
  172. jint compressed_direct_buf_off = (*env)->GetIntField(env, this, 
  173. ZlibDecompressor_compressedDirectBufOff);
  174. jint compressed_direct_buf_len = (*env)->GetIntField(env, this, 
  175. ZlibDecompressor_compressedDirectBufLen);
  176. jarray uncompressed_direct_buf = (jarray)(*env)->GetObjectField(env, this, 
  177. ZlibDecompressor_uncompressedDirectBuf);
  178. jint uncompressed_direct_buf_len = (*env)->GetIntField(env, this, 
  179. ZlibDecompressor_directBufferSize);
  180.     // Get the input direct buffer
  181.     LOCK_CLASS(env, clazz, "ZlibDecompressor");
  182. Bytef *compressed_bytes = (*env)->GetDirectBufferAddress(env, 
  183. compressed_direct_buf);
  184.     UNLOCK_CLASS(env, clazz, "ZlibDecompressor");
  185.     
  186. if (!compressed_bytes) {
  187.     return (jint)0;
  188. }
  189.     // Get the output direct buffer
  190.     LOCK_CLASS(env, clazz, "ZlibDecompressor");
  191. Bytef *uncompressed_bytes = (*env)->GetDirectBufferAddress(env, 
  192. uncompressed_direct_buf);
  193.     UNLOCK_CLASS(env, clazz, "ZlibDecompressor");
  194. if (!uncompressed_bytes) {
  195.     return (jint)0;
  196. }
  197. // Re-calibrate the z_stream
  198. stream->next_in  = compressed_bytes + compressed_direct_buf_off;
  199. stream->next_out = uncompressed_bytes;
  200. stream->avail_in  = compressed_direct_buf_len;
  201. stream->avail_out = uncompressed_direct_buf_len;
  202. // Decompress
  203. int rv = dlsym_inflate(stream, Z_PARTIAL_FLUSH);
  204. // Contingency? - Report error by throwing appropriate exceptions
  205. int no_decompressed_bytes = 0;
  206. switch (rv) {
  207. case Z_STREAM_END:
  208. {
  209.     (*env)->SetBooleanField(env, this, ZlibDecompressor_finished, JNI_TRUE);
  210. } // cascade down
  211. case Z_OK:
  212. {
  213.     compressed_direct_buf_off += compressed_direct_buf_len - stream->avail_in;
  214.     (*env)->SetIntField(env, this, ZlibDecompressor_compressedDirectBufOff, 
  215.      compressed_direct_buf_off);
  216.     (*env)->SetIntField(env, this, ZlibDecompressor_compressedDirectBufLen, 
  217.      stream->avail_in);
  218.     no_decompressed_bytes = uncompressed_direct_buf_len - stream->avail_out;
  219. }
  220. break;
  221. case Z_NEED_DICT:
  222. {
  223.     (*env)->SetBooleanField(env, this, ZlibDecompressor_needDict, JNI_TRUE);
  224.     compressed_direct_buf_off += compressed_direct_buf_len - stream->avail_in;
  225.     (*env)->SetIntField(env, this, ZlibDecompressor_compressedDirectBufOff, 
  226.      compressed_direct_buf_off);
  227.     (*env)->SetIntField(env, this, ZlibDecompressor_compressedDirectBufLen, 
  228.      stream->avail_in);
  229. }
  230. break;
  231. case Z_BUF_ERROR:
  232. break;
  233. case Z_DATA_ERROR:
  234. {
  235.     THROW(env, "java/io/IOException", stream->msg);
  236. }
  237. break;
  238. case Z_MEM_ERROR:
  239. {
  240.     THROW(env, "java/lang/OutOfMemoryError", NULL);
  241. }
  242. break;
  243. default:
  244. {
  245.     THROW(env, "java/lang/InternalError", stream->msg);
  246. }
  247. break;
  248.     }
  249.     
  250.     return no_decompressed_bytes;
  251. }
  252. JNIEXPORT jlong JNICALL
  253. Java_org_apache_hadoop_io_compress_zlib_ZlibDecompressor_getBytesRead(
  254. JNIEnv *env, jclass cls, jlong stream
  255. ) {
  256.     return (ZSTREAM(stream))->total_in;
  257. }
  258. JNIEXPORT jlong JNICALL
  259. Java_org_apache_hadoop_io_compress_zlib_ZlibDecompressor_getBytesWritten(
  260. JNIEnv *env, jclass cls, jlong stream
  261. ) {
  262.     return (ZSTREAM(stream))->total_out;
  263. }
  264. JNIEXPORT void JNICALL
  265. Java_org_apache_hadoop_io_compress_zlib_ZlibDecompressor_reset(
  266. JNIEnv *env, jclass cls, jlong stream
  267. ) {
  268.     if (dlsym_inflateReset(ZSTREAM(stream)) != Z_OK) {
  269. THROW(env, "java/lang/InternalError", 0);
  270.     }
  271. }
  272. JNIEXPORT void JNICALL
  273. Java_org_apache_hadoop_io_compress_zlib_ZlibDecompressor_end(
  274. JNIEnv *env, jclass cls, jlong stream
  275. ) {
  276.     if (dlsym_inflateEnd(ZSTREAM(stream)) == Z_STREAM_ERROR) {
  277. THROW(env, "java/lang/InternalError", 0);
  278.     } else {
  279. free(ZSTREAM(stream));
  280.     }
  281. }
  282. /**
  283.  * vim: sw=2: ts=2: et:
  284.  */