1 | /* |
2 | * << Haru Free PDF Library >> -- hpdf_streams.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 | #ifndef _CRT_SECURE_NO_WARNINGS |
18 | #define _CRT_SECURE_NO_WARNINGS |
19 | #endif |
20 | |
21 | #ifndef UNDER_CE |
22 | #include <errno.h> |
23 | #endif |
24 | #ifndef HPDF_UNUSED |
25 | #define HPDF_UNUSED(a) ((void)(a)) |
26 | #endif |
27 | |
28 | #include "hpdf_conf.h" |
29 | #include "hpdf_consts.h" |
30 | #include "hpdf_utils.h" |
31 | #include "hpdf_streams.h" |
32 | |
33 | #ifndef LIBHPDF_HAVE_NOZLIB |
34 | #include <zlib.h> |
35 | #include <zconf.h> |
36 | #endif /* LIBHPDF_HAVE_NOZLIB */ |
37 | |
38 | HPDF_STATUS |
39 | HPDF_MemStream_WriteFunc (HPDF_Stream stream, |
40 | const HPDF_BYTE *ptr, |
41 | HPDF_UINT siz); |
42 | |
43 | |
44 | HPDF_STATUS |
45 | HPDF_MemStream_SeekFunc (HPDF_Stream stream, |
46 | HPDF_INT pos, |
47 | HPDF_WhenceMode mode); |
48 | |
49 | |
50 | HPDF_STATUS |
51 | HPDF_MemStream_ReadFunc (HPDF_Stream stream, |
52 | HPDF_BYTE *buf, |
53 | HPDF_UINT *size); |
54 | |
55 | |
56 | HPDF_INT32 |
57 | HPDF_MemStream_TellFunc (HPDF_Stream stream); |
58 | |
59 | |
60 | HPDF_UINT32 |
61 | HPDF_MemStream_SizeFunc (HPDF_Stream stream); |
62 | |
63 | |
64 | void |
65 | HPDF_MemStream_FreeFunc (HPDF_Stream stream); |
66 | |
67 | HPDF_STATUS |
68 | HPDF_MemStream_InWrite (HPDF_Stream stream, |
69 | const HPDF_BYTE **ptr, |
70 | HPDF_UINT *count); |
71 | |
72 | HPDF_STATUS |
73 | HPDF_Stream_WriteToStreamWithDeflate (HPDF_Stream src, |
74 | HPDF_Stream dst, |
75 | HPDF_Encrypt e); |
76 | |
77 | |
78 | HPDF_STATUS |
79 | HPDF_FileReader_ReadFunc (HPDF_Stream stream, |
80 | HPDF_BYTE *ptr, |
81 | HPDF_UINT *siz); |
82 | |
83 | |
84 | HPDF_STATUS |
85 | HPDF_FileReader_SeekFunc (HPDF_Stream stream, |
86 | HPDF_INT pos, |
87 | HPDF_WhenceMode mode); |
88 | |
89 | |
90 | HPDF_INT32 |
91 | HPDF_FileStream_TellFunc (HPDF_Stream stream); |
92 | |
93 | |
94 | HPDF_UINT32 |
95 | HPDF_FileStream_SizeFunc (HPDF_Stream stream); |
96 | |
97 | |
98 | HPDF_STATUS |
99 | HPDF_FileWriter_WriteFunc (HPDF_Stream stream, |
100 | const HPDF_BYTE *ptr, |
101 | HPDF_UINT siz); |
102 | |
103 | void |
104 | HPDF_FileStream_FreeFunc (HPDF_Stream stream); |
105 | |
106 | |
107 | |
108 | /* |
109 | * HPDF_Stream_Read |
110 | * |
111 | * stream : Pointer to a HPDF_Stream object. |
112 | * ptr : Pointer to a buffer to copy read data. |
113 | * size : Pointer to a variable which indecates buffer size. |
114 | * |
115 | * HPDF_Stream_read returns HPDF_OK when success. On failer, it returns |
116 | * error-code returned by reading function of this stream. |
117 | * |
118 | */ |
119 | |
120 | HPDF_STATUS |
121 | HPDF_Stream_Read (HPDF_Stream stream, |
122 | HPDF_BYTE *ptr, |
123 | HPDF_UINT *size) |
124 | { |
125 | if (!(stream->read_fn)) |
126 | return HPDF_SetError (stream->error, HPDF_INVALID_OPERATION, 0); |
127 | |
128 | /* |
129 | if (HPDF_Error_GetCode(stream->error) != HPDF_NOERROR) |
130 | return HPDF_THIS_FUNC_WAS_SKIPPED; |
131 | */ |
132 | |
133 | return stream->read_fn(stream, ptr, size); |
134 | } |
135 | |
136 | |
137 | /* |
138 | * HPDF_Stream_ReadLn |
139 | * |
140 | * stream : Pointer to a HPDF_Stream object. |
141 | * s : Pointer to a buffer to copy read data. |
142 | * size : buffer-size of s. |
143 | * |
144 | * Read from stream until the buffer is exhausted or line-feed charactor is |
145 | * read. |
146 | * |
147 | */ |
148 | HPDF_STATUS |
149 | HPDF_Stream_ReadLn (HPDF_Stream stream, |
150 | char *s, |
151 | HPDF_UINT *size) |
152 | { |
153 | char buf[HPDF_STREAM_BUF_SIZ]; |
154 | HPDF_UINT r_size = *size; |
155 | HPDF_UINT read_size = HPDF_STREAM_BUF_SIZ; |
156 | |
157 | HPDF_PTRACE((" HPDF_Stream_ReadLn\n" )); |
158 | |
159 | if (!stream) |
160 | return HPDF_INVALID_PARAMETER; |
161 | |
162 | if (!s || *size == 0) |
163 | return HPDF_SetError (stream->error, HPDF_INVALID_PARAMETER, 0); |
164 | |
165 | if (!(stream->seek_fn) || !(stream->read_fn)) |
166 | return HPDF_SetError (stream->error, HPDF_INVALID_OPERATION, 0); |
167 | |
168 | if (r_size < HPDF_STREAM_BUF_SIZ) |
169 | read_size = r_size; |
170 | |
171 | *size = 0; |
172 | |
173 | while (r_size > 1) { |
174 | char *pbuf = buf; |
175 | HPDF_STATUS ret = HPDF_Stream_Read (stream, (HPDF_BYTE *)buf, &read_size); |
176 | |
177 | if (ret != HPDF_OK && read_size == 0) |
178 | return ret; |
179 | |
180 | r_size -= read_size; |
181 | |
182 | while (read_size > 0) { |
183 | if (*pbuf == 0x0A || *pbuf == 0x0D) { |
184 | *s = 0; |
185 | read_size--; |
186 | |
187 | /* handling CR-LF marker */ |
188 | if (*pbuf == 0x0D || read_size > 1) { |
189 | pbuf++; |
190 | |
191 | if (*pbuf == 0x0A) |
192 | read_size--; |
193 | } |
194 | |
195 | if (read_size > 0) |
196 | return HPDF_Stream_Seek (stream, 0 - read_size, |
197 | HPDF_SEEK_CUR); |
198 | else |
199 | return HPDF_OK; |
200 | } |
201 | |
202 | *s++ = *pbuf++; |
203 | read_size--; |
204 | (*size)++; |
205 | } |
206 | |
207 | if (r_size < HPDF_STREAM_BUF_SIZ) |
208 | read_size = r_size; |
209 | else |
210 | read_size = HPDF_STREAM_BUF_SIZ; |
211 | |
212 | if (ret == HPDF_STREAM_EOF) |
213 | return HPDF_STREAM_EOF; |
214 | } |
215 | |
216 | *s = 0; |
217 | |
218 | return HPDF_STREAM_READLN_CONTINUE; |
219 | } |
220 | |
221 | |
222 | /* |
223 | * HPDF_Stream_Write |
224 | * |
225 | * stream : Pointer to a HPDF_Stream object. |
226 | * ptr : Pointer to a buffer to write. |
227 | * siz : The size of buffer to write. |
228 | * |
229 | * HPDF_Stream_Write returns HPDF_OK when success. On failer, it returns |
230 | * error-code returned by writing function of this stream. |
231 | * |
232 | */ |
233 | HPDF_STATUS |
234 | HPDF_Stream_Write (HPDF_Stream stream, |
235 | const HPDF_BYTE *ptr, |
236 | HPDF_UINT size) |
237 | { |
238 | HPDF_STATUS ret; |
239 | |
240 | HPDF_PTRACE((" HPDF_Stream_Write\n" )); |
241 | |
242 | if (!(stream->write_fn)) |
243 | return HPDF_SetError(stream->error, HPDF_INVALID_OPERATION, 0); |
244 | |
245 | /* |
246 | if (HPDF_Error_GetCode(stream->error) != HPDF_NOERROR) |
247 | return HPDF_THIS_FUNC_WAS_SKIPPED; |
248 | */ |
249 | |
250 | ret = stream->write_fn(stream, ptr, size); |
251 | |
252 | if (ret != HPDF_OK) |
253 | return ret; |
254 | |
255 | stream->size += size; |
256 | |
257 | return HPDF_OK; |
258 | } |
259 | |
260 | |
261 | HPDF_STATUS |
262 | HPDF_Stream_WriteChar (HPDF_Stream stream, |
263 | char value) |
264 | { |
265 | return HPDF_Stream_Write(stream, (HPDF_BYTE *)&value, sizeof(char)); |
266 | } |
267 | |
268 | |
269 | HPDF_STATUS |
270 | HPDF_Stream_WriteStr (HPDF_Stream stream, |
271 | const char *value) |
272 | { |
273 | HPDF_UINT len = HPDF_StrLen(value, -1); |
274 | |
275 | return HPDF_Stream_Write(stream, (HPDF_BYTE *)value, len); |
276 | } |
277 | |
278 | HPDF_STATUS |
279 | HPDF_Stream_WriteUChar (HPDF_Stream stream, |
280 | HPDF_BYTE value) |
281 | { |
282 | return HPDF_Stream_Write(stream, &value, sizeof(HPDF_BYTE)); |
283 | } |
284 | |
285 | HPDF_STATUS |
286 | HPDF_Stream_WriteInt (HPDF_Stream stream, |
287 | HPDF_INT value) |
288 | { |
289 | char buf[HPDF_INT_LEN + 1]; |
290 | |
291 | char* p = HPDF_IToA(buf, value, buf + HPDF_INT_LEN); |
292 | |
293 | return HPDF_Stream_Write(stream, (HPDF_BYTE *)buf, (HPDF_UINT)(p - buf)); |
294 | } |
295 | |
296 | HPDF_STATUS |
297 | HPDF_Stream_WriteUInt (HPDF_Stream stream, |
298 | HPDF_UINT value) |
299 | { |
300 | return HPDF_Stream_WriteInt(stream, (HPDF_INT)value); |
301 | } |
302 | |
303 | HPDF_STATUS |
304 | HPDF_Stream_WriteReal (HPDF_Stream stream, |
305 | HPDF_REAL value) |
306 | { |
307 | char buf[HPDF_REAL_LEN + 1]; |
308 | |
309 | char* p = HPDF_FToA(buf, value, buf + HPDF_REAL_LEN); |
310 | |
311 | return HPDF_Stream_Write(stream, (HPDF_BYTE *)buf, (HPDF_UINT)(p - buf)); |
312 | } |
313 | |
314 | void |
315 | HPDF_Stream_Free (HPDF_Stream stream) |
316 | { |
317 | if (!stream) |
318 | return; |
319 | |
320 | if (stream->free_fn) |
321 | stream->free_fn(stream); |
322 | |
323 | stream->sig_bytes = 0; |
324 | |
325 | HPDF_FreeMem(stream->mmgr, stream); |
326 | } |
327 | |
328 | HPDF_STATUS |
329 | HPDF_Stream_Seek (HPDF_Stream stream, |
330 | HPDF_INT pos, |
331 | HPDF_WhenceMode mode) |
332 | { |
333 | HPDF_PTRACE((" HPDF_Stream_Seek\n" )); |
334 | |
335 | if (!(stream->seek_fn)) |
336 | return HPDF_SetError (stream->error, HPDF_INVALID_OPERATION, 0); |
337 | |
338 | if (HPDF_Error_GetCode(stream->error) != 0) |
339 | return HPDF_THIS_FUNC_WAS_SKIPPED; |
340 | |
341 | return stream->seek_fn(stream, pos, mode); |
342 | } |
343 | |
344 | |
345 | HPDF_INT32 |
346 | HPDF_Stream_Tell (HPDF_Stream stream) |
347 | { |
348 | HPDF_PTRACE((" HPDF_Stream_Tell\n" )); |
349 | |
350 | if (!(stream->tell_fn)) |
351 | return HPDF_SetError (stream->error, HPDF_INVALID_OPERATION, 0); |
352 | |
353 | if (HPDF_Error_GetCode(stream->error) != 0) |
354 | return HPDF_THIS_FUNC_WAS_SKIPPED; |
355 | |
356 | return stream->tell_fn(stream); |
357 | } |
358 | |
359 | |
360 | HPDF_UINT32 |
361 | HPDF_Stream_Size (HPDF_Stream stream) |
362 | { |
363 | HPDF_PTRACE((" HPDF_Stream_Tell\n" )); |
364 | |
365 | if (stream->write_fn) |
366 | return stream->size; |
367 | |
368 | if (!(stream->size_fn)) { |
369 | HPDF_SetError (stream->error, HPDF_INVALID_OPERATION, 0); |
370 | return 0; |
371 | } |
372 | |
373 | if (HPDF_Error_GetCode(stream->error) != 0) |
374 | return 0; |
375 | |
376 | return stream->size_fn(stream); |
377 | } |
378 | |
379 | |
380 | HPDF_STATUS |
381 | HPDF_Stream_WriteEscapeName (HPDF_Stream stream, |
382 | const char *value) |
383 | { |
384 | char tmp_char[HPDF_LIMIT_MAX_NAME_LEN * 3 + 2]; |
385 | HPDF_UINT len; |
386 | HPDF_INT i; |
387 | const HPDF_BYTE* pos1; |
388 | char* pos2; |
389 | |
390 | HPDF_PTRACE((" HPDF_Stream_WriteEscapeName\n" )); |
391 | |
392 | len = HPDF_StrLen (value, HPDF_LIMIT_MAX_NAME_LEN); |
393 | pos1 = (HPDF_BYTE*)value; |
394 | pos2 = tmp_char; |
395 | |
396 | *pos2++ = '/'; |
397 | for (i = 0; i < (HPDF_INT32)len; i++) { |
398 | HPDF_BYTE c = *pos1++; |
399 | if (HPDF_NEEDS_ESCAPE(c)) { |
400 | *pos2++ = '#'; |
401 | *pos2 = (char)(c >> 4); |
402 | if (*pos2 <= 9) |
403 | *pos2 += 0x30; |
404 | else |
405 | *pos2 += 0x41 - 10; |
406 | pos2++; |
407 | |
408 | *pos2 = (char)(c & 0x0f); |
409 | if (*pos2 <= 9) |
410 | *pos2 += 0x30; |
411 | else |
412 | *pos2 += 0x41 - 10; |
413 | pos2++; |
414 | } else |
415 | *pos2++ = c; |
416 | } |
417 | *pos2 = 0; |
418 | |
419 | return HPDF_Stream_Write (stream, (HPDF_BYTE *)tmp_char, HPDF_StrLen(tmp_char, -1)); |
420 | } |
421 | |
422 | HPDF_STATUS |
423 | HPDF_Stream_WriteEscapeText2 (HPDF_Stream stream, |
424 | const char *text, |
425 | HPDF_UINT len) |
426 | { |
427 | char buf[HPDF_TEXT_DEFAULT_LEN]; |
428 | HPDF_UINT idx = 0; |
429 | HPDF_INT i; |
430 | const char* p = text; |
431 | HPDF_STATUS ret; |
432 | |
433 | HPDF_PTRACE((" HPDF_Stream_WriteEscapeText2\n" )); |
434 | |
435 | /* The following block is commented out because it violates "PDF Spec 7.3.4.2 Literal Strings". |
436 | * It states that the two matching parentheses must still be present to represent an empty |
437 | * string of zero length. |
438 | */ |
439 | /* |
440 | if (!len) |
441 | return HPDF_OK; |
442 | */ |
443 | |
444 | buf[idx++] = '('; |
445 | |
446 | for (i = 0; i < (HPDF_INT)len; i++) { |
447 | HPDF_BYTE c = (HPDF_BYTE)*p++; |
448 | if (HPDF_NEEDS_ESCAPE(c)) { |
449 | buf[idx++] = '\\'; |
450 | |
451 | buf[idx] = (char)(c >> 6); |
452 | buf[idx] += 0x30; |
453 | idx++; |
454 | buf[idx] = (char)((c & 0x38) >> 3); |
455 | buf[idx] += 0x30; |
456 | idx++; |
457 | buf[idx] = (char)(c & 0x07); |
458 | buf[idx] += 0x30; |
459 | idx++; |
460 | } |
461 | else |
462 | buf[idx++] = c; |
463 | |
464 | if (idx > HPDF_TEXT_DEFAULT_LEN - 4) { |
465 | ret = HPDF_Stream_Write (stream, (HPDF_BYTE *)buf, idx); |
466 | if (ret != HPDF_OK) |
467 | return ret; |
468 | idx = 0; |
469 | } |
470 | } |
471 | buf[idx++] = ')'; |
472 | |
473 | ret = HPDF_Stream_Write (stream, (HPDF_BYTE *)buf, idx); |
474 | |
475 | return ret; |
476 | } |
477 | |
478 | HPDF_STATUS |
479 | HPDF_Stream_WriteEscapeText (HPDF_Stream stream, |
480 | const char *text) |
481 | { |
482 | HPDF_UINT len; |
483 | |
484 | HPDF_PTRACE((" HPDF_Stream_WriteEscapeText\n" )); |
485 | |
486 | len = (text == NULL) ? 0 : HPDF_StrLen (text, HPDF_LIMIT_MAX_STRING_LEN); |
487 | |
488 | return HPDF_Stream_WriteEscapeText2(stream, text, len); |
489 | } |
490 | |
491 | HPDF_STATUS |
492 | HPDF_Stream_WriteBinary (HPDF_Stream stream, |
493 | const HPDF_BYTE *data, |
494 | HPDF_UINT len, |
495 | HPDF_Encrypt e) |
496 | { |
497 | char buf[HPDF_TEXT_DEFAULT_LEN]; |
498 | HPDF_BYTE ebuf[HPDF_TEXT_DEFAULT_LEN]; |
499 | HPDF_BYTE *pbuf = NULL; |
500 | HPDF_BOOL flg = HPDF_FALSE; |
501 | HPDF_UINT idx = 0; |
502 | HPDF_UINT i; |
503 | const HPDF_BYTE* p; |
504 | HPDF_STATUS ret = HPDF_OK; |
505 | |
506 | HPDF_PTRACE((" HPDF_Stream_WriteBinary\n" )); |
507 | |
508 | if (e) { |
509 | if (len <= HPDF_TEXT_DEFAULT_LEN) |
510 | pbuf = ebuf; |
511 | else { |
512 | pbuf = (HPDF_BYTE *)HPDF_GetMem (stream->mmgr, len); |
513 | flg = HPDF_TRUE; |
514 | } |
515 | |
516 | HPDF_Encrypt_CryptBuf (e, data, pbuf, len); |
517 | p = pbuf; |
518 | } else { |
519 | p = data; |
520 | } |
521 | |
522 | for (i = 0; i < len; i++, p++) { |
523 | char c = (char)(*p >> 4); |
524 | |
525 | if (c <= 9) |
526 | c += 0x30; |
527 | else |
528 | c += 0x41 - 10; |
529 | buf[idx++] = c; |
530 | |
531 | c = (char)(*p & 0x0f); |
532 | if (c <= 9) |
533 | c += 0x30; |
534 | else |
535 | c += 0x41 - 10; |
536 | buf[idx++] = c; |
537 | |
538 | if (idx > HPDF_TEXT_DEFAULT_LEN - 2) { |
539 | ret = HPDF_Stream_Write (stream, (HPDF_BYTE *)buf, idx); |
540 | if (ret != HPDF_OK) { |
541 | if (flg) |
542 | HPDF_FreeMem (stream->mmgr, pbuf); |
543 | return ret; |
544 | } |
545 | idx = 0; |
546 | } |
547 | } |
548 | |
549 | if (idx > 0) { |
550 | ret = HPDF_Stream_Write (stream, (HPDF_BYTE *)buf, idx); |
551 | } |
552 | |
553 | if (flg) |
554 | HPDF_FreeMem (stream->mmgr, pbuf); |
555 | |
556 | return ret; |
557 | } |
558 | |
559 | |
560 | HPDF_STATUS |
561 | HPDF_Stream_WriteToStreamWithDeflate (HPDF_Stream src, |
562 | HPDF_Stream dst, |
563 | HPDF_Encrypt e) |
564 | { |
565 | #ifndef LIBHPDF_HAVE_NOZLIB |
566 | |
567 | #define DEFLATE_BUF_SIZ ((HPDF_INT)(HPDF_STREAM_BUF_SIZ * 1.1) + 13) |
568 | |
569 | HPDF_STATUS ret; |
570 | HPDF_BOOL flg; |
571 | |
572 | z_stream strm; |
573 | Bytef inbuf[HPDF_STREAM_BUF_SIZ]; |
574 | Bytef otbuf[DEFLATE_BUF_SIZ]; |
575 | HPDF_BYTE ebuf[DEFLATE_BUF_SIZ]; |
576 | |
577 | HPDF_PTRACE((" HPDF_Stream_WriteToStreamWithDeflate\n" )); |
578 | |
579 | /* initialize input stream */ |
580 | ret = HPDF_Stream_Seek (src, 0, HPDF_SEEK_SET); |
581 | if (ret != HPDF_OK) |
582 | return ret; |
583 | |
584 | /* initialize decompression stream. */ |
585 | HPDF_MemSet(&strm, 0x00, sizeof(z_stream)); |
586 | strm.next_out = otbuf; |
587 | strm.avail_out = DEFLATE_BUF_SIZ; |
588 | |
589 | ret = deflateInit_(&strm, Z_DEFAULT_COMPRESSION, ZLIB_VERSION, |
590 | sizeof(z_stream)); |
591 | if (ret != Z_OK) |
592 | return HPDF_SetError (src->error, HPDF_ZLIB_ERROR, ret); |
593 | |
594 | strm.next_in = inbuf; |
595 | strm.avail_in = 0; |
596 | |
597 | flg = HPDF_FALSE; |
598 | for (;;) { |
599 | HPDF_UINT size = HPDF_STREAM_BUF_SIZ; |
600 | |
601 | ret = HPDF_Stream_Read (src, inbuf, &size); |
602 | |
603 | strm.next_in = inbuf; |
604 | strm.avail_in = size; |
605 | |
606 | if (ret != HPDF_OK) { |
607 | if (ret == HPDF_STREAM_EOF) { |
608 | flg = HPDF_TRUE; |
609 | if (size == 0) |
610 | break; |
611 | } else { |
612 | deflateEnd(&strm); |
613 | return ret; |
614 | } |
615 | } |
616 | |
617 | while (strm.avail_in > 0) { |
618 | ret = deflate(&strm, Z_NO_FLUSH); |
619 | if (ret != Z_OK && ret != Z_STREAM_END) { |
620 | deflateEnd(&strm); |
621 | return HPDF_SetError (src->error, HPDF_ZLIB_ERROR, ret); |
622 | } |
623 | |
624 | if (strm.avail_out == 0) { |
625 | if (e) { |
626 | HPDF_Encrypt_CryptBuf (e, otbuf, ebuf, DEFLATE_BUF_SIZ); |
627 | ret = HPDF_Stream_Write(dst, ebuf, DEFLATE_BUF_SIZ); |
628 | } else |
629 | ret = HPDF_Stream_Write (dst, otbuf, DEFLATE_BUF_SIZ); |
630 | |
631 | if (ret != HPDF_OK) { |
632 | deflateEnd(&strm); |
633 | return HPDF_SetError (src->error, HPDF_ZLIB_ERROR, ret); |
634 | } |
635 | |
636 | strm.next_out = otbuf; |
637 | strm.avail_out = DEFLATE_BUF_SIZ; |
638 | } |
639 | } |
640 | |
641 | if (flg) |
642 | break; |
643 | } |
644 | |
645 | flg = HPDF_FALSE; |
646 | for (;;) { |
647 | ret = deflate(&strm, Z_FINISH); |
648 | if (ret != Z_OK && ret != Z_STREAM_END) { |
649 | deflateEnd(&strm); |
650 | return HPDF_SetError (src->error, HPDF_ZLIB_ERROR, ret); |
651 | } |
652 | |
653 | if (ret == Z_STREAM_END) |
654 | flg = HPDF_TRUE; |
655 | |
656 | if (strm.avail_out < DEFLATE_BUF_SIZ) { |
657 | HPDF_UINT osize = DEFLATE_BUF_SIZ - strm.avail_out; |
658 | if (e) { |
659 | HPDF_Encrypt_CryptBuf (e, otbuf, ebuf, osize); |
660 | ret = HPDF_Stream_Write(dst, ebuf, osize); |
661 | } else |
662 | ret = HPDF_Stream_Write (dst, otbuf, osize); |
663 | |
664 | if (ret != HPDF_OK) { |
665 | deflateEnd(&strm); |
666 | return HPDF_SetError (src->error, HPDF_ZLIB_ERROR, ret); |
667 | } |
668 | |
669 | strm.next_out = otbuf; |
670 | strm.avail_out = DEFLATE_BUF_SIZ; |
671 | } |
672 | |
673 | if (flg) |
674 | break; |
675 | } |
676 | |
677 | deflateEnd(&strm); |
678 | return HPDF_OK; |
679 | #else /* LIBHPDF_HAVE_NOZLIB */ |
680 | HPDF_UNUSED (e); |
681 | HPDF_UNUSED (dst); |
682 | HPDF_UNUSED (src); |
683 | return HPDF_UNSUPPORTED_FUNC; |
684 | #endif /* LIBHPDF_HAVE_NOZLIB */ |
685 | } |
686 | |
687 | HPDF_STATUS |
688 | HPDF_Stream_WriteToStream (HPDF_Stream src, |
689 | HPDF_Stream dst, |
690 | HPDF_UINT filter, |
691 | HPDF_Encrypt e) |
692 | { |
693 | HPDF_STATUS ret; |
694 | HPDF_BYTE buf[HPDF_STREAM_BUF_SIZ]; |
695 | HPDF_BYTE ebuf[HPDF_STREAM_BUF_SIZ]; |
696 | HPDF_BOOL flg; |
697 | |
698 | HPDF_PTRACE((" HPDF_Stream_WriteToStream\n" )); |
699 | HPDF_UNUSED (filter); |
700 | |
701 | if (!dst || !(dst->write_fn)) { |
702 | HPDF_SetError (src->error, HPDF_INVALID_OBJECT, 0); |
703 | return HPDF_INVALID_OBJECT; |
704 | } |
705 | |
706 | if (HPDF_Error_GetCode (src->error) != HPDF_NOERROR || |
707 | HPDF_Error_GetCode (dst->error) != HPDF_NOERROR) |
708 | return HPDF_THIS_FUNC_WAS_SKIPPED; |
709 | |
710 | /* initialize input stream */ |
711 | if (HPDF_Stream_Size (src) == 0) |
712 | return HPDF_OK; |
713 | |
714 | #ifndef LIBHPDF_HAVE_NOZLIB |
715 | if (filter & HPDF_STREAM_FILTER_FLATE_DECODE) |
716 | return HPDF_Stream_WriteToStreamWithDeflate (src, dst, e); |
717 | #endif /* LIBHPDF_HAVE_NOZLIB */ |
718 | |
719 | ret = HPDF_Stream_Seek (src, 0, HPDF_SEEK_SET); |
720 | if (ret != HPDF_OK) |
721 | return ret; |
722 | |
723 | flg = HPDF_FALSE; |
724 | for (;;) { |
725 | HPDF_UINT size = HPDF_STREAM_BUF_SIZ; |
726 | |
727 | ret = HPDF_Stream_Read (src, buf, &size); |
728 | |
729 | if (ret != HPDF_OK) { |
730 | if (ret == HPDF_STREAM_EOF) { |
731 | flg = HPDF_TRUE; |
732 | if (size == 0) |
733 | break; |
734 | } else { |
735 | return ret; |
736 | } |
737 | } |
738 | |
739 | if (e) { |
740 | HPDF_Encrypt_CryptBuf (e, buf, ebuf, size); |
741 | ret = HPDF_Stream_Write(dst, ebuf, size); |
742 | } else { |
743 | ret = HPDF_Stream_Write(dst, buf, size); |
744 | } |
745 | |
746 | if (ret != HPDF_OK) |
747 | return ret; |
748 | |
749 | if (flg) |
750 | break; |
751 | } |
752 | |
753 | return HPDF_OK; |
754 | } |
755 | |
756 | HPDF_Stream |
757 | HPDF_FileReader_New (HPDF_MMgr mmgr, |
758 | const char *fname) |
759 | { |
760 | HPDF_Stream stream; |
761 | HPDF_FILEP fp = HPDF_FOPEN (fname, "rb" ); |
762 | |
763 | HPDF_PTRACE((" HPDF_FileReader_New\n" )); |
764 | |
765 | if (!fp) { |
766 | #ifdef UNDER_CE |
767 | HPDF_SetError (mmgr->error, HPDF_FILE_OPEN_ERROR, GetLastError()); |
768 | #else |
769 | HPDF_SetError (mmgr->error, HPDF_FILE_OPEN_ERROR, errno); |
770 | #endif |
771 | return NULL; |
772 | } |
773 | |
774 | stream = (HPDF_Stream)HPDF_GetMem(mmgr, sizeof(HPDF_Stream_Rec)); |
775 | |
776 | if (stream) { |
777 | HPDF_MemSet(stream, 0, sizeof(HPDF_Stream_Rec)); |
778 | stream->sig_bytes = HPDF_STREAM_SIG_BYTES; |
779 | stream->type = HPDF_STREAM_FILE; |
780 | stream->error = mmgr->error; |
781 | stream->mmgr = mmgr; |
782 | stream->read_fn = HPDF_FileReader_ReadFunc; |
783 | stream->seek_fn = HPDF_FileReader_SeekFunc; |
784 | stream->tell_fn = HPDF_FileStream_TellFunc; |
785 | stream->size_fn = HPDF_FileStream_SizeFunc; |
786 | stream->free_fn = HPDF_FileStream_FreeFunc; |
787 | stream->attr = fp; |
788 | } |
789 | |
790 | return stream; |
791 | } |
792 | |
793 | /* |
794 | * HPDF_FileReader_ReadFunc |
795 | * |
796 | * Reading data function for HPDF_FileReader. |
797 | * |
798 | */ |
799 | |
800 | HPDF_STATUS |
801 | HPDF_FileReader_ReadFunc (HPDF_Stream stream, |
802 | HPDF_BYTE *ptr, |
803 | HPDF_UINT *siz) |
804 | { |
805 | HPDF_FILEP fp = (HPDF_FILEP)stream->attr; |
806 | HPDF_UINT rsiz; |
807 | |
808 | HPDF_PTRACE((" HPDF_FileReader_ReadFunc\n" )); |
809 | |
810 | HPDF_MemSet(ptr, 0, *siz); |
811 | rsiz = HPDF_FREAD(ptr, 1, *siz, fp); |
812 | |
813 | if (rsiz != *siz) { |
814 | if (HPDF_FEOF(fp)) { |
815 | |
816 | *siz = rsiz; |
817 | |
818 | return HPDF_STREAM_EOF; |
819 | } |
820 | |
821 | return HPDF_SetError (stream->error, HPDF_FILE_IO_ERROR, HPDF_FERROR(fp)); |
822 | } |
823 | |
824 | return HPDF_OK; |
825 | } |
826 | |
827 | /* |
828 | * HPDF_FileReader_SeekFunc |
829 | * |
830 | * Seeking data function for HPDF_FileReader. |
831 | * |
832 | * stream : Pointer to a HPDF_Stream object. |
833 | * pos : New position of stream object. |
834 | * HPDF_whence_mode : Seeking mode describing below. |
835 | * HPDF_SEEK_SET : Absolute file position |
836 | * HPDF_SEEK_CUR : Relative to the current file position |
837 | * HPDF_SEEK_END : Relative to the current end of file. |
838 | * |
839 | * HPDF_FileReader_seek_fn returns HPDF_OK when successful. On failer |
840 | * the result is HPDF_FILE_IO_ERROR and HPDF_Error_GetCode2() returns the |
841 | * error which returned by file seeking function of platform. |
842 | * |
843 | */ |
844 | |
845 | HPDF_STATUS |
846 | HPDF_FileReader_SeekFunc (HPDF_Stream stream, |
847 | HPDF_INT pos, |
848 | HPDF_WhenceMode mode) |
849 | { |
850 | HPDF_FILEP fp = (HPDF_FILEP)stream->attr; |
851 | HPDF_INT whence; |
852 | |
853 | HPDF_PTRACE((" HPDF_FileReader_SeekFunc\n" )); |
854 | |
855 | switch (mode) { |
856 | case HPDF_SEEK_CUR: |
857 | whence = SEEK_CUR; |
858 | break; |
859 | case HPDF_SEEK_END: |
860 | whence = SEEK_END; |
861 | break; |
862 | default: |
863 | whence = SEEK_SET; |
864 | } |
865 | |
866 | if (HPDF_FSEEK (fp, pos, whence) != 0) { |
867 | return HPDF_SetError (stream->error, HPDF_FILE_IO_ERROR, HPDF_FERROR(fp)); |
868 | } |
869 | |
870 | return HPDF_OK; |
871 | } |
872 | |
873 | |
874 | HPDF_INT32 |
875 | HPDF_FileStream_TellFunc (HPDF_Stream stream) |
876 | { |
877 | HPDF_INT32 ret; |
878 | HPDF_FILEP fp = (HPDF_FILEP)stream->attr; |
879 | |
880 | HPDF_PTRACE((" HPDF_FileReader_TellFunc\n" )); |
881 | |
882 | if ((ret = HPDF_FTELL (fp)) < 0) { |
883 | return HPDF_SetError (stream->error, HPDF_FILE_IO_ERROR, |
884 | HPDF_FERROR(fp)); |
885 | } |
886 | |
887 | return ret; |
888 | } |
889 | |
890 | |
891 | HPDF_UINT32 |
892 | HPDF_FileStream_SizeFunc (HPDF_Stream stream) |
893 | { |
894 | HPDF_INT size; |
895 | HPDF_INT ptr; |
896 | HPDF_FILEP fp = (HPDF_FILEP)stream->attr; |
897 | |
898 | HPDF_PTRACE((" HPDF_FileReader_SizeFunc\n" )); |
899 | |
900 | /* save current file-pointer */ |
901 | if ((ptr = HPDF_FTELL (fp)) < 0) { |
902 | HPDF_SetError (stream->error, HPDF_FILE_IO_ERROR, |
903 | HPDF_FERROR(fp)); |
904 | return 0; |
905 | } |
906 | |
907 | /* move file-pointer to the end of the file */ |
908 | if (HPDF_FSEEK (fp, 0, SEEK_END) < 0) { |
909 | HPDF_SetError (stream->error, HPDF_FILE_IO_ERROR, |
910 | HPDF_FERROR(fp)); |
911 | return 0; |
912 | } |
913 | |
914 | /* get the pointer of the end of the file */ |
915 | if ((size = HPDF_FTELL (fp)) < 0) { |
916 | HPDF_SetError (stream->error, HPDF_FILE_IO_ERROR, |
917 | HPDF_FERROR(fp)); |
918 | return 0; |
919 | } |
920 | |
921 | /* restore current file-pointer */ |
922 | if (HPDF_FSEEK (fp, ptr, SEEK_SET) < 0) { |
923 | HPDF_SetError (stream->error, HPDF_FILE_IO_ERROR, |
924 | HPDF_FERROR(fp)); |
925 | return 0; |
926 | } |
927 | |
928 | return (HPDF_UINT32)size; |
929 | } |
930 | |
931 | |
932 | HPDF_Stream |
933 | HPDF_FileWriter_New (HPDF_MMgr mmgr, |
934 | const char *fname) |
935 | { |
936 | HPDF_Stream stream; |
937 | HPDF_FILEP fp = HPDF_FOPEN (fname, "wb" ); |
938 | |
939 | HPDF_PTRACE((" HPDF_FileWriter_New\n" )); |
940 | |
941 | if (!fp) { |
942 | #ifdef UNDER_CE |
943 | HPDF_SetError (mmgr->error, HPDF_FILE_OPEN_ERROR, GetLastError()); |
944 | #else |
945 | HPDF_SetError (mmgr->error, HPDF_FILE_OPEN_ERROR, errno); |
946 | #endif |
947 | return NULL; |
948 | } |
949 | |
950 | stream = (HPDF_Stream)HPDF_GetMem (mmgr, sizeof(HPDF_Stream_Rec)); |
951 | |
952 | if (stream) { |
953 | HPDF_MemSet (stream, 0, sizeof(HPDF_Stream_Rec)); |
954 | stream->sig_bytes = HPDF_STREAM_SIG_BYTES; |
955 | stream->error = mmgr->error; |
956 | stream->mmgr = mmgr; |
957 | stream->write_fn = HPDF_FileWriter_WriteFunc; |
958 | stream->free_fn = HPDF_FileStream_FreeFunc; |
959 | stream->tell_fn = HPDF_FileStream_TellFunc; |
960 | stream->attr = fp; |
961 | stream->type = HPDF_STREAM_FILE; |
962 | } |
963 | |
964 | return stream; |
965 | } |
966 | |
967 | HPDF_STATUS |
968 | HPDF_FileWriter_WriteFunc (HPDF_Stream stream, |
969 | const HPDF_BYTE *ptr, |
970 | HPDF_UINT siz) |
971 | { |
972 | HPDF_FILEP fp; |
973 | HPDF_UINT ret; |
974 | |
975 | HPDF_PTRACE((" HPDF_FileWriter_WriteFunc\n" )); |
976 | |
977 | fp = (HPDF_FILEP)stream->attr; |
978 | ret = HPDF_FWRITE (ptr, 1, siz, fp); |
979 | |
980 | if (ret != siz) { |
981 | return HPDF_SetError (stream->error, HPDF_FILE_IO_ERROR, HPDF_FERROR(fp)); |
982 | } |
983 | |
984 | return HPDF_OK; |
985 | } |
986 | |
987 | |
988 | void |
989 | HPDF_FileStream_FreeFunc (HPDF_Stream stream) |
990 | { |
991 | HPDF_FILEP fp; |
992 | |
993 | HPDF_PTRACE((" HPDF_FileStream_FreeFunc\n" )); |
994 | |
995 | fp = (HPDF_FILEP)stream->attr; |
996 | |
997 | if (fp) |
998 | HPDF_FCLOSE(fp); |
999 | |
1000 | stream->attr = NULL; |
1001 | } |
1002 | |
1003 | HPDF_STATUS |
1004 | HPDF_MemStream_InWrite (HPDF_Stream stream, |
1005 | const HPDF_BYTE **ptr, |
1006 | HPDF_UINT *count) |
1007 | { |
1008 | HPDF_MemStreamAttr attr = (HPDF_MemStreamAttr)stream->attr; |
1009 | HPDF_UINT rsize = attr->buf_siz - attr->w_pos; |
1010 | |
1011 | HPDF_PTRACE((" HPDF_MemStream_InWrite\n" )); |
1012 | |
1013 | if (*count <= 0) |
1014 | return HPDF_OK; |
1015 | |
1016 | if (rsize >= *count) { |
1017 | HPDF_MemCpy (attr->w_ptr, *ptr, *count); |
1018 | attr->w_ptr += *count; |
1019 | attr->w_pos += *count; |
1020 | *count = 0; |
1021 | } else { |
1022 | if (rsize > 0) { |
1023 | HPDF_MemCpy (attr->w_ptr, *ptr, rsize); |
1024 | *ptr += rsize; |
1025 | *count -= rsize; |
1026 | } |
1027 | attr->w_ptr = (HPDF_BYTE*)HPDF_GetMem (stream->mmgr, attr->buf_siz); |
1028 | |
1029 | if (attr->w_ptr == NULL) |
1030 | return HPDF_Error_GetCode (stream->error); |
1031 | |
1032 | if (HPDF_List_Add (attr->buf, attr->w_ptr) != HPDF_OK) { |
1033 | HPDF_FreeMem (stream->mmgr, attr->w_ptr); |
1034 | attr->w_ptr = NULL; |
1035 | |
1036 | return HPDF_Error_GetCode (stream->error); |
1037 | } |
1038 | attr->w_pos = 0; |
1039 | } |
1040 | return HPDF_OK; |
1041 | } |
1042 | |
1043 | |
1044 | HPDF_STATUS |
1045 | HPDF_MemStream_WriteFunc (HPDF_Stream stream, |
1046 | const HPDF_BYTE *ptr, |
1047 | HPDF_UINT siz) |
1048 | { |
1049 | HPDF_UINT wsiz = siz; |
1050 | |
1051 | HPDF_PTRACE((" HPDF_MemStream_WriteFunc\n" )); |
1052 | |
1053 | if (HPDF_Error_GetCode (stream->error) != 0) |
1054 | return HPDF_THIS_FUNC_WAS_SKIPPED; |
1055 | |
1056 | while (wsiz > 0) { |
1057 | HPDF_STATUS ret = HPDF_MemStream_InWrite (stream, &ptr, &wsiz); |
1058 | if (ret != HPDF_OK) |
1059 | return ret; |
1060 | } |
1061 | |
1062 | return HPDF_OK; |
1063 | } |
1064 | |
1065 | |
1066 | HPDF_INT32 |
1067 | HPDF_MemStream_TellFunc (HPDF_Stream stream) |
1068 | { |
1069 | HPDF_INT32 ret; |
1070 | HPDF_MemStreamAttr attr = (HPDF_MemStreamAttr)stream->attr; |
1071 | |
1072 | HPDF_PTRACE((" HPDF_MemStream_TellFunc\n" )); |
1073 | |
1074 | ret = attr->r_ptr_idx * attr->buf_siz; |
1075 | ret += attr->r_pos; |
1076 | |
1077 | return ret; |
1078 | } |
1079 | |
1080 | |
1081 | HPDF_UINT32 |
1082 | HPDF_MemStream_SizeFunc (HPDF_Stream stream) |
1083 | { |
1084 | HPDF_PTRACE((" HPDF_MemStream_SizeFunc\n" )); |
1085 | |
1086 | return stream->size; |
1087 | } |
1088 | |
1089 | HPDF_STATUS |
1090 | HPDF_MemStream_SeekFunc (HPDF_Stream stream, |
1091 | HPDF_INT pos, |
1092 | HPDF_WhenceMode mode) |
1093 | { |
1094 | HPDF_MemStreamAttr attr = (HPDF_MemStreamAttr)stream->attr; |
1095 | |
1096 | HPDF_PTRACE((" HPDF_MemStream_SeekFunc\n" )); |
1097 | |
1098 | if (mode == HPDF_SEEK_CUR) { |
1099 | pos += (attr->r_ptr_idx * attr->buf_siz); |
1100 | pos += attr->r_pos; |
1101 | } else if (mode == HPDF_SEEK_END) |
1102 | pos = stream->size - pos; |
1103 | |
1104 | if (pos > (HPDF_INT)stream->size) { |
1105 | return HPDF_SetError (stream->error, HPDF_STREAM_EOF, 0); |
1106 | } |
1107 | |
1108 | if (stream->size == 0) { |
1109 | return HPDF_OK; |
1110 | } |
1111 | |
1112 | attr->r_ptr_idx = pos / attr->buf_siz; |
1113 | attr->r_pos = pos % attr->buf_siz; |
1114 | attr->r_ptr = (HPDF_BYTE*)HPDF_List_ItemAt (attr->buf, attr->r_ptr_idx); |
1115 | if (attr->r_ptr == NULL) { |
1116 | HPDF_SetError (stream->error, HPDF_INVALID_OBJECT, 0); |
1117 | return HPDF_INVALID_OBJECT; |
1118 | } else |
1119 | attr->r_ptr += attr->r_pos; |
1120 | |
1121 | return HPDF_OK; |
1122 | } |
1123 | |
1124 | |
1125 | HPDF_BYTE* |
1126 | HPDF_MemStream_GetBufPtr (HPDF_Stream stream, |
1127 | HPDF_UINT index, |
1128 | HPDF_UINT *length) |
1129 | { |
1130 | HPDF_BYTE *ret; |
1131 | HPDF_MemStreamAttr attr; |
1132 | |
1133 | HPDF_PTRACE((" HPDF_MemStream_GetBufPtr\n" )); |
1134 | |
1135 | if (stream->type != HPDF_STREAM_MEMORY) { |
1136 | HPDF_SetError (stream->error, HPDF_INVALID_OBJECT, 0); |
1137 | return NULL; |
1138 | } |
1139 | |
1140 | attr = (HPDF_MemStreamAttr)stream->attr; |
1141 | |
1142 | ret = (HPDF_BYTE *)HPDF_List_ItemAt (attr->buf, index); |
1143 | if (ret == NULL) { |
1144 | HPDF_SetError (stream->error, HPDF_INVALID_PARAMETER, 0); |
1145 | *length = 0; |
1146 | return NULL; |
1147 | } |
1148 | |
1149 | *length = (attr->buf->count - 1 == index) ? attr->w_pos : attr->buf_siz; |
1150 | return ret; |
1151 | } |
1152 | |
1153 | |
1154 | void |
1155 | HPDF_MemStream_FreeData (HPDF_Stream stream) |
1156 | { |
1157 | HPDF_MemStreamAttr attr; |
1158 | HPDF_UINT i; |
1159 | |
1160 | HPDF_PTRACE((" HPDF_MemStream_FreeData\n" )); |
1161 | |
1162 | if (!stream || stream->type != HPDF_STREAM_MEMORY) |
1163 | return; |
1164 | |
1165 | attr = (HPDF_MemStreamAttr)stream->attr; |
1166 | |
1167 | for (i = 0; i < attr->buf->count; i++) |
1168 | HPDF_FreeMem (stream->mmgr, HPDF_List_ItemAt (attr->buf, i)); |
1169 | |
1170 | HPDF_List_Clear(attr->buf); |
1171 | |
1172 | stream->size = 0; |
1173 | attr->w_pos = attr->buf_siz; |
1174 | attr->w_ptr = NULL; |
1175 | attr->r_ptr_idx = 0; |
1176 | attr->r_pos = 0; |
1177 | } |
1178 | |
1179 | void |
1180 | HPDF_MemStream_FreeFunc (HPDF_Stream stream) |
1181 | { |
1182 | HPDF_MemStreamAttr attr; |
1183 | |
1184 | HPDF_PTRACE((" HPDF_MemStream_FreeFunc\n" )); |
1185 | |
1186 | attr = (HPDF_MemStreamAttr)stream->attr; |
1187 | HPDF_MemStream_FreeData (stream); |
1188 | HPDF_List_Free (attr->buf); |
1189 | HPDF_FreeMem (stream->mmgr, attr); |
1190 | stream->attr = NULL; |
1191 | } |
1192 | |
1193 | HPDF_Stream |
1194 | HPDF_MemStream_New (HPDF_MMgr mmgr, |
1195 | HPDF_UINT buf_siz) |
1196 | { |
1197 | HPDF_Stream stream; |
1198 | |
1199 | HPDF_PTRACE((" HPDF_MemStream_New\n" )); |
1200 | |
1201 | /* Create new HPDF_Stream object. */ |
1202 | stream = (HPDF_Stream)HPDF_GetMem (mmgr, sizeof(HPDF_Stream_Rec)); |
1203 | |
1204 | if (stream) { |
1205 | /* Create attribute struct. */ |
1206 | HPDF_MemStreamAttr attr = (HPDF_MemStreamAttr)HPDF_GetMem (mmgr, |
1207 | sizeof(HPDF_MemStreamAttr_Rec)); |
1208 | |
1209 | if (!attr) { |
1210 | HPDF_FreeMem (mmgr, stream); |
1211 | return NULL; |
1212 | } |
1213 | |
1214 | HPDF_MemSet (stream, 0, sizeof(HPDF_Stream_Rec)); |
1215 | HPDF_MemSet (attr, 0, sizeof(HPDF_MemStreamAttr_Rec)); |
1216 | |
1217 | attr->buf = HPDF_List_New (mmgr, HPDF_DEF_ITEMS_PER_BLOCK); |
1218 | if (!attr->buf) { |
1219 | HPDF_FreeMem (mmgr, stream); |
1220 | HPDF_FreeMem (mmgr, attr); |
1221 | return NULL; |
1222 | } |
1223 | |
1224 | stream->sig_bytes = HPDF_STREAM_SIG_BYTES; |
1225 | stream->type = HPDF_STREAM_MEMORY; |
1226 | stream->error = mmgr->error; |
1227 | stream->mmgr = mmgr; |
1228 | stream->attr = attr; |
1229 | attr->buf_siz = (buf_siz > 0) ? buf_siz : HPDF_STREAM_BUF_SIZ; |
1230 | attr->w_pos = attr->buf_siz; |
1231 | |
1232 | stream->write_fn = HPDF_MemStream_WriteFunc; |
1233 | stream->read_fn = HPDF_MemStream_ReadFunc; |
1234 | stream->seek_fn = HPDF_MemStream_SeekFunc; |
1235 | stream->tell_fn = HPDF_MemStream_TellFunc; |
1236 | stream->size_fn = HPDF_MemStream_SizeFunc; |
1237 | stream->free_fn = HPDF_MemStream_FreeFunc; |
1238 | } |
1239 | |
1240 | return stream; |
1241 | } |
1242 | |
1243 | HPDF_UINT |
1244 | HPDF_MemStream_GetBufSize (HPDF_Stream stream) |
1245 | { |
1246 | HPDF_MemStreamAttr attr; |
1247 | |
1248 | HPDF_PTRACE((" HPDF_MemStream_GetBufSize\n" )); |
1249 | |
1250 | if (!stream || stream->type != HPDF_STREAM_MEMORY) |
1251 | return 0; |
1252 | |
1253 | attr = (HPDF_MemStreamAttr)stream->attr; |
1254 | return attr->buf_siz; |
1255 | } |
1256 | |
1257 | HPDF_UINT |
1258 | HPDF_MemStream_GetBufCount (HPDF_Stream stream) |
1259 | { |
1260 | HPDF_MemStreamAttr attr; |
1261 | |
1262 | HPDF_PTRACE((" HPDF_MemStream_GetBufCount\n" )); |
1263 | |
1264 | if (!stream || stream->type != HPDF_STREAM_MEMORY) |
1265 | return 0; |
1266 | |
1267 | attr = (HPDF_MemStreamAttr)stream->attr; |
1268 | return attr->buf->count; |
1269 | } |
1270 | |
1271 | HPDF_STATUS |
1272 | HPDF_MemStream_ReadFunc (HPDF_Stream stream, |
1273 | HPDF_BYTE *buf, |
1274 | HPDF_UINT *size) |
1275 | { |
1276 | HPDF_MemStreamAttr attr = (HPDF_MemStreamAttr)stream->attr; |
1277 | HPDF_UINT buf_size; |
1278 | HPDF_UINT rlen = *size; |
1279 | |
1280 | HPDF_PTRACE((" HPDF_MemStream_ReadFunc\n" )); |
1281 | |
1282 | *size = 0; |
1283 | |
1284 | while (rlen > 0) { |
1285 | HPDF_UINT tmp_len; |
1286 | |
1287 | if (attr->buf->count == 0) |
1288 | return HPDF_STREAM_EOF; |
1289 | |
1290 | if (attr->buf->count - 1 > attr->r_ptr_idx) |
1291 | tmp_len = attr->buf_siz - attr->r_pos; |
1292 | else if (attr->buf->count - 1 == attr->r_ptr_idx) |
1293 | tmp_len = attr->w_pos - attr->r_pos; |
1294 | else |
1295 | return HPDF_STREAM_EOF; |
1296 | |
1297 | if (!attr->r_ptr) |
1298 | attr->r_ptr = (HPDF_BYTE*)HPDF_List_ItemAt (attr->buf, |
1299 | attr->r_ptr_idx); |
1300 | |
1301 | if (tmp_len >= rlen) { |
1302 | HPDF_MemCpy (buf, attr->r_ptr, rlen); |
1303 | attr->r_pos += rlen; |
1304 | *size += rlen; |
1305 | attr->r_ptr += rlen; |
1306 | return HPDF_OK; |
1307 | } else { |
1308 | buf = HPDF_MemCpy (buf, attr->r_ptr, tmp_len); |
1309 | rlen -= tmp_len; |
1310 | *size += tmp_len; |
1311 | |
1312 | if (attr->r_ptr_idx == attr->buf->count - 1) { |
1313 | attr->r_ptr += tmp_len; |
1314 | attr->r_pos += tmp_len; |
1315 | return HPDF_STREAM_EOF; |
1316 | } |
1317 | |
1318 | attr->r_ptr_idx++; |
1319 | attr->r_pos = 0; |
1320 | attr->r_ptr = HPDF_MemStream_GetBufPtr (stream, attr->r_ptr_idx, |
1321 | &buf_size); |
1322 | } |
1323 | } |
1324 | |
1325 | return HPDF_OK; |
1326 | } |
1327 | |
1328 | |
1329 | HPDF_STATUS |
1330 | HPDF_MemStream_Rewrite (HPDF_Stream stream, |
1331 | HPDF_BYTE *buf, |
1332 | HPDF_UINT size) |
1333 | { |
1334 | HPDF_MemStreamAttr attr = (HPDF_MemStreamAttr)stream->attr; |
1335 | HPDF_UINT buf_size; |
1336 | HPDF_UINT rlen = size; |
1337 | |
1338 | HPDF_PTRACE((" HPDF_MemStream_Rewrite\n" )); |
1339 | |
1340 | while (rlen > 0) { |
1341 | HPDF_UINT tmp_len; |
1342 | |
1343 | if (attr->buf->count <= attr->r_ptr_idx) { |
1344 | HPDF_STATUS ret = HPDF_MemStream_WriteFunc (stream, buf, rlen); |
1345 | attr->r_ptr_idx = attr->buf->count; |
1346 | attr->r_pos = attr->w_pos; |
1347 | attr->r_ptr = attr->w_ptr; |
1348 | return ret; |
1349 | } else if (attr->buf->count == attr->r_ptr_idx) |
1350 | tmp_len = attr->w_pos - attr->r_pos; |
1351 | else |
1352 | tmp_len = attr->buf_siz - attr->r_pos; |
1353 | |
1354 | if (tmp_len >= rlen) { |
1355 | HPDF_MemCpy(attr->r_ptr, buf, rlen); |
1356 | attr->r_pos += rlen; |
1357 | attr->r_ptr += rlen; |
1358 | return HPDF_OK; |
1359 | } else { |
1360 | HPDF_MemCpy(attr->r_ptr, buf, tmp_len); |
1361 | buf += tmp_len; |
1362 | rlen -= tmp_len; |
1363 | attr->r_ptr_idx++; |
1364 | |
1365 | if (attr->buf->count > attr->r_ptr_idx) { |
1366 | attr->r_pos = 0; |
1367 | attr->r_ptr = HPDF_MemStream_GetBufPtr (stream, attr->r_ptr_idx, |
1368 | &buf_size); |
1369 | } |
1370 | } |
1371 | } |
1372 | return HPDF_OK; |
1373 | } |
1374 | |
1375 | /* |
1376 | * HPDF_CallbackReader_new |
1377 | * |
1378 | * Constractor for HPDF_CallbackReader. |
1379 | * |
1380 | * mmgr : Pointer to a HPDF_MMgr object. |
1381 | * read_fn : Pointer to a user function for reading data. |
1382 | * seek_fn : Pointer to a user function for seeking data. |
1383 | * data : Pointer to a data which defined by user. |
1384 | * |
1385 | * return: If success, It returns pointer to new HPDF_Stream object, |
1386 | * otherwise, it returns NULL. |
1387 | * |
1388 | */ |
1389 | |
1390 | |
1391 | HPDF_Stream |
1392 | HPDF_CallbackReader_New (HPDF_MMgr mmgr, |
1393 | HPDF_Stream_Read_Func read_fn, |
1394 | HPDF_Stream_Seek_Func seek_fn, |
1395 | HPDF_Stream_Tell_Func tell_fn, |
1396 | HPDF_Stream_Size_Func size_fn, |
1397 | void* data) |
1398 | { |
1399 | HPDF_Stream stream; |
1400 | |
1401 | HPDF_PTRACE((" HPDF_CallbackReader_New\n" )); |
1402 | |
1403 | stream = (HPDF_Stream)HPDF_GetMem (mmgr, sizeof(HPDF_Stream_Rec)); |
1404 | |
1405 | if (stream) { |
1406 | HPDF_MemSet (stream, 0, sizeof(HPDF_Stream_Rec)); |
1407 | stream->sig_bytes = HPDF_STREAM_SIG_BYTES; |
1408 | stream->error = mmgr->error; |
1409 | stream->mmgr = mmgr; |
1410 | stream->read_fn = read_fn; |
1411 | stream->seek_fn = seek_fn; |
1412 | stream->tell_fn = tell_fn; |
1413 | stream->size_fn = size_fn; |
1414 | stream->attr = data; |
1415 | stream->type = HPDF_STREAM_CALLBACK; |
1416 | } |
1417 | |
1418 | return stream; |
1419 | } |
1420 | |
1421 | /* |
1422 | * HPDF_CallbackWriter_new |
1423 | * |
1424 | * Constractor for HPDF_CallbackWriter. |
1425 | * |
1426 | * mmgr : Pointer to a HPDF_MMgr object. |
1427 | * read_fn : Pointer to a user function for writing data. |
1428 | * data : Pointer to a data which defined by user. |
1429 | * |
1430 | * return: If success, It returns pointer to new HPDF_Stream object, |
1431 | * otherwise, it returns NULL. |
1432 | * |
1433 | */ |
1434 | |
1435 | |
1436 | HPDF_Stream |
1437 | HPDF_CallbackWriter_New (HPDF_MMgr mmgr, |
1438 | HPDF_Stream_Write_Func write_fn, |
1439 | void* data) |
1440 | { |
1441 | HPDF_Stream stream; |
1442 | |
1443 | HPDF_PTRACE((" HPDF_CallbackWriter_New\n" )); |
1444 | |
1445 | stream = (HPDF_Stream)HPDF_GetMem (mmgr, sizeof(HPDF_Stream_Rec)); |
1446 | |
1447 | if (stream) { |
1448 | HPDF_MemSet (stream, 0, sizeof(HPDF_Stream_Rec)); |
1449 | stream->sig_bytes = HPDF_STREAM_SIG_BYTES; |
1450 | stream->error = mmgr->error; |
1451 | stream->mmgr = mmgr; |
1452 | stream->write_fn = write_fn; |
1453 | stream->attr = data; |
1454 | stream->type = HPDF_STREAM_CALLBACK; |
1455 | } |
1456 | |
1457 | return stream; |
1458 | } |
1459 | |
1460 | |
1461 | |
1462 | HPDF_STATUS |
1463 | HPDF_Stream_Validate (HPDF_Stream stream) |
1464 | { |
1465 | if (!stream || stream->sig_bytes != HPDF_STREAM_SIG_BYTES) |
1466 | return HPDF_FALSE; |
1467 | else |
1468 | return HPDF_TRUE; |
1469 | } |
1470 | |
1471 | |