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 #include "ZipUtilities.h"
19 
20 #include <nativehelper/JNIHelp.h>
21 
22 #include "JniException.h"
23 
throwExceptionForZlibError(JNIEnv * env,const char * exceptionClassName,int error,NativeZipStream * stream)24 void throwExceptionForZlibError(JNIEnv* env, const char* exceptionClassName, int error,
25     NativeZipStream* stream) {
26   if (error == Z_MEM_ERROR) {
27     jniThrowOutOfMemoryError(env, NULL);
28   } else if (stream != NULL && stream->stream.msg != NULL) {
29     jniThrowException(env, exceptionClassName, stream->stream.msg);
30   } else {
31     jniThrowException(env, exceptionClassName, zError(error));
32   }
33 }
34 
NativeZipStream()35 NativeZipStream::NativeZipStream() : inCap(0), totalIn(0), totalOut(0) {
36   // Let zlib use its default allocator.
37   stream.opaque = Z_NULL;
38   stream.zalloc = Z_NULL;
39   stream.zfree = Z_NULL;
40 }
41 
~NativeZipStream()42 NativeZipStream::~NativeZipStream() {
43 }
44 
setDictionary(JNIEnv * env,jbyteArray javaDictionary,int off,int len,bool inflate)45 void NativeZipStream::setDictionary(JNIEnv* env, jbyteArray javaDictionary, int off, int len,
46     bool inflate) {
47   std::unique_ptr<jbyte[]> dictionaryBytes(new jbyte[len]);
48   if (dictionaryBytes.get() == NULL) {
49     jniThrowOutOfMemoryError(env, NULL);
50     return;
51   }
52   env->GetByteArrayRegion(javaDictionary, off, len, &dictionaryBytes[0]);
53   const Bytef* dictionary = reinterpret_cast<const Bytef*>(&dictionaryBytes[0]);
54   int err;
55   if (inflate) {
56     err = inflateSetDictionary(&stream, dictionary, len);
57   } else {
58     err = deflateSetDictionary(&stream, dictionary, len);
59   }
60   if (err != Z_OK) {
61     throwExceptionForZlibError(env, "java/lang/IllegalArgumentException", err, NULL);
62     return;
63   }
64   mDict.reset(dictionaryBytes.release());
65 }
66 
setInput(JNIEnv * env,jbyteArray buf,jint off,jint len)67 void NativeZipStream::setInput(JNIEnv* env, jbyteArray buf, jint off, jint len) {
68   input.reset(new jbyte[len]);
69   if (input.get() == NULL) {
70     inCap = 0;
71     jniThrowOutOfMemoryError(env, NULL);
72     return;
73   }
74   inCap = len;
75   if (buf != NULL) {
76     env->GetByteArrayRegion(buf, off, len, &input[0]);
77   }
78   stream.next_in = reinterpret_cast<Bytef*>(&input[0]);
79   stream.avail_in = len;
80 }
81 
toNativeZipStream(jlong address)82 NativeZipStream* toNativeZipStream(jlong address) {
83   return reinterpret_cast<NativeZipStream*>(static_cast<uintptr_t>(address));
84 }
85