1 /*
2  * << Haru Free PDF Library >> -- hpdf_utils.c
3  *
4  * URL: http://libharu.org
5  *
6  * Copyright (c) 1999-2006 Takeshi Kanno <takeshi_kanno@est.hi-ho.ne.jp>
7  * Copyright (c) 2007-2009 Antony Dovgal <tony@daylessday.org>
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 
18 #include <stdlib.h>
19 #include "hpdf_utils.h"
20 #include "hpdf_consts.h"
21 
22 /*---------------------------------------------------------------------------*/
23 
24 HPDF_INT
HPDF_AToI(const char * s)25 HPDF_AToI  (const char  *s)
26 {
27     HPDF_BOOL flg = HPDF_FALSE;
28     HPDF_INT  v = 0;
29 
30     if (!s) {
31         return 0;
32     }
33 
34     /* increment pointer until the charactor of 's' is not
35      * white-space-charactor.
36      */
37     while (*s) {
38         if (HPDF_IS_WHITE_SPACE(*s))
39             s++;
40         else {
41             if (*s == '-') {
42                 flg = HPDF_TRUE;
43                 s++;
44             }
45             break;
46         }
47     }
48 
49     while (*s >= '0' && *s <= '9') {
50         v *= 10;
51         v += *s - '0';
52         s++;
53     }
54 
55     if (flg)
56         v *= -1;
57 
58     return v;
59 }
60 
61 
62 HPDF_DOUBLE
HPDF_AToF(const char * s)63 HPDF_AToF  (const char  *s)
64 {
65     HPDF_BOOL flg = HPDF_FALSE;
66     HPDF_INT i = 0;
67     HPDF_DOUBLE v;
68     HPDF_INT tmp = 1;
69 
70     /* increment pointer until the charactor of 's' is not
71      * white-space-charactor.
72      */
73     while (*s) {
74         if (HPDF_IS_WHITE_SPACE(*s))
75             s++;
76         else {
77             if (*s == '-') {
78                 flg = HPDF_TRUE;
79                 s++;
80             }
81             break;
82         }
83     }
84 
85     while (*s >= '0' && *s <= '9') {
86         if (i > 3276)
87             break;
88 
89         i *= 10;
90         i += *s - '0';
91         s++;
92     }
93 
94     if (*s == '.') {
95         s++;
96         while (*s >= '0' && *s <= '9') {
97             if (i > 214748364)
98                 break;
99 
100             i *= 10;
101             i += *s - '0';
102             s++;
103             tmp *= 10;
104         }
105     }
106 
107     v = (HPDF_DOUBLE)i / tmp;
108 
109     if (flg)
110         v *= -1;
111 
112     return v;
113 }
114 
115 
116 char*
HPDF_IToA(char * s,HPDF_INT32 val,char * eptr)117 HPDF_IToA  (char        *s,
118             HPDF_INT32   val,
119             char        *eptr)
120 {
121     char* t;
122     char buf[HPDF_INT_LEN + 1];
123 
124     if (val < 0) {
125         if (val < HPDF_LIMIT_MIN_INT)
126             val = HPDF_LIMIT_MIN_INT;
127         *s++ = '-';
128         val = -val;
129     } else if (val > HPDF_LIMIT_MAX_INT) {
130         val = HPDF_LIMIT_MAX_INT;
131     } else if (val == 0) {
132         *s++ = '0';
133     }
134 
135     t = buf + HPDF_INT_LEN;
136     *t-- = 0;
137 
138     while (val > 0) {
139         *t = (char)((char)(val % 10) + '0');
140         val /= 10;
141         t--;
142     }
143 
144     t++;
145     while (s < eptr && *t != 0)
146       *s++ = *t++;
147     *s = 0;
148 
149     return s;
150 }
151 
152 
153 char*
HPDF_IToA2(char * s,HPDF_UINT32 val,HPDF_UINT len)154 HPDF_IToA2  (char         *s,
155              HPDF_UINT32   val,
156              HPDF_UINT     len)
157 {
158     char* t;
159     char* u;
160 
161     if (val > HPDF_LIMIT_MAX_INT)
162         val = HPDF_LIMIT_MAX_INT;
163 
164     u = s + len - 1;
165     *u = 0;
166     t = u - 1;
167     while (val > 0 && t >= s) {
168         *t = (char)((char)(val % 10) + '0');
169         val /= 10;
170         t--;
171     }
172 
173     while (s <= t)
174         *t-- = '0';
175 
176     return s + len - 1;
177 }
178 
179 
180 char*
HPDF_FToA(char * s,HPDF_REAL val,char * eptr)181 HPDF_FToA  (char       *s,
182             HPDF_REAL   val,
183             char       *eptr)
184 {
185     HPDF_INT32 int_val;
186     HPDF_INT32 fpart_val;
187     char buf[HPDF_REAL_LEN + 1];
188     char* sptr = s;
189     char* t;
190     HPDF_UINT32 i;
191 
192     if (val > HPDF_LIMIT_MAX_REAL)
193         val = HPDF_LIMIT_MAX_REAL;
194     else
195     if (val < HPDF_LIMIT_MIN_REAL)
196         val = HPDF_LIMIT_MIN_REAL;
197 
198     t = buf + HPDF_REAL_LEN;
199     *t-- = 0;
200 
201     if (val < 0) {
202         *s++ = '-';
203         val = -val;
204     }
205 
206     /* separate an integer part and a decimal part. */
207     int_val = (HPDF_INT32)(val + 0.000005);
208     fpart_val = (HPDF_INT32)((HPDF_REAL)(val - int_val + 0.000005) * 100000);
209 
210     /* process decimal part */
211     for (i = 0; i < 5; i++) {
212         *t = (char)((char)(fpart_val % 10) + '0');
213         fpart_val /= 10;
214         t--;
215     }
216 
217     /* process integer part */
218     *t-- = '.';
219     *t = '0';
220     if (int_val == 0)
221         t--;
222 
223     while (int_val > 0) {
224         *t = (char)((char)(int_val % 10) + '0');
225         int_val /= 10;
226         t--;
227     }
228 
229     t++;
230     while (s <= eptr && *t != 0)
231         *s++ = *t++;
232     s--;
233 
234     /* delete an excessive decimal portion. */
235     while (s > sptr) {
236         if (*s == '0')
237             *s = 0;
238         else {
239             if (*s == '.')
240                 *s = 0;
241             break;
242         }
243         s--;
244     }
245 
246     return (*s == 0) ? s : ++s;
247 }
248 
249 
250 HPDF_BYTE*
HPDF_MemCpy(HPDF_BYTE * out,const HPDF_BYTE * in,HPDF_UINT n)251 HPDF_MemCpy  (HPDF_BYTE*         out,
252               const HPDF_BYTE   *in,
253               HPDF_UINT          n)
254 {
255     while (n > 0) {
256         *out++ = *in++;
257         n--;
258     }
259 
260     return out;
261 }
262 
263 
264 HPDF_BYTE*
HPDF_StrCpy(char * out,const char * in,char * eptr)265 HPDF_StrCpy  (char          *out,
266               const char    *in,
267               char          *eptr)
268 {
269     if (in != NULL) {
270         while (eptr > out && *in != 0)
271             *out++ = *in++;
272     }
273 
274     *out = 0;
275 
276     return (HPDF_BYTE *)out;
277 }
278 
279 
280 HPDF_INT
HPDF_MemCmp(const HPDF_BYTE * s1,const HPDF_BYTE * s2,HPDF_UINT n)281 HPDF_MemCmp  (const HPDF_BYTE   *s1,
282               const HPDF_BYTE   *s2,
283               HPDF_UINT          n)
284 {
285     if (n == 0)
286         return 0;
287 
288     while (*s1 == *s2) {
289         n--;
290         if (n == 0)
291             return 0;
292         s1++;
293         s2++;
294     }
295 
296     return *s1 - *s2;
297 }
298 
299 
300 HPDF_INT
HPDF_StrCmp(const char * s1,const char * s2)301 HPDF_StrCmp  (const char   *s1,
302               const char   *s2)
303 {
304     if (!s1 || !s2) {
305         if (!s1 && s2)
306             return -1;
307         else
308             return 1;
309     }
310 
311     while (*s1 == *s2) {
312         s1++;
313         s2++;
314         if (*s1 == 0 || *s2 == 0)
315             break;
316     }
317 
318     return (HPDF_BYTE)*s1 - (HPDF_BYTE)*s2;
319 }
320 
321 
322 void*
HPDF_MemSet(void * s,HPDF_BYTE c,HPDF_UINT n)323 HPDF_MemSet  (void        *s,
324               HPDF_BYTE    c,
325               HPDF_UINT    n)
326 {
327     HPDF_BYTE* b = (HPDF_BYTE*)s;
328 
329     while (n > 0) {
330         *b = c;
331         b++;
332         n--;
333     }
334 
335     return b;
336 }
337 
338 
339 HPDF_UINT
HPDF_StrLen(const char * s,HPDF_INT maxlen)340 HPDF_StrLen  (const char   *s,
341               HPDF_INT      maxlen)
342 {
343     HPDF_INT len = 0;
344 
345     if (!s)
346         return 0;
347 
348     while (*s != 0 && (maxlen < 0 || len < maxlen)) {
349         s++;
350         len++;
351     }
352 
353     return (HPDF_UINT)len;
354 }
355 
356 
357 const char*
HPDF_StrStr(const char * s1,const char * s2,HPDF_UINT maxlen)358 HPDF_StrStr  (const char   *s1,
359               const char   *s2,
360               HPDF_UINT     maxlen)
361 {
362     HPDF_UINT len = HPDF_StrLen (s2, -1);
363 
364     if (!s1)
365         return NULL;
366 
367     if (len == 0)
368         return s1;
369 
370     if (maxlen == 0)
371         maxlen = HPDF_StrLen (s1, -1);
372 
373     if (maxlen < len)
374         return NULL;
375 
376     maxlen -= len;
377     maxlen++;
378 
379     while (maxlen > 0) {
380         if (HPDF_MemCmp ((HPDF_BYTE *)s1, (HPDF_BYTE *)s2, len) == 0)
381             return s1;
382 
383         s1++;
384         maxlen--;
385     }
386 
387     return NULL;
388 }
389 
390 
391 HPDF_Box
HPDF_ToBox(HPDF_INT16 left,HPDF_INT16 bottom,HPDF_INT16 right,HPDF_INT16 top)392 HPDF_ToBox  (HPDF_INT16   left,
393              HPDF_INT16   bottom,
394              HPDF_INT16   right,
395              HPDF_INT16   top)
396 {
397     HPDF_Box box;
398 
399     box.left = left;
400     box.bottom = bottom;
401     box.right = right;
402     box.top = top;
403 
404     return box;
405 }
406 
407 
408 HPDF_Point
HPDF_ToPoint(HPDF_INT16 x,HPDF_INT16 y)409 HPDF_ToPoint  (HPDF_INT16   x,
410                HPDF_INT16   y)
411 {
412     HPDF_Point point;
413 
414     point.x = x;
415     point.y = y;
416 
417     return point;
418 }
419 
420 HPDF_Rect
HPDF_ToRect(HPDF_REAL left,HPDF_REAL bottom,HPDF_REAL right,HPDF_REAL top)421 HPDF_ToRect  (HPDF_REAL   left,
422               HPDF_REAL   bottom,
423               HPDF_REAL   right,
424               HPDF_REAL   top)
425 {
426     HPDF_Rect rect;
427 
428     rect.left = left;
429     rect.bottom = bottom;
430     rect.right = right;
431     rect.top = top;
432 
433     return rect;
434 }
435 
436 
437 void
HPDF_UInt16Swap(HPDF_UINT16 * value)438 HPDF_UInt16Swap  (HPDF_UINT16  *value)
439 {
440     HPDF_BYTE u[2];
441 
442     HPDF_MemCpy (u, (HPDF_BYTE*)value, 2);
443     *value = (HPDF_UINT16)((HPDF_UINT16)u[0] << 8 | (HPDF_UINT16)u[1]);
444 }
445 
446