genx4r-fotopedia 0.0.6

Sign up to get free protection for your applications and to get access to all the features.
data/ext/genx4r/genx.h ADDED
@@ -0,0 +1,287 @@
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
@@ -0,0 +1,570 @@
1
+ /* Copyright (c) 2004 Garrett Rooney
2
+ *
3
+ * Permission is hereby granted, free of charge, to any person obtaining
4
+ * a copy of this software and associated documentation files (the
5
+ * "Software"), to deal in the Software without restriction, including
6
+ * without limitation the rights to use, copy, modify, merge, publish,
7
+ * distribute, sublicense, and/or sell copies of the Software, and to
8
+ * permit persons to whom the Software is furnished to do so, subject to
9
+ * the following conditions:
10
+ *
11
+ * The above copyright notice and this permission notice shall be included
12
+ * in all copies or substantial portions of the Software.
13
+ *
14
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY
15
+ * KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE
16
+ * WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
17
+ * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
18
+ * LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
19
+ * OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
20
+ * WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */
21
+
22
+ /* $Id: genx4r.c 494 2004-11-25 15:21:41Z rooneg $ */
23
+
24
+ #include "ruby.h"
25
+
26
+ #include "genx.h"
27
+
28
+ static VALUE rb_mGenX;
29
+ static VALUE rb_cGenXWriter;
30
+
31
+ static VALUE rb_cGenXNamespace;
32
+ static VALUE rb_cGenXAttribute;
33
+ static VALUE rb_cGenXElement;
34
+
35
+ static VALUE rb_cGenXException;
36
+
37
+ static void
38
+ writer_mark (genxWriter w)
39
+ {}
40
+
41
+ static void
42
+ writer_free (genxWriter w)
43
+ {
44
+ genxDispose (w);
45
+ }
46
+
47
+ #define GENX4R_ERR(expr, w) \
48
+ do { \
49
+ genxStatus genx4r__status = (expr); \
50
+ if (genx4r__status) \
51
+ rb_raise (rb_cGenXException, "%s", genxLastErrorMessage (w)); \
52
+ } while (0)
53
+
54
+ static VALUE
55
+ call_write (VALUE ary)
56
+ {
57
+ rb_funcall (rb_ary_entry (ary, 0),
58
+ rb_intern ("<<"),
59
+ 1,
60
+ rb_ary_entry (ary, 1));
61
+
62
+ return Qtrue;
63
+ }
64
+
65
+ static VALUE
66
+ call_flush (VALUE file)
67
+ {
68
+ rb_funcall (file, rb_intern ("flush"), 0);
69
+
70
+ return Qtrue;
71
+ }
72
+
73
+ static VALUE
74
+ handle_exception (VALUE unused)
75
+ {
76
+ return Qfalse;
77
+ }
78
+
79
+ static genxStatus
80
+ writer_send (void *baton, constUtf8 s)
81
+ {
82
+ VALUE file = (VALUE) baton;
83
+ VALUE ary;
84
+
85
+ if (! rb_respond_to (file, rb_intern ("<<")))
86
+ rb_raise (rb_eRuntimeError, "target must respond to '<<'");
87
+
88
+ ary = rb_ary_new2 (2);
89
+
90
+ rb_ary_store (ary, 0, file);
91
+ rb_ary_store (ary, 1, rb_str_new2 (s));
92
+
93
+ if (rb_rescue (call_write, ary, handle_exception, Qnil) == Qfalse)
94
+ return GENX_IO_ERROR;
95
+ else
96
+ return GENX_SUCCESS;
97
+ }
98
+
99
+ static genxStatus
100
+ writer_send_bounded (void *baton, constUtf8 start, constUtf8 end)
101
+ {
102
+ VALUE file = (VALUE) baton;
103
+ VALUE ary;
104
+
105
+ if (! rb_respond_to (file, rb_intern ("<<")))
106
+ rb_raise (rb_eRuntimeError, "target must respond to '<<'");
107
+
108
+ ary = rb_ary_new2 (2);
109
+
110
+ rb_ary_store (ary, 0, file);
111
+ rb_ary_store (ary, 1, rb_str_new (start, end - start));
112
+
113
+ if (rb_rescue (call_write, ary, handle_exception, Qnil) == Qfalse)
114
+ return GENX_IO_ERROR;
115
+ else
116
+ return GENX_SUCCESS;
117
+ }
118
+
119
+ static genxStatus
120
+ writer_flush (void *baton)
121
+ {
122
+ VALUE file = (VALUE) baton;
123
+
124
+ /* if we can't flush, just let it go... */
125
+ if (! rb_respond_to (file, rb_intern ("flush")))
126
+ return GENX_SUCCESS;
127
+
128
+ if (rb_rescue (call_flush, file, handle_exception, Qnil) == Qfalse)
129
+ return GENX_IO_ERROR;
130
+ else
131
+ return GENX_SUCCESS;
132
+ }
133
+
134
+ static genxSender writer_sender = { writer_send,
135
+ writer_send_bounded,
136
+ writer_flush };
137
+
138
+ static VALUE
139
+ writer_begin_document (VALUE self, VALUE file)
140
+ {
141
+ genxWriter w;
142
+
143
+ Data_Get_Struct (self, struct genxWriter_rec, w);
144
+
145
+ if (! rb_respond_to (file, rb_intern ("<<")))
146
+ rb_raise (rb_eRuntimeError, "target must respond to '<<'");
147
+
148
+ genxSetUserData(w, (void *) file);
149
+
150
+ GENX4R_ERR (genxStartDocSender (w, &writer_sender), w);
151
+
152
+ return Qnil;
153
+ }
154
+
155
+ static VALUE
156
+ writer_end_document (VALUE self)
157
+ {
158
+ genxWriter w;
159
+
160
+ Data_Get_Struct (self, struct genxWriter_rec, w);
161
+
162
+ GENX4R_ERR (genxEndDocument (w), w);
163
+
164
+ return Qnil;
165
+ }
166
+
167
+ static VALUE
168
+ writer_document (VALUE self, VALUE file)
169
+ {
170
+ writer_begin_document (self, file);
171
+
172
+ if (rb_block_given_p ())
173
+ {
174
+ rb_yield (Qnil);
175
+
176
+ writer_end_document (self);
177
+
178
+ return Qnil;
179
+ }
180
+ else
181
+ rb_raise (rb_eRuntimeError, "must be called with a block");
182
+ }
183
+
184
+ static VALUE
185
+ writer_comment (VALUE self, VALUE arg)
186
+ {
187
+ genxWriter w;
188
+
189
+ Check_Type (arg, T_STRING);
190
+
191
+ Data_Get_Struct (self, struct genxWriter_rec, w);
192
+
193
+ GENX4R_ERR (genxComment (w, (constUtf8) RSTRING (arg)->ptr), w);
194
+
195
+ return Qnil;
196
+ }
197
+
198
+ static VALUE
199
+ writer_attribute (int argc, VALUE *argv, VALUE self)
200
+ {
201
+ genxAttribute attr = 0;
202
+ genxWriter w;
203
+ VALUE xmlns, name, value;
204
+ int nslen = 0;
205
+
206
+ switch (argc)
207
+ {
208
+ case 2:
209
+ xmlns = 0;
210
+ if (CLASS_OF (argv[0]) == rb_cGenXAttribute)
211
+ {
212
+ Data_Get_Struct (argv[0], struct genxAttribute_rec, attr);
213
+ name = 0;
214
+ }
215
+ else
216
+ name = argv[0];
217
+
218
+ value = argv[1];
219
+ break;
220
+
221
+ case 3:
222
+ xmlns = argv[0];
223
+ name = argv[1];
224
+ value = argv[2];
225
+ break;
226
+
227
+ default:
228
+ rb_raise (rb_eRuntimeError, "invalid arguments");
229
+ }
230
+
231
+ if (xmlns)
232
+ {
233
+ Check_Type (xmlns, T_STRING);
234
+ nslen = RSTRING (xmlns)->len;
235
+ }
236
+
237
+ if (name)
238
+ Check_Type (name, T_STRING);
239
+
240
+ Check_Type (value, T_STRING);
241
+
242
+ Data_Get_Struct (self, struct genxWriter_rec, w);
243
+
244
+ if (attr)
245
+ GENX4R_ERR (genxAddAttribute (attr, (constUtf8) RSTRING (value)->ptr), w);
246
+ else
247
+ GENX4R_ERR (genxAddAttributeLiteral
248
+ (w,
249
+ nslen ? (constUtf8) RSTRING (xmlns)->ptr : NULL,
250
+ (constUtf8) RSTRING (name)->ptr,
251
+ (constUtf8) RSTRING (value)->ptr), w);
252
+
253
+ return Qnil;
254
+ }
255
+
256
+ static VALUE
257
+ writer_begin_element (int argc, VALUE *argv, VALUE self)
258
+ {
259
+ genxWriter w;
260
+ genxElement elem = 0;
261
+ VALUE xmlns, name;
262
+ int nslen = 0;
263
+
264
+ switch (argc)
265
+ {
266
+ case 1:
267
+ xmlns = 0;
268
+ if (CLASS_OF (argv[0]) == rb_cGenXElement)
269
+ {
270
+ Data_Get_Struct (argv[0], struct genxElement_rec, elem);
271
+ name = 0;
272
+ }
273
+ else
274
+ name = argv[0];
275
+ break;
276
+
277
+ case 2:
278
+ xmlns = argv[0];
279
+ name = argv[1];
280
+ break;
281
+
282
+ default:
283
+ rb_raise (rb_eRuntimeError, "invalid arguments");
284
+ }
285
+
286
+ if (xmlns)
287
+ {
288
+ Check_Type (xmlns, T_STRING);
289
+ nslen = RSTRING (xmlns)->len;
290
+ }
291
+
292
+ if (name)
293
+ Check_Type (name, T_STRING);
294
+
295
+ Data_Get_Struct (self, struct genxWriter_rec, w);
296
+
297
+ if (elem)
298
+ GENX4R_ERR (genxStartElement (elem), w);
299
+ else
300
+ GENX4R_ERR (genxStartElementLiteral
301
+ (w,
302
+ nslen ? (constUtf8) RSTRING (xmlns)->ptr : NULL,
303
+ (constUtf8) RSTRING (name)->ptr), w);
304
+
305
+ return Qnil;
306
+ }
307
+
308
+ static VALUE
309
+ writer_end_element (VALUE self)
310
+ {
311
+ genxWriter w;
312
+
313
+ Data_Get_Struct (self, struct genxWriter_rec, w);
314
+
315
+ GENX4R_ERR (genxEndElement (w), w);
316
+
317
+ return Qnil;
318
+ }
319
+
320
+ static VALUE
321
+ writer_element (int argc, VALUE *argv, VALUE self)
322
+ {
323
+ writer_begin_element (argc, argv, self);
324
+
325
+ if (rb_block_given_p ())
326
+ {
327
+ rb_yield (Qnil);
328
+
329
+ writer_end_element (self);
330
+
331
+ return Qnil;
332
+ }
333
+ else
334
+ rb_raise (rb_eRuntimeError, "must be called with a block");
335
+ }
336
+
337
+ static VALUE
338
+ writer_pi (VALUE self, VALUE target, VALUE text)
339
+ {
340
+ genxWriter w;
341
+
342
+ Check_Type (target, T_STRING);
343
+ Check_Type (text, T_STRING);
344
+
345
+ Data_Get_Struct (self, struct genxWriter_rec, w);
346
+
347
+ GENX4R_ERR (genxPI (w,
348
+ (constUtf8) RSTRING (target)->ptr,
349
+ (constUtf8) RSTRING (text)->ptr), w);
350
+
351
+ return Qnil;
352
+ }
353
+
354
+ static VALUE
355
+ writer_text (VALUE self, VALUE text)
356
+ {
357
+ genxWriter w;
358
+
359
+ Check_Type (text, T_STRING);
360
+
361
+ Data_Get_Struct (self, struct genxWriter_rec, w);
362
+
363
+ GENX4R_ERR (genxAddText (w, (constUtf8) RSTRING (text)->ptr), w);
364
+
365
+ return Qnil;
366
+ }
367
+
368
+ static VALUE
369
+ writer_character (VALUE self, VALUE ch)
370
+ {
371
+ genxWriter w;
372
+
373
+ int c = NUM2INT (ch);
374
+
375
+ Data_Get_Struct (self, struct genxWriter_rec, w);
376
+
377
+ GENX4R_ERR (genxAddCharacter (w, c), w);
378
+
379
+ return Qnil;
380
+ }
381
+
382
+ #if RUBY_VERSION_MAJOR >= 1 && RUBY_VERSION_MINOR >= 8
383
+ static VALUE
384
+ writer_allocate (VALUE klass)
385
+ {
386
+ genxWriter writer = genxNew (NULL, NULL, NULL);
387
+
388
+ return Data_Wrap_Struct (klass, writer_mark, writer_free, writer);
389
+ }
390
+ #else
391
+ static VALUE
392
+ writer_new (VALUE klass)
393
+ {
394
+ genxWriter writer = genxNew (NULL, NULL, NULL);
395
+
396
+ return Data_Wrap_Struct (klass, writer_mark, writer_free, writer);
397
+ }
398
+ #endif
399
+
400
+ static VALUE
401
+ writer_declare_namespace (int argc, VALUE *argv, VALUE self)
402
+ {
403
+ VALUE uri, prefix = 0;
404
+ genxStatus st = 0;
405
+ genxNamespace ns;
406
+ genxWriter w;
407
+
408
+ rb_scan_args (argc, argv, "11", &uri, &prefix);
409
+
410
+ Check_Type (uri, T_STRING);
411
+ if (prefix)
412
+ Check_Type (prefix, T_STRING);
413
+
414
+ Data_Get_Struct (self, struct genxWriter_rec, w);
415
+
416
+ ns = genxDeclareNamespace (w,
417
+ (constUtf8) RSTRING (uri)->ptr,
418
+ prefix ? (constUtf8) RSTRING (prefix)->ptr : NULL,
419
+ &st);
420
+
421
+ if (st)
422
+ rb_raise (rb_cGenXException, "%s", genxGetErrorMessage (w, st));
423
+
424
+ return Data_Wrap_Struct (rb_cGenXNamespace, NULL, NULL, ns);
425
+ }
426
+
427
+ static VALUE
428
+ writer_declare_element (int argc, VALUE *argv, VALUE self)
429
+ {
430
+ genxNamespace ns = 0;
431
+ genxStatus st = 0;
432
+ genxElement elem;
433
+ genxWriter w;
434
+ VALUE name;
435
+
436
+ switch (argc)
437
+ {
438
+ case 1:
439
+ name = argv[0];
440
+ break;
441
+
442
+ case 2:
443
+ if (CLASS_OF (argv[0]) == rb_cGenXNamespace) {
444
+ Data_Get_Struct (argv[0], struct genxNamespace_rec, ns);
445
+ } else {
446
+ rb_raise (rb_eRuntimeError, "invalid arguments");
447
+ }
448
+ name = argv[1];
449
+ break;
450
+
451
+ default:
452
+ rb_raise (rb_eRuntimeError, "invalid arguments");
453
+ }
454
+
455
+ Check_Type (name, T_STRING);
456
+
457
+ Data_Get_Struct (self, struct genxWriter_rec, w);
458
+
459
+ elem = genxDeclareElement (w, ns, RSTRING (name)->ptr, &st);
460
+ if (st)
461
+ rb_raise (rb_cGenXException, "%s", genxGetErrorMessage (w, st));
462
+
463
+ return Data_Wrap_Struct (rb_cGenXElement, NULL, NULL, elem);
464
+ }
465
+
466
+ static VALUE
467
+ writer_declare_attribute (int argc, VALUE *argv, VALUE self)
468
+ {
469
+ genxNamespace ns = 0;
470
+ genxAttribute attr;
471
+ genxStatus st = 0;
472
+ genxWriter w;
473
+ VALUE name;
474
+
475
+ switch (argc)
476
+ {
477
+ case 1:
478
+ name = argv[0];
479
+ break;
480
+
481
+ case 2:
482
+ if (CLASS_OF (argv[0]) == rb_cGenXNamespace) {
483
+ Data_Get_Struct (argv[0], struct genxNamespace_rec, ns);
484
+ } else {
485
+ rb_raise (rb_eRuntimeError, "invalid arguments");
486
+ }
487
+ name = argv[1];
488
+ break;
489
+
490
+ default:
491
+ rb_raise (rb_eRuntimeError, "invalid arguments");
492
+ }
493
+
494
+ Check_Type (name, T_STRING);
495
+
496
+ Data_Get_Struct (self, struct genxWriter_rec, w);
497
+
498
+ attr = genxDeclareAttribute (w, ns, RSTRING (name)->ptr, &st);
499
+ if (st)
500
+ rb_raise (rb_cGenXException, "%s", genxGetErrorMessage (w, st));
501
+
502
+ return Data_Wrap_Struct (rb_cGenXAttribute, NULL, NULL, attr);
503
+ }
504
+
505
+ void
506
+ Init_genx4r ()
507
+ {
508
+ rb_mGenX = rb_define_module ("GenX");
509
+
510
+ rb_cGenXWriter = rb_define_class_under (rb_mGenX, "Writer", rb_cObject);
511
+
512
+ #if RUBY_VERSION_MAJOR >= 1 && RUBY_VERSION_MINOR >= 8
513
+ rb_define_alloc_func (rb_cGenXWriter, writer_allocate);
514
+ #else
515
+ rb_define_singleton_method(rb_cGenXWriter, "new", writer_new, 0);
516
+ #endif
517
+
518
+ rb_define_method (rb_cGenXWriter, "document", writer_document, 1);
519
+
520
+ rb_define_method (rb_cGenXWriter,
521
+ "begin_document",
522
+ writer_begin_document,
523
+ 1);
524
+
525
+ rb_define_method (rb_cGenXWriter,
526
+ "end_document",
527
+ writer_end_document,
528
+ 0);
529
+
530
+ rb_define_method (rb_cGenXWriter, "comment", writer_comment, 1);
531
+ rb_define_method (rb_cGenXWriter, "pi", writer_pi, 2);
532
+
533
+ rb_define_method (rb_cGenXWriter, "element", writer_element, -1);
534
+
535
+ rb_define_method (rb_cGenXWriter, "begin_element", writer_begin_element, -1);
536
+ rb_define_method (rb_cGenXWriter, "end_element", writer_end_element, 0);
537
+
538
+ rb_define_method (rb_cGenXWriter, "attribute", writer_attribute, -1);
539
+ rb_define_method (rb_cGenXWriter, "text", writer_text, 1);
540
+ rb_define_method (rb_cGenXWriter, "character", writer_character, 1);
541
+
542
+ rb_define_method (rb_cGenXWriter,
543
+ "declare_namespace",
544
+ writer_declare_namespace,
545
+ -1);
546
+
547
+ rb_define_method (rb_cGenXWriter,
548
+ "declare_element",
549
+ writer_declare_element,
550
+ -1);
551
+
552
+ rb_define_method (rb_cGenXWriter,
553
+ "declare_attribute",
554
+ writer_declare_attribute,
555
+ -1);
556
+
557
+ rb_cGenXNamespace = rb_define_class_under (rb_mGenX,
558
+ "Namespace",
559
+ rb_cObject);
560
+
561
+ rb_cGenXElement = rb_define_class_under (rb_mGenX, "Element", rb_cObject);
562
+
563
+ rb_cGenXAttribute = rb_define_class_under (rb_mGenX,
564
+ "Attribute",
565
+ rb_cObject);
566
+
567
+ rb_cGenXException = rb_define_class_under (rb_mGenX,
568
+ "Exception",
569
+ rb_eStandardError);
570
+ }