diff options
author | Sebastian Rasmussen <sebras@gmail.com> | 2016-07-17 16:49:34 +0800 |
---|---|---|
committer | Sebastian Rasmussen <sebras@gmail.com> | 2016-07-17 22:33:52 +0800 |
commit | 90bf2e01390bf77c91034dec06a1e6aabd8235ec (patch) | |
tree | 58f2a241b314e4b77968f9bc2c296a83de1971ae | |
parent | 8625af9d32111e555eef595d6fcca739b0249253 (diff) | |
download | mupdf-90bf2e01390bf77c91034dec06a1e6aabd8235ec.tar.xz |
JNI: Extend Buffer interface, especially for reading.
-rw-r--r-- | platform/java/mupdf_native.c | 135 | ||||
-rw-r--r-- | platform/java/mupdf_native.h | 32 | ||||
-rw-r--r-- | platform/java/src/com/artifex/mupdf/fitz/Buffer.java | 5 |
3 files changed, 166 insertions, 6 deletions
diff --git a/platform/java/mupdf_native.c b/platform/java/mupdf_native.c index d7870c0a..332f87ab 100644 --- a/platform/java/mupdf_native.c +++ b/platform/java/mupdf_native.c @@ -60,9 +60,11 @@ static jclass cls_DocumentWriter; static jclass cls_Exception; static jclass cls_Font; static jclass cls_Image; +static jclass cls_IndexOutOfBoundsException; static jclass cls_Link; static jclass cls_Matrix; static jclass cls_NativeDevice; +static jclass cls_NullPointerException; static jclass cls_Object; static jclass cls_OutOfMemoryError; static jclass cls_Outline; @@ -445,6 +447,8 @@ static int find_fids(JNIEnv *env) mid_Object_toString = get_method(&err, env, "toString", "()Ljava/lang/String;"); cls_Exception = get_class(&err, env, "java/lang/Exception"); + cls_IndexOutOfBoundsException = get_class(&err, env, "java/lang/IndexOutOfBoundsException"); + cls_NullPointerException = get_class(&err, env, "java/lang/NullPointerException"); cls_OutOfMemoryError = get_class(&err, env, "java/lang/OutOfMemoryError"); @@ -462,9 +466,11 @@ static void lose_fids(JNIEnv *env) (*env)->DeleteGlobalRef(env, cls_Exception); (*env)->DeleteGlobalRef(env, cls_Font); (*env)->DeleteGlobalRef(env, cls_Image); + (*env)->DeleteGlobalRef(env, cls_IndexOutOfBoundsException); (*env)->DeleteGlobalRef(env, cls_Link); (*env)->DeleteGlobalRef(env, cls_Matrix); (*env)->DeleteGlobalRef(env, cls_NativeDevice); + (*env)->DeleteGlobalRef(env, cls_NullPointerException); (*env)->DeleteGlobalRef(env, cls_Object); (*env)->DeleteGlobalRef(env, cls_OutOfMemoryError); (*env)->DeleteGlobalRef(env, cls_Outline); @@ -4343,6 +4349,88 @@ FUN(Buffer_getLength)(JNIEnv *env, jobject self) return buf->len; } +JNIEXPORT jint JNICALL +FUN(Buffer_readByte)(JNIEnv *env, jobject self, jint jat) +{ + fz_context *ctx = get_context(env); + fz_buffer *buf = from_Buffer(env, self); + size_t at = (size_t) jat; + + if (ctx == NULL || buf == NULL || jat < 0) + return -1; + + if (at >= buf->len) + return -1; + + return buf->data[at]; +} + +JNIEXPORT jint JNICALL +FUN(Buffer_readBytes)(JNIEnv *env, jobject self, jint jat, jobject jbs) +{ + fz_context *ctx = get_context(env); + fz_buffer *buf = from_Buffer(env, self); + size_t at = (size_t) jat; + jbyte *bs = NULL; + size_t len = 0; + size_t remaining_input = 0; + size_t remaining_output = 0; + + if (ctx == NULL || buf == NULL || jat < 0 || jbs == NULL) + return -1; + + if (at >= buf->len) + return -1; + + remaining_input = buf->len - at; + remaining_output = (*env)->GetArrayLength(env, jbs); + len = fz_mini(0, remaining_output); + len = fz_mini(len, remaining_input); + + bs = (*env)->GetByteArrayElements(env, jbs, NULL); + memcpy(bs, &buf->data[at], len); + (*env)->ReleaseByteArrayElements(env, jbs, bs, JNI_ABORT); + + return len; +} + +JNIEXPORT jint JNICALL +FUN(Buffer_readBytesInto)(JNIEnv *env, jobject self, jint jat, jobject jbs, jint joff, jint jlen) +{ + fz_context *ctx = get_context(env); + fz_buffer *buf = from_Buffer(env, self); + size_t at = (size_t) jat; + jbyte *bs = NULL; + jsize off = (jsize) joff; + jsize len = (jsize) jlen; + jsize bslen = 0; + + if (ctx == NULL || buf == NULL || jat < 0) + return -1; + + if (jbs == NULL) + (*env)->ThrowNew(env, cls_NullPointerException, "buffer is null"); + + bslen = (*env)->GetArrayLength(env, jbs); + if (joff < 0) + (*env)->ThrowNew(env, cls_IndexOutOfBoundsException, "offset is negative"); + if (jlen < 0) + (*env)->ThrowNew(env, cls_IndexOutOfBoundsException, "length is negative"); + if (len > bslen - off) + (*env)->ThrowNew(env, cls_IndexOutOfBoundsException, "offset + length is outside of buffer"); + + if (at >= buf->len) + return -1; + + len = fz_mini(len, buf->len - at); + + bs = (*env)->GetByteArrayElements(env, jbs, NULL); + memcpy(&bs[off], &buf->data[at], len); + (*env)->ReleaseByteArrayElements(env, jbs, bs, JNI_ABORT); + + return len; +} + JNIEXPORT void JNICALL FUN(Buffer_writeByte)(JNIEnv *env, jobject self, jbyte b) { @@ -4363,23 +4451,58 @@ FUN(Buffer_writeBytes)(JNIEnv *env, jobject self, jobject jbs) { fz_context *ctx = get_context(env); fz_buffer *buf = from_Buffer(env, self); + jsize len = 0; jbyte *bs = NULL; - int n = 0; if (ctx == NULL || buf == NULL || jbs == NULL) return; - n = (*env)->GetArrayLength(env, jbs); + len = (*env)->GetArrayLength(env, jbs); + bs = (*env)->GetByteArrayElements(env, jbs, NULL); + + fz_try(ctx) + fz_write_buffer(ctx, buf, bs, len); + fz_always(ctx) + (*env)->ReleaseByteArrayElements(env, jbs, bs, JNI_ABORT); + fz_catch(ctx) + jni_rethrow(env, ctx); +} + +JNIEXPORT void JNICALL +FUN(Buffer_writeBytesFrom)(JNIEnv *env, jobject self, jobject jbs, jint joff, jint jlen) +{ + fz_context *ctx = get_context(env); + fz_buffer *buf = from_Buffer(env, self); + jbyte *bs = NULL; + jsize off = (jsize) joff; + jsize len = (jsize) jlen; + jsize bslen = 0; + + if (ctx == NULL || buf == NULL) + return; + + if (jbs == NULL) + (*env)->ThrowNew(env, cls_NullPointerException, "buffer is null"); + + bslen = (*env)->GetArrayLength(env, jbs); + if (joff < 0) + (*env)->ThrowNew(env, cls_IndexOutOfBoundsException, "offset is negative"); + if (jlen < 0) + (*env)->ThrowNew(env, cls_IndexOutOfBoundsException, "length is negative"); + if (off + len >= bslen) + (*env)->ThrowNew(env, cls_IndexOutOfBoundsException, "offset + length is outside of buffer"); + bs = (*env)->GetByteArrayElements(env, jbs, NULL); fz_try(ctx) - fz_write_buffer(ctx, buf, bs, n); + fz_write_buffer(ctx, buf, &bs[off], len); fz_always(ctx) (*env)->ReleaseByteArrayElements(env, jbs, bs, JNI_ABORT); fz_catch(ctx) jni_rethrow(env, ctx); } + JNIEXPORT void JNICALL FUN(Buffer_writeBuffer)(JNIEnv *env, jobject self, jobject jbuf) { @@ -4442,14 +4565,14 @@ FUN(Buffer_writeLines)(JNIEnv *env, jobject self, jobject jlines) fz_context *ctx = get_context(env); fz_buffer *buf = from_Buffer(env, self); int i = 0; - int n = 0; + jsize len = 0; if (ctx == NULL || buf == NULL || jlines == NULL) return; - n = (*env)->GetArrayLength(env, jlines); + len = (*env)->GetArrayLength(env, jlines); - for (i = 0; i < n; ++i) + for (i = 0; i < len; ++i) { jobject jline = (*env)->GetObjectArrayElement(env, jlines, i); const char *line = NULL; diff --git a/platform/java/mupdf_native.h b/platform/java/mupdf_native.h index e56e43af..e3902a21 100644 --- a/platform/java/mupdf_native.h +++ b/platform/java/mupdf_native.h @@ -94,6 +94,30 @@ JNIEXPORT jint JNICALL Java_com_artifex_mupdf_fitz_Buffer_getLength /* * Class: com_artifex_mupdf_fitz_Buffer + * Method: readByte + * Signature: (I)I + */ +JNIEXPORT jint JNICALL Java_com_artifex_mupdf_fitz_Buffer_readByte + (JNIEnv *, jobject, jint); + +/* + * Class: com_artifex_mupdf_fitz_Buffer + * Method: readBytes + * Signature: (I[B)I + */ +JNIEXPORT jint JNICALL Java_com_artifex_mupdf_fitz_Buffer_readBytes + (JNIEnv *, jobject, jint, jbyteArray); + +/* + * Class: com_artifex_mupdf_fitz_Buffer + * Method: readBytesInto + * Signature: (I[BII)I + */ +JNIEXPORT jint JNICALL Java_com_artifex_mupdf_fitz_Buffer_readBytesInto + (JNIEnv *, jobject, jint, jbyteArray, jint, jint); + +/* + * Class: com_artifex_mupdf_fitz_Buffer * Method: writeByte * Signature: (B)V */ @@ -110,6 +134,14 @@ JNIEXPORT void JNICALL Java_com_artifex_mupdf_fitz_Buffer_writeBytes /* * Class: com_artifex_mupdf_fitz_Buffer + * Method: writeBytesFrom + * Signature: ([BII)V + */ +JNIEXPORT void JNICALL Java_com_artifex_mupdf_fitz_Buffer_writeBytesFrom + (JNIEnv *, jobject, jbyteArray, jint, jint); + +/* + * Class: com_artifex_mupdf_fitz_Buffer * Method: writeBuffer * Signature: (Lcom/artifex/mupdf/fitz/Buffer;)V */ diff --git a/platform/java/src/com/artifex/mupdf/fitz/Buffer.java b/platform/java/src/com/artifex/mupdf/fitz/Buffer.java index 7f23b062..c98e9985 100644 --- a/platform/java/src/com/artifex/mupdf/fitz/Buffer.java +++ b/platform/java/src/com/artifex/mupdf/fitz/Buffer.java @@ -28,8 +28,13 @@ public class Buffer } public native int getLength(); + public native int readByte(int at); + public native int readBytes(int at, byte[] bs); + public native int readBytesInto(int at, byte[] bs, int off, int len); + public native void writeByte(byte b); public native void writeBytes(byte[] bs); + public native void writeBytesFrom(byte[] bs, int off, int len); public native void writeBuffer(Buffer buf); public native void writeRune(int rune); public native void writeLine(String line); |