1 /* 2 * Licensed to the Apache Software Foundation (ASF) under one or more 3 * contributor license agreements. See the NOTICE file distributed with 4 * this work for additional information regarding copyright ownership. 5 * The ASF licenses this file to You under the Apache License, Version 2.0 6 * (the "License"); you may not use this file except in compliance with 7 * the License. You may obtain a copy of the License at 8 * 9 * http://www.apache.org/licenses/LICENSE-2.0 10 * 11 * Unless required by applicable law or agreed to in writing, software 12 * distributed under the License is distributed on an "AS IS" BASIS, 13 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 14 * See the License for the specific language governing permissions and 15 * limitations under the License. 16 */ 17 18 #if !defined(zip_h) 19 #define zip_h 20 21 #include "JNIHelp.h" 22 #include "JniException.h" 23 #include "UniquePtr.h" 24 #include "jni.h" 25 #include "zlib.h" 26 27 static void throwExceptionForZlibError(JNIEnv* env, const char* exceptionClassName, int error) { 28 if (error == Z_MEM_ERROR) { 29 jniThrowOutOfMemoryError(env, NULL); 30 } else { 31 jniThrowException(env, exceptionClassName, zError(error)); 32 } 33 } 34 35 class NativeZipStream { 36 public: 37 UniquePtr<jbyte[]> input; 38 int inCap; 39 z_stream stream; 40 41 NativeZipStream() : input(NULL), inCap(0), mDict(NULL) { 42 // Let zlib use its default allocator. 43 stream.opaque = Z_NULL; 44 stream.zalloc = Z_NULL; 45 stream.zfree = Z_NULL; 46 } 47 48 ~NativeZipStream() { 49 } 50 51 void setDictionary(JNIEnv* env, jbyteArray javaDictionary, int off, int len, bool inflate) { 52 UniquePtr<jbyte[]> dictionaryBytes(new jbyte[len]); 53 if (dictionaryBytes.get() == NULL) { 54 jniThrowOutOfMemoryError(env, NULL); 55 return; 56 } 57 env->GetByteArrayRegion(javaDictionary, off, len, &dictionaryBytes[0]); 58 const Bytef* dictionary = reinterpret_cast<const Bytef*>(&dictionaryBytes[0]); 59 int err; 60 if (inflate) { 61 err = inflateSetDictionary(&stream, dictionary, len); 62 } else { 63 err = deflateSetDictionary(&stream, dictionary, len); 64 } 65 if (err != Z_OK) { 66 throwExceptionForZlibError(env, "java/lang/IllegalArgumentException", err); 67 return; 68 } 69 mDict.reset(dictionaryBytes.release()); 70 } 71 72 void setInput(JNIEnv* env, jbyteArray buf, jint off, jint len) { 73 input.reset(new jbyte[len]); 74 if (input.get() == NULL) { 75 inCap = 0; 76 jniThrowOutOfMemoryError(env, NULL); 77 return; 78 } 79 inCap = len; 80 if (buf != NULL) { 81 env->GetByteArrayRegion(buf, off, len, &input[0]); 82 } 83 stream.next_in = reinterpret_cast<Bytef*>(&input[0]); 84 stream.avail_in = len; 85 } 86 87 private: 88 UniquePtr<jbyte[]> mDict; 89 90 // Disallow copy and assignment. 91 NativeZipStream(const NativeZipStream&); 92 void operator=(const NativeZipStream&); 93 }; 94 95 static NativeZipStream* toNativeZipStream(jlong address) { 96 return reinterpret_cast<NativeZipStream*>(static_cast<uintptr_t>(address)); 97 } 98 99 #endif /* zip_h */ 100