#3693: Compile natives as C instead of C++, check malloc/calloc return values for null
This commit is contained in:
92
native/src/main/c/NativeCompressImpl.c
Normal file
92
native/src/main/c/NativeCompressImpl.c
Normal file
@@ -0,0 +1,92 @@
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
|
||||
#include <zlib.h>
|
||||
#include "shared.h"
|
||||
#include "net_md_5_bungee_jni_zlib_NativeCompressImpl.h"
|
||||
|
||||
typedef unsigned char byte;
|
||||
|
||||
static jclass classID;
|
||||
static jfieldID consumedID;
|
||||
static jfieldID finishedID;
|
||||
static jmethodID makeExceptionID;
|
||||
|
||||
void JNICALL Java_net_md_15_bungee_jni_zlib_NativeCompressImpl_initFields(JNIEnv* env, jclass clazz) {
|
||||
classID = clazz;
|
||||
// We trust that these will be there
|
||||
consumedID = (*env)->GetFieldID(env, clazz, "consumed", "I");
|
||||
finishedID = (*env)->GetFieldID(env, clazz, "finished", "Z");
|
||||
makeExceptionID = (*env)->GetMethodID(env, clazz, "makeException", "(Ljava/lang/String;I)Lnet/md_5/bungee/jni/NativeCodeException;");
|
||||
}
|
||||
|
||||
jint throwException(JNIEnv *env, const char* message, int err) {
|
||||
jstring jMessage = (*env)->NewStringUTF(env, message);
|
||||
jthrowable throwable = (jthrowable) (*env)->CallStaticObjectMethod(env, classID, makeExceptionID, jMessage, err);
|
||||
return (*env)->Throw(env, throwable);
|
||||
}
|
||||
|
||||
void JNICALL Java_net_md_15_bungee_jni_zlib_NativeCompressImpl_reset(JNIEnv* env, jobject obj, jlong ctx, jboolean compress) {
|
||||
z_stream* stream = (z_stream*) ctx;
|
||||
int ret = (compress) ? deflateReset(stream) : inflateReset(stream);
|
||||
|
||||
if (ret != Z_OK) {
|
||||
throwException(env, "Could not reset z_stream", ret);
|
||||
}
|
||||
}
|
||||
|
||||
void JNICALL Java_net_md_15_bungee_jni_zlib_NativeCompressImpl_end(JNIEnv* env, jobject obj, jlong ctx, jboolean compress) {
|
||||
z_stream* stream = (z_stream*) ctx;
|
||||
int ret = (compress) ? deflateEnd(stream) : inflateEnd(stream);
|
||||
|
||||
free(stream);
|
||||
|
||||
if (ret != Z_OK) {
|
||||
throwException(env, "Could not free z_stream: ", ret);
|
||||
}
|
||||
}
|
||||
|
||||
jlong JNICALL Java_net_md_15_bungee_jni_zlib_NativeCompressImpl_init(JNIEnv* env, jobject obj, jboolean compress, jint level) {
|
||||
z_stream* stream = (z_stream*) calloc(1, sizeof (z_stream));
|
||||
if (!stream) {
|
||||
throwOutOfMemoryError(env, "Failed to calloc new z_stream");
|
||||
return 0;
|
||||
}
|
||||
|
||||
int ret = (compress) ? deflateInit(stream, level) : inflateInit(stream);
|
||||
|
||||
if (ret != Z_OK) {
|
||||
free(stream);
|
||||
throwException(env, "Could not init z_stream", ret);
|
||||
return 0;
|
||||
}
|
||||
|
||||
return (jlong) stream;
|
||||
}
|
||||
|
||||
jint JNICALL Java_net_md_15_bungee_jni_zlib_NativeCompressImpl_process(JNIEnv* env, jobject obj, jlong ctx, jlong in, jint inLength, jlong out, jint outLength, jboolean compress) {
|
||||
z_stream* stream = (z_stream*) ctx;
|
||||
|
||||
stream->avail_in = inLength;
|
||||
stream->next_in = (byte*) in;
|
||||
|
||||
stream->avail_out = outLength;
|
||||
stream->next_out = (byte*) out;
|
||||
|
||||
int ret = (compress) ? deflate(stream, Z_FINISH) : inflate(stream, Z_PARTIAL_FLUSH);
|
||||
|
||||
switch (ret) {
|
||||
case Z_STREAM_END:
|
||||
(*env)->SetBooleanField(env, obj, finishedID, JNI_TRUE);
|
||||
break;
|
||||
case Z_OK:
|
||||
break;
|
||||
default:
|
||||
throwException(env, "Unknown z_stream return code", ret);
|
||||
return -1;
|
||||
}
|
||||
|
||||
(*env)->SetIntField(env, obj, consumedID, inLength - stream->avail_in);
|
||||
|
||||
return outLength - stream->avail_out;
|
||||
}
|
Reference in New Issue
Block a user