hpdf_string.c 5.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202
  1. /*
  2. * << Haru Free PDF Library >> -- hpdf_string.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 <string.h>
  18. #include "hpdf_conf.h"
  19. #include "hpdf_utils.h"
  20. #include "hpdf_objects.h"
  21. static const HPDF_BYTE UNICODE_HEADER[] = {
  22. 0xFE, 0xFF
  23. };
  24. HPDF_String
  25. HPDF_String_New (HPDF_MMgr mmgr,
  26. const char *value,
  27. HPDF_Encoder encoder)
  28. {
  29. HPDF_String obj;
  30. HPDF_PTRACE((" HPDF_String_New\n"));
  31. obj = (HPDF_String)HPDF_GetMem (mmgr, sizeof(HPDF_String_Rec));
  32. if (obj) {
  33. HPDF_MemSet (&obj->header, 0, sizeof(HPDF_Obj_Header));
  34. obj->header.obj_class = HPDF_OCLASS_STRING;
  35. obj->mmgr = mmgr;
  36. obj->error = mmgr->error;
  37. obj->encoder = encoder;
  38. obj->value = NULL;
  39. obj->len = 0;
  40. if (HPDF_String_SetValue (obj, value) != HPDF_OK) {
  41. HPDF_FreeMem (obj->mmgr, obj);
  42. return NULL;
  43. }
  44. }
  45. return obj;
  46. }
  47. HPDF_STATUS
  48. HPDF_String_SetValue (HPDF_String obj,
  49. const char *value)
  50. {
  51. HPDF_UINT len;
  52. HPDF_STATUS ret = HPDF_OK;
  53. HPDF_PTRACE((" HPDF_String_SetValue\n"));
  54. if (obj->value) {
  55. HPDF_FreeMem (obj->mmgr, obj->value);
  56. obj->len = 0;
  57. }
  58. len = HPDF_StrLen(value, HPDF_LIMIT_MAX_STRING_LEN + 1);
  59. if (len > HPDF_LIMIT_MAX_STRING_LEN)
  60. return HPDF_SetError (obj->error, HPDF_STRING_OUT_OF_RANGE, 0);
  61. obj->value = HPDF_GetMem (obj->mmgr, len + 1);
  62. if (!obj->value)
  63. return HPDF_Error_GetCode (obj->error);
  64. HPDF_StrCpy ((char *)obj->value, value, (char *)obj->value + len);
  65. obj->len = len;
  66. return ret;
  67. }
  68. void
  69. HPDF_String_Free (HPDF_String obj)
  70. {
  71. if (!obj)
  72. return;
  73. HPDF_PTRACE((" HPDF_String_Free\n"));
  74. HPDF_FreeMem (obj->mmgr, obj->value);
  75. HPDF_FreeMem (obj->mmgr, obj);
  76. }
  77. HPDF_STATUS
  78. HPDF_String_Write (HPDF_String obj,
  79. HPDF_Stream stream,
  80. HPDF_Encrypt e)
  81. {
  82. HPDF_STATUS ret;
  83. /*
  84. * When encoder is not NULL, text is changed to unicode using encoder,
  85. * and it outputs by HPDF_write_binary method.
  86. */
  87. HPDF_PTRACE((" HPDF_String_Write\n"));
  88. if (e)
  89. HPDF_Encrypt_Reset (e);
  90. if (obj->encoder == NULL) {
  91. if (e) {
  92. if ((ret = HPDF_Stream_WriteChar (stream, '<')) != HPDF_OK)
  93. return ret;
  94. if ((ret = HPDF_Stream_WriteBinary (stream, obj->value,
  95. HPDF_StrLen ((char *)obj->value, -1), e)) != HPDF_OK)
  96. return ret;
  97. return HPDF_Stream_WriteChar (stream, '>');
  98. } else {
  99. return HPDF_Stream_WriteEscapeText (stream, (char *)obj->value);
  100. }
  101. } else {
  102. HPDF_BYTE* src = obj->value;
  103. HPDF_BYTE buf[HPDF_TEXT_DEFAULT_LEN * 2];
  104. HPDF_UINT tmp_len = 0;
  105. HPDF_BYTE* pbuf = buf;
  106. HPDF_INT32 len = obj->len;
  107. HPDF_ParseText_Rec parse_state;
  108. HPDF_UINT i;
  109. if ((ret = HPDF_Stream_WriteChar (stream, '<')) != HPDF_OK)
  110. return ret;
  111. if ((ret = HPDF_Stream_WriteBinary (stream, UNICODE_HEADER, 2, e))
  112. != HPDF_OK)
  113. return ret;
  114. HPDF_Encoder_SetParseText (obj->encoder, &parse_state, src, len);
  115. for (i = 0; (HPDF_INT32)i < len; i++) {
  116. HPDF_BYTE b = src[i];
  117. HPDF_UNICODE tmp_unicode;
  118. HPDF_ByteType btype = HPDF_Encoder_ByteType (obj->encoder,
  119. &parse_state);
  120. if (tmp_len >= HPDF_TEXT_DEFAULT_LEN - 1) {
  121. if ((ret = HPDF_Stream_WriteBinary (stream, buf,
  122. tmp_len * 2, e)) != HPDF_OK)
  123. return ret;
  124. tmp_len = 0;
  125. pbuf = buf;
  126. }
  127. if (btype != HPDF_BYTE_TYPE_TRIAL) {
  128. if (btype == HPDF_BYTE_TYPE_LEAD) {
  129. HPDF_BYTE b2 = src[i + 1];
  130. HPDF_UINT16 char_code = (HPDF_UINT16)((HPDF_UINT) b * 256 + b2);
  131. tmp_unicode = HPDF_Encoder_ToUnicode (obj->encoder,
  132. char_code);
  133. } else {
  134. tmp_unicode = HPDF_Encoder_ToUnicode (obj->encoder, b);
  135. }
  136. HPDF_UInt16Swap (&tmp_unicode);
  137. HPDF_MemCpy (pbuf, (HPDF_BYTE*)&tmp_unicode, 2);
  138. pbuf += 2;
  139. tmp_len++;
  140. }
  141. }
  142. if (tmp_len > 0) {
  143. if ((ret = HPDF_Stream_WriteBinary (stream, buf, tmp_len * 2, e))
  144. != HPDF_OK)
  145. return ret;
  146. }
  147. if ((ret = HPDF_Stream_WriteChar (stream, '>')) != HPDF_OK)
  148. return ret;
  149. }
  150. return HPDF_OK;
  151. }
  152. HPDF_INT32
  153. HPDF_String_Cmp (HPDF_String s1,
  154. HPDF_String s2)
  155. {
  156. if (s1->len < s2->len) return -1;
  157. if (s1->len > s2->len) return +1;
  158. return memcmp(s1->value, s2->value, s1->len);
  159. }