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 |
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 |
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* |
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* |
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* |
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* |
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* |
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 |
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 |
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* |
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 |
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* |
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 |
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 |
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 |
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 |
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 | |