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
38HPDF_STATUS
39HPDF_MemStream_WriteFunc (HPDF_Stream stream,
40 const HPDF_BYTE *ptr,
41 HPDF_UINT siz);
42
43
44HPDF_STATUS
45HPDF_MemStream_SeekFunc (HPDF_Stream stream,
46 HPDF_INT pos,
47 HPDF_WhenceMode mode);
48
49
50HPDF_STATUS
51HPDF_MemStream_ReadFunc (HPDF_Stream stream,
52 HPDF_BYTE *buf,
53 HPDF_UINT *size);
54
55
56HPDF_INT32
57HPDF_MemStream_TellFunc (HPDF_Stream stream);
58
59
60HPDF_UINT32
61HPDF_MemStream_SizeFunc (HPDF_Stream stream);
62
63
64void
65HPDF_MemStream_FreeFunc (HPDF_Stream stream);
66
67HPDF_STATUS
68HPDF_MemStream_InWrite (HPDF_Stream stream,
69 const HPDF_BYTE **ptr,
70 HPDF_UINT *count);
71
72HPDF_STATUS
73HPDF_Stream_WriteToStreamWithDeflate (HPDF_Stream src,
74 HPDF_Stream dst,
75 HPDF_Encrypt e);
76
77
78HPDF_STATUS
79HPDF_FileReader_ReadFunc (HPDF_Stream stream,
80 HPDF_BYTE *ptr,
81 HPDF_UINT *siz);
82
83
84HPDF_STATUS
85HPDF_FileReader_SeekFunc (HPDF_Stream stream,
86 HPDF_INT pos,
87 HPDF_WhenceMode mode);
88
89
90HPDF_INT32
91HPDF_FileStream_TellFunc (HPDF_Stream stream);
92
93
94HPDF_UINT32
95HPDF_FileStream_SizeFunc (HPDF_Stream stream);
96
97
98HPDF_STATUS
99HPDF_FileWriter_WriteFunc (HPDF_Stream stream,
100 const HPDF_BYTE *ptr,
101 HPDF_UINT siz);
102
103void
104HPDF_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
120HPDF_STATUS
121HPDF_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 */
148HPDF_STATUS
149HPDF_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 */
233HPDF_STATUS
234HPDF_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
261HPDF_STATUS
262HPDF_Stream_WriteChar (HPDF_Stream stream,
263 char value)
264{
265 return HPDF_Stream_Write(stream, (HPDF_BYTE *)&value, sizeof(char));
266}
267
268
269HPDF_STATUS
270HPDF_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
278HPDF_STATUS
279HPDF_Stream_WriteUChar (HPDF_Stream stream,
280 HPDF_BYTE value)
281{
282 return HPDF_Stream_Write(stream, &value, sizeof(HPDF_BYTE));
283}
284
285HPDF_STATUS
286HPDF_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
296HPDF_STATUS
297HPDF_Stream_WriteUInt (HPDF_Stream stream,
298 HPDF_UINT value)
299{
300 return HPDF_Stream_WriteInt(stream, (HPDF_INT)value);
301}
302
303HPDF_STATUS
304HPDF_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
314void
315HPDF_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
328HPDF_STATUS
329HPDF_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
345HPDF_INT32
346HPDF_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
360HPDF_UINT32
361HPDF_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
380HPDF_STATUS
381HPDF_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
422HPDF_STATUS
423HPDF_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
478HPDF_STATUS
479HPDF_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
491HPDF_STATUS
492HPDF_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
560HPDF_STATUS
561HPDF_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
687HPDF_STATUS
688HPDF_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
756HPDF_Stream
757HPDF_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
800HPDF_STATUS
801HPDF_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
845HPDF_STATUS
846HPDF_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
874HPDF_INT32
875HPDF_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
891HPDF_UINT32
892HPDF_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
932HPDF_Stream
933HPDF_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
967HPDF_STATUS
968HPDF_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
988void
989HPDF_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
1003HPDF_STATUS
1004HPDF_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
1044HPDF_STATUS
1045HPDF_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
1066HPDF_INT32
1067HPDF_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
1081HPDF_UINT32
1082HPDF_MemStream_SizeFunc (HPDF_Stream stream)
1083{
1084 HPDF_PTRACE((" HPDF_MemStream_SizeFunc\n"));
1085
1086 return stream->size;
1087}
1088
1089HPDF_STATUS
1090HPDF_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
1125HPDF_BYTE*
1126HPDF_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
1154void
1155HPDF_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
1179void
1180HPDF_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
1193HPDF_Stream
1194HPDF_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
1243HPDF_UINT
1244HPDF_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
1257HPDF_UINT
1258HPDF_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
1271HPDF_STATUS
1272HPDF_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
1329HPDF_STATUS
1330HPDF_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
1391HPDF_Stream
1392HPDF_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
1436HPDF_Stream
1437HPDF_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
1462HPDF_STATUS
1463HPDF_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