lib/genx/genx.h (7535B) - raw
1
2 /*
3 * genx - C-callable library for generating XML documents
4 */
5
6 /*
7 * Copyright (c) 2004 by Tim Bray and Sun Microsystems. For copying
8 * permission, see http://www.tbray.org/ongoing/genx/COPYING
9 */
10
11 #include <stdio.h>
12
13 #ifdef __cplusplus
14 extern "C" {
15 #endif
16
17 /*
18 * Note on error handling: genx routines mostly return
19 * GENX_SUCCESS (guaranteed to be zero) in normal circumstances, one of
20 * these other GENX_ values on a memory allocation or I/O failure or if the
21 * call would result in non-well-formed output.
22 * You can associate an error message with one of these codes explicitly
23 * or with the most recent error using genxGetErrorMessage() and
24 * genxLastErrorMessage(); see below.
25 */
26 typedef enum
27 {
28 GENX_SUCCESS = 0,
29 GENX_BAD_UTF8,
30 GENX_NON_XML_CHARACTER,
31 GENX_BAD_NAME,
32 GENX_ALLOC_FAILED,
33 GENX_BAD_NAMESPACE_NAME,
34 GENX_INTERNAL_ERROR,
35 GENX_DUPLICATE_PREFIX,
36 GENX_SEQUENCE_ERROR,
37 GENX_NO_START_TAG,
38 GENX_IO_ERROR,
39 GENX_MISSING_VALUE,
40 GENX_MALFORMED_COMMENT,
41 GENX_XML_PI_TARGET,
42 GENX_MALFORMED_PI,
43 GENX_DUPLICATE_ATTRIBUTE,
44 GENX_ATTRIBUTE_IN_DEFAULT_NAMESPACE,
45 GENX_DUPLICATE_NAMESPACE,
46 GENX_BAD_DEFAULT_DECLARATION
47 } genxStatus;
48
49 /* character types */
50 #define GENX_XML_CHAR 1
51 #define GENX_LETTER 2
52 #define GENX_NAMECHAR 4
53
54 /* a UTF-8 string */
55 typedef unsigned char * utf8;
56 typedef const unsigned char * constUtf8;
57
58 /*
59 * genx's own types
60 */
61 typedef struct genxWriter_rec * genxWriter;
62 typedef struct genxNamespace_rec * genxNamespace;
63 typedef struct genxElement_rec * genxElement;
64 typedef struct genxAttribute_rec * genxAttribute;
65
66 /*
67 * Constructors, set/get
68 */
69
70 /*
71 * Create a new writer. For generating multiple XML documents, it's most
72 * efficient to re-use the same genx object. However, you can only write
73 * one document at a time with a writer.
74 * Returns NULL if it fails, which can only be due to an allocation failure.
75 */
76 genxWriter genxNew(void * (*alloc)(void * userData, int bytes),
77 void (* dealloc)(void * userData, void * data),
78 void * userData);
79
80 /*
81 * Dispose of a writer, freeing all associated memory
82 */
83 void genxDispose(genxWriter w);
84
85 /*
86 * Set/get
87 */
88
89 /*
90 * The userdata pointer will be passed to memory-allocation
91 * and I/O callbacks. If not set, genx will pass NULL
92 */
93 void genxSetUserData(genxWriter w, void * userData);
94 void * genxGetUserData(genxWriter w);
95
96 /*
97 * User-provided memory allocator, if desired. For example, if you were
98 * in an Apache module, you could arrange for genx to use ap_palloc by
99 * making the pool accessible via the userData call.
100 * The "dealloc" is to be used to free memory allocated with "alloc". If
101 * alloc is provided but dealloc is NULL, genx will not attempt to free
102 * the memory; this would be appropriate in an Apache context.
103 * If "alloc" is not provided, genx routines use malloc() to allocate memory
104 */
105 void genxSetAlloc(genxWriter w,
106 void * (* alloc)(void * userData, int bytes));
107 void genxSetDealloc(genxWriter w,
108 void (* dealloc)(void * userData, void * data));
109 void * (* genxGetAlloc(genxWriter w))(void * userData, int bytes);
110 void (* genxGetDealloc(genxWriter w))(void * userData, void * data);
111
112 /*
113 * Get the prefix associated with a namespace
114 */
115 utf8 genxGetNamespacePrefix(genxNamespace ns);
116
117 /*
118 * Declaration functions
119 */
120
121 /*
122 * Declare a namespace. The provided prefix is the default but can be
123 * overridden by genxAddNamespace. If no default prefiix is provided,
124 * genx will generate one of the form g-%d.
125 * On error, returns NULL and signals via statusp
126 */
127 genxNamespace genxDeclareNamespace(genxWriter w,
128 constUtf8 uri, constUtf8 prefix,
129 genxStatus * statusP);
130
131 /*
132 * Declare an element
133 * If something failed, returns NULL and sets the status code via statusP
134 */
135 genxElement genxDeclareElement(genxWriter w,
136 genxNamespace ns, constUtf8 type,
137 genxStatus * statusP);
138
139 /*
140 * Declare an attribute
141 */
142 genxAttribute genxDeclareAttribute(genxWriter w,
143 genxNamespace ns,
144 constUtf8 name, genxStatus * statusP);
145
146 /*
147 * Writing XML
148 */
149
150 /*
151 * Start a new document.
152 */
153 genxStatus genxStartDocFile(genxWriter w, FILE * file);
154
155 /*
156 * Caller-provided I/O package.
157 * First form is for a null-terminated string.
158 * for second, if you have s="abcdef" and want to send "abc", you'd call
159 * sendBounded(userData, s, s + 3)
160 */
161 typedef struct
162 {
163 genxStatus (* send)(void * userData, constUtf8 s);
164 genxStatus (* sendBounded)(void * userData, constUtf8 start, constUtf8 end);
165 genxStatus (* flush)(void * userData);
166 } genxSender;
167
168 genxStatus genxStartDocSender(genxWriter w, genxSender * sender);
169
170 /*
171 * End a document. Calls "flush"
172 */
173 genxStatus genxEndDocument(genxWriter w);
174
175 /*
176 * Write a comment
177 */
178 genxStatus genxComment(genxWriter w, constUtf8 text);
179
180 /*
181 * Write a PI
182 */
183 genxStatus genxPI(genxWriter w, constUtf8 target, constUtf8 text);
184
185 /*
186 * Start an element
187 */
188 genxStatus genxStartElementLiteral(genxWriter w,
189 constUtf8 xmlns, constUtf8 type);
190
191 /*
192 * Start a predeclared element
193 * - element must have been declared
194 */
195 genxStatus genxStartElement(genxElement e);
196
197 /*
198 * Write an attribute
199 */
200 genxStatus genxAddAttributeLiteral(genxWriter w, constUtf8 xmlns,
201 constUtf8 name, constUtf8 value);
202
203 /*
204 * Write a predeclared attribute
205 */
206 genxStatus genxAddAttribute(genxAttribute a, constUtf8 value);
207
208 /*
209 * add a namespace declaration
210 */
211 genxStatus genxAddNamespace(genxNamespace ns, utf8 prefix);
212
213 /*
214 * Clear default namespace declaration
215 */
216 genxStatus genxUnsetDefaultNamespace(genxWriter w);
217
218 /*
219 * Write an end tag
220 */
221 genxStatus genxEndElement(genxWriter w);
222
223 /*
224 * Write some text
225 * You can't write any text outside the root element, except with
226 * genxComment and genxPI
227 */
228 genxStatus genxAddText(genxWriter w, constUtf8 start);
229 genxStatus genxAddCountedText(genxWriter w, constUtf8 start, int byteCount);
230 genxStatus genxAddBoundedText(genxWriter w, constUtf8 start, constUtf8 end);
231
232 /*
233 * Write one character. The integer value is the Unicode character
234 * value, as usually expressed in U+XXXX notation.
235 */
236 genxStatus genxAddCharacter(genxWriter w, int c);
237
238 /*
239 * Utility routines
240 */
241
242 /*
243 * Return the Unicode character encoded by the UTF-8 pointed-to by the
244 * argument, and advance the argument past the encoding of the character.
245 * Returns -1 if the UTF-8 is malformed, in which case advances the
246 * argument to point at the first byte past the point past the malformed
247 * ones.
248 */
249 int genxNextUnicodeChar(constUtf8 * sp);
250
251 /*
252 * Scan a buffer allegedly full of UTF-8 encoded XML characters; return
253 * one of GENX_SUCCESS, GENX_BAD_UTF8, or GENX_NON_XML_CHARACTER
254 */
255 genxStatus genxCheckText(genxWriter w, constUtf8 s);
256
257 /*
258 * return character status, the OR of GENX_XML_CHAR,
259 * GENX_LETTER, and GENX_NAMECHAR
260 */
261 int genxCharClass(genxWriter w, int c);
262
263 /*
264 * Silently wipe any non-XML characters out of a chunk of text.
265 * If you call this on a string before you pass it addText or
266 * addAttribute, you will never get an error from genx unless
267 * (a) there's a bug in your software, e.g. a malformed element name, or
268 * (b) there's a memory allocation or I/O error
269 * The output can never be longer than the input.
270 * Returns true if any changes were made.
271 */
272 int genxScrubText(genxWriter w, constUtf8 in, utf8 out);
273
274 /*
275 * return error messages
276 */
277 char * genxGetErrorMessage(genxWriter w, genxStatus status);
278 char * genxLastErrorMessage(genxWriter w);
279
280 /*
281 * return version
282 */
283 char * genxGetVersion();
284
285 #ifdef __cplusplus
286 }
287 #endif