OSDN Git Service

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