Mercurial > hgrepos > Python2 > PyMuPDF
comparison mupdf-source/platform/java/jni/buffer.c @ 3:2c135c81b16c
MERGE: upstream PyMuPDF 1.26.4 with MuPDF 1.26.7
| author | Franz Glasner <fzglas.hg@dom66.de> |
|---|---|
| date | Mon, 15 Sep 2025 11:44:09 +0200 |
| parents | b50eed0cc0ef |
| children |
comparison
equal
deleted
inserted
replaced
| 0:6015a75abc2d | 3:2c135c81b16c |
|---|---|
| 1 // Copyright (C) 2004-2025 Artifex Software, Inc. | |
| 2 // | |
| 3 // This file is part of MuPDF. | |
| 4 // | |
| 5 // MuPDF is free software: you can redistribute it and/or modify it under the | |
| 6 // terms of the GNU Affero General Public License as published by the Free | |
| 7 // Software Foundation, either version 3 of the License, or (at your option) | |
| 8 // any later version. | |
| 9 // | |
| 10 // MuPDF is distributed in the hope that it will be useful, but WITHOUT ANY | |
| 11 // WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS | |
| 12 // FOR A PARTICULAR PURPOSE. See the GNU Affero General Public License for more | |
| 13 // details. | |
| 14 // | |
| 15 // You should have received a copy of the GNU Affero General Public License | |
| 16 // along with MuPDF. If not, see <https://www.gnu.org/licenses/agpl-3.0.en.html> | |
| 17 // | |
| 18 // Alternative licensing terms are available from the licensor. | |
| 19 // For commercial licensing, see <https://www.artifex.com/> or contact | |
| 20 // Artifex Software, Inc., 39 Mesa Street, Suite 108A, San Francisco, | |
| 21 // CA 94129, USA, for further information. | |
| 22 | |
| 23 /* Buffer interface */ | |
| 24 | |
| 25 JNIEXPORT void JNICALL | |
| 26 FUN(Buffer_finalize)(JNIEnv *env, jobject self) | |
| 27 { | |
| 28 fz_context *ctx = get_context(env); | |
| 29 fz_buffer *buf = from_Buffer_safe(env, self); | |
| 30 if (!ctx || !buf) return; | |
| 31 (*env)->SetLongField(env, self, fid_Buffer_pointer, 0); | |
| 32 fz_drop_buffer(ctx, buf); | |
| 33 } | |
| 34 | |
| 35 JNIEXPORT jlong JNICALL | |
| 36 FUN(Buffer_newNativeBuffer)(JNIEnv *env, jobject self, jint n) | |
| 37 { | |
| 38 fz_context *ctx = get_context(env); | |
| 39 fz_buffer *buf = NULL; | |
| 40 | |
| 41 if (!ctx) return 0; | |
| 42 if (n < 0) jni_throw_arg(env, "n cannot be negative"); | |
| 43 | |
| 44 fz_try(ctx) | |
| 45 buf = fz_new_buffer(ctx, n); | |
| 46 fz_catch(ctx) | |
| 47 jni_rethrow(env, ctx); | |
| 48 | |
| 49 return jlong_cast(buf); | |
| 50 } | |
| 51 | |
| 52 JNIEXPORT jint JNICALL | |
| 53 FUN(Buffer_getLength)(JNIEnv *env, jobject self) | |
| 54 { | |
| 55 fz_context *ctx = get_context(env); | |
| 56 fz_buffer *buf = from_Buffer(env, self); | |
| 57 | |
| 58 if (!ctx || !buf) return -1; | |
| 59 | |
| 60 return (jint)fz_buffer_storage(ctx, buf, NULL); | |
| 61 } | |
| 62 | |
| 63 JNIEXPORT jint JNICALL | |
| 64 FUN(Buffer_readByte)(JNIEnv *env, jobject self, jint jat) | |
| 65 { | |
| 66 fz_context *ctx = get_context(env); | |
| 67 fz_buffer *buf = from_Buffer(env, self); | |
| 68 size_t at = (size_t) jat; | |
| 69 size_t len; | |
| 70 unsigned char *data; | |
| 71 | |
| 72 if (!ctx || !buf) return -1; | |
| 73 if (jat < 0) jni_throw_oob(env, "at is negative"); | |
| 74 | |
| 75 len = fz_buffer_storage(ctx, buf, &data); | |
| 76 if (at >= len) | |
| 77 return -1; | |
| 78 | |
| 79 return data[at]; | |
| 80 } | |
| 81 | |
| 82 JNIEXPORT jint JNICALL | |
| 83 FUN(Buffer_readBytes)(JNIEnv *env, jobject self, jint jat, jobject jbs) | |
| 84 { | |
| 85 fz_context *ctx = get_context(env); | |
| 86 fz_buffer *buf = from_Buffer(env, self); | |
| 87 size_t at = (size_t) jat; | |
| 88 jbyte *bs = NULL; | |
| 89 size_t len; | |
| 90 size_t remaining_input = 0; | |
| 91 size_t remaining_output = 0; | |
| 92 unsigned char *data; | |
| 93 | |
| 94 if (!ctx || !buf) return -1; | |
| 95 if (jat < 0) jni_throw_oob(env, "at is negative"); | |
| 96 if (!jbs) jni_throw_arg(env, "buffer must not be null"); | |
| 97 | |
| 98 len = fz_buffer_storage(ctx, buf, &data); | |
| 99 if (at >= len) | |
| 100 return -1; | |
| 101 | |
| 102 remaining_input = len - at; | |
| 103 remaining_output = (*env)->GetArrayLength(env, jbs); | |
| 104 len = fz_minz(remaining_output, remaining_input); | |
| 105 | |
| 106 bs = (*env)->GetByteArrayElements(env, jbs, NULL); | |
| 107 if (!bs) jni_throw_io(env, "cannot get bytes to read"); | |
| 108 | |
| 109 memcpy(bs, &data[at], len); | |
| 110 (*env)->ReleaseByteArrayElements(env, jbs, bs, 0); | |
| 111 | |
| 112 return (jint)len; | |
| 113 } | |
| 114 | |
| 115 JNIEXPORT jint JNICALL | |
| 116 FUN(Buffer_readBytesInto)(JNIEnv *env, jobject self, jint jat, jobject jbs, jint joff, jint jlen) | |
| 117 { | |
| 118 fz_context *ctx = get_context(env); | |
| 119 fz_buffer *buf = from_Buffer(env, self); | |
| 120 size_t at = (size_t) jat; | |
| 121 jbyte *bs = NULL; | |
| 122 size_t off = (size_t) joff; | |
| 123 size_t len = (size_t) jlen; | |
| 124 size_t bslen = 0; | |
| 125 size_t blen; | |
| 126 unsigned char *data; | |
| 127 | |
| 128 if (!ctx || !buf) return -1; | |
| 129 if (jat < 0) jni_throw_oob(env, "at is negative"); | |
| 130 if (!jbs) jni_throw_arg(env, "buffer must not be null"); | |
| 131 if (joff < 0) jni_throw_oob(env, "offset is negative"); | |
| 132 if (jlen < 0) jni_throw_oob(env, "length is negative"); | |
| 133 | |
| 134 bslen = (*env)->GetArrayLength(env, jbs); | |
| 135 if (len > bslen - off) jni_throw_oob(env, "offset + length is outside of buffer"); | |
| 136 | |
| 137 blen = fz_buffer_storage(ctx, buf, &data); | |
| 138 if (at >= blen) | |
| 139 return -1; | |
| 140 | |
| 141 len = fz_minz(len, blen - at); | |
| 142 | |
| 143 bs = (*env)->GetByteArrayElements(env, jbs, NULL); | |
| 144 if (!bs) jni_throw_io(env, "cannot get bytes to read"); | |
| 145 | |
| 146 memcpy(&bs[off], &data[at], len); | |
| 147 (*env)->ReleaseByteArrayElements(env, jbs, bs, 0); | |
| 148 | |
| 149 return (jint)len; | |
| 150 } | |
| 151 | |
| 152 JNIEXPORT void JNICALL | |
| 153 FUN(Buffer_writeByte)(JNIEnv *env, jobject self, jbyte b) | |
| 154 { | |
| 155 fz_context *ctx = get_context(env); | |
| 156 fz_buffer *buf = from_Buffer(env, self); | |
| 157 | |
| 158 if (!ctx || !buf) return; | |
| 159 | |
| 160 fz_try(ctx) | |
| 161 fz_append_byte(ctx, buf, b); | |
| 162 fz_catch(ctx) | |
| 163 jni_rethrow_void(env, ctx); | |
| 164 } | |
| 165 | |
| 166 JNIEXPORT void JNICALL | |
| 167 FUN(Buffer_writeBytes)(JNIEnv *env, jobject self, jobject jbs) | |
| 168 { | |
| 169 fz_context *ctx = get_context(env); | |
| 170 fz_buffer *buf = from_Buffer(env, self); | |
| 171 jsize len = 0; | |
| 172 jbyte *bs = NULL; | |
| 173 | |
| 174 if (!ctx || !buf) return; | |
| 175 if (!jbs) jni_throw_arg_void(env, "buffer must not be null"); | |
| 176 | |
| 177 len = (*env)->GetArrayLength(env, jbs); | |
| 178 bs = (*env)->GetByteArrayElements(env, jbs, NULL); | |
| 179 if (!bs) jni_throw_io_void(env, "cannot get bytes to write"); | |
| 180 | |
| 181 fz_try(ctx) | |
| 182 fz_append_data(ctx, buf, bs, len); | |
| 183 fz_always(ctx) | |
| 184 (*env)->ReleaseByteArrayElements(env, jbs, bs, JNI_ABORT); | |
| 185 fz_catch(ctx) | |
| 186 jni_rethrow_void(env, ctx); | |
| 187 } | |
| 188 | |
| 189 JNIEXPORT void JNICALL | |
| 190 FUN(Buffer_writeBytesFrom)(JNIEnv *env, jobject self, jobject jbs, jint joff, jint jlen) | |
| 191 { | |
| 192 fz_context *ctx = get_context(env); | |
| 193 fz_buffer *buf = from_Buffer(env, self); | |
| 194 jbyte *bs = NULL; | |
| 195 jsize off = (jsize) joff; | |
| 196 jsize len = (jsize) jlen; | |
| 197 jsize bslen = 0; | |
| 198 | |
| 199 if (!ctx || !buf) return; | |
| 200 if (!jbs) jni_throw_arg_void(env, "buffer must not be null"); | |
| 201 | |
| 202 bslen = (*env)->GetArrayLength(env, jbs); | |
| 203 if (joff < 0) jni_throw_oob_void(env, "offset is negative"); | |
| 204 if (jlen < 0) jni_throw_oob_void(env, "length is negative"); | |
| 205 if (off + len > bslen) jni_throw_oob_void(env, "offset + length is outside of buffer"); | |
| 206 | |
| 207 bs = (*env)->GetByteArrayElements(env, jbs, NULL); | |
| 208 if (!bs) jni_throw_io_void(env, "cannot get bytes to write"); | |
| 209 | |
| 210 fz_try(ctx) | |
| 211 fz_append_data(ctx, buf, &bs[off], len); | |
| 212 fz_always(ctx) | |
| 213 (*env)->ReleaseByteArrayElements(env, jbs, bs, JNI_ABORT); | |
| 214 fz_catch(ctx) | |
| 215 jni_rethrow_void(env, ctx); | |
| 216 } | |
| 217 | |
| 218 JNIEXPORT void JNICALL | |
| 219 FUN(Buffer_writeBuffer)(JNIEnv *env, jobject self, jobject jbuf) | |
| 220 { | |
| 221 fz_context *ctx = get_context(env); | |
| 222 fz_buffer *buf = from_Buffer(env, self); | |
| 223 fz_buffer *cat = from_Buffer(env, jbuf); | |
| 224 | |
| 225 if (!ctx || !buf) return; | |
| 226 if (!cat) jni_throw_arg_void(env, "buffer must not be null"); | |
| 227 | |
| 228 fz_try(ctx) | |
| 229 fz_append_buffer(ctx, buf, cat); | |
| 230 fz_catch(ctx) | |
| 231 jni_rethrow_void(env, ctx); | |
| 232 } | |
| 233 | |
| 234 JNIEXPORT void JNICALL | |
| 235 FUN(Buffer_writeRune)(JNIEnv *env, jobject self, jint rune) | |
| 236 { | |
| 237 fz_context *ctx = get_context(env); | |
| 238 fz_buffer *buf = from_Buffer(env, self); | |
| 239 | |
| 240 if (!ctx || !buf) return; | |
| 241 | |
| 242 fz_try(ctx) | |
| 243 fz_append_rune(ctx, buf, rune); | |
| 244 fz_catch(ctx) | |
| 245 jni_rethrow_void(env, ctx); | |
| 246 } | |
| 247 | |
| 248 JNIEXPORT void JNICALL | |
| 249 FUN(Buffer_writeLine)(JNIEnv *env, jobject self, jstring jline) | |
| 250 { | |
| 251 fz_context *ctx = get_context(env); | |
| 252 fz_buffer *buf = from_Buffer(env, self); | |
| 253 const char *line = NULL; | |
| 254 | |
| 255 if (!ctx || !buf) return; | |
| 256 if (!jline) jni_throw_arg_void(env, "line must not be null"); | |
| 257 | |
| 258 line = (*env)->GetStringUTFChars(env, jline, NULL); | |
| 259 if (!line) return; | |
| 260 | |
| 261 fz_try(ctx) | |
| 262 { | |
| 263 fz_append_string(ctx, buf, line); | |
| 264 fz_append_byte(ctx, buf, '\n'); | |
| 265 } | |
| 266 fz_always(ctx) | |
| 267 (*env)->ReleaseStringUTFChars(env, jline, line); | |
| 268 fz_catch(ctx) | |
| 269 jni_rethrow_void(env, ctx); | |
| 270 } | |
| 271 | |
| 272 JNIEXPORT void JNICALL | |
| 273 FUN(Buffer_writeLines)(JNIEnv *env, jobject self, jobject jlines) | |
| 274 { | |
| 275 fz_context *ctx = get_context(env); | |
| 276 fz_buffer *buf = from_Buffer(env, self); | |
| 277 int i = 0; | |
| 278 jsize len = 0; | |
| 279 | |
| 280 if (!ctx || !buf) return; | |
| 281 if (!jlines) jni_throw_arg_void(env, "lines must not be null"); | |
| 282 | |
| 283 len = (*env)->GetArrayLength(env, jlines); | |
| 284 | |
| 285 for (i = 0; i < len; ++i) | |
| 286 { | |
| 287 const char *line; | |
| 288 jobject jline; | |
| 289 | |
| 290 jline = (*env)->GetObjectArrayElement(env, jlines, i); | |
| 291 if ((*env)->ExceptionCheck(env)) return; | |
| 292 | |
| 293 if (!jline) | |
| 294 continue; | |
| 295 line = (*env)->GetStringUTFChars(env, jline, NULL); | |
| 296 if (!line) return; | |
| 297 | |
| 298 fz_try(ctx) | |
| 299 { | |
| 300 fz_append_string(ctx, buf, line); | |
| 301 fz_append_byte(ctx, buf, '\n'); | |
| 302 } | |
| 303 fz_always(ctx) | |
| 304 (*env)->ReleaseStringUTFChars(env, jline, line); | |
| 305 fz_catch(ctx) | |
| 306 jni_rethrow_void(env, ctx); | |
| 307 } | |
| 308 } | |
| 309 | |
| 310 JNIEXPORT void JNICALL | |
| 311 FUN(Buffer_save)(JNIEnv *env, jobject self, jstring jfilename) | |
| 312 { | |
| 313 fz_context *ctx = get_context(env); | |
| 314 fz_buffer *buf = from_Buffer(env, self); | |
| 315 const char *filename = NULL; | |
| 316 | |
| 317 if (!ctx || !buf) return; | |
| 318 if (jfilename) | |
| 319 { | |
| 320 filename = (*env)->GetStringUTFChars(env, jfilename, NULL); | |
| 321 if (!filename) return; | |
| 322 } | |
| 323 | |
| 324 fz_try(ctx) | |
| 325 fz_save_buffer(ctx, buf, filename); | |
| 326 fz_always(ctx) | |
| 327 if (filename) | |
| 328 (*env)->ReleaseStringUTFChars(env, jfilename, filename); | |
| 329 fz_catch(ctx) | |
| 330 jni_rethrow_void(env, ctx); | |
| 331 } | |
| 332 | |
| 333 JNIEXPORT jobject JNICALL | |
| 334 FUN(Buffer_slice)(JNIEnv *env, jobject self, jint start, jint end) | |
| 335 { | |
| 336 fz_context *ctx = get_context(env); | |
| 337 fz_buffer *buf = from_Buffer(env, self); | |
| 338 fz_buffer *copy = NULL; | |
| 339 jobject jcopy = NULL; | |
| 340 | |
| 341 if (!ctx || !buf) return NULL; | |
| 342 | |
| 343 fz_try(ctx) | |
| 344 copy = fz_slice_buffer(ctx, buf, start, end); | |
| 345 fz_catch(ctx) | |
| 346 jni_rethrow(env, ctx); | |
| 347 | |
| 348 jcopy = (*env)->NewObject(env, cls_Buffer, mid_Buffer_init, copy); | |
| 349 if (!jcopy || (*env)->ExceptionCheck(env)) | |
| 350 return NULL; | |
| 351 | |
| 352 return jcopy; | |
| 353 } | |
| 354 | |
| 355 JNIEXPORT jstring JNICALL | |
| 356 FUN(Buffer_asString)(JNIEnv *env, jobject self) | |
| 357 { | |
| 358 fz_context *ctx = get_context(env); | |
| 359 fz_buffer *buf = from_Buffer(env, self); | |
| 360 const char *s = NULL; | |
| 361 | |
| 362 if (!ctx || !buf) return NULL; | |
| 363 | |
| 364 fz_try(ctx) | |
| 365 s = fz_string_from_buffer(ctx, buf); | |
| 366 fz_catch(ctx) | |
| 367 jni_rethrow(env, ctx); | |
| 368 | |
| 369 return to_String_safe(ctx, env, s); | |
| 370 } |
