PageRenderTime 43ms CodeModel.GetById 9ms RepoModel.GetById 0ms app.codeStats 0ms

/TeXmacs-1.0.7.11-src/src/Plugins/Pdf/dvipdfmx/pst_obj.c

#
C | 894 lines | 717 code | 119 blank | 58 comment | 113 complexity | 9d31d0a017f203e577c40597ef682328 MD5 | raw file
Possible License(s): GPL-3.0, GPL-2.0, MPL-2.0-no-copyleft-exception
  1. /* $Header: /home/cvsroot/dvipdfmx/src/pst_obj.c,v 1.9 2008/11/30 21:12:27 matthias Exp $
  2. This is dvipdfmx, an eXtended version of dvipdfm by Mark A. Wicks.
  3. Copyright (C) 2002 by Jin-Hwan Cho and Shunsaku Hirata,
  4. the dvipdfmx project team <dvipdfmx@project.ktug.or.kr>
  5. Copyright (C) 1998, 1999 by Mark A. Wicks <mwicks@kettering.edu>
  6. This program is free software; you can redistribute it and/or modify
  7. it under the terms of the GNU General Public License as published by
  8. the Free Software Foundation; either version 2 of the License, or
  9. (at your option) any later version.
  10. This program is distributed in the hope that it will be useful,
  11. but WITHOUT ANY WARRANTY; without even the implied warranty of
  12. MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  13. GNU General Public License for more details.
  14. You should have received a copy of the GNU General Public License
  15. along with this program; if not, write to the Free Software
  16. Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA.
  17. */
  18. #include <string.h>
  19. #include <stdlib.h>
  20. #include <errno.h>
  21. #include "system.h"
  22. #include "mem.h"
  23. #include "error.h"
  24. #include "dpxutil.h"
  25. #include "pst.h"
  26. #include "pst_obj.h"
  27. struct pst_obj
  28. {
  29. pst_type type;
  30. void *data;
  31. };
  32. static const char *pst_const_null = "null";
  33. static const char *pst_const_mark = "mark";
  34. /*
  35. static const char *pst_const_true = "true";
  36. static const char *pst_const_false = "false";
  37. */
  38. typedef char * pst_null;
  39. typedef struct { char value; } pst_boolean;
  40. typedef struct { long value; } pst_integer;
  41. typedef struct { double value; } pst_real;
  42. typedef struct { char *value; } pst_name;
  43. typedef struct
  44. {
  45. long length;
  46. unsigned char *value;
  47. } pst_string;
  48. /* BOOLEAN */
  49. static pst_boolean *pst_boolean_new (char value) ;
  50. static void pst_boolean_release (pst_boolean *obj);
  51. static long pst_boolean_IV (pst_boolean *obj);
  52. static double pst_boolean_RV (pst_boolean *obj);
  53. static unsigned char *pst_boolean_SV (pst_boolean *obj);
  54. static long pst_boolean_length (pst_boolean *obj);
  55. static void *pst_boolean_data_ptr(pst_boolean *obj);
  56. /* NUMBERS */
  57. static pst_integer *pst_integer_new (long value) ;
  58. static void pst_integer_release (pst_integer *obj);
  59. static long pst_integer_IV (pst_integer *obj);
  60. static double pst_integer_RV (pst_integer *obj);
  61. static unsigned char *pst_integer_SV (pst_integer *obj);
  62. static unsigned int pst_integer_length (pst_integer *obj);
  63. static void *pst_integer_data_ptr(pst_integer *obj);
  64. static pst_real *pst_real_new (double value) ;
  65. static void pst_real_release (pst_real *obj);
  66. static long pst_real_IV (pst_real *obj);
  67. static double pst_real_RV (pst_real *obj);
  68. static unsigned char *pst_real_SV (pst_real *obj);
  69. static void *pst_real_data_ptr (pst_real *obj);
  70. static unsigned int pst_real_length (pst_real *obj);
  71. /* NAME */
  72. static pst_name *pst_name_new (const char *name) ;
  73. static void pst_name_release (pst_name *obj);
  74. static long pst_name_IV (pst_name *obj);
  75. static double pst_name_RV (pst_name *obj);
  76. static unsigned char *pst_name_SV (pst_name *obj);
  77. static void *pst_name_data_ptr (pst_name *obj);
  78. static unsigned int pst_name_length (pst_name *obj);
  79. /* STRING */
  80. static pst_string *pst_string_parse_literal (unsigned char **inbuf, unsigned char *inbufend);
  81. static pst_string *pst_string_parse_hex (unsigned char **inbuf, unsigned char *inbufend);
  82. static pst_string *pst_string_new (unsigned char *str, unsigned int len);
  83. static void pst_string_release (pst_string *obj) ;
  84. static long pst_string_IV (pst_string *obj) ;
  85. static double pst_string_RV (pst_string *obj) ;
  86. static unsigned char *pst_string_SV (pst_string *obj) ;
  87. static void *pst_string_data_ptr (pst_string *obj) ;
  88. static unsigned int pst_string_length (pst_string *obj) ;
  89. #define TYPE_ERROR() ERROR("Operation not defined for this type of object.")
  90. pst_obj *
  91. pst_new_obj (pst_type type, void *data)
  92. {
  93. pst_obj *obj;
  94. obj = NEW(1, struct pst_obj);
  95. obj->type = type;
  96. obj->data = data;
  97. return obj;
  98. }
  99. pst_obj *
  100. pst_new_mark (void)
  101. {
  102. return pst_new_obj(PST_TYPE_MARK, (void *)pst_const_mark);
  103. }
  104. void
  105. pst_release_obj (pst_obj *obj)
  106. {
  107. ASSERT(obj);
  108. switch (obj->type) {
  109. case PST_TYPE_BOOLEAN: pst_boolean_release(obj->data); break;
  110. case PST_TYPE_INTEGER: pst_integer_release(obj->data); break;
  111. case PST_TYPE_REAL: pst_real_release(obj->data); break;
  112. case PST_TYPE_NAME: pst_name_release(obj->data); break;
  113. case PST_TYPE_STRING: pst_string_release(obj->data); break;
  114. case PST_TYPE_NULL:
  115. case PST_TYPE_MARK:
  116. break;
  117. case PST_TYPE_UNKNOWN:
  118. if (obj->data)
  119. RELEASE(obj->data);
  120. break;
  121. default:
  122. ERROR("Unrecognized object type: %d", obj->type);
  123. }
  124. RELEASE(obj);
  125. }
  126. pst_type
  127. pst_type_of (pst_obj *obj)
  128. {
  129. ASSERT(obj);
  130. return obj->type;
  131. }
  132. long
  133. pst_length_of (pst_obj *obj)
  134. {
  135. long len = 0;
  136. ASSERT(obj);
  137. switch (obj->type) {
  138. case PST_TYPE_BOOLEAN: len = pst_boolean_length(obj->data); break;
  139. case PST_TYPE_INTEGER: len = pst_integer_length(obj->data); break;
  140. case PST_TYPE_REAL: len = pst_real_length(obj->data); break;
  141. case PST_TYPE_NAME: len = pst_name_length(obj->data); break;
  142. case PST_TYPE_STRING: len = pst_string_length(obj->data); break;
  143. case PST_TYPE_NULL:
  144. case PST_TYPE_MARK:
  145. TYPE_ERROR();
  146. break;
  147. case PST_TYPE_UNKNOWN:
  148. len = strlen(obj->data);
  149. break;
  150. default:
  151. ERROR("Unrecognized object type: %d", obj->type);
  152. }
  153. return len;
  154. }
  155. long
  156. pst_getIV (pst_obj *obj)
  157. {
  158. long iv = 0;
  159. ASSERT(obj);
  160. switch (obj->type) {
  161. case PST_TYPE_BOOLEAN: iv = pst_boolean_IV(obj->data); break;
  162. case PST_TYPE_INTEGER: iv = pst_integer_IV(obj->data); break;
  163. case PST_TYPE_REAL: iv = pst_real_IV(obj->data); break;
  164. case PST_TYPE_NAME: iv = pst_name_IV(obj->data); break;
  165. case PST_TYPE_STRING: iv = pst_string_IV(obj->data); break;
  166. case PST_TYPE_NULL:
  167. case PST_TYPE_MARK:
  168. TYPE_ERROR();
  169. break;
  170. case PST_TYPE_UNKNOWN:
  171. ERROR("Cannot convert object of type UNKNOWN to integer value.");
  172. break;
  173. default:
  174. ERROR("Unrecognized object type: %d", obj->type);
  175. }
  176. return iv;
  177. }
  178. double
  179. pst_getRV (pst_obj *obj)
  180. {
  181. double rv = 0.0;
  182. ASSERT(obj);
  183. switch (obj->type) {
  184. case PST_TYPE_BOOLEAN: rv = pst_boolean_RV(obj->data); break;
  185. case PST_TYPE_INTEGER: rv = pst_integer_RV(obj->data); break;
  186. case PST_TYPE_REAL: rv = pst_real_RV(obj->data); break;
  187. case PST_TYPE_NAME: rv = pst_name_RV(obj->data); break;
  188. case PST_TYPE_STRING: rv = pst_string_RV(obj->data); break;
  189. case PST_TYPE_NULL:
  190. case PST_TYPE_MARK:
  191. TYPE_ERROR();
  192. break;
  193. case PST_TYPE_UNKNOWN:
  194. ERROR("Cannot convert object of type UNKNOWN to real value.");
  195. break;
  196. default:
  197. ERROR("Unrecognized object type: %d", obj->type);
  198. }
  199. return rv;
  200. }
  201. /* Length can be obtained by pst_length_of(). */
  202. unsigned char *
  203. pst_getSV (pst_obj *obj)
  204. {
  205. unsigned char *sv = NULL;
  206. ASSERT(obj);
  207. switch (obj->type) {
  208. case PST_TYPE_BOOLEAN: sv = pst_boolean_SV(obj->data); break;
  209. case PST_TYPE_INTEGER: sv = pst_integer_SV(obj->data); break;
  210. case PST_TYPE_REAL: sv = pst_real_SV(obj->data); break;
  211. case PST_TYPE_NAME: sv = pst_name_SV(obj->data); break;
  212. case PST_TYPE_STRING: sv = pst_string_SV(obj->data); break;
  213. case PST_TYPE_NULL:
  214. case PST_TYPE_MARK:
  215. TYPE_ERROR();
  216. break;
  217. case PST_TYPE_UNKNOWN:
  218. {
  219. long len;
  220. len = strlen((char *) obj->data);
  221. if (len > 0) {
  222. sv = NEW(len+1, unsigned char);
  223. memcpy(sv, obj->data, len);
  224. sv[len] = '\0';
  225. } else {
  226. sv = NULL;
  227. }
  228. break;
  229. }
  230. default:
  231. ERROR("Unrecognized object type: %d", obj->type);
  232. }
  233. return sv;
  234. }
  235. void *
  236. pst_data_ptr (pst_obj *obj)
  237. {
  238. char *p = NULL;
  239. ASSERT(obj);
  240. switch (obj->type) {
  241. case PST_TYPE_BOOLEAN: p = pst_boolean_data_ptr(obj->data); break;
  242. case PST_TYPE_INTEGER: p = pst_integer_data_ptr(obj->data); break;
  243. case PST_TYPE_REAL: p = pst_real_data_ptr(obj->data); break;
  244. case PST_TYPE_NAME: p = pst_name_data_ptr(obj->data); break;
  245. case PST_TYPE_STRING: p = pst_string_data_ptr(obj->data); break;
  246. case PST_TYPE_NULL:
  247. case PST_TYPE_MARK:
  248. TYPE_ERROR();
  249. break;
  250. case PST_TYPE_UNKNOWN:
  251. p = obj->data;
  252. break;
  253. default:
  254. ERROR("Unrecognized object type: %d", obj->type);
  255. }
  256. return (void *)p;
  257. }
  258. /* BOOLEAN */
  259. static pst_boolean *
  260. pst_boolean_new (char value)
  261. {
  262. pst_boolean *obj;
  263. obj = NEW(1, pst_boolean);
  264. obj->value = value;
  265. return obj;
  266. }
  267. static void
  268. pst_boolean_release (pst_boolean *obj)
  269. {
  270. ASSERT(obj);
  271. RELEASE(obj);
  272. }
  273. static long
  274. pst_boolean_IV (pst_boolean *obj)
  275. {
  276. ASSERT(obj);
  277. return (long) obj->value;
  278. }
  279. static double
  280. pst_boolean_RV (pst_boolean *obj)
  281. {
  282. ASSERT(obj);
  283. return (double) obj->value;
  284. }
  285. static unsigned char *
  286. pst_boolean_SV (pst_boolean *obj)
  287. {
  288. unsigned char *str;
  289. ASSERT(obj);
  290. if (obj->value) {
  291. str = NEW(5, unsigned char);
  292. memcpy(str, "true", 4);
  293. str[4] = '\0';
  294. } else {
  295. str = NEW(6, unsigned char);
  296. memcpy(str, "false", 5);
  297. str[5] = '\0';
  298. }
  299. return str;
  300. }
  301. static long
  302. pst_boolean_length (pst_boolean *obj)
  303. {
  304. TYPE_ERROR();
  305. return 0;
  306. }
  307. static void *
  308. pst_boolean_data_ptr (pst_boolean *obj)
  309. {
  310. ASSERT(obj);
  311. return (void*) &(obj->value);
  312. }
  313. pst_obj *
  314. pst_parse_boolean (unsigned char **inbuf, unsigned char *inbufend)
  315. {
  316. if (*inbuf + 4 <= inbufend &&
  317. memcmp(*inbuf, "true", 4) == 0 &&
  318. PST_TOKEN_END(*inbuf + 4, inbufend)) {
  319. *inbuf += 4;
  320. return pst_new_obj(PST_TYPE_BOOLEAN, pst_boolean_new(1));
  321. } else if (*inbuf + 5 <= inbufend &&
  322. memcmp(*inbuf, "false", 5) == 0 &&
  323. PST_TOKEN_END(*inbuf + 5, inbufend)) {
  324. *inbuf += 5;
  325. return pst_new_obj(PST_TYPE_BOOLEAN, pst_boolean_new(0));
  326. } else
  327. return NULL;
  328. }
  329. /* NULL */
  330. pst_obj *
  331. pst_parse_null (unsigned char **inbuf, unsigned char *inbufend)
  332. {
  333. if (*inbuf + 4 <= inbufend &&
  334. memcmp(*inbuf, "null", 4) == 0 &&
  335. PST_TOKEN_END(*inbuf+4, inbufend)) {
  336. *inbuf += 4;
  337. return pst_new_obj(PST_TYPE_NULL, (void*)pst_const_null);
  338. } else
  339. return NULL;
  340. }
  341. /* INTEGER */
  342. static pst_integer *
  343. pst_integer_new (long value)
  344. {
  345. pst_integer *obj;
  346. obj = NEW(1, pst_integer);
  347. obj->value = value;
  348. return obj;
  349. }
  350. static void
  351. pst_integer_release (pst_integer *obj)
  352. {
  353. ASSERT(obj);
  354. RELEASE(obj);
  355. }
  356. static long
  357. pst_integer_IV (pst_integer *obj)
  358. {
  359. ASSERT(obj);
  360. return (long) obj->value;
  361. }
  362. static double
  363. pst_integer_RV (pst_integer *obj)
  364. {
  365. ASSERT(obj);
  366. return (double) obj->value;
  367. }
  368. static unsigned char *
  369. pst_integer_SV (pst_integer *obj)
  370. {
  371. char *value;
  372. int len;
  373. char fmt_buf[PST_MAX_DIGITS+5];
  374. ASSERT(obj);
  375. len = sprintf(fmt_buf, "%ld", obj->value);
  376. value = NEW(len, char);
  377. strcpy(value, fmt_buf);
  378. return (unsigned char *) value;
  379. }
  380. static void *
  381. pst_integer_data_ptr (pst_integer *obj)
  382. {
  383. ASSERT(obj);
  384. return (void*) &(obj->value);
  385. }
  386. static unsigned int
  387. pst_integer_length (pst_integer *obj)
  388. {
  389. TYPE_ERROR();
  390. return 0;
  391. }
  392. /* REAL */
  393. static pst_real *
  394. pst_real_new (double value)
  395. {
  396. pst_real *obj;
  397. obj = NEW(1, pst_real);
  398. obj->value = value;
  399. return obj;
  400. }
  401. static void
  402. pst_real_release (pst_real *obj)
  403. {
  404. ASSERT(obj);
  405. RELEASE(obj);
  406. }
  407. static long
  408. pst_real_IV (pst_real *obj)
  409. {
  410. ASSERT(obj);
  411. return (long) obj->value;
  412. }
  413. static double
  414. pst_real_RV (pst_real *obj)
  415. {
  416. ASSERT(obj);
  417. return (double) obj->value;
  418. }
  419. static unsigned char *
  420. pst_real_SV (pst_real *obj)
  421. {
  422. char *value;
  423. int len;
  424. char fmt_buf[PST_MAX_DIGITS+5];
  425. ASSERT(obj);
  426. len = sprintf(fmt_buf, "%.5g", obj->value);
  427. value = NEW(len, char);
  428. strcpy(value, fmt_buf);
  429. return (unsigned char *) value;
  430. }
  431. static void *
  432. pst_real_data_ptr (pst_real *obj)
  433. {
  434. ASSERT(obj);
  435. return (void*) &(obj->value);
  436. }
  437. static unsigned int
  438. pst_real_length (pst_real *obj)
  439. {
  440. TYPE_ERROR();
  441. return 0;
  442. }
  443. /* NOTE: the input buffer must be null-terminated, i.e., *inbufend == 0 */
  444. /* leading white-space is ignored */
  445. pst_obj *
  446. pst_parse_number (unsigned char **inbuf, unsigned char *inbufend)
  447. {
  448. unsigned char *cur;
  449. long lval;
  450. double dval;
  451. errno = 0;
  452. lval = strtol((char *) *inbuf, (char **) (void *) &cur, 10);
  453. if (errno || *cur == '.' || *cur == 'e' || *cur == 'E') {
  454. /* real */
  455. errno = 0;
  456. dval = strtod((char *) *inbuf, (char **) (void *) &cur);
  457. if (!errno && PST_TOKEN_END(cur, inbufend)) {
  458. *inbuf = cur;
  459. return pst_new_obj(PST_TYPE_REAL, pst_real_new(dval));
  460. }
  461. } else if (cur != *inbuf && PST_TOKEN_END(cur, inbufend)) {
  462. /* integer */
  463. *inbuf = cur;
  464. return pst_new_obj(PST_TYPE_INTEGER, pst_integer_new(lval));
  465. } else if (lval >= 2 && lval <= 36 && *cur == '#' && isalnum(*++cur) &&
  466. /* strtod allows leading "0x" for hex numbers, but we don't */
  467. (lval != 16 || (cur[1] != 'x' && cur[1] != 'X'))) {
  468. /* integer with radix */
  469. /* Can the base have a (plus) sign? I think yes. */
  470. errno = 0;
  471. lval = strtol((char *) cur, (char **) (void *) &cur, lval);
  472. if (!errno && PST_TOKEN_END(cur, inbufend)) {
  473. *inbuf = cur;
  474. return pst_new_obj(PST_TYPE_INTEGER, pst_integer_new(lval));
  475. }
  476. }
  477. /* error */
  478. return NULL;
  479. }
  480. /* NAME */
  481. /*
  482. * \0 is not allowed for name object.
  483. */
  484. static pst_name *
  485. pst_name_new (const char *name)
  486. {
  487. pst_name *obj;
  488. obj = NEW(1, pst_name);
  489. obj->value = NEW(strlen(name)+1, char);
  490. strcpy(obj->value, name);
  491. return obj;
  492. }
  493. static void
  494. pst_name_release (pst_name *obj)
  495. {
  496. ASSERT(obj);
  497. if (obj->value)
  498. RELEASE(obj->value);
  499. RELEASE(obj);
  500. }
  501. #if 0
  502. int
  503. pst_name_is_valid (const char *name)
  504. {
  505. static const char *valid_chars =
  506. "!\"#$&'*+,-.0123456789:;=?@ABCDEFGHIJKLMNOPQRSTUVWXYZ\\^_`abcdefghijklmnopqrstuvwxyz|~";
  507. if (strspn(name, valid_chars) == strlen(name))
  508. return 1;
  509. else
  510. return 0;
  511. }
  512. char *
  513. pst_name_encode (const char *name)
  514. {
  515. char *encoded_name, *p;
  516. int i, len;
  517. char c;
  518. len = strlen(name);
  519. if (len > PST_NAME_LEN_MAX) {
  520. WARN("Input string too long for name object. String will be truncated.");
  521. len = PST_NAME_LEN_MAX;
  522. }
  523. p = encoded_name = NEW(3*len+1, char);
  524. for (i = 0; i < len; i++) {
  525. c = name[i];
  526. if (c < '!' || c > '~' ||
  527. c == '#' || is_delim(c) || is_space(c)) {
  528. *p++ = '#';
  529. putxpair(c, &p);
  530. } else {
  531. *p++ = c;
  532. }
  533. }
  534. *p = '\0';
  535. return encoded_name;
  536. }
  537. #endif
  538. pst_obj *
  539. pst_parse_name (unsigned char **inbuf, unsigned char *inbufend) /* / is required */
  540. {
  541. unsigned char wbuf[PST_NAME_LEN_MAX+1];
  542. unsigned char c, *p = wbuf, *cur = *inbuf;
  543. int len = 0;
  544. if (*cur != '/')
  545. return NULL;
  546. cur++;
  547. while (!PST_TOKEN_END(cur, inbufend)) {
  548. c = *cur++;
  549. if (c == '#') {
  550. int val;
  551. if (cur + 2 >= inbufend) {
  552. WARN("Premature end of input name string.");
  553. break;
  554. }
  555. val = getxpair(&cur);
  556. if (val <= 0) {
  557. WARN("Invalid char for name object. (ignored)");
  558. continue;
  559. } else
  560. c = (unsigned char) val;
  561. }
  562. if (len < PST_NAME_LEN_MAX)
  563. *p++ = c;
  564. len++;
  565. }
  566. *p = '\0';
  567. if (len > PST_NAME_LEN_MAX)
  568. WARN("String too long for name object. Output will be truncated.");
  569. *inbuf = cur;
  570. return pst_new_obj(PST_TYPE_NAME, pst_name_new((char *)wbuf));
  571. }
  572. static long
  573. pst_name_IV (pst_name *obj)
  574. {
  575. TYPE_ERROR();
  576. return 0;
  577. }
  578. static double
  579. pst_name_RV (pst_name *obj)
  580. {
  581. TYPE_ERROR();
  582. return 0;
  583. }
  584. static unsigned char *
  585. pst_name_SV (pst_name *obj)
  586. {
  587. char *value;
  588. value = NEW(strlen(obj->value)+1, char);
  589. strcpy(value, obj->value);
  590. return (unsigned char *) value;
  591. }
  592. static void *
  593. pst_name_data_ptr (pst_name *obj)
  594. {
  595. ASSERT(obj);
  596. return obj->value;
  597. }
  598. static unsigned int
  599. pst_name_length (pst_name *obj)
  600. {
  601. ASSERT(obj);
  602. return strlen(obj->value);
  603. }
  604. /* STRING */
  605. /*
  606. * TODO: ascii85 string <~ .... ~>
  607. */
  608. static pst_string *
  609. pst_string_new (unsigned char *str, unsigned int len)
  610. {
  611. pst_string *obj;
  612. obj = NEW(1, pst_string);
  613. obj->length = len;
  614. obj->value = NULL;
  615. if (len > 0) {
  616. obj->value = NEW(len, unsigned char);
  617. if (str)
  618. memcpy(obj->value, str, len);
  619. }
  620. return obj;
  621. }
  622. static void
  623. pst_string_release (pst_string *obj)
  624. {
  625. ASSERT(obj);
  626. if (obj->value)
  627. RELEASE(obj->value);
  628. RELEASE(obj);
  629. }
  630. pst_obj *
  631. pst_parse_string (unsigned char **inbuf, unsigned char *inbufend)
  632. {
  633. if (*inbuf + 2 >= inbufend) {
  634. return NULL;
  635. } else if (**inbuf == '(')
  636. return pst_new_obj(PST_TYPE_STRING, pst_string_parse_literal(inbuf, inbufend));
  637. else if (**inbuf == '<' && *(*inbuf+1) == '~')
  638. ERROR("ASCII85 string not supported yet.");
  639. else if (**inbuf == '<')
  640. return pst_new_obj(PST_TYPE_STRING, pst_string_parse_hex(inbuf, inbufend));
  641. return NULL;
  642. }
  643. static pst_string *
  644. pst_string_parse_literal (unsigned char **inbuf, unsigned char *inbufend)
  645. {
  646. unsigned char wbuf[PST_STRING_LEN_MAX];
  647. unsigned char *cur = *inbuf, c = 0;
  648. long len = 0, balance = 1;
  649. if (cur + 2 > inbufend || *cur != '(')
  650. return NULL;
  651. cur++;
  652. while (cur < inbufend && len < PST_STRING_LEN_MAX && balance > 0) {
  653. c = *(cur++);
  654. switch (c) {
  655. case '\\':
  656. {
  657. unsigned char unescaped, valid;
  658. unescaped = esctouc(&cur, inbufend, &valid);
  659. if (valid)
  660. wbuf[len++] = unescaped;
  661. }
  662. break;
  663. case '(':
  664. balance++;
  665. wbuf[len++] = '(';
  666. break;
  667. case ')':
  668. balance--;
  669. if (balance > 0)
  670. wbuf[len++] = ')';
  671. break;
  672. /*
  673. * An end-of-line marker (\n, \r or \r\n), not preceeded by a backslash,
  674. * must be converted to single \n.
  675. */
  676. case '\r':
  677. if (cur < inbufend && *cur == '\n')
  678. cur++;
  679. wbuf[len++] = '\n';
  680. break;
  681. default:
  682. wbuf[len++] = c;
  683. }
  684. }
  685. if (c != ')')
  686. return NULL;
  687. *inbuf = cur;
  688. return pst_string_new(wbuf, len);
  689. }
  690. static pst_string *
  691. pst_string_parse_hex (unsigned char **inbuf, unsigned char *inbufend)
  692. {
  693. unsigned char wbuf[PST_STRING_LEN_MAX];
  694. unsigned char *cur = *inbuf;
  695. unsigned long len = 0;
  696. if (cur + 2 > inbufend || *cur != '<' ||
  697. (*cur == '<' && *(cur+1) == '<'))
  698. return NULL;
  699. cur++;
  700. /* PDF Reference does not specify how to treat invalid char */
  701. while (cur < inbufend && len < PST_STRING_LEN_MAX) {
  702. int hi, lo;
  703. skip_white_spaces(&cur, inbufend);
  704. if (*cur == '>')
  705. break;
  706. hi = xtoi(*(cur++));
  707. if (hi < 0) {
  708. WARN("Invalid char for hex string <%x> treated as <0>.", *(cur-1));
  709. hi = 0;
  710. }
  711. skip_white_spaces(&cur, inbufend);
  712. if (*cur == '>')
  713. break;
  714. /* 0 is appended if final hex digit is missing */
  715. lo = (cur < inbufend) ? xtoi(*(cur++)) : 0;
  716. if (lo < 0) {
  717. WARN("Invalid char for hex string <%x> treated as <0>.", *(cur-1));
  718. lo = 0;
  719. }
  720. wbuf[len++] = (hi << 4) | lo;
  721. }
  722. if (*cur++ != '>')
  723. return NULL;
  724. *inbuf = cur;
  725. return pst_string_new(wbuf, len);
  726. }
  727. static long
  728. pst_string_IV (pst_string *obj)
  729. {
  730. return (long) pst_string_RV(obj);
  731. }
  732. static double
  733. pst_string_RV (pst_string *obj)
  734. {
  735. pst_obj *nobj;
  736. unsigned char *p, *end;
  737. double rv;
  738. ASSERT(obj);
  739. p = obj->value;
  740. end = p + obj->length;
  741. nobj = pst_parse_number(&p, end);
  742. if (nobj == NULL || p != end)
  743. ERROR("Cound not convert string to real value.");
  744. rv = pst_getRV(nobj);
  745. pst_release_obj(nobj);
  746. return rv;
  747. }
  748. static unsigned char *
  749. pst_string_SV (pst_string *obj)
  750. {
  751. unsigned char *str = NULL;
  752. ASSERT(obj);
  753. str = NEW(obj->length + 1, unsigned char);
  754. memcpy(str, obj->value, obj->length);
  755. str[obj->length] = '\0';
  756. return str;
  757. }
  758. static void *
  759. pst_string_data_ptr (pst_string *obj)
  760. {
  761. ASSERT(obj);
  762. return obj->value;
  763. }
  764. static unsigned int
  765. pst_string_length (pst_string *obj)
  766. {
  767. ASSERT(obj);
  768. return obj->length;
  769. }