1 /* Copyright (C) 1997, 1998, 1999 Aladdin Enterprises. All rights reserved.
2
3 This software is provided AS-IS with no warranty, either express or
4 implied.
5
6 This software is distributed under license and may not be copied,
7 modified or distributed except as expressly authorized under the terms
8 of the license contained in the file LICENSE in this distribution.
9
10 For more information about licensing, please refer to
11 http://www.ghostscript.com/licensing/. For information on
12 commercial licensing, go to http://www.artifex.com/licensing/ or
13 contact Artifex Software, Inc., 101 Lucas Valley Road #110,
14 San Rafael, CA 94903, U.S.A., +1(415)492-9861.
15 */
16
17 /* $Id: gsdsrc.c,v 1.4 2002/02/21 22:24:52 giles Exp $ */
18 /* DataSource procedures */
19
20 #include "memory_.h"
21 #include "gx.h"
22 #include "gsdsrc.h"
23 #include "gserrors.h"
24 #include "stream.h"
25
26 /* GC descriptor */
27 public_st_data_source();
28 private
ENUM_PTRS_WITH(data_source_enum_ptrs,gs_data_source_t * psrc)29 ENUM_PTRS_WITH(data_source_enum_ptrs, gs_data_source_t *psrc)
30 {
31 if (psrc->type == data_source_type_string)
32 ENUM_RETURN_CONST_STRING_PTR(gs_data_source_t, data.str);
33 else if (psrc->type == data_source_type_stream)
34 ENUM_RETURN_PTR(gs_data_source_t, data.strm);
35 else /* bytes or floats */
36 ENUM_RETURN_PTR(gs_data_source_t, data.str.data);
37 }
38 ENUM_PTRS_END
RELOC_PTRS_WITH(data_source_reloc_ptrs,gs_data_source_t * psrc)39 private RELOC_PTRS_WITH(data_source_reloc_ptrs, gs_data_source_t *psrc)
40 {
41 if (psrc->type == data_source_type_string)
42 RELOC_CONST_STRING_PTR(gs_data_source_t, data.str);
43 else if (psrc->type == data_source_type_stream)
44 RELOC_PTR(gs_data_source_t, data.strm);
45 else /* bytes or floats */
46 RELOC_PTR(gs_data_source_t, data.str.data);
47 }
48 RELOC_PTRS_END
49
50 /* Access data from a string or a byte object. */
51 /* Does *not* check bounds. */
52 int
data_source_access_string(const gs_data_source_t * psrc,ulong start,uint length,byte * buf,const byte ** ptr)53 data_source_access_string(const gs_data_source_t * psrc, ulong start,
54 uint length, byte * buf, const byte ** ptr)
55 {
56 const byte *p = psrc->data.str.data + start;
57
58 if (ptr)
59 *ptr = p;
60 else
61 memcpy(buf, p, length);
62 return 0;
63 }
64 /* access_bytes is identical to access_string, but has a different */
65 /* GC procedure. */
66 int
data_source_access_bytes(const gs_data_source_t * psrc,ulong start,uint length,byte * buf,const byte ** ptr)67 data_source_access_bytes(const gs_data_source_t * psrc, ulong start,
68 uint length, byte * buf, const byte ** ptr)
69 {
70 const byte *p = psrc->data.str.data + start;
71
72 if (ptr)
73 *ptr = p;
74 else
75 memcpy(buf, p, length);
76 return 0;
77 }
78
79 /* Access data from a stream. */
80 /* Returns gs_error_rangecheck if out of bounds. */
81 int
data_source_access_stream(const gs_data_source_t * psrc,ulong start,uint length,byte * buf,const byte ** ptr)82 data_source_access_stream(const gs_data_source_t * psrc, ulong start,
83 uint length, byte * buf, const byte ** ptr)
84 {
85 stream *s = psrc->data.strm;
86 const byte *p;
87
88 if (start >= s->position &&
89 (p = start - s->position + s->cbuf) + length <=
90 s->cursor.r.limit + 1
91 ) {
92 if (ptr)
93 *ptr = p;
94 else
95 memcpy(buf, p, length);
96 } else {
97 uint nread;
98 int code = sseek(s, start);
99
100 if (code < 0)
101 return_error(gs_error_rangecheck);
102 code = sgets(s, buf, length, &nread);
103 if (code < 0)
104 return_error(gs_error_rangecheck);
105 if (nread != length)
106 return_error(gs_error_rangecheck);
107 if (ptr)
108 *ptr = buf;
109 }
110 return 0;
111 }
112