1 /* Copyright (C) 2001-2019 Artifex Software, Inc.
2    All Rights Reserved.
3 
4    This software is provided AS-IS with no warranty, either express or
5    implied.
6 
7    This software is distributed under license and may not be copied,
8    modified or distributed except as expressly authorized under the terms
9    of the license contained in the file LICENSE in this distribution.
10 
11    Refer to licensing information at http://www.artifex.com or contact
12    Artifex Software, Inc.,  1305 Grant Avenue - Suite 200, Novato,
13    CA 94945, U.S.A., +1(415)492-9861, for further information.
14 */
15 
16 
17 /* DataSource definitions */
18 
19 #ifndef gsdsrc_INCLUDED
20 #  define gsdsrc_INCLUDED
21 
22 #include "gsstruct.h"
23 #include "scommon.h"
24 
25 /* ---------------- Types and structures ---------------- */
26 
27 /*
28  * A gs_data_source_t represents the data source for various constructs.  It
29  * can be a string (either a gs_string or a byte-type object), a
30  * positionable, non-procedure-based stream, or an array of floats.  An
31  * ordinary positionable file stream will do, as long as the client doesn't
32  * attempt to read past the EOF.
33  *
34  * The handling of floats is anomalous, but we don't see a good alternative
35  * at the moment.
36  */
37 
38 /*
39  * Prepare to access a block of data from a source.  buf must be a client-
40  * supplied buffer of at least length bytes.  If ptr == 0, always copy the
41  * data into buf.  If ptr != 0, either copy the data into buf and set *ptr =
42  * buf, or set *ptr to point to the data (which might be invalidated by the
43  * next call).  Note that this procedure may or may not do bounds checking.
44  */
45 #define data_source_proc_access(proc)\
46   int proc(const gs_data_source_t *psrc, ulong start, uint length,\
47            byte *buf, const byte **ptr)
48 
49 typedef enum {
50     data_source_type_string,
51     data_source_type_bytes,
52     data_source_type_floats,
53     data_source_type_stream
54 } gs_data_source_type_t;
55 typedef struct gs_data_source_s gs_data_source_t;
56 struct gs_data_source_s {
57     data_source_proc_access((*access));
58     gs_data_source_type_t type;
59     union d_ {
60         gs_const_string str;	/* also used for byte objects */
61         stream *strm;
62     } data;
63 };
64 
65 #define data_source_access_only(psrc, start, length, buf, ptr)\
66   (*(psrc)->access)(psrc, (ulong)(start), length, buf, ptr)
67 #define data_source_access(psrc, start, length, buf, ptr)\
68   BEGIN\
69     int code_ = data_source_access_only(psrc, start, length, buf, ptr);\
70     if ( code_ < 0 ) return code_;\
71   END
72 #define data_source_copy_only(psrc, start, length, buf)\
73   data_source_access_only(psrc, start, length, buf, (const byte **)0)
74 #define data_source_copy(psrc, start, length, buf)\
75   data_source_access(psrc, start, length, buf, (const byte **)0)
76 
77 /*
78  * Data sources are always embedded in other structures, but they do have
79  * pointers that need to be traced and relocated, so they do have a GC
80  * structure type.
81  */
82 extern_st(st_data_source);
83 #define public_st_data_source()	/* in gsdsrc.c */\
84   gs_public_st_composite(st_data_source, gs_data_source_t, "gs_data_source_t",\
85     data_source_enum_ptrs, data_source_reloc_ptrs)
86 #define st_data_source_max_ptrs 1
87 
88 /* ---------------- Procedures ---------------- */
89 
90 /* Initialize a data source of the various known types. */
91 data_source_proc_access(data_source_access_string);
92 #define data_source_init_string(psrc, strg)\
93   ((psrc)->type = data_source_type_string,\
94    (psrc)->data.str = strg, (psrc)->access = data_source_access_string)
95 #define data_source_init_string2(psrc, bytes, len)\
96   ((psrc)->type = data_source_type_string,\
97    (psrc)->data.str.data = bytes, (psrc)->data.str.size = len,\
98    (psrc)->access = data_source_access_string)
99 data_source_proc_access(data_source_access_bytes);
100 #define data_source_init_bytes(psrc, bytes, len)\
101   ((psrc)->type = data_source_type_bytes,\
102    (psrc)->data.str.data = bytes, (psrc)->data.str.size = len,\
103    (psrc)->access = data_source_access_bytes)
104 #define data_source_init_floats(psrc, floats, count)\
105   ((psrc)->type = data_source_type_floats,\
106    (psrc)->data.str.data = (byte *)floats,\
107    (psrc)->data.str.size = (count) * sizeof(float),\
108    (psrc)->access = data_source_access_bytes)
109 data_source_proc_access(data_source_access_stream);
110 #define data_source_init_stream(psrc, s)\
111   ((psrc)->type = data_source_type_stream,\
112    (psrc)->data.strm = s, (psrc)->access = data_source_access_stream)
113 
114 #define data_source_is_stream(dsource)\
115   ((dsource).type == data_source_type_stream)
116 #define data_source_is_array(dsource)\
117   ((dsource).type == data_source_type_floats)
118 
119 #endif /* gsdsrc_INCLUDED */
120