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

网格计算

开发平台:

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_ZlibCompressor.h"
  43. static jfieldID ZlibCompressor_clazz;
  44. static jfieldID ZlibCompressor_stream;
  45. static jfieldID ZlibCompressor_uncompressedDirectBuf;
  46. static jfieldID ZlibCompressor_uncompressedDirectBufOff;
  47. static jfieldID ZlibCompressor_uncompressedDirectBufLen;
  48. static jfieldID ZlibCompressor_compressedDirectBuf;
  49. static jfieldID ZlibCompressor_directBufferSize;
  50. static jfieldID ZlibCompressor_finish;
  51. static jfieldID ZlibCompressor_finished;
  52. static int (*dlsym_deflateInit2_)(z_streamp, int, int, int, int, int, const char *, int);
  53. static int (*dlsym_deflate)(z_streamp, int);
  54. static int (*dlsym_deflateSetDictionary)(z_streamp, const Bytef *, uInt);
  55. static int (*dlsym_deflateReset)(z_streamp);
  56. static int (*dlsym_deflateEnd)(z_streamp);
  57. JNIEXPORT void JNICALL
  58. Java_org_apache_hadoop_io_compress_zlib_ZlibCompressor_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. }
  67. // Locate the requisite symbols from libz.so
  68. dlerror();                                 // Clear any existing error
  69. LOAD_DYNAMIC_SYMBOL(dlsym_deflateInit2_, env, libz, "deflateInit2_");
  70. LOAD_DYNAMIC_SYMBOL(dlsym_deflate, env, libz, "deflate");
  71. LOAD_DYNAMIC_SYMBOL(dlsym_deflateSetDictionary, env, libz, "deflateSetDictionary");
  72. LOAD_DYNAMIC_SYMBOL(dlsym_deflateReset, env, libz, "deflateReset");
  73. LOAD_DYNAMIC_SYMBOL(dlsym_deflateEnd, env, libz, "deflateEnd");
  74. // Initialize the requisite fieldIds
  75.     ZlibCompressor_clazz = (*env)->GetStaticFieldID(env, class, "clazz", 
  76.                                                       "Ljava/lang/Class;");
  77.     ZlibCompressor_stream = (*env)->GetFieldID(env, class, "stream", "J");
  78.     ZlibCompressor_finish = (*env)->GetFieldID(env, class, "finish", "Z");
  79.     ZlibCompressor_finished = (*env)->GetFieldID(env, class, "finished", "Z");
  80.     ZlibCompressor_uncompressedDirectBuf = (*env)->GetFieldID(env, class, 
  81.      "uncompressedDirectBuf", 
  82.      "Ljava/nio/Buffer;");
  83.     ZlibCompressor_uncompressedDirectBufOff = (*env)->GetFieldID(env, class, 
  84.      "uncompressedDirectBufOff", "I");
  85.     ZlibCompressor_uncompressedDirectBufLen = (*env)->GetFieldID(env, class, 
  86.      "uncompressedDirectBufLen", "I");
  87.     ZlibCompressor_compressedDirectBuf = (*env)->GetFieldID(env, class, 
  88.      "compressedDirectBuf", 
  89.      "Ljava/nio/Buffer;");
  90.     ZlibCompressor_directBufferSize = (*env)->GetFieldID(env, class, 
  91.      "directBufferSize", "I");
  92. }
  93. JNIEXPORT jlong JNICALL
  94. Java_org_apache_hadoop_io_compress_zlib_ZlibCompressor_init(
  95. JNIEnv *env, jclass class, jint level, jint strategy, jint windowBits
  96. ) {
  97. // Create a z_stream
  98.     z_stream *stream = malloc(sizeof(z_stream));
  99.     if (!stream) {
  100. THROW(env, "java/lang/OutOfMemoryError", NULL);
  101. return (jlong)0;
  102.     }
  103.     memset((void*)stream, 0, sizeof(z_stream));
  104. // Initialize stream
  105. static const int memLevel = 8;  // See zconf.h
  106.     int rv = (*dlsym_deflateInit2_)(stream, level, Z_DEFLATED, windowBits,
  107.      memLevel, strategy, ZLIB_VERSION, sizeof(z_stream));
  108.     
  109.     if (rv != Z_OK) {
  110.     // Contingency - Report error by throwing appropriate exceptions
  111.     free(stream);
  112.     stream = NULL;
  113. switch (rv) {
  114. case Z_MEM_ERROR: 
  115.     {
  116.      THROW(env, "java/lang/OutOfMemoryError", NULL);
  117.     }
  118. break;
  119. case Z_STREAM_ERROR:
  120.      {
  121.      THROW(env, "java/lang/IllegalArgumentException", NULL);
  122.      }
  123.     break;
  124. default:
  125.      {
  126.      THROW(env, "java/lang/InternalError", NULL);
  127.      }
  128.     break;
  129.     }
  130. }
  131.     return JLONG(stream);
  132. }
  133. JNIEXPORT void JNICALL
  134. Java_org_apache_hadoop_io_compress_ZlibCompressor_setDictionary(
  135. JNIEnv *env, jclass class, jlong stream, 
  136. jarray b, jint off, jint len
  137. ) {
  138.     Bytef *buf = (*env)->GetPrimitiveArrayCritical(env, b, 0);
  139.     if (!buf) {
  140.         return;
  141.     }
  142.     int rv = dlsym_deflateSetDictionary(ZSTREAM(stream), buf + off, len);
  143.     (*env)->ReleasePrimitiveArrayCritical(env, b, buf, 0);
  144.     
  145.     if (rv != Z_OK) {
  146.      // Contingency - Report error by throwing appropriate exceptions
  147.     switch (rv) {
  148.     case Z_STREAM_ERROR:
  149. {
  150.      THROW(env, "java/lang/IllegalArgumentException", NULL);
  151. }
  152. break;
  153.      default:
  154. {
  155. THROW(env, "java/lang/InternalError", (ZSTREAM(stream))->msg);
  156. }
  157. break;
  158.     }
  159.     }
  160. }
  161. JNIEXPORT jint JNICALL
  162. Java_org_apache_hadoop_io_compress_zlib_ZlibCompressor_deflateBytesDirect(
  163. JNIEnv *env, jobject this
  164. ) {
  165. // Get members of ZlibCompressor
  166.     z_stream *stream = ZSTREAM(
  167.      (*env)->GetLongField(env, this, 
  168.      ZlibCompressor_stream)
  169.      );
  170.     if (!stream) {
  171. THROW(env, "java/lang/NullPointerException", NULL);
  172. return (jint)0;
  173.     } 
  174.     // Get members of ZlibCompressor
  175.     jobject clazz = (*env)->GetStaticObjectField(env, this, 
  176.                                                  ZlibCompressor_clazz);
  177. jobject uncompressed_direct_buf = (*env)->GetObjectField(env, this, 
  178. ZlibCompressor_uncompressedDirectBuf);
  179. jint uncompressed_direct_buf_off = (*env)->GetIntField(env, this, 
  180. ZlibCompressor_uncompressedDirectBufOff);
  181. jint uncompressed_direct_buf_len = (*env)->GetIntField(env, this, 
  182. ZlibCompressor_uncompressedDirectBufLen);
  183. jobject compressed_direct_buf = (*env)->GetObjectField(env, this, 
  184. ZlibCompressor_compressedDirectBuf);
  185. jint compressed_direct_buf_len = (*env)->GetIntField(env, this, 
  186. ZlibCompressor_directBufferSize);
  187. jboolean finish = (*env)->GetBooleanField(env, this, ZlibCompressor_finish);
  188.     // Get the input direct buffer
  189.     LOCK_CLASS(env, clazz, "ZlibCompressor");
  190. Bytef* uncompressed_bytes = (*env)->GetDirectBufferAddress(env, 
  191. uncompressed_direct_buf);
  192.     UNLOCK_CLASS(env, clazz, "ZlibCompressor");
  193.     
  194.    if (uncompressed_bytes == 0) {
  195.      return (jint)0;
  196. }
  197.     // Get the output direct buffer
  198.     LOCK_CLASS(env, clazz, "ZlibCompressor");
  199. Bytef* compressed_bytes = (*env)->GetDirectBufferAddress(env, 
  200. compressed_direct_buf);
  201.     UNLOCK_CLASS(env, clazz, "ZlibCompressor");
  202.    if (compressed_bytes == 0) {
  203. return (jint)0;
  204. }
  205. // Re-calibrate the z_stream
  206.    stream->next_in = uncompressed_bytes + uncompressed_direct_buf_off;
  207.    stream->next_out = compressed_bytes;
  208.    stream->avail_in = uncompressed_direct_buf_len;
  209. stream->avail_out = compressed_direct_buf_len;
  210. // Compress
  211. int rv = dlsym_deflate(stream, finish ? Z_FINISH : Z_NO_FLUSH);
  212. jint no_compressed_bytes = 0;
  213. switch (rv) {
  214.      // Contingency? - Report error by throwing appropriate exceptions
  215.    case Z_STREAM_END:
  216.    {
  217.    (*env)->SetBooleanField(env, this, ZlibCompressor_finished, JNI_TRUE);
  218.    } // cascade
  219.    case Z_OK: 
  220.    {
  221.    uncompressed_direct_buf_off += uncompressed_direct_buf_len - stream->avail_in;
  222. (*env)->SetIntField(env, this, 
  223. ZlibCompressor_uncompressedDirectBufOff, uncompressed_direct_buf_off);
  224. (*env)->SetIntField(env, this, 
  225. ZlibCompressor_uncompressedDirectBufLen, stream->avail_in);
  226. no_compressed_bytes = compressed_direct_buf_len - stream->avail_out;
  227.    }
  228.    break;
  229.    case Z_BUF_ERROR:
  230.    break;
  231.    default:
  232. {
  233. THROW(env, "java/lang/InternalError", stream->msg);
  234. }
  235. break;
  236.    }
  237.   
  238.    return no_compressed_bytes;
  239. }
  240. JNIEXPORT jlong JNICALL
  241. Java_org_apache_hadoop_io_compress_zlib_ZlibCompressor_getBytesRead(
  242. JNIEnv *env, jclass class, jlong stream
  243. ) {
  244.     return (ZSTREAM(stream))->total_in;
  245. }
  246. JNIEXPORT jlong JNICALL
  247. Java_org_apache_hadoop_io_compress_zlib_ZlibCompressor_getBytesWritten(
  248. JNIEnv *env, jclass class, jlong stream
  249. ) {
  250.     return (ZSTREAM(stream))->total_out;
  251. }
  252. JNIEXPORT void JNICALL
  253. Java_org_apache_hadoop_io_compress_zlib_ZlibCompressor_reset(
  254. JNIEnv *env, jclass class, jlong stream
  255. ) {
  256.     if (dlsym_deflateReset(ZSTREAM(stream)) != Z_OK) {
  257. THROW(env, "java/lang/InternalError", NULL);
  258.     }
  259. }
  260. JNIEXPORT void JNICALL
  261. Java_org_apache_hadoop_io_compress_zlib_ZlibCompressor_end(
  262. JNIEnv *env, jclass class, jlong stream
  263. ) {
  264.     if (dlsym_deflateEnd(ZSTREAM(stream)) == Z_STREAM_ERROR) {
  265. THROW(env, "java/lang/InternalError", NULL);
  266.     } else {
  267. free(ZSTREAM(stream));
  268.     }
  269. }
  270. /**
  271.  * vim: sw=2: ts=2: et:
  272.  */