OSDN Git Service

binding with libharu.
[putex/putex.git] / src / texsourc / lib / libhpdf / src / hpdf_streams.c
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