Path: blob/master/src/java.base/share/native/libzip/Deflater.c
41149 views
/*1* Copyright (c) 1997, 2020, Oracle and/or its affiliates. All rights reserved.2* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.3*4* This code is free software; you can redistribute it and/or modify it5* under the terms of the GNU General Public License version 2 only, as6* published by the Free Software Foundation. Oracle designates this7* particular file as subject to the "Classpath" exception as provided8* by Oracle in the LICENSE file that accompanied this code.9*10* This code is distributed in the hope that it will be useful, but WITHOUT11* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or12* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License13* version 2 for more details (a copy is included in the LICENSE file that14* accompanied this code).15*16* You should have received a copy of the GNU General Public License version17* 2 along with this work; if not, write to the Free Software Foundation,18* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.19*20* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA21* or visit www.oracle.com if you need additional information or have any22* questions.23*/2425/*26* Native method support for java.util.zip.Deflater27*/2829#include <stdio.h>30#include <stdlib.h>31#include "jlong.h"32#include "jni.h"33#include "jni_util.h"34#include <zlib.h>3536#include "java_util_zip_Deflater.h"3738#define DEF_MEM_LEVEL 83940JNIEXPORT jlong JNICALL41Java_java_util_zip_Deflater_init(JNIEnv *env, jclass cls, jint level,42jint strategy, jboolean nowrap)43{44z_stream *strm = calloc(1, sizeof(z_stream));4546if (strm == 0) {47JNU_ThrowOutOfMemoryError(env, 0);48return jlong_zero;49} else {50const char *msg;51int ret = deflateInit2(strm, level, Z_DEFLATED,52nowrap ? -MAX_WBITS : MAX_WBITS,53DEF_MEM_LEVEL, strategy);54switch (ret) {55case Z_OK:56return ptr_to_jlong(strm);57case Z_MEM_ERROR:58free(strm);59JNU_ThrowOutOfMemoryError(env, 0);60return jlong_zero;61case Z_STREAM_ERROR:62free(strm);63JNU_ThrowIllegalArgumentException(env, 0);64return jlong_zero;65default:66msg = ((strm->msg != NULL) ? strm->msg :67(ret == Z_VERSION_ERROR) ?68"zlib returned Z_VERSION_ERROR: "69"compile time and runtime zlib implementations differ" :70"unknown error initializing zlib library");71free(strm);72JNU_ThrowInternalError(env, msg);73return jlong_zero;74}75}76}7778static void throwInternalErrorHelper(JNIEnv *env, z_stream *strm, const char *fixmsg) {79const char *msg = NULL;80msg = (strm->msg != NULL) ? strm->msg : fixmsg;81JNU_ThrowInternalError(env, msg);82}8384static void checkSetDictionaryResult(JNIEnv *env, jlong addr, jint res)85{86z_stream *strm = (z_stream *) jlong_to_ptr(addr);87switch (res) {88case Z_OK:89break;90case Z_STREAM_ERROR:91JNU_ThrowIllegalArgumentException(env, 0);92break;93default:94throwInternalErrorHelper(env, strm, "unknown error in checkSetDictionaryResult");95break;96}97}9899JNIEXPORT void JNICALL100Java_java_util_zip_Deflater_setDictionary(JNIEnv *env, jclass cls, jlong addr,101jbyteArray b, jint off, jint len)102{103int res;104Bytef *buf = (*env)->GetPrimitiveArrayCritical(env, b, 0);105if (buf == NULL) /* out of memory */106return;107res = deflateSetDictionary(jlong_to_ptr(addr), buf + off, len);108(*env)->ReleasePrimitiveArrayCritical(env, b, buf, 0);109checkSetDictionaryResult(env, addr, res);110}111112JNIEXPORT void JNICALL113Java_java_util_zip_Deflater_setDictionaryBuffer(JNIEnv *env, jclass cls, jlong addr,114jlong bufferAddr, jint len)115{116int res;117Bytef *buf = jlong_to_ptr(bufferAddr);118res = deflateSetDictionary(jlong_to_ptr(addr), buf, len);119checkSetDictionaryResult(env, addr, res);120}121122static jint doDeflate(JNIEnv *env, jlong addr,123jbyte *input, jint inputLen,124jbyte *output, jint outputLen,125jint flush, jint params)126{127z_stream *strm = jlong_to_ptr(addr);128int setParams = params & 1;129int res;130131strm->next_in = (Bytef *) input;132strm->next_out = (Bytef *) output;133strm->avail_in = inputLen;134strm->avail_out = outputLen;135136if (setParams) {137int strategy = (params >> 1) & 3;138int level = params >> 3;139res = deflateParams(strm, level, strategy);140} else {141res = deflate(strm, flush);142}143return res;144}145146static jlong checkDeflateStatus(JNIEnv *env, jlong addr,147jint inputLen,148jint outputLen,149jint params, int res)150{151z_stream *strm = jlong_to_ptr(addr);152jint inputUsed = 0, outputUsed = 0;153int finished = 0;154int setParams = params & 1;155156if (setParams) {157switch (res) {158case Z_OK:159setParams = 0;160/* fall through */161case Z_BUF_ERROR:162inputUsed = inputLen - strm->avail_in;163outputUsed = outputLen - strm->avail_out;164break;165default:166throwInternalErrorHelper(env, strm, "unknown error in checkDeflateStatus, setParams case");167return 0;168}169} else {170switch (res) {171case Z_STREAM_END:172finished = 1;173/* fall through */174case Z_OK:175case Z_BUF_ERROR:176inputUsed = inputLen - strm->avail_in;177outputUsed = outputLen - strm->avail_out;178break;179default:180throwInternalErrorHelper(env, strm, "unknown error in checkDeflateStatus");181return 0;182}183}184return ((jlong)inputUsed) | (((jlong)outputUsed) << 31) | (((jlong)finished) << 62) | (((jlong)setParams) << 63);185}186187JNIEXPORT jlong JNICALL188Java_java_util_zip_Deflater_deflateBytesBytes(JNIEnv *env, jobject this, jlong addr,189jbyteArray inputArray, jint inputOff, jint inputLen,190jbyteArray outputArray, jint outputOff, jint outputLen,191jint flush, jint params)192{193jbyte *input = (*env)->GetPrimitiveArrayCritical(env, inputArray, 0);194jbyte *output;195jlong retVal;196jint res;197198if (input == NULL) {199if (inputLen != 0 && (*env)->ExceptionOccurred(env) == NULL)200JNU_ThrowOutOfMemoryError(env, 0);201return 0L;202}203output = (*env)->GetPrimitiveArrayCritical(env, outputArray, 0);204if (output == NULL) {205(*env)->ReleasePrimitiveArrayCritical(env, inputArray, input, 0);206if (outputLen != 0 && (*env)->ExceptionOccurred(env) == NULL)207JNU_ThrowOutOfMemoryError(env, 0);208return 0L;209}210211res = doDeflate(env, addr, input + inputOff, inputLen,output + outputOff,212outputLen, flush, params);213214(*env)->ReleasePrimitiveArrayCritical(env, outputArray, output, 0);215(*env)->ReleasePrimitiveArrayCritical(env, inputArray, input, 0);216217retVal = checkDeflateStatus(env, addr, inputLen, outputLen, params, res);218return retVal;219}220221222JNIEXPORT jlong JNICALL223Java_java_util_zip_Deflater_deflateBytesBuffer(JNIEnv *env, jobject this, jlong addr,224jbyteArray inputArray, jint inputOff, jint inputLen,225jlong outputBuffer, jint outputLen,226jint flush, jint params)227{228jbyte *input = (*env)->GetPrimitiveArrayCritical(env, inputArray, 0);229jbyte *output;230jlong retVal;231jint res;232if (input == NULL) {233if (inputLen != 0 && (*env)->ExceptionOccurred(env) == NULL)234JNU_ThrowOutOfMemoryError(env, 0);235return 0L;236}237output = jlong_to_ptr(outputBuffer);238239res = doDeflate(env, addr, input + inputOff, inputLen, output, outputLen,240flush, params);241242(*env)->ReleasePrimitiveArrayCritical(env, inputArray, input, 0);243244retVal = checkDeflateStatus(env, addr, inputLen, outputLen, params, res);245return retVal;246}247248JNIEXPORT jlong JNICALL249Java_java_util_zip_Deflater_deflateBufferBytes(JNIEnv *env, jobject this, jlong addr,250jlong inputBuffer, jint inputLen,251jbyteArray outputArray, jint outputOff, jint outputLen,252jint flush, jint params)253{254jbyte *input = jlong_to_ptr(inputBuffer);255jbyte *output = (*env)->GetPrimitiveArrayCritical(env, outputArray, 0);256jlong retVal;257jint res;258if (output == NULL) {259if (outputLen != 0 && (*env)->ExceptionOccurred(env) == NULL)260JNU_ThrowOutOfMemoryError(env, 0);261return 0L;262}263264res = doDeflate(env, addr, input, inputLen, output + outputOff, outputLen,265flush, params);266(*env)->ReleasePrimitiveArrayCritical(env, outputArray, output, 0);267268retVal = checkDeflateStatus(env, addr, inputLen, outputLen, params, res);269return retVal;270}271272JNIEXPORT jlong JNICALL273Java_java_util_zip_Deflater_deflateBufferBuffer(JNIEnv *env, jobject this, jlong addr,274jlong inputBuffer, jint inputLen,275jlong outputBuffer, jint outputLen,276jint flush, jint params)277{278jbyte *input = jlong_to_ptr(inputBuffer);279jbyte *output = jlong_to_ptr(outputBuffer);280jlong retVal;281jint res;282283res = doDeflate(env, addr, input, inputLen, output, outputLen, flush, params);284retVal = checkDeflateStatus(env, addr, inputLen, outputLen, params, res);285return retVal;286}287288JNIEXPORT jint JNICALL289Java_java_util_zip_Deflater_getAdler(JNIEnv *env, jclass cls, jlong addr)290{291return ((z_stream *)jlong_to_ptr(addr))->adler;292}293294JNIEXPORT void JNICALL295Java_java_util_zip_Deflater_reset(JNIEnv *env, jclass cls, jlong addr)296{297if (deflateReset((z_stream *)jlong_to_ptr(addr)) != Z_OK) {298JNU_ThrowInternalError(env, "deflateReset failed");299}300}301302JNIEXPORT void JNICALL303Java_java_util_zip_Deflater_end(JNIEnv *env, jclass cls, jlong addr)304{305if (deflateEnd((z_stream *)jlong_to_ptr(addr)) == Z_STREAM_ERROR) {306JNU_ThrowInternalError(env, "deflateEnd failed");307} else {308free((z_stream *)jlong_to_ptr(addr));309}310}311312313