xref: /plan9/sys/src/cmd/gs/src/gsdsrc.c (revision 593dc095aefb2a85c828727bbfa9da139a49bdf4)
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