/fitz/base_object.c

https://github.com/mescher/mupdf · C · 802 lines · 681 code · 118 blank · 3 comment · 119 complexity · 7599aefa3e8169277229d0282a987779 MD5 · raw file

  1. #include "fitz.h"
  2. typedef enum fz_objkind_e
  3. {
  4. FZ_NULL,
  5. FZ_BOOL,
  6. FZ_INT,
  7. FZ_REAL,
  8. FZ_STRING,
  9. FZ_NAME,
  10. FZ_ARRAY,
  11. FZ_DICT,
  12. FZ_INDIRECT
  13. } fz_objkind;
  14. struct keyval
  15. {
  16. fz_obj *k;
  17. fz_obj *v;
  18. };
  19. struct fz_obj_s
  20. {
  21. int refs;
  22. fz_objkind kind;
  23. union
  24. {
  25. int b;
  26. int i;
  27. float f;
  28. struct {
  29. unsigned short len;
  30. char buf[1];
  31. } s;
  32. char n[1];
  33. struct {
  34. int len;
  35. int cap;
  36. fz_obj **items;
  37. } a;
  38. struct {
  39. char sorted;
  40. int len;
  41. int cap;
  42. struct keyval *items;
  43. } d;
  44. struct {
  45. int num;
  46. int gen;
  47. struct pdf_xref_s *xref;
  48. } r;
  49. } u;
  50. };
  51. static fz_obj *fz_resolve_indirect_null(fz_obj *ref)
  52. {
  53. return ref;
  54. }
  55. fz_obj* (*fz_resolve_indirect)(fz_obj*) = fz_resolve_indirect_null;
  56. fz_obj *
  57. fz_new_null(void)
  58. {
  59. fz_obj *obj = fz_malloc(sizeof(fz_obj));
  60. obj->refs = 1;
  61. obj->kind = FZ_NULL;
  62. return obj;
  63. }
  64. fz_obj *
  65. fz_new_bool(int b)
  66. {
  67. fz_obj *obj = fz_malloc(sizeof(fz_obj));
  68. obj->refs = 1;
  69. obj->kind = FZ_BOOL;
  70. obj->u.b = b;
  71. return obj;
  72. }
  73. fz_obj *
  74. fz_new_int(int i)
  75. {
  76. fz_obj *obj = fz_malloc(sizeof(fz_obj));
  77. obj->refs = 1;
  78. obj->kind = FZ_INT;
  79. obj->u.i = i;
  80. return obj;
  81. }
  82. fz_obj *
  83. fz_new_real(float f)
  84. {
  85. fz_obj *obj = fz_malloc(sizeof(fz_obj));
  86. obj->refs = 1;
  87. obj->kind = FZ_REAL;
  88. obj->u.f = f;
  89. return obj;
  90. }
  91. fz_obj *
  92. fz_new_string(char *str, int len)
  93. {
  94. fz_obj *obj = fz_malloc(offsetof(fz_obj, u.s.buf) + len + 1);
  95. obj->refs = 1;
  96. obj->kind = FZ_STRING;
  97. obj->u.s.len = len;
  98. memcpy(obj->u.s.buf, str, len);
  99. obj->u.s.buf[len] = '\0';
  100. return obj;
  101. }
  102. fz_obj *
  103. fz_new_name(char *str)
  104. {
  105. fz_obj *obj = fz_malloc(offsetof(fz_obj, u.n) + strlen(str) + 1);
  106. obj->refs = 1;
  107. obj->kind = FZ_NAME;
  108. strcpy(obj->u.n, str);
  109. return obj;
  110. }
  111. fz_obj *
  112. fz_new_indirect(int num, int gen, void *xref)
  113. {
  114. fz_obj *obj = fz_malloc(sizeof(fz_obj));
  115. obj->refs = 1;
  116. obj->kind = FZ_INDIRECT;
  117. obj->u.r.num = num;
  118. obj->u.r.gen = gen;
  119. obj->u.r.xref = xref;
  120. return obj;
  121. }
  122. fz_obj *
  123. fz_keep_obj(fz_obj *obj)
  124. {
  125. assert(obj != NULL);
  126. obj->refs ++;
  127. return obj;
  128. }
  129. int fz_is_indirect(fz_obj *obj)
  130. {
  131. return obj ? obj->kind == FZ_INDIRECT : 0;
  132. }
  133. int fz_is_null(fz_obj *obj)
  134. {
  135. obj = fz_resolve_indirect(obj);
  136. return obj ? obj->kind == FZ_NULL : 0;
  137. }
  138. int fz_is_bool(fz_obj *obj)
  139. {
  140. obj = fz_resolve_indirect(obj);
  141. return obj ? obj->kind == FZ_BOOL : 0;
  142. }
  143. int fz_is_int(fz_obj *obj)
  144. {
  145. obj = fz_resolve_indirect(obj);
  146. return obj ? obj->kind == FZ_INT : 0;
  147. }
  148. int fz_is_real(fz_obj *obj)
  149. {
  150. obj = fz_resolve_indirect(obj);
  151. return obj ? obj->kind == FZ_REAL : 0;
  152. }
  153. int fz_is_string(fz_obj *obj)
  154. {
  155. obj = fz_resolve_indirect(obj);
  156. return obj ? obj->kind == FZ_STRING : 0;
  157. }
  158. int fz_is_name(fz_obj *obj)
  159. {
  160. obj = fz_resolve_indirect(obj);
  161. return obj ? obj->kind == FZ_NAME : 0;
  162. }
  163. int fz_is_array(fz_obj *obj)
  164. {
  165. obj = fz_resolve_indirect(obj);
  166. return obj ? obj->kind == FZ_ARRAY : 0;
  167. }
  168. int fz_is_dict(fz_obj *obj)
  169. {
  170. obj = fz_resolve_indirect(obj);
  171. return obj ? obj->kind == FZ_DICT : 0;
  172. }
  173. int fz_to_bool(fz_obj *obj)
  174. {
  175. obj = fz_resolve_indirect(obj);
  176. if (fz_is_bool(obj))
  177. return obj->u.b;
  178. return 0;
  179. }
  180. int fz_to_int(fz_obj *obj)
  181. {
  182. obj = fz_resolve_indirect(obj);
  183. if (fz_is_int(obj))
  184. return obj->u.i;
  185. if (fz_is_real(obj))
  186. return obj->u.f;
  187. return 0;
  188. }
  189. float fz_to_real(fz_obj *obj)
  190. {
  191. obj = fz_resolve_indirect(obj);
  192. if (fz_is_real(obj))
  193. return obj->u.f;
  194. if (fz_is_int(obj))
  195. return obj->u.i;
  196. return 0;
  197. }
  198. char *fz_to_name(fz_obj *obj)
  199. {
  200. obj = fz_resolve_indirect(obj);
  201. if (fz_is_name(obj))
  202. return obj->u.n;
  203. return "";
  204. }
  205. char *fz_to_str_buf(fz_obj *obj)
  206. {
  207. obj = fz_resolve_indirect(obj);
  208. if (fz_is_string(obj))
  209. return obj->u.s.buf;
  210. return "";
  211. }
  212. int fz_to_str_len(fz_obj *obj)
  213. {
  214. obj = fz_resolve_indirect(obj);
  215. if (fz_is_string(obj))
  216. return obj->u.s.len;
  217. return 0;
  218. }
  219. /* for use by pdf_crypt_obj_imp to decrypt AES string in place */
  220. void fz_set_str_len(fz_obj *obj, int newlen)
  221. {
  222. obj = fz_resolve_indirect(obj);
  223. if (fz_is_string(obj))
  224. if (newlen < obj->u.s.len)
  225. obj->u.s.len = newlen;
  226. }
  227. int fz_to_num(fz_obj *obj)
  228. {
  229. if (fz_is_indirect(obj))
  230. return obj->u.r.num;
  231. return 0;
  232. }
  233. int fz_to_gen(fz_obj *obj)
  234. {
  235. if (fz_is_indirect(obj))
  236. return obj->u.r.gen;
  237. return 0;
  238. }
  239. void *fz_get_indirect_xref(fz_obj *obj)
  240. {
  241. if (fz_is_indirect(obj))
  242. return obj->u.r.xref;
  243. return NULL;
  244. }
  245. int
  246. fz_objcmp(fz_obj *a, fz_obj *b)
  247. {
  248. int i;
  249. if (a == b)
  250. return 0;
  251. if (!a || !b)
  252. return 1;
  253. if (a->kind != b->kind)
  254. return 1;
  255. switch (a->kind)
  256. {
  257. case FZ_NULL:
  258. return 0;
  259. case FZ_BOOL:
  260. return a->u.b - b->u.b;
  261. case FZ_INT:
  262. return a->u.i - b->u.i;
  263. case FZ_REAL:
  264. if (a->u.f < b->u.f)
  265. return -1;
  266. if (a->u.f > b->u.f)
  267. return 1;
  268. return 0;
  269. case FZ_STRING:
  270. if (a->u.s.len < b->u.s.len)
  271. {
  272. if (memcmp(a->u.s.buf, b->u.s.buf, a->u.s.len) <= 0)
  273. return -1;
  274. return 1;
  275. }
  276. if (a->u.s.len > b->u.s.len)
  277. {
  278. if (memcmp(a->u.s.buf, b->u.s.buf, b->u.s.len) >= 0)
  279. return 1;
  280. return -1;
  281. }
  282. return memcmp(a->u.s.buf, b->u.s.buf, a->u.s.len);
  283. case FZ_NAME:
  284. return strcmp(a->u.n, b->u.n);
  285. case FZ_INDIRECT:
  286. if (a->u.r.num == b->u.r.num)
  287. return a->u.r.gen - b->u.r.gen;
  288. return a->u.r.num - b->u.r.num;
  289. case FZ_ARRAY:
  290. if (a->u.a.len != b->u.a.len)
  291. return a->u.a.len - b->u.a.len;
  292. for (i = 0; i < a->u.a.len; i++)
  293. if (fz_objcmp(a->u.a.items[i], b->u.a.items[i]))
  294. return 1;
  295. return 0;
  296. case FZ_DICT:
  297. if (a->u.d.len != b->u.d.len)
  298. return a->u.d.len - b->u.d.len;
  299. for (i = 0; i < a->u.d.len; i++)
  300. {
  301. if (fz_objcmp(a->u.d.items[i].k, b->u.d.items[i].k))
  302. return 1;
  303. if (fz_objcmp(a->u.d.items[i].v, b->u.d.items[i].v))
  304. return 1;
  305. }
  306. return 0;
  307. }
  308. return 1;
  309. }
  310. static char *
  311. fz_objkindstr(fz_obj *obj)
  312. {
  313. if (obj == NULL)
  314. return "<NULL>";
  315. switch (obj->kind)
  316. {
  317. case FZ_NULL: return "null";
  318. case FZ_BOOL: return "boolean";
  319. case FZ_INT: return "integer";
  320. case FZ_REAL: return "real";
  321. case FZ_STRING: return "string";
  322. case FZ_NAME: return "name";
  323. case FZ_ARRAY: return "array";
  324. case FZ_DICT: return "dictionary";
  325. case FZ_INDIRECT: return "reference";
  326. }
  327. return "<unknown>";
  328. }
  329. fz_obj *
  330. fz_new_array(int initialcap)
  331. {
  332. fz_obj *obj;
  333. int i;
  334. obj = fz_malloc(sizeof(fz_obj));
  335. obj->refs = 1;
  336. obj->kind = FZ_ARRAY;
  337. obj->u.a.len = 0;
  338. obj->u.a.cap = initialcap > 1 ? initialcap : 6;
  339. obj->u.a.items = fz_calloc(obj->u.a.cap, sizeof(fz_obj*));
  340. for (i = 0; i < obj->u.a.cap; i++)
  341. obj->u.a.items[i] = NULL;
  342. return obj;
  343. }
  344. fz_obj *
  345. fz_copy_array(fz_obj *obj)
  346. {
  347. fz_obj *new;
  348. int i;
  349. if (fz_is_indirect(obj) || !fz_is_array(obj))
  350. fz_warn("assert: not an array (%s)", fz_objkindstr(obj));
  351. new = fz_new_array(fz_array_len(obj));
  352. for (i = 0; i < fz_array_len(obj); i++)
  353. fz_array_push(new, fz_array_get(obj, i));
  354. return new;
  355. }
  356. int
  357. fz_array_len(fz_obj *obj)
  358. {
  359. obj = fz_resolve_indirect(obj);
  360. if (!fz_is_array(obj))
  361. return 0;
  362. return obj->u.a.len;
  363. }
  364. fz_obj *
  365. fz_array_get(fz_obj *obj, int i)
  366. {
  367. obj = fz_resolve_indirect(obj);
  368. if (!fz_is_array(obj))
  369. return NULL;
  370. if (i < 0 || i >= obj->u.a.len)
  371. return NULL;
  372. return obj->u.a.items[i];
  373. }
  374. void
  375. fz_array_put(fz_obj *obj, int i, fz_obj *item)
  376. {
  377. obj = fz_resolve_indirect(obj);
  378. if (!fz_is_array(obj))
  379. fz_warn("assert: not an array (%s)", fz_objkindstr(obj));
  380. else if (i < 0)
  381. fz_warn("assert: index %d < 0", i);
  382. else if (i >= obj->u.a.len)
  383. fz_warn("assert: index %d > length %d", i, obj->u.a.len);
  384. else
  385. {
  386. if (obj->u.a.items[i])
  387. fz_drop_obj(obj->u.a.items[i]);
  388. obj->u.a.items[i] = fz_keep_obj(item);
  389. }
  390. }
  391. void
  392. fz_array_push(fz_obj *obj, fz_obj *item)
  393. {
  394. obj = fz_resolve_indirect(obj);
  395. if (!fz_is_array(obj))
  396. fz_warn("assert: not an array (%s)", fz_objkindstr(obj));
  397. else
  398. {
  399. if (obj->u.a.len + 1 > obj->u.a.cap)
  400. {
  401. int i;
  402. obj->u.a.cap = (obj->u.a.cap * 3) / 2;
  403. obj->u.a.items = fz_realloc(obj->u.a.items, obj->u.a.cap, sizeof(fz_obj*));
  404. for (i = obj->u.a.len ; i < obj->u.a.cap; i++)
  405. obj->u.a.items[i] = NULL;
  406. }
  407. obj->u.a.items[obj->u.a.len] = fz_keep_obj(item);
  408. obj->u.a.len++;
  409. }
  410. }
  411. void
  412. fz_array_insert(fz_obj *obj, fz_obj *item)
  413. {
  414. obj = fz_resolve_indirect(obj);
  415. if (!fz_is_array(obj))
  416. fz_warn("assert: not an array (%s)", fz_objkindstr(obj));
  417. else
  418. {
  419. if (obj->u.a.len + 1 > obj->u.a.cap)
  420. {
  421. int i;
  422. obj->u.a.cap = (obj->u.a.cap * 3) / 2;
  423. obj->u.a.items = fz_realloc(obj->u.a.items, obj->u.a.cap, sizeof(fz_obj*));
  424. for (i = obj->u.a.len ; i < obj->u.a.cap; i++)
  425. obj->u.a.items[i] = NULL;
  426. }
  427. memmove(obj->u.a.items + 1, obj->u.a.items, obj->u.a.len * sizeof(fz_obj*));
  428. obj->u.a.items[0] = fz_keep_obj(item);
  429. obj->u.a.len++;
  430. }
  431. }
  432. /* dicts may only have names as keys! */
  433. static int keyvalcmp(const void *ap, const void *bp)
  434. {
  435. const struct keyval *a = ap;
  436. const struct keyval *b = bp;
  437. return strcmp(fz_to_name(a->k), fz_to_name(b->k));
  438. }
  439. fz_obj *
  440. fz_new_dict(int initialcap)
  441. {
  442. fz_obj *obj;
  443. int i;
  444. obj = fz_malloc(sizeof(fz_obj));
  445. obj->refs = 1;
  446. obj->kind = FZ_DICT;
  447. obj->u.d.sorted = 1;
  448. obj->u.d.len = 0;
  449. obj->u.d.cap = initialcap > 1 ? initialcap : 10;
  450. obj->u.d.items = fz_calloc(obj->u.d.cap, sizeof(struct keyval));
  451. for (i = 0; i < obj->u.d.cap; i++)
  452. {
  453. obj->u.d.items[i].k = NULL;
  454. obj->u.d.items[i].v = NULL;
  455. }
  456. return obj;
  457. }
  458. fz_obj *
  459. fz_copy_dict(fz_obj *obj)
  460. {
  461. fz_obj *new;
  462. int i;
  463. if (fz_is_indirect(obj) || !fz_is_dict(obj))
  464. fz_throw("assert: not a dict (%s)", fz_objkindstr(obj));
  465. new = fz_new_dict(fz_dict_len(obj));
  466. for (i = 0; i < fz_dict_len(obj); i++)
  467. fz_dict_put(new, fz_dict_get_key(obj, i), fz_dict_get_val(obj, i));
  468. return new;
  469. }
  470. int
  471. fz_dict_len(fz_obj *obj)
  472. {
  473. obj = fz_resolve_indirect(obj);
  474. if (!fz_is_dict(obj))
  475. return 0;
  476. return obj->u.d.len;
  477. }
  478. fz_obj *
  479. fz_dict_get_key(fz_obj *obj, int i)
  480. {
  481. obj = fz_resolve_indirect(obj);
  482. if (!fz_is_dict(obj))
  483. return NULL;
  484. if (i < 0 || i >= obj->u.d.len)
  485. return NULL;
  486. return obj->u.d.items[i].k;
  487. }
  488. fz_obj *
  489. fz_dict_get_val(fz_obj *obj, int i)
  490. {
  491. obj = fz_resolve_indirect(obj);
  492. if (!fz_is_dict(obj))
  493. return NULL;
  494. if (i < 0 || i >= obj->u.d.len)
  495. return NULL;
  496. return obj->u.d.items[i].v;
  497. }
  498. static int
  499. fz_dict_finds(fz_obj *obj, char *key)
  500. {
  501. if (obj->u.d.sorted)
  502. {
  503. int l = 0;
  504. int r = obj->u.d.len - 1;
  505. while (l <= r)
  506. {
  507. int m = (l + r) >> 1;
  508. int c = -strcmp(fz_to_name(obj->u.d.items[m].k), key);
  509. if (c < 0)
  510. r = m - 1;
  511. else if (c > 0)
  512. l = m + 1;
  513. else
  514. return m;
  515. }
  516. }
  517. else
  518. {
  519. int i;
  520. for (i = 0; i < obj->u.d.len; i++)
  521. if (strcmp(fz_to_name(obj->u.d.items[i].k), key) == 0)
  522. return i;
  523. }
  524. return -1;
  525. }
  526. fz_obj *
  527. fz_dict_gets(fz_obj *obj, char *key)
  528. {
  529. int i;
  530. obj = fz_resolve_indirect(obj);
  531. if (!fz_is_dict(obj))
  532. return NULL;
  533. i = fz_dict_finds(obj, key);
  534. if (i >= 0)
  535. return obj->u.d.items[i].v;
  536. return NULL;
  537. }
  538. fz_obj *
  539. fz_dict_get(fz_obj *obj, fz_obj *key)
  540. {
  541. if (fz_is_name(key))
  542. return fz_dict_gets(obj, fz_to_name(key));
  543. return NULL;
  544. }
  545. fz_obj *
  546. fz_dict_getsa(fz_obj *obj, char *key, char *abbrev)
  547. {
  548. fz_obj *v;
  549. v = fz_dict_gets(obj, key);
  550. if (v)
  551. return v;
  552. return fz_dict_gets(obj, abbrev);
  553. }
  554. void
  555. fz_dict_put(fz_obj *obj, fz_obj *key, fz_obj *val)
  556. {
  557. char *s;
  558. int i;
  559. obj = fz_resolve_indirect(obj);
  560. if (!fz_is_dict(obj))
  561. {
  562. fz_warn("assert: not a dict (%s)", fz_objkindstr(obj));
  563. return;
  564. }
  565. if (fz_is_name(key))
  566. s = fz_to_name(key);
  567. else
  568. {
  569. fz_warn("assert: key is not a name (%s)", fz_objkindstr(obj));
  570. return;
  571. }
  572. if (!val)
  573. {
  574. fz_warn("assert: val does not exist for key (%s)", s);
  575. return;
  576. }
  577. i = fz_dict_finds(obj, s);
  578. if (i >= 0)
  579. {
  580. fz_drop_obj(obj->u.d.items[i].v);
  581. obj->u.d.items[i].v = fz_keep_obj(val);
  582. return;
  583. }
  584. if (obj->u.d.len + 1 > obj->u.d.cap)
  585. {
  586. obj->u.d.cap = (obj->u.d.cap * 3) / 2;
  587. obj->u.d.items = fz_realloc(obj->u.d.items, obj->u.d.cap, sizeof(struct keyval));
  588. for (i = obj->u.d.len; i < obj->u.d.cap; i++)
  589. {
  590. obj->u.d.items[i].k = NULL;
  591. obj->u.d.items[i].v = NULL;
  592. }
  593. }
  594. /* borked! */
  595. if (obj->u.d.len)
  596. if (strcmp(fz_to_name(obj->u.d.items[obj->u.d.len - 1].k), s) > 0)
  597. obj->u.d.sorted = 0;
  598. obj->u.d.items[obj->u.d.len].k = fz_keep_obj(key);
  599. obj->u.d.items[obj->u.d.len].v = fz_keep_obj(val);
  600. obj->u.d.len ++;
  601. }
  602. void
  603. fz_dict_puts(fz_obj *obj, char *key, fz_obj *val)
  604. {
  605. fz_obj *keyobj = fz_new_name(key);
  606. fz_dict_put(obj, keyobj, val);
  607. fz_drop_obj(keyobj);
  608. }
  609. void
  610. fz_dict_dels(fz_obj *obj, char *key)
  611. {
  612. obj = fz_resolve_indirect(obj);
  613. if (!fz_is_dict(obj))
  614. fz_warn("assert: not a dict (%s)", fz_objkindstr(obj));
  615. else
  616. {
  617. int i = fz_dict_finds(obj, key);
  618. if (i >= 0)
  619. {
  620. fz_drop_obj(obj->u.d.items[i].k);
  621. fz_drop_obj(obj->u.d.items[i].v);
  622. obj->u.d.sorted = 0;
  623. obj->u.d.items[i] = obj->u.d.items[obj->u.d.len-1];
  624. obj->u.d.len --;
  625. }
  626. }
  627. }
  628. void
  629. fz_dict_del(fz_obj *obj, fz_obj *key)
  630. {
  631. if (fz_is_name(key))
  632. fz_dict_dels(obj, fz_to_name(key));
  633. else
  634. fz_warn("assert: key is not a name (%s)", fz_objkindstr(obj));
  635. }
  636. void
  637. fz_sort_dict(fz_obj *obj)
  638. {
  639. obj = fz_resolve_indirect(obj);
  640. if (!fz_is_dict(obj))
  641. return;
  642. if (!obj->u.d.sorted)
  643. {
  644. qsort(obj->u.d.items, obj->u.d.len, sizeof(struct keyval), keyvalcmp);
  645. obj->u.d.sorted = 1;
  646. }
  647. }
  648. static void
  649. fz_free_array(fz_obj *obj)
  650. {
  651. int i;
  652. for (i = 0; i < obj->u.a.len; i++)
  653. if (obj->u.a.items[i])
  654. fz_drop_obj(obj->u.a.items[i]);
  655. fz_free(obj->u.a.items);
  656. fz_free(obj);
  657. }
  658. static void
  659. fz_free_dict(fz_obj *obj)
  660. {
  661. int i;
  662. for (i = 0; i < obj->u.d.len; i++) {
  663. if (obj->u.d.items[i].k)
  664. fz_drop_obj(obj->u.d.items[i].k);
  665. if (obj->u.d.items[i].v)
  666. fz_drop_obj(obj->u.d.items[i].v);
  667. }
  668. fz_free(obj->u.d.items);
  669. fz_free(obj);
  670. }
  671. void
  672. fz_drop_obj(fz_obj *obj)
  673. {
  674. assert(obj != NULL);
  675. if (--obj->refs == 0)
  676. {
  677. if (obj->kind == FZ_ARRAY)
  678. fz_free_array(obj);
  679. else if (obj->kind == FZ_DICT)
  680. fz_free_dict(obj);
  681. else
  682. fz_free(obj);
  683. }
  684. }