xref: /plan9/sys/src/cmd/gs/src/gsdsrc.h (revision 593dc095aefb2a85c828727bbfa9da139a49bdf4)
1 /* Copyright (C) 1997, 2000 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.h,v 1.6 2002/06/16 08:45:42 lpd Exp $ */
18 /* DataSource definitions */
19 
20 #ifndef gsdsrc_INCLUDED
21 #  define gsdsrc_INCLUDED
22 
23 #include "gsstruct.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 #ifndef stream_DEFINED
39 #  define stream_DEFINED
40 typedef struct stream_s stream;
41 #endif
42 
43 /*
44  * Prepare to access a block of data from a source.  buf must be a client-
45  * supplied buffer of at least length bytes.  If ptr == 0, always copy the
46  * data into buf.  If ptr != 0, either copy the data into buf and set *ptr =
47  * buf, or set *ptr to point to the data (which might be invalidated by the
48  * next call).  Note that this procedure may or may not do bounds checking.
49  */
50 #define data_source_proc_access(proc)\
51   int proc(const gs_data_source_t *psrc, ulong start, uint length,\
52 	   byte *buf, const byte **ptr)
53 
54 typedef enum {
55     data_source_type_string,
56     data_source_type_bytes,
57     data_source_type_floats,
58     data_source_type_stream
59 } gs_data_source_type_t;
60 #ifndef gs_data_source_DEFINED
61 #  define gs_data_source_DEFINED
62 typedef struct gs_data_source_s gs_data_source_t;
63 #endif
64 struct gs_data_source_s {
65     data_source_proc_access((*access));
66     gs_data_source_type_t type;
67     union d_ {
68 	gs_const_string str;	/* also used for byte objects */
69 	stream *strm;
70     } data;
71 };
72 
73 #define data_source_access_only(psrc, start, length, buf, ptr)\
74   (*(psrc)->access)(psrc, (ulong)(start), length, buf, ptr)
75 #define data_source_access(psrc, start, length, buf, ptr)\
76   BEGIN\
77     int code_ = data_source_access_only(psrc, start, length, buf, ptr);\
78     if ( code_ < 0 ) return code_;\
79   END
80 #define data_source_copy_only(psrc, start, length, buf)\
81   data_source_access_only(psrc, start, length, buf, (const byte **)0)
82 #define data_source_copy(psrc, start, length, buf)\
83   data_source_access(psrc, start, length, buf, (const byte **)0)
84 
85 /*
86  * Data sources are always embedded in other structures, but they do have
87  * pointers that need to be traced and relocated, so they do have a GC
88  * structure type.
89  */
90 extern_st(st_data_source);
91 #define public_st_data_source()	/* in gsdsrc.c */\
92   gs_public_st_composite(st_data_source, gs_data_source_t, "gs_data_source_t",\
93     data_source_enum_ptrs, data_source_reloc_ptrs)
94 #define st_data_source_max_ptrs 1
95 
96 /* ---------------- Procedures ---------------- */
97 
98 /* Initialize a data source of the various known types. */
99 data_source_proc_access(data_source_access_string);
100 #define data_source_init_string(psrc, strg)\
101   ((psrc)->type = data_source_type_string,\
102    (psrc)->data.str = strg, (psrc)->access = data_source_access_string)
103 #define data_source_init_string2(psrc, bytes, len)\
104   ((psrc)->type = data_source_type_string,\
105    (psrc)->data.str.data = bytes, (psrc)->data.str.size = len,\
106    (psrc)->access = data_source_access_string)
107 data_source_proc_access(data_source_access_bytes);
108 #define data_source_init_bytes(psrc, bytes, len)\
109   ((psrc)->type = data_source_type_bytes,\
110    (psrc)->data.str.data = bytes, (psrc)->data.str.size = len,\
111    (psrc)->access = data_source_access_bytes)
112 #define data_source_init_floats(psrc, floats, count)\
113   ((psrc)->type = data_source_type_floats,\
114    (psrc)->data.str.data = (byte *)floats,\
115    (psrc)->data.str.size = (count) * sizeof(float),\
116    (psrc)->access = data_source_access_bytes)
117 data_source_proc_access(data_source_access_stream);
118 #define data_source_init_stream(psrc, s)\
119   ((psrc)->type = data_source_type_stream,\
120    (psrc)->data.strm = s, (psrc)->access = data_source_access_stream)
121 
122 #define data_source_is_stream(dsource)\
123   ((dsource).type == data_source_type_stream)
124 #define data_source_is_array(dsource)\
125   ((dsource).type == data_source_type_floats)
126 
127 #endif /* gsdsrc_INCLUDED */
128