hpdf_array.c 8.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354
  1. /*
  2. * << Haru Free PDF Library >> -- hpdf_array.c
  3. *
  4. * URL: http://libharu.org
  5. *
  6. * Copyright (c) 1999-2006 Takeshi Kanno <[email protected]>
  7. * Copyright (c) 2007-2009 Antony Dovgal <[email protected]>
  8. *
  9. * Permission to use, copy, modify, distribute and sell this software
  10. * and its documentation for any purpose is hereby granted without fee,
  11. * provided that the above copyright notice appear in all copies and
  12. * that both that copyright notice and this permission notice appear
  13. * in supporting documentation.
  14. * It is provided "as is" without express or implied warranty.
  15. *
  16. */
  17. #include "hpdf_conf.h"
  18. #include "hpdf_utils.h"
  19. #include "hpdf_objects.h"
  20. HPDF_Array
  21. HPDF_Array_New (HPDF_MMgr mmgr)
  22. {
  23. HPDF_Array obj;
  24. HPDF_PTRACE((" HPDF_Array_New\n"));
  25. obj = HPDF_GetMem (mmgr, sizeof(HPDF_Array_Rec));
  26. if (obj) {
  27. HPDF_MemSet (obj, 0, sizeof(HPDF_Array_Rec));
  28. obj->header.obj_class = HPDF_OCLASS_ARRAY;
  29. obj->mmgr = mmgr;
  30. obj->error = mmgr->error;
  31. obj->list = HPDF_List_New (mmgr, HPDF_DEF_ITEMS_PER_BLOCK);
  32. if (!obj->list) {
  33. HPDF_FreeMem (mmgr, obj);
  34. obj = NULL;
  35. }
  36. }
  37. return obj;
  38. }
  39. HPDF_Array
  40. HPDF_Box_Array_New (HPDF_MMgr mmgr,
  41. HPDF_Box box)
  42. {
  43. HPDF_Array obj;
  44. HPDF_STATUS ret = HPDF_OK;
  45. HPDF_PTRACE((" HPDF_Box_Array_New\n"));
  46. obj = HPDF_Array_New (mmgr);
  47. if (!obj)
  48. return NULL;
  49. ret += HPDF_Array_Add (obj, HPDF_Real_New (mmgr, box.left));
  50. ret += HPDF_Array_Add (obj, HPDF_Real_New (mmgr, box.bottom));
  51. ret += HPDF_Array_Add (obj, HPDF_Real_New (mmgr, box.right));
  52. ret += HPDF_Array_Add (obj, HPDF_Real_New (mmgr, box.top));
  53. if (ret != HPDF_OK) {
  54. HPDF_Array_Free (obj);
  55. return NULL;
  56. }
  57. return obj;
  58. }
  59. void
  60. HPDF_Array_Free (HPDF_Array array)
  61. {
  62. if (!array)
  63. return;
  64. HPDF_PTRACE((" HPDF_Array_Free\n"));
  65. HPDF_Array_Clear (array);
  66. HPDF_List_Free (array->list);
  67. array->header.obj_class = 0;
  68. HPDF_FreeMem (array->mmgr, array);
  69. }
  70. HPDF_STATUS
  71. HPDF_Array_Write (HPDF_Array array,
  72. HPDF_Stream stream,
  73. HPDF_Encrypt e)
  74. {
  75. HPDF_UINT i;
  76. HPDF_STATUS ret;
  77. HPDF_PTRACE((" HPDF_Array_Write\n"));
  78. ret = HPDF_Stream_WriteStr (stream, "[ ");
  79. if (ret != HPDF_OK)
  80. return ret;
  81. for (i = 0; i < array->list->count; i++) {
  82. void * element = HPDF_List_ItemAt (array->list, i);
  83. ret = HPDF_Obj_Write (element, stream, e);
  84. if (ret != HPDF_OK)
  85. return ret;
  86. ret = HPDF_Stream_WriteChar (stream, ' ');
  87. if (ret != HPDF_OK)
  88. return ret;
  89. }
  90. ret = HPDF_Stream_WriteChar (stream, ']');
  91. return ret;
  92. }
  93. HPDF_STATUS
  94. HPDF_Array_AddNumber (HPDF_Array array,
  95. HPDF_INT32 value)
  96. {
  97. HPDF_Number n = HPDF_Number_New (array->mmgr, value);
  98. HPDF_PTRACE((" HPDF_Array_AddNumber\n"));
  99. if (!n)
  100. return HPDF_Error_GetCode (array->error);
  101. else
  102. return HPDF_Array_Add (array, n);
  103. }
  104. HPDF_STATUS
  105. HPDF_Array_AddReal (HPDF_Array array,
  106. HPDF_REAL value)
  107. {
  108. HPDF_Real r = HPDF_Real_New (array->mmgr, value);
  109. HPDF_PTRACE((" HPDF_Array_AddReal\n"));
  110. if (!r)
  111. return HPDF_Error_GetCode (array->error);
  112. else
  113. return HPDF_Array_Add (array, r);
  114. }
  115. HPDF_STATUS
  116. HPDF_Array_AddName (HPDF_Array array,
  117. const char *value)
  118. {
  119. HPDF_Name n = HPDF_Name_New (array->mmgr, value);
  120. HPDF_PTRACE((" HPDF_Array_AddName\n"));
  121. if (!n)
  122. return HPDF_Error_GetCode (array->error);
  123. else
  124. return HPDF_Array_Add (array, n);
  125. }
  126. HPDF_STATUS
  127. HPDF_Array_Add (HPDF_Array array,
  128. void *obj)
  129. {
  130. HPDF_Obj_Header *header;
  131. HPDF_STATUS ret;
  132. HPDF_PTRACE((" HPDF_Array_Add\n"));
  133. if (!obj) {
  134. if (HPDF_Error_GetCode (array->error) == HPDF_OK)
  135. return HPDF_SetError (array->error, HPDF_INVALID_OBJECT, 0);
  136. else
  137. return HPDF_INVALID_OBJECT;
  138. }
  139. header = (HPDF_Obj_Header *)obj;
  140. if (header->obj_id & HPDF_OTYPE_DIRECT)
  141. return HPDF_SetError (array->error, HPDF_INVALID_OBJECT, 0);
  142. if (array->list->count >= HPDF_LIMIT_MAX_ARRAY) {
  143. HPDF_PTRACE((" HPDF_Array_Add exceed limitatin of array count(%d)\n",
  144. HPDF_LIMIT_MAX_ARRAY));
  145. HPDF_Obj_Free (array->mmgr, obj);
  146. return HPDF_SetError (array->error, HPDF_ARRAY_COUNT_ERR, 0);
  147. }
  148. if (header->obj_id & HPDF_OTYPE_INDIRECT) {
  149. HPDF_Proxy proxy = HPDF_Proxy_New (array->mmgr, obj);
  150. if (!proxy) {
  151. HPDF_Obj_Free (array->mmgr, obj);
  152. return HPDF_Error_GetCode (array->error);
  153. }
  154. proxy->header.obj_id |= HPDF_OTYPE_DIRECT;
  155. obj = proxy;
  156. } else
  157. header->obj_id |= HPDF_OTYPE_DIRECT;
  158. ret = HPDF_List_Add (array->list, obj);
  159. if (ret != HPDF_OK)
  160. HPDF_Obj_Free (array->mmgr, obj);
  161. return ret;
  162. }
  163. HPDF_UINT
  164. HPDF_Array_Items (HPDF_Array array)
  165. {
  166. return array->list->count;
  167. }
  168. HPDF_STATUS
  169. HPDF_Array_Insert (HPDF_Array array,
  170. void *target,
  171. void *obj)
  172. {
  173. HPDF_Obj_Header *header;
  174. HPDF_STATUS ret;
  175. HPDF_UINT i;
  176. HPDF_PTRACE((" HPDF_Array_Insert\n"));
  177. if (!obj) {
  178. if (HPDF_Error_GetCode (array->error) == HPDF_OK)
  179. return HPDF_SetError (array->error, HPDF_INVALID_OBJECT, 0);
  180. else
  181. return HPDF_INVALID_OBJECT;
  182. }
  183. header = (HPDF_Obj_Header *)obj;
  184. if (header->obj_id & HPDF_OTYPE_DIRECT) {
  185. HPDF_PTRACE((" HPDF_Array_Add this object cannot owned by array "
  186. "obj=0x%08X\n", (HPDF_UINT)array));
  187. return HPDF_SetError (array->error, HPDF_INVALID_OBJECT, 0);
  188. }
  189. if (array->list->count >= HPDF_LIMIT_MAX_ARRAY) {
  190. HPDF_PTRACE((" HPDF_Array_Add exceed limitatin of array count(%d)\n",
  191. HPDF_LIMIT_MAX_ARRAY));
  192. HPDF_Obj_Free (array->mmgr, obj);
  193. return HPDF_SetError (array->error, HPDF_ARRAY_COUNT_ERR, 0);
  194. }
  195. if (header->obj_id & HPDF_OTYPE_INDIRECT) {
  196. HPDF_Proxy proxy = HPDF_Proxy_New (array->mmgr, obj);
  197. if (!proxy) {
  198. HPDF_Obj_Free (array->mmgr, obj);
  199. return HPDF_Error_GetCode (array->error);
  200. }
  201. proxy->header.obj_id |= HPDF_OTYPE_DIRECT;
  202. obj = proxy;
  203. } else
  204. header->obj_id |= HPDF_OTYPE_DIRECT;
  205. /* get the target-object from object-list
  206. * consider that the pointer contained in list may be proxy-object.
  207. */
  208. for (i = 0; i < array->list->count; i++) {
  209. void *ptr = HPDF_List_ItemAt (array->list, i);
  210. void *obj_ptr;
  211. header = (HPDF_Obj_Header *)obj;
  212. if (header->obj_class == HPDF_OCLASS_PROXY)
  213. obj_ptr = ((HPDF_Proxy)ptr)->obj;
  214. else
  215. obj_ptr = ptr;
  216. if (obj_ptr == target) {
  217. ret = HPDF_List_Insert (array->list, ptr, obj);
  218. if (ret != HPDF_OK)
  219. HPDF_Obj_Free (array->mmgr, obj);
  220. return ret;
  221. }
  222. }
  223. HPDF_Obj_Free (array->mmgr, obj);
  224. return HPDF_ITEM_NOT_FOUND;
  225. }
  226. void*
  227. HPDF_Array_GetItem (HPDF_Array array,
  228. HPDF_UINT index,
  229. HPDF_UINT16 obj_class)
  230. {
  231. void *obj;
  232. HPDF_Obj_Header *header;
  233. HPDF_PTRACE((" HPDF_Array_GetItem\n"));
  234. obj = HPDF_List_ItemAt (array->list, index);
  235. if (!obj) {
  236. HPDF_SetError (array->error, HPDF_ARRAY_ITEM_NOT_FOUND, 0);
  237. return NULL;
  238. }
  239. header = (HPDF_Obj_Header *)obj;
  240. if (header->obj_class == HPDF_OCLASS_PROXY) {
  241. obj = ((HPDF_Proxy)obj)->obj;
  242. header = (HPDF_Obj_Header *)obj;
  243. }
  244. if ((header->obj_class & HPDF_OCLASS_ANY) != obj_class) {
  245. HPDF_SetError (array->error, HPDF_ARRAY_ITEM_UNEXPECTED_TYPE, 0);
  246. return NULL;
  247. }
  248. return obj;
  249. }
  250. void
  251. HPDF_Array_Clear (HPDF_Array array)
  252. {
  253. HPDF_UINT i;
  254. HPDF_PTRACE((" HPDF_Array_Clear\n"));
  255. if (!array)
  256. return;
  257. for (i = 0; i < array->list->count; i++) {
  258. void * obj = HPDF_List_ItemAt (array->list, i);
  259. if (obj) {
  260. HPDF_Obj_Free (array->mmgr, obj);
  261. }
  262. }
  263. HPDF_List_Clear (array->list);
  264. }