dom.c 9.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419
  1. // Copyright (C) 2004-2021 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. /* DOM interface */
  23. JNIEXPORT void JNICALL
  24. FUN(DOM_finalize)(JNIEnv *env, jobject self)
  25. {
  26. fz_context *ctx = get_context(env);
  27. fz_xml *xml = from_DOM_safe(env, self);
  28. if (!ctx || !xml) return;
  29. (*env)->SetLongField(env, self, fid_DOM_pointer, 0);
  30. fz_drop_xml(ctx, xml);
  31. }
  32. JNIEXPORT void JNICALL
  33. FUN(DOM_insertBefore)(JNIEnv *env, jobject self, jobject jxml)
  34. {
  35. fz_context *ctx = get_context(env);
  36. fz_xml *me = from_DOM_safe(env, self);
  37. fz_xml *xml = from_DOM_safe(env, jxml);
  38. fz_try(ctx)
  39. fz_dom_insert_before(ctx, me, xml);
  40. fz_catch(ctx)
  41. jni_rethrow_void(env, ctx);
  42. }
  43. JNIEXPORT void JNICALL
  44. FUN(DOM_insertAfter)(JNIEnv *env, jobject self, jobject jxml)
  45. {
  46. fz_context *ctx = get_context(env);
  47. fz_xml *me = from_DOM_safe(env, self);
  48. fz_xml *xml = from_DOM_safe(env, jxml);
  49. fz_try(ctx)
  50. fz_dom_insert_after(ctx, me, xml);
  51. fz_catch(ctx)
  52. jni_rethrow_void(env, ctx);
  53. }
  54. JNIEXPORT void JNICALL
  55. FUN(DOM_appendChild)(JNIEnv *env, jobject self, jobject jxml)
  56. {
  57. fz_context *ctx = get_context(env);
  58. fz_xml *me = from_DOM_safe(env, self);
  59. fz_xml *xml = from_DOM_safe(env, jxml);
  60. fz_try(ctx)
  61. fz_dom_append_child(ctx, me, xml);
  62. fz_catch(ctx)
  63. jni_rethrow_void(env, ctx);
  64. }
  65. JNIEXPORT void JNICALL
  66. FUN(DOM_remove)(JNIEnv *env, jobject self)
  67. {
  68. fz_context *ctx = get_context(env);
  69. fz_xml *me = from_DOM_safe(env, self);
  70. fz_try(ctx)
  71. fz_dom_remove(ctx, me);
  72. fz_catch(ctx)
  73. jni_rethrow_void(env, ctx);
  74. }
  75. JNIEXPORT jobject JNICALL
  76. FUN(DOM_clone)(JNIEnv *env, jobject self)
  77. {
  78. fz_context *ctx = get_context(env);
  79. fz_xml *me = from_DOM_safe(env, self);
  80. fz_xml *clone = NULL;
  81. fz_var(clone);
  82. fz_try(ctx)
  83. clone = fz_dom_clone(ctx, me);
  84. fz_catch(ctx)
  85. jni_rethrow(env, ctx);
  86. return to_DOM_safe(ctx, env, clone);
  87. }
  88. JNIEXPORT jobject JNICALL
  89. FUN(DOM_parent)(JNIEnv *env, jobject self)
  90. {
  91. fz_context *ctx = get_context(env);
  92. fz_xml *me = from_DOM_safe(env, self);
  93. fz_xml *parent = NULL;
  94. fz_var(parent);
  95. fz_try(ctx)
  96. parent = fz_dom_clone(ctx, me);
  97. fz_catch(ctx)
  98. jni_rethrow(env, ctx);
  99. return to_DOM_safe(ctx, env, parent);
  100. }
  101. JNIEXPORT jobject JNICALL
  102. FUN(DOM_firstChild)(JNIEnv *env, jobject self)
  103. {
  104. fz_context *ctx = get_context(env);
  105. fz_xml *me = from_DOM_safe(env, self);
  106. fz_xml *child = NULL;
  107. fz_var(child);
  108. fz_try(ctx)
  109. child = fz_dom_first_child(ctx, me);
  110. fz_catch(ctx)
  111. jni_rethrow(env, ctx);
  112. return to_DOM_safe(ctx, env, child);
  113. }
  114. JNIEXPORT jobject JNICALL
  115. FUN(DOM_next)(JNIEnv *env, jobject self)
  116. {
  117. fz_context *ctx = get_context(env);
  118. fz_xml *me = from_DOM_safe(env, self);
  119. fz_xml *next = NULL;
  120. fz_var(next);
  121. fz_try(ctx)
  122. next = fz_dom_next(ctx, me);
  123. fz_catch(ctx)
  124. jni_rethrow(env, ctx);
  125. return to_DOM_safe(ctx, env, next);
  126. }
  127. JNIEXPORT jobject JNICALL
  128. FUN(DOM_previous)(JNIEnv *env, jobject self)
  129. {
  130. fz_context *ctx = get_context(env);
  131. fz_xml *me = from_DOM_safe(env, self);
  132. fz_xml *prev = NULL;
  133. fz_var(prev);
  134. fz_try(ctx)
  135. prev = fz_dom_previous(ctx, me);
  136. fz_catch(ctx)
  137. jni_rethrow(env, ctx);
  138. return to_DOM_safe(ctx, env, prev);
  139. }
  140. JNIEXPORT jobject JNICALL
  141. FUN(DOM_removeAttribute)(JNIEnv *env, jobject self, jstring jatt)
  142. {
  143. fz_context *ctx = get_context(env);
  144. fz_xml *dom = from_DOM_safe(env, self);
  145. const char *att = NULL;
  146. if (!jatt)
  147. return NULL;
  148. att = (*env)->GetStringUTFChars(env, jatt, NULL);
  149. if (!att) jni_throw_run(env, "cannot get characters in attribute name");
  150. fz_try(ctx)
  151. fz_dom_remove_attribute(ctx, dom, att);
  152. fz_always(ctx)
  153. (*env)->ReleaseStringUTFChars(env, jatt, att);
  154. fz_catch(ctx)
  155. jni_rethrow(env, ctx);
  156. return self;
  157. }
  158. JNIEXPORT jstring JNICALL
  159. FUN(DOM_attribute)(JNIEnv *env, jobject self, jstring jatt)
  160. {
  161. fz_context *ctx = get_context(env);
  162. fz_xml *dom = from_DOM_safe(env, self);
  163. const char *att = NULL;
  164. const char *val = NULL;
  165. if (!jatt)
  166. return NULL;
  167. att = (*env)->GetStringUTFChars(env, jatt, NULL);
  168. if (!att) jni_throw_run(env, "cannot get characters in attribute name");
  169. fz_try(ctx)
  170. val = fz_dom_attribute(ctx, dom, att);
  171. fz_always(ctx)
  172. (*env)->ReleaseStringUTFChars(env, jatt, att);
  173. fz_catch(ctx)
  174. jni_rethrow(env, ctx);
  175. return to_String_safe(ctx, env, val);
  176. }
  177. JNIEXPORT jobjectArray JNICALL
  178. FUN(DOM_attributes)(JNIEnv *env, jobject self)
  179. {
  180. fz_context *ctx = get_context(env);
  181. fz_xml *dom = from_DOM_safe(env, self);
  182. const char *att = NULL;
  183. const char *val = NULL;
  184. jobjectArray jarr;
  185. jstring jatt, jval;
  186. jobject jobj;
  187. size_t i;
  188. int n;
  189. fz_try(ctx)
  190. {
  191. n = 0;
  192. while (1)
  193. {
  194. val = fz_dom_get_attribute(ctx, dom, n, &att);
  195. if (att == NULL)
  196. break;
  197. n++;
  198. }
  199. }
  200. fz_catch(ctx)
  201. jni_rethrow(env, ctx);
  202. jarr = (*env)->NewObjectArray(env, n, cls_DOMAttribute, NULL);
  203. if (!jarr) jni_throw_run(env, "cannot create attribute array");
  204. for (i = 0; i < (size_t)n; i++)
  205. {
  206. fz_try(ctx)
  207. val = fz_dom_get_attribute(ctx, dom, i, &att);
  208. fz_catch(ctx)
  209. jni_rethrow(env, ctx);
  210. jobj = (*env)->NewObject(env, cls_DOMAttribute, mid_DOMAttribute_init);
  211. if (!jobj) jni_throw_run(env, "cannot create DOMAttribute");
  212. jatt = (*env)->NewStringUTF(env, att);
  213. if (!jatt) jni_throw_run(env, "cannot create String from attribute");
  214. if (val == NULL)
  215. jval = NULL;
  216. else {
  217. jval = (*env)->NewStringUTF(env, val);
  218. if (!jval) jni_throw_run(env, "cannot create String from attribute");
  219. }
  220. (*env)->SetObjectField(env, jobj, fid_DOMAttribute_attribute, jatt);
  221. (*env)->SetObjectField(env, jobj, fid_DOMAttribute_value, jval);
  222. (*env)->SetObjectArrayElement(env, jarr, i, jobj);
  223. if ((*env)->ExceptionCheck(env))
  224. return NULL;
  225. }
  226. return jarr;
  227. }
  228. JNIEXPORT jobject JNICALL
  229. FUN(DOM_find)(JNIEnv *env, jobject self, jstring jtag, jstring jatt, jstring jval)
  230. {
  231. fz_context *ctx = get_context(env);
  232. fz_xml *me = from_DOM_safe(env, self);
  233. const char *tag = NULL;
  234. const char *att = NULL;
  235. const char *val = NULL;
  236. fz_xml *xml;
  237. if (jtag)
  238. {
  239. tag = (*env)->GetStringUTFChars(env, jtag, NULL);
  240. if (!tag) jni_throw_run(env, "cannot get characters in attribute name");
  241. }
  242. if (jatt)
  243. {
  244. att = (*env)->GetStringUTFChars(env, jatt, NULL);
  245. if (!att) jni_throw_run(env, "cannot get characters in attribute name");
  246. }
  247. if (jval)
  248. {
  249. val = (*env)->GetStringUTFChars(env, jval, NULL);
  250. if (!val) jni_throw_run(env, "cannot get characters in attribute name");
  251. }
  252. fz_try(ctx)
  253. xml = fz_dom_find(ctx, me, tag, att, val);
  254. fz_always(ctx)
  255. {
  256. (*env)->ReleaseStringUTFChars(env, jtag, tag);
  257. (*env)->ReleaseStringUTFChars(env, jatt, att);
  258. (*env)->ReleaseStringUTFChars(env, jval, val);
  259. }
  260. fz_catch(ctx)
  261. jni_rethrow(env, ctx);
  262. return to_DOM_safe(ctx, env, xml);
  263. }
  264. JNIEXPORT jobject JNICALL
  265. FUN(DOM_findNext)(JNIEnv *env, jobject self, jstring jtag, jstring jatt, jstring jval)
  266. {
  267. fz_context *ctx = get_context(env);
  268. fz_xml *me = from_DOM_safe(env, self);
  269. const char *tag = NULL;
  270. const char *att = NULL;
  271. const char *val = NULL;
  272. fz_xml *xml;
  273. if (jtag)
  274. {
  275. tag = (*env)->GetStringUTFChars(env, jtag, NULL);
  276. if (!tag) jni_throw_run(env, "cannot get characters in attribute name");
  277. }
  278. if (jatt)
  279. {
  280. att = (*env)->GetStringUTFChars(env, jatt, NULL);
  281. if (!att) jni_throw_run(env, "cannot get characters in attribute name");
  282. }
  283. if (jval)
  284. {
  285. val = (*env)->GetStringUTFChars(env, jval, NULL);
  286. if (!val) jni_throw_run(env, "cannot get characters in attribute name");
  287. }
  288. fz_try(ctx)
  289. xml = fz_dom_find_next(ctx, me, tag, att, val);
  290. fz_always(ctx)
  291. {
  292. (*env)->ReleaseStringUTFChars(env, jtag, tag);
  293. (*env)->ReleaseStringUTFChars(env, jatt, att);
  294. (*env)->ReleaseStringUTFChars(env, jval, val);
  295. }
  296. fz_catch(ctx)
  297. jni_rethrow(env, ctx);
  298. return to_DOM_safe(ctx, env, xml);
  299. }
  300. JNIEXPORT jobject JNICALL
  301. FUN(DOM_body)(JNIEnv *env, jobject self)
  302. {
  303. fz_context *ctx = get_context(env);
  304. fz_xml *dom = from_DOM_safe(env, self);
  305. return to_DOM_safe(ctx, env, fz_dom_body(ctx, dom));
  306. }
  307. JNIEXPORT jobject JNICALL
  308. FUN(DOM_document)(JNIEnv *env, jobject self)
  309. {
  310. fz_context *ctx = get_context(env);
  311. fz_xml *dom = from_DOM_safe(env, self);
  312. return to_DOM_safe(ctx, env, fz_dom_document_element(ctx, dom));
  313. }
  314. JNIEXPORT jobject JNICALL
  315. FUN(DOM_createTextNode)(JNIEnv *env, jobject self, jstring jtext)
  316. {
  317. fz_context *ctx = get_context(env);
  318. fz_xml *dom = from_DOM_safe(env, self);
  319. const char *text = NULL;
  320. fz_xml *elt;
  321. if (!jtext)
  322. return NULL;
  323. text = (*env)->GetStringUTFChars(env, jtext, NULL);
  324. if (!text) jni_throw_run(env, "cannot get characters in text string");
  325. fz_try(ctx)
  326. elt = fz_dom_create_text_node(ctx, dom, text);
  327. fz_always(ctx)
  328. (*env)->ReleaseStringUTFChars(env, jtext, text);
  329. fz_catch(ctx)
  330. jni_rethrow(env, ctx);
  331. return to_DOM_safe(ctx, env, elt);
  332. }
  333. JNIEXPORT jobject JNICALL
  334. FUN(DOM_createElement)(JNIEnv *env, jobject self, jstring jtag)
  335. {
  336. fz_context *ctx = get_context(env);
  337. fz_xml *dom = from_DOM_safe(env, self);
  338. const char *tag = NULL;
  339. fz_xml *elt;
  340. if (!jtag)
  341. return NULL;
  342. tag = (*env)->GetStringUTFChars(env, jtag, NULL);
  343. if (!tag) jni_throw_run(env, "cannot get characters in tag");
  344. fz_try(ctx)
  345. elt = fz_dom_create_element(ctx, dom, tag);
  346. fz_always(ctx)
  347. (*env)->ReleaseStringUTFChars(env, jtag, tag);
  348. fz_catch(ctx)
  349. jni_rethrow(env, ctx);
  350. return to_DOM_safe(ctx, env, elt);
  351. }