ox 2.14.14 → 2.14.16

Sign up to get free protection for your applications and to get access to all the features.
data/ext/ox/dump.c CHANGED
@@ -3,84 +3,83 @@
3
3
  * All rights reserved.
4
4
  */
5
5
 
6
- #include <stdlib.h>
7
6
  #include <errno.h>
8
- #include <time.h>
9
7
  #include <stdio.h>
8
+ #include <stdlib.h>
10
9
  #include <string.h>
10
+ #include <time.h>
11
11
 
12
12
  #include "base64.h"
13
13
  #include "cache8.h"
14
14
  #include "ox.h"
15
15
 
16
- #define USE_B64 0
16
+ #define USE_B64 0
17
17
  #define MAX_DEPTH 1000
18
18
 
19
- typedef unsigned long ulong;
19
+ typedef unsigned long ulong;
20
20
 
21
21
  typedef struct _str {
22
- const char *str;
23
- size_t len;
22
+ const char *str;
23
+ size_t len;
24
24
  } *Str;
25
25
 
26
26
  typedef struct _element {
27
- struct _str clas;
28
- struct _str attr;
29
- unsigned long id;
30
- int indent; /* < 0 indicates no \n */
31
- int closed;
32
- char type;
27
+ struct _str clas;
28
+ struct _str attr;
29
+ unsigned long id;
30
+ int indent; /* < 0 indicates no \n */
31
+ int closed;
32
+ char type;
33
33
  } *Element;
34
34
 
35
35
  typedef struct _out {
36
- void (*w_start)(struct _out *out, Element e);
37
- void (*w_end)(struct _out *out, Element e);
38
- void (*w_time)(struct _out *out, VALUE obj);
39
- char *buf;
40
- char *end;
41
- char *cur;
42
- Cache8 circ_cache;
43
- unsigned long circ_cnt;
44
- int indent;
45
- int depth; /* used by dumpHash */
46
- Options opts;
47
- VALUE obj;
36
+ void (*w_start)(struct _out *out, Element e);
37
+ void (*w_end)(struct _out *out, Element e);
38
+ void (*w_time)(struct _out *out, VALUE obj);
39
+ char *buf;
40
+ char *end;
41
+ char *cur;
42
+ Cache8 circ_cache;
43
+ unsigned long circ_cnt;
44
+ int indent;
45
+ int depth; /* used by dumpHash */
46
+ Options opts;
47
+ VALUE obj;
48
48
  } *Out;
49
49
 
50
- static void dump_obj_to_xml(VALUE obj, Options copts, Out out);
50
+ static void dump_obj_to_xml(VALUE obj, Options copts, Out out);
51
51
 
52
- static void dump_first_obj(VALUE obj, Out out);
53
- static void dump_obj(ID aid, VALUE obj, int depth, Out out);
54
- static void dump_gen_doc(VALUE obj, int depth, Out out);
55
- static void dump_gen_element(VALUE obj, int depth, Out out);
56
- static void dump_gen_instruct(VALUE obj, int depth, Out out);
57
- static int dump_gen_attr(VALUE key, VALUE value, VALUE ov);
58
- static int dump_gen_nodes(VALUE obj, int depth, Out out);
59
- static void dump_gen_val_node(VALUE obj, int depth,
60
- const char *pre, size_t plen,
61
- const char *suf, size_t slen, Out out);
52
+ static void dump_first_obj(VALUE obj, Out out);
53
+ static void dump_obj(ID aid, VALUE obj, int depth, Out out);
54
+ static void dump_gen_doc(VALUE obj, int depth, Out out);
55
+ static void dump_gen_element(VALUE obj, int depth, Out out);
56
+ static void dump_gen_instruct(VALUE obj, int depth, Out out);
57
+ static int dump_gen_attr(VALUE key, VALUE value, VALUE ov);
58
+ static int dump_gen_nodes(VALUE obj, int depth, Out out);
59
+ static void
60
+ dump_gen_val_node(VALUE obj, int depth, const char *pre, size_t plen, const char *suf, size_t slen, Out out);
62
61
 
63
- static void dump_start(Out out, Element e);
64
- static void dump_end(Out out, Element e);
62
+ static void dump_start(Out out, Element e);
63
+ static void dump_end(Out out, Element e);
65
64
 
66
- static void grow(Out out, size_t len);
65
+ static void grow(Out out, size_t len);
67
66
 
68
- static void dump_value(Out out, const char *value, size_t size);
69
- static void dump_str_value(Out out, const char *value, size_t size, const char *table);
70
- static int dump_var(ID key, VALUE value, VALUE ov);
71
- static void dump_num(Out out, VALUE obj);
72
- static void dump_date(Out out, VALUE obj);
73
- static void dump_time_thin(Out out, VALUE obj);
74
- static void dump_time_xsd(Out out, VALUE obj);
75
- static int dump_hash(VALUE key, VALUE value, VALUE ov);
67
+ static void dump_value(Out out, const char *value, size_t size);
68
+ static void dump_str_value(Out out, const char *value, size_t size, const char *table);
69
+ static int dump_var(ID key, VALUE value, VALUE ov);
70
+ static void dump_num(Out out, VALUE obj);
71
+ static void dump_date(Out out, VALUE obj);
72
+ static void dump_time_thin(Out out, VALUE obj);
73
+ static void dump_time_xsd(Out out, VALUE obj);
74
+ static int dump_hash(VALUE key, VALUE value, VALUE ov);
76
75
 
77
- static int is_xml_friendly(const uchar *str, int len, const char *table);
76
+ static int is_xml_friendly(const uchar *str, int len, const char *table);
78
77
 
79
- static const char hex_chars[17] = "0123456789abcdef";
78
+ static const char hex_chars[17] = "0123456789abcdef";
80
79
 
81
80
  // The : character is equivalent to 10. Used for replacement characters up to 10
82
81
  // characters long such as '&#x10FFFF;'.
83
- static const char xml_friendly_chars[257] = "\
82
+ static const char xml_friendly_chars[257] = "\
84
83
  :::::::::11::1::::::::::::::::::\
85
84
  11611156111111111111111111114141\
86
85
  11111111111111111111111111111111\
@@ -90,7 +89,7 @@ static const char xml_friendly_chars[257] = "\
90
89
  11111111111111111111111111111111\
91
90
  11111111111111111111111111111111";
92
91
 
93
- static const char xml_quote_chars[257] = "\
92
+ static const char xml_quote_chars[257] = "\
94
93
  :::::::::11::1::::::::::::::::::\
95
94
  11611151111111111111111111114141\
96
95
  11111111111111111111111111111111\
@@ -100,7 +99,7 @@ static const char xml_quote_chars[257] = "\
100
99
  11111111111111111111111111111111\
101
100
  11111111111111111111111111111111";
102
101
 
103
- static const char xml_element_chars[257] = "\
102
+ static const char xml_element_chars[257] = "\
104
103
  :::::::::11::1::::::::::::::::::\
105
104
  11111151111111111111111111114141\
106
105
  11111111111111111111111111111111\
@@ -110,916 +109,902 @@ static const char xml_element_chars[257] = "\
110
109
  11111111111111111111111111111111\
111
110
  11111111111111111111111111111111";
112
111
 
113
- inline static int
114
- is_xml_friendly(const uchar *str, int len, const char *table) {
112
+ inline static int is_xml_friendly(const uchar *str, int len, const char *table) {
115
113
  for (; 0 < len; str++, len--) {
116
- if ('1' != table[*str]) {
117
- return 0;
118
- }
114
+ if ('1' != table[*str]) {
115
+ return 0;
116
+ }
119
117
  }
120
118
  return 1;
121
119
  }
122
120
 
123
- inline static size_t
124
- xml_str_len(const uchar *str, size_t len, const char *table) {
125
- size_t size = 0;
121
+ inline static size_t xml_str_len(const uchar *str, size_t len, const char *table) {
122
+ size_t size = 0;
126
123
 
127
124
  for (; 0 < len; str++, len--) {
128
- size += xml_friendly_chars[*str];
125
+ size += xml_friendly_chars[*str];
129
126
  }
130
127
  return size - len * (size_t)'0';
131
128
  }
132
129
 
133
- inline static void
134
- dump_hex(uchar c, Out out) {
135
- uchar d = (c >> 4) & 0x0F;
130
+ inline static void dump_hex(uchar c, Out out) {
131
+ uchar d = (c >> 4) & 0x0F;
136
132
 
137
133
  *out->cur++ = hex_chars[d];
138
- d = c & 0x0F;
134
+ d = c & 0x0F;
139
135
  *out->cur++ = hex_chars[d];
140
136
  }
141
137
 
142
- static Type
143
- obj_class_code(VALUE obj) {
144
- VALUE clas = rb_obj_class(obj);
138
+ static Type obj_class_code(VALUE obj) {
139
+ VALUE clas = rb_obj_class(obj);
145
140
 
146
141
  switch (rb_type(obj)) {
147
- case T_NIL: return NilClassCode;
148
- case T_ARRAY: return ArrayCode;
149
- case T_HASH: return HashCode;
150
- case T_TRUE: return TrueClassCode;
151
- case T_FALSE: return FalseClassCode;
152
- case T_FIXNUM: return FixnumCode;
153
- case T_FLOAT: return FloatCode;
154
- case T_STRING: return (is_xml_friendly((uchar*)StringValuePtr(obj), (int)RSTRING_LEN(obj), xml_element_chars)) ? StringCode : String64Code;
155
- case T_SYMBOL:
156
- {
157
- const char *sym = rb_id2name(SYM2ID(obj));
158
-
159
- return (is_xml_friendly((uchar*)sym, (int)strlen(sym), xml_element_chars)) ? SymbolCode : Symbol64Code;
160
- }
161
- case T_DATA: return (rb_cTime == clas) ? TimeCode : ((ox_date_class == clas) ? DateCode : 0);
162
- case T_STRUCT: return (rb_cRange == clas) ? RangeCode : StructCode;
163
- case T_OBJECT: return (ox_document_clas == clas || ox_element_clas == clas) ? RawCode : ObjectCode;
164
- case T_REGEXP: return RegexpCode;
165
- case T_BIGNUM: return BignumCode;
142
+ case T_NIL: return NilClassCode;
143
+ case T_ARRAY: return ArrayCode;
144
+ case T_HASH: return HashCode;
145
+ case T_TRUE: return TrueClassCode;
146
+ case T_FALSE: return FalseClassCode;
147
+ case T_FIXNUM: return FixnumCode;
148
+ case T_FLOAT: return FloatCode;
149
+ case T_STRING:
150
+ return (is_xml_friendly((uchar *)StringValuePtr(obj), (int)RSTRING_LEN(obj), xml_element_chars)) ? StringCode
151
+ : String64Code;
152
+ case T_SYMBOL: {
153
+ const char *sym = rb_id2name(SYM2ID(obj));
154
+
155
+ return (is_xml_friendly((uchar *)sym, (int)strlen(sym), xml_element_chars)) ? SymbolCode : Symbol64Code;
156
+ }
157
+ case T_DATA: return (rb_cTime == clas) ? TimeCode : ((ox_date_class == clas) ? DateCode : 0);
158
+ case T_STRUCT: return (rb_cRange == clas) ? RangeCode : StructCode;
159
+ case T_OBJECT: return (ox_document_clas == clas || ox_element_clas == clas) ? RawCode : ObjectCode;
160
+ case T_REGEXP: return RegexpCode;
161
+ case T_BIGNUM: return BignumCode;
166
162
  #ifdef T_COMPLEX
167
- case T_COMPLEX: return ComplexCode;
163
+ case T_COMPLEX: return ComplexCode;
168
164
  #endif
169
165
  #ifdef T_RATIONAL
170
- case T_RATIONAL: return RationalCode;
166
+ case T_RATIONAL: return RationalCode;
171
167
  #endif
172
- case T_CLASS: return ClassCode;
173
- default: return 0;
168
+ case T_CLASS: return ClassCode;
169
+ default: return 0;
174
170
  }
175
171
  }
176
172
 
177
- inline static void
178
- fill_indent(Out out, int cnt) {
173
+ inline static void fill_indent(Out out, int cnt) {
179
174
  if (0 <= cnt) {
180
- *out->cur++ = '\n';
181
- if (0 < out->opts->margin_len) {
182
- memcpy(out->cur, out->opts->margin, out->opts->margin_len);
183
- out->cur += out->opts->margin_len;
184
- }
185
- for (; 0 < cnt; cnt--) {
186
- *out->cur++ = ' ';
187
- }
175
+ *out->cur++ = '\n';
176
+ if (0 < out->opts->margin_len) {
177
+ memcpy(out->cur, out->opts->margin, out->opts->margin_len);
178
+ out->cur += out->opts->margin_len;
179
+ }
180
+ for (; 0 < cnt; cnt--) {
181
+ *out->cur++ = ' ';
182
+ }
188
183
  }
189
184
  }
190
185
 
191
- inline static void
192
- fill_value(Out out, const char *value, size_t len) {
186
+ inline static void fill_value(Out out, const char *value, size_t len) {
193
187
  if (6 < len) {
194
- memcpy(out->cur, value, len);
195
- out->cur += len;
188
+ memcpy(out->cur, value, len);
189
+ out->cur += len;
196
190
  } else {
197
- for (; 0 < len; len--, value++) {
198
- *out->cur++ = *value;
199
- }
191
+ for (; 0 < len; len--, value++) {
192
+ *out->cur++ = *value;
193
+ }
200
194
  }
201
195
  }
202
196
 
203
- inline static void
204
- fill_attr(Out out, char name, const char *value, size_t len) {
197
+ inline static void fill_attr(Out out, char name, const char *value, size_t len) {
205
198
  *out->cur++ = ' ';
206
199
  *out->cur++ = name;
207
200
  *out->cur++ = '=';
208
201
  *out->cur++ = '"';
209
202
  if (6 < len) {
210
- memcpy(out->cur, value, len);
211
- out->cur += len;
203
+ memcpy(out->cur, value, len);
204
+ out->cur += len;
212
205
  } else {
213
- for (; 0 < len; len--, value++) {
214
- *out->cur++ = *value;
215
- }
206
+ for (; 0 < len; len--, value++) {
207
+ *out->cur++ = *value;
208
+ }
216
209
  }
217
210
  *out->cur++ = '"';
218
211
  }
219
212
 
220
- inline static const char*
221
- ulong2str(ulong num, char *end) {
222
- char *b;
213
+ inline static const char *ulong2str(ulong num, char *end) {
214
+ char *b;
223
215
 
224
216
  *end-- = '\0';
225
217
  for (b = end; 0 < num || b == end; num /= 10, b--) {
226
- *b = (num % 10) + '0';
218
+ *b = (num % 10) + '0';
227
219
  }
228
220
  b++;
229
221
 
230
222
  return b;
231
223
  }
232
224
 
233
- static int
234
- check_circular(Out out, VALUE obj, Element e) {
235
- slot_t *slot;
236
- slot_t id;
237
- int result;
225
+ static int check_circular(Out out, VALUE obj, Element e) {
226
+ slot_t *slot;
227
+ slot_t id;
228
+ int result;
238
229
 
239
230
  if (0 == (id = ox_cache8_get(out->circ_cache, obj, &slot))) {
240
- out->circ_cnt++;
241
- id = out->circ_cnt;
242
- *slot = id;
243
- e->id = id;
244
- result = 0;
231
+ out->circ_cnt++;
232
+ id = out->circ_cnt;
233
+ *slot = id;
234
+ e->id = id;
235
+ result = 0;
245
236
  } else {
246
- e->type = RefCode; e->clas.len = 0; e->clas.str = 0;
247
- e->closed = 1;
248
- e->id = id;
249
- out->w_start(out, e);
250
- result = 1;
237
+ e->type = RefCode;
238
+ e->clas.len = 0;
239
+ e->clas.str = 0;
240
+ e->closed = 1;
241
+ e->id = id;
242
+ out->w_start(out, e);
243
+ result = 1;
251
244
  }
252
245
  return result;
253
246
  }
254
247
 
255
- static void
256
- grow(Out out, size_t len) {
257
- size_t size = out->end - out->buf;
258
- long pos = out->cur - out->buf;
248
+ static void grow(Out out, size_t len) {
249
+ size_t size = out->end - out->buf;
250
+ long pos = out->cur - out->buf;
259
251
 
260
252
  size *= 2;
261
253
  if (size <= len * 2 + pos) {
262
- size += len;
254
+ size += len;
263
255
  }
264
256
  REALLOC_N(out->buf, char, size + 10); /* 10 extra for terminator character plus extra (paranoid) */
265
257
  out->end = out->buf + size;
266
258
  out->cur = out->buf + pos;
267
259
  }
268
260
 
269
- static void
270
- dump_start(Out out, Element e) {
271
- size_t size = e->indent + 4 + out->opts->margin_len;
261
+ static void dump_start(Out out, Element e) {
262
+ size_t size = e->indent + 4 + out->opts->margin_len;
272
263
 
273
264
  if (0 < e->attr.len) { /* a="attr" */
274
- size += e->attr.len + 5;
265
+ size += e->attr.len + 5;
275
266
  }
276
267
  if (0 < e->clas.len) { /* c="class" */
277
- size += e->clas.len + 5;
268
+ size += e->clas.len + 5;
278
269
  }
279
270
  if (0 < e->id) { /* i="id" */
280
- size += 24; /* over estimate, 19 digits */
271
+ size += 24; /* over estimate, 19 digits */
281
272
  }
282
273
  if (out->end - out->cur <= (long)size) {
283
- grow(out, size);
274
+ grow(out, size);
284
275
  }
285
276
  if (out->buf + out->opts->margin_len < out->cur) {
286
- fill_indent(out, e->indent);
277
+ fill_indent(out, e->indent);
287
278
  }
288
279
  *out->cur++ = '<';
289
280
  *out->cur++ = e->type;
290
281
  if (0 < e->attr.len) {
291
- fill_attr(out, 'a', e->attr.str, e->attr.len);
282
+ fill_attr(out, 'a', e->attr.str, e->attr.len);
292
283
  }
293
- if ((ObjectCode == e->type || ExceptionCode == e->type || StructCode == e->type || ClassCode == e->type) && 0 < e->clas.len) {
294
- fill_attr(out, 'c', e->clas.str, e->clas.len);
284
+ if ((ObjectCode == e->type || ExceptionCode == e->type || StructCode == e->type || ClassCode == e->type) &&
285
+ 0 < e->clas.len) {
286
+ fill_attr(out, 'c', e->clas.str, e->clas.len);
295
287
  }
296
288
  if (0 < e->id) {
297
- char buf[32];
298
- char *end = buf + sizeof(buf) - 1;
299
- const char *s = ulong2str(e->id, end);
289
+ char buf[32];
290
+ char *end = buf + sizeof(buf) - 1;
291
+ const char *s = ulong2str(e->id, end);
300
292
 
301
- fill_attr(out, 'i', s, end - s);
293
+ fill_attr(out, 'i', s, end - s);
302
294
  }
303
295
  if (e->closed) {
304
- if (out->opts->no_empty) {
305
- *out->cur++ = '>';
306
- *out->cur++ = '<';
307
- *out->cur++ = '/';
308
- *out->cur++ = e->type;
309
- } else {
310
- *out->cur++ = '/';
311
- }
296
+ if (out->opts->no_empty) {
297
+ *out->cur++ = '>';
298
+ *out->cur++ = '<';
299
+ *out->cur++ = '/';
300
+ *out->cur++ = e->type;
301
+ } else {
302
+ *out->cur++ = '/';
303
+ }
312
304
  }
313
305
  *out->cur++ = '>';
314
- *out->cur = '\0';
306
+ *out->cur = '\0';
315
307
  }
316
308
 
317
- static void
318
- dump_end(Out out, Element e) {
319
- size_t size = e->indent + 5 + out->opts->margin_len;
309
+ static void dump_end(Out out, Element e) {
310
+ size_t size = e->indent + 5 + out->opts->margin_len;
320
311
 
321
312
  if (out->end - out->cur <= (long)size) {
322
- grow(out, size);
313
+ grow(out, size);
323
314
  }
324
315
  fill_indent(out, e->indent);
325
316
  *out->cur++ = '<';
326
317
  *out->cur++ = '/';
327
318
  *out->cur++ = e->type;
328
319
  *out->cur++ = '>';
329
- *out->cur = '\0';
320
+ *out->cur = '\0';
330
321
  }
331
322
 
332
- inline static void
333
- dump_value(Out out, const char *value, size_t size) {
323
+ inline static void dump_value(Out out, const char *value, size_t size) {
334
324
  if (out->end - out->cur <= (long)size) {
335
- grow(out, size);
325
+ grow(out, size);
336
326
  }
337
327
  if (6 < size) {
338
- memcpy(out->cur, value, size);
339
- out->cur += size;
328
+ memcpy(out->cur, value, size);
329
+ out->cur += size;
340
330
  } else {
341
- for (; 0 < size; size--, value++) {
342
- *out->cur++ = *value;
343
- }
331
+ for (; 0 < size; size--, value++) {
332
+ *out->cur++ = *value;
333
+ }
344
334
  }
345
335
  *out->cur = '\0';
346
336
  }
347
337
 
348
- inline static void
349
- dump_str_value(Out out, const char *value, size_t size, const char *table) {
350
- size_t xsize = xml_str_len((const uchar*)value, size, table);
338
+ inline static void dump_str_value(Out out, const char *value, size_t size, const char *table) {
339
+ size_t xsize = xml_str_len((const uchar *)value, size, table);
351
340
 
352
341
  if (out->end - out->cur <= (long)xsize) {
353
- grow(out, xsize);
342
+ grow(out, xsize);
354
343
  }
355
344
  for (; 0 < size; size--, value++) {
356
- if ('1' == table[(uchar)*value]) {
357
- *out->cur++ = *value;
358
- } else {
359
- switch (*value) {
360
- case '"':
361
- *out->cur++ = '&';
362
- *out->cur++ = 'q';
363
- *out->cur++ = 'u';
364
- *out->cur++ = 'o';
365
- *out->cur++ = 't';
366
- *out->cur++ = ';';
367
- break;
368
- case '&':
369
- *out->cur++ = '&';
370
- *out->cur++ = 'a';
371
- *out->cur++ = 'm';
372
- *out->cur++ = 'p';
373
- *out->cur++ = ';';
374
- break;
375
- case '\'':
376
- *out->cur++ = '&';
377
- *out->cur++ = 'a';
378
- *out->cur++ = 'p';
379
- *out->cur++ = 'o';
380
- *out->cur++ = 's';
381
- *out->cur++ = ';';
382
- break;
383
- case '<':
384
- *out->cur++ = '&';
385
- *out->cur++ = 'l';
386
- *out->cur++ = 't';
387
- *out->cur++ = ';';
388
- break;
389
- case '>':
390
- *out->cur++ = '&';
391
- *out->cur++ = 'g';
392
- *out->cur++ = 't';
393
- *out->cur++ = ';';
394
- break;
395
- default:
396
- // Must be one of the invalid characters.
397
- if (StrictEffort == out->opts->effort) {
398
- rb_raise(ox_syntax_error_class, "'\\#x%02x' is not a valid XML character.", *value);
399
- }
400
- if (Yes == out->opts->allow_invalid) {
401
- *out->cur++ = '&';
402
- *out->cur++ = '#';
403
- *out->cur++ = 'x';
404
- *out->cur++ = '0';
405
- *out->cur++ = '0';
406
- dump_hex(*value, out);
407
- *out->cur++ = ';';
408
- } else if ('\0' != *out->opts->inv_repl) {
409
- // If the empty string then ignore. The first character of
410
- // the replacement is the length.
411
- memcpy(out->cur, out->opts->inv_repl + 1, (size_t)*out->opts->inv_repl);
412
- out->cur += *out->opts->inv_repl;
413
- }
414
- break;
415
- }
416
- }
345
+ if ('1' == table[(uchar)*value]) {
346
+ *out->cur++ = *value;
347
+ } else {
348
+ switch (*value) {
349
+ case '"':
350
+ *out->cur++ = '&';
351
+ *out->cur++ = 'q';
352
+ *out->cur++ = 'u';
353
+ *out->cur++ = 'o';
354
+ *out->cur++ = 't';
355
+ *out->cur++ = ';';
356
+ break;
357
+ case '&':
358
+ *out->cur++ = '&';
359
+ *out->cur++ = 'a';
360
+ *out->cur++ = 'm';
361
+ *out->cur++ = 'p';
362
+ *out->cur++ = ';';
363
+ break;
364
+ case '\'':
365
+ *out->cur++ = '&';
366
+ *out->cur++ = 'a';
367
+ *out->cur++ = 'p';
368
+ *out->cur++ = 'o';
369
+ *out->cur++ = 's';
370
+ *out->cur++ = ';';
371
+ break;
372
+ case '<':
373
+ *out->cur++ = '&';
374
+ *out->cur++ = 'l';
375
+ *out->cur++ = 't';
376
+ *out->cur++ = ';';
377
+ break;
378
+ case '>':
379
+ *out->cur++ = '&';
380
+ *out->cur++ = 'g';
381
+ *out->cur++ = 't';
382
+ *out->cur++ = ';';
383
+ break;
384
+ default:
385
+ // Must be one of the invalid characters.
386
+ if (StrictEffort == out->opts->effort) {
387
+ rb_raise(ox_syntax_error_class, "'\\#x%02x' is not a valid XML character.", *value);
388
+ }
389
+ if (Yes == out->opts->allow_invalid) {
390
+ *out->cur++ = '&';
391
+ *out->cur++ = '#';
392
+ *out->cur++ = 'x';
393
+ *out->cur++ = '0';
394
+ *out->cur++ = '0';
395
+ dump_hex(*value, out);
396
+ *out->cur++ = ';';
397
+ } else if ('\0' != *out->opts->inv_repl) {
398
+ // If the empty string then ignore. The first character of
399
+ // the replacement is the length.
400
+ memcpy(out->cur, out->opts->inv_repl + 1, (size_t)*out->opts->inv_repl);
401
+ out->cur += *out->opts->inv_repl;
402
+ }
403
+ break;
404
+ }
405
+ }
417
406
  }
418
407
  *out->cur = '\0';
419
408
  }
420
409
 
421
- inline static void
422
- dump_num(Out out, VALUE obj) {
423
- char buf[32];
424
- char *b = buf + sizeof(buf) - 1;
425
- long num = NUM2LONG(obj);
426
- int neg = 0;
410
+ inline static void dump_num(Out out, VALUE obj) {
411
+ char buf[32];
412
+ char *b = buf + sizeof(buf) - 1;
413
+ long num = NUM2LONG(obj);
414
+ int neg = 0;
427
415
 
428
416
  if (0 > num) {
429
- neg = 1;
430
- num = -num;
417
+ neg = 1;
418
+ num = -num;
431
419
  }
432
420
  *b-- = '\0';
433
421
  if (0 < num) {
434
- for (; 0 < num; num /= 10, b--) {
435
- *b = (num % 10) + '0';
436
- }
437
- if (neg) {
438
- *b = '-';
439
- } else {
440
- b++;
441
- }
422
+ for (; 0 < num; num /= 10, b--) {
423
+ *b = (num % 10) + '0';
424
+ }
425
+ if (neg) {
426
+ *b = '-';
427
+ } else {
428
+ b++;
429
+ }
442
430
  } else {
443
- *b = '0';
431
+ *b = '0';
444
432
  }
445
433
  if (out->end - out->cur <= (long)(sizeof(buf) - (b - buf))) {
446
- grow(out, sizeof(buf) - (b - buf));
434
+ grow(out, sizeof(buf) - (b - buf));
447
435
  }
448
436
  for (; '\0' != *b; b++) {
449
- *out->cur++ = *b;
437
+ *out->cur++ = *b;
450
438
  }
451
439
  *out->cur = '\0';
452
440
  }
453
441
 
454
- static void
455
- dump_time_thin(Out out, VALUE obj) {
456
- char buf[64];
457
- char *b = buf + sizeof(buf) - 1;
442
+ static void dump_time_thin(Out out, VALUE obj) {
443
+ char buf[64];
444
+ char *b = buf + sizeof(buf) - 1;
458
445
  #if HAVE_RB_TIME_TIMESPEC
459
- struct timespec ts = rb_time_timespec(obj);
460
- time_t sec = ts.tv_sec;
461
- long nsec = ts.tv_nsec;
446
+ struct timespec ts = rb_time_timespec(obj);
447
+ time_t sec = ts.tv_sec;
448
+ long nsec = ts.tv_nsec;
462
449
  #else
463
- time_t sec = NUM2LONG(rb_funcall2(obj, ox_tv_sec_id, 0, 0));
464
- long nsec = NUM2LONG(rb_funcall2(obj, ox_tv_nsec_id, 0, 0));
465
- //long nsec = NUM2LONG(rb_funcall2(obj, ox_tv_usec_id, 0, 0)) * 1000;
450
+ time_t sec = NUM2LONG(rb_funcall2(obj, ox_tv_sec_id, 0, 0));
451
+ long nsec = NUM2LONG(rb_funcall2(obj, ox_tv_nsec_id, 0, 0));
452
+ // long nsec = NUM2LONG(rb_funcall2(obj, ox_tv_usec_id, 0, 0)) * 1000;
466
453
  #endif
467
- char *dot = b - 10;
468
- long size;
454
+ char *dot = b - 10;
455
+ long size;
469
456
 
470
457
  *b-- = '\0';
471
458
  for (; dot < b; b--, nsec /= 10) {
472
- *b = '0' + (nsec % 10);
459
+ *b = '0' + (nsec % 10);
473
460
  }
474
461
  *b-- = '.';
475
462
  for (; 0 < sec; b--, sec /= 10) {
476
- *b = '0' + (sec % 10);
463
+ *b = '0' + (sec % 10);
477
464
  }
478
465
  b++;
479
466
  size = sizeof(buf) - (b - buf) - 1;
480
467
  if (out->end - out->cur <= size) {
481
- grow(out, size);
468
+ grow(out, size);
482
469
  }
483
470
  memcpy(out->cur, b, size);
484
471
  out->cur += size;
485
472
  }
486
473
 
487
- static void
488
- dump_date(Out out, VALUE obj) {
489
- char buf[64];
490
- char *b = buf + sizeof(buf) - 1;
491
- long jd = NUM2LONG(rb_funcall2(obj, ox_jd_id, 0, 0));
492
- long size;
474
+ static void dump_date(Out out, VALUE obj) {
475
+ char buf[64];
476
+ char *b = buf + sizeof(buf) - 1;
477
+ long jd = NUM2LONG(rb_funcall2(obj, ox_jd_id, 0, 0));
478
+ long size;
493
479
 
494
480
  *b-- = '\0';
495
481
  for (; 0 < jd; b--, jd /= 10) {
496
- *b = '0' + (jd % 10);
482
+ *b = '0' + (jd % 10);
497
483
  }
498
484
  b++;
499
485
  if ('\0' == *b) {
500
- b--;
501
- *b = '0';
486
+ b--;
487
+ *b = '0';
502
488
  }
503
489
  size = sizeof(buf) - (b - buf) - 1;
504
490
  if (out->end - out->cur <= size) {
505
- grow(out, size);
491
+ grow(out, size);
506
492
  }
507
493
  memcpy(out->cur, b, size);
508
494
  out->cur += size;
509
495
  }
510
496
 
511
- static void
512
- dump_time_xsd(Out out, VALUE obj) {
513
- struct tm *tm;
497
+ static void dump_time_xsd(Out out, VALUE obj) {
498
+ struct tm *tm;
514
499
  #if HAVE_RB_TIME_TIMESPEC
515
- struct timespec ts = rb_time_timespec(obj);
516
- time_t sec = ts.tv_sec;
517
- long nsec = ts.tv_nsec;
500
+ struct timespec ts = rb_time_timespec(obj);
501
+ time_t sec = ts.tv_sec;
502
+ long nsec = ts.tv_nsec;
518
503
  #else
519
- time_t sec = NUM2LONG(rb_funcall2(obj, ox_tv_sec_id, 0, 0));
520
- long nsec = NUM2LONG(rb_funcall2(obj, ox_tv_nsec_id, 0, 0));
521
- //long nsec = NUM2LONG(rb_funcall2(obj, ox_tv_usec_id, 0, 0)) * 1000;
504
+ time_t sec = NUM2LONG(rb_funcall2(obj, ox_tv_sec_id, 0, 0));
505
+ long nsec = NUM2LONG(rb_funcall2(obj, ox_tv_nsec_id, 0, 0));
506
+ // long nsec = NUM2LONG(rb_funcall2(obj, ox_tv_usec_id, 0, 0)) * 1000;
522
507
  #endif
523
- int tzhour, tzmin;
524
- char tzsign = '+';
508
+ int tzhour, tzmin;
509
+ char tzsign = '+';
525
510
 
526
511
  if (out->end - out->cur <= 33) {
527
- grow(out, 33);
512
+ grow(out, 33);
528
513
  }
529
514
  /* 2010-07-09T10:47:45.895826+09:00 */
530
515
  tm = localtime(&sec);
531
516
  #if HAVE_ST_TM_GMTOFF
532
517
  if (0 > tm->tm_gmtoff) {
533
- tzsign = '-';
534
- tzhour = (int)(tm->tm_gmtoff / -3600);
535
- tzmin = (int)(tm->tm_gmtoff / -60) - (tzhour * 60);
518
+ tzsign = '-';
519
+ tzhour = (int)(tm->tm_gmtoff / -3600);
520
+ tzmin = (int)(tm->tm_gmtoff / -60) - (tzhour * 60);
536
521
  } else {
537
- tzhour = (int)(tm->tm_gmtoff / 3600);
538
- tzmin = (int)(tm->tm_gmtoff / 60) - (tzhour * 60);
522
+ tzhour = (int)(tm->tm_gmtoff / 3600);
523
+ tzmin = (int)(tm->tm_gmtoff / 60) - (tzhour * 60);
539
524
  }
540
525
  #else
541
526
  tzhour = 0;
542
- tzmin = 0;
527
+ tzmin = 0;
543
528
  #endif
544
529
  /* TBD replace with more efficient printer */
545
- out->cur += sprintf(out->cur, "%04d-%02d-%02dT%02d:%02d:%02d.%06ld%c%02d:%02d",
546
- tm->tm_year + 1900, tm->tm_mon + 1, tm->tm_mday,
547
- tm->tm_hour, tm->tm_min, tm->tm_sec, nsec / 1000,
548
- tzsign, tzhour, tzmin);
530
+ out->cur += sprintf(out->cur,
531
+ "%04d-%02d-%02dT%02d:%02d:%02d.%06ld%c%02d:%02d",
532
+ tm->tm_year + 1900,
533
+ tm->tm_mon + 1,
534
+ tm->tm_mday,
535
+ tm->tm_hour,
536
+ tm->tm_min,
537
+ tm->tm_sec,
538
+ nsec / 1000,
539
+ tzsign,
540
+ tzhour,
541
+ tzmin);
549
542
  }
550
543
 
551
- static void
552
- dump_first_obj(VALUE obj, Out out) {
553
- char buf[128];
554
- Options copts = out->opts;
555
- int cnt;
544
+ static void dump_first_obj(VALUE obj, Out out) {
545
+ char buf[128];
546
+ Options copts = out->opts;
547
+ int cnt;
556
548
 
557
549
  if (Yes == copts->with_xml) {
558
- if (0 < copts->margin_len) {
559
- dump_value(out, copts->margin, copts->margin_len);
560
- }
561
- if ('\0' == *copts->encoding) {
562
- dump_value(out, "<?xml version=\"1.0\"?>", 21);
563
- } else {
564
- cnt = snprintf(buf, sizeof(buf), "<?xml version=\"1.0\" encoding=\"%s\"?>", copts->encoding);
565
- dump_value(out, buf, cnt);
566
- }
550
+ if (0 < copts->margin_len) {
551
+ dump_value(out, copts->margin, copts->margin_len);
552
+ }
553
+ if ('\0' == *copts->encoding) {
554
+ dump_value(out, "<?xml version=\"1.0\"?>", 21);
555
+ } else {
556
+ cnt = snprintf(buf, sizeof(buf), "<?xml version=\"1.0\" encoding=\"%s\"?>", copts->encoding);
557
+ dump_value(out, buf, cnt);
558
+ }
567
559
  }
568
560
  if (Yes == copts->with_instruct) {
569
- if (out->buf < out->cur) {
570
- dump_value(out, "\n", 1);
571
- }
572
- if (0 < copts->margin_len) {
573
- dump_value(out, copts->margin, copts->margin_len);
574
- }
575
- cnt = snprintf(buf, sizeof(buf), "<?ox version=\"1.0\" mode=\"object\"%s%s?>",
576
- (Yes == copts->circular) ? " circular=\"yes\"" : ((No == copts->circular) ? " circular=\"no\"" : ""),
577
- (Yes == copts->xsd_date) ? " xsd_date=\"yes\"" : ((No == copts->xsd_date) ? " xsd_date=\"no\"" : ""));
578
- dump_value(out, buf, cnt);
561
+ if (out->buf < out->cur) {
562
+ dump_value(out, "\n", 1);
563
+ }
564
+ if (0 < copts->margin_len) {
565
+ dump_value(out, copts->margin, copts->margin_len);
566
+ }
567
+ cnt = snprintf(
568
+ buf,
569
+ sizeof(buf),
570
+ "<?ox version=\"1.0\" mode=\"object\"%s%s?>",
571
+ (Yes == copts->circular) ? " circular=\"yes\"" : ((No == copts->circular) ? " circular=\"no\"" : ""),
572
+ (Yes == copts->xsd_date) ? " xsd_date=\"yes\"" : ((No == copts->xsd_date) ? " xsd_date=\"no\"" : ""));
573
+ dump_value(out, buf, cnt);
579
574
  }
580
575
  if (Yes == copts->with_dtd) {
581
- if (0 < copts->margin_len) {
582
- dump_value(out, copts->margin, copts->margin_len);
583
- }
584
- cnt = snprintf(buf, sizeof(buf), "%s<!DOCTYPE %c SYSTEM \"ox.dtd\">", (out->buf < out->cur) ? "\n" : "", obj_class_code(obj));
585
- dump_value(out, buf, cnt);
576
+ if (0 < copts->margin_len) {
577
+ dump_value(out, copts->margin, copts->margin_len);
578
+ }
579
+ cnt = snprintf(buf,
580
+ sizeof(buf),
581
+ "%s<!DOCTYPE %c SYSTEM \"ox.dtd\">",
582
+ (out->buf < out->cur) ? "\n" : "",
583
+ obj_class_code(obj));
584
+ dump_value(out, buf, cnt);
586
585
  }
587
586
  if (0 < copts->margin_len) {
588
- dump_value(out, copts->margin, copts->margin_len);
587
+ dump_value(out, copts->margin, copts->margin_len);
589
588
  }
590
589
  dump_obj(0, obj, 0, out);
591
590
  }
592
591
 
593
- static void
594
- dump_obj(ID aid, VALUE obj, int depth, Out out) {
595
- struct _element e;
596
- VALUE prev_obj = out->obj;
597
- char value_buf[64];
598
- int cnt;
592
+ static void dump_obj(ID aid, VALUE obj, int depth, Out out) {
593
+ struct _element e;
594
+ VALUE prev_obj = out->obj;
595
+ char value_buf[64];
596
+ int cnt;
599
597
 
600
598
  if (MAX_DEPTH < depth) {
601
- rb_raise(rb_eSysStackError, "maximum depth exceeded");
599
+ rb_raise(rb_eSysStackError, "maximum depth exceeded");
602
600
  }
603
601
  out->obj = obj;
604
602
  if (0 == aid) {
605
- e.attr.str = 0;
606
- e.attr.len = 0;
603
+ e.attr.str = 0;
604
+ e.attr.len = 0;
607
605
  } else {
608
- e.attr.str = rb_id2name(aid);
609
- // Ruby 2.3 started to return NULL for some IDs so check for
610
- // NULL. Ignore if NULL aid.
611
- if (NULL == e.attr.str) {
612
- return;
613
- }
614
- e.attr.len = strlen(e.attr.str);
606
+ e.attr.str = rb_id2name(aid);
607
+ // Ruby 2.3 started to return NULL for some IDs so check for
608
+ // NULL. Ignore if NULL aid.
609
+ if (NULL == e.attr.str) {
610
+ return;
611
+ }
612
+ e.attr.len = strlen(e.attr.str);
615
613
  }
616
614
  e.closed = 0;
617
615
  if (0 == depth) {
618
- e.indent = (0 <= out->indent) ? 0 : -1;
616
+ e.indent = (0 <= out->indent) ? 0 : -1;
619
617
  } else if (0 > out->indent) {
620
- e.indent = -1;
618
+ e.indent = -1;
621
619
  } else if (0 == out->indent) {
622
- e.indent = 0;
620
+ e.indent = 0;
623
621
  } else {
624
- e.indent = depth * out->indent;
622
+ e.indent = depth * out->indent;
625
623
  }
626
- e.id = 0;
624
+ e.id = 0;
627
625
  e.clas.len = 0;
628
626
  e.clas.str = 0;
629
627
  switch (rb_type(obj)) {
630
628
  case T_NIL:
631
- e.type = NilClassCode;
632
- e.closed = 1;
633
- out->w_start(out, &e);
634
- break;
629
+ e.type = NilClassCode;
630
+ e.closed = 1;
631
+ out->w_start(out, &e);
632
+ break;
635
633
  case T_ARRAY:
636
- if (0 != out->circ_cache && check_circular(out, obj, &e)) {
637
- break;
638
- }
639
- cnt = (int)RARRAY_LEN(obj);
640
- e.type = ArrayCode;
641
- e.closed = (0 >= cnt);
642
- out->w_start(out, &e);
643
- if (!e.closed) {
644
- const VALUE *np = RARRAY_PTR(obj);
645
- int i;
646
- int d2 = depth + 1;
647
-
648
- for (i = cnt; 0 < i; i--, np++) {
649
- dump_obj(0, *np, d2, out);
650
- }
651
- out->w_end(out, &e);
652
- }
653
- break;
634
+ if (0 != out->circ_cache && check_circular(out, obj, &e)) {
635
+ break;
636
+ }
637
+ cnt = (int)RARRAY_LEN(obj);
638
+ e.type = ArrayCode;
639
+ e.closed = (0 >= cnt);
640
+ out->w_start(out, &e);
641
+ if (!e.closed) {
642
+ const VALUE *np = RARRAY_PTR(obj);
643
+ int i;
644
+ int d2 = depth + 1;
645
+
646
+ for (i = cnt; 0 < i; i--, np++) {
647
+ dump_obj(0, *np, d2, out);
648
+ }
649
+ out->w_end(out, &e);
650
+ }
651
+ break;
654
652
  case T_HASH:
655
- if (0 != out->circ_cache && check_circular(out, obj, &e)) {
656
- break;
657
- }
658
- cnt = (int)RHASH_SIZE(obj);
659
- e.type = HashCode;
660
- e.closed = (0 >= cnt);
661
- out->w_start(out, &e);
662
- if (0 < cnt) {
663
- unsigned int od = out->depth;
664
-
665
- out->depth = depth + 1;
666
- rb_hash_foreach(obj, dump_hash, (VALUE)out);
667
- out->depth = od;
668
- out->w_end(out, &e);
669
- }
670
- break;
653
+ if (0 != out->circ_cache && check_circular(out, obj, &e)) {
654
+ break;
655
+ }
656
+ cnt = (int)RHASH_SIZE(obj);
657
+ e.type = HashCode;
658
+ e.closed = (0 >= cnt);
659
+ out->w_start(out, &e);
660
+ if (0 < cnt) {
661
+ unsigned int od = out->depth;
662
+
663
+ out->depth = depth + 1;
664
+ rb_hash_foreach(obj, dump_hash, (VALUE)out);
665
+ out->depth = od;
666
+ out->w_end(out, &e);
667
+ }
668
+ break;
671
669
  case T_TRUE:
672
- e.type = TrueClassCode;
673
- e.closed = 1;
674
- out->w_start(out, &e);
675
- break;
670
+ e.type = TrueClassCode;
671
+ e.closed = 1;
672
+ out->w_start(out, &e);
673
+ break;
676
674
  case T_FALSE:
677
- e.type = FalseClassCode;
678
- e.closed = 1;
679
- out->w_start(out, &e);
680
- break;
675
+ e.type = FalseClassCode;
676
+ e.closed = 1;
677
+ out->w_start(out, &e);
678
+ break;
681
679
  case T_FIXNUM:
682
- e.type = FixnumCode;
683
- out->w_start(out, &e);
684
- dump_num(out, obj);
685
- e.indent = -1;
686
- out->w_end(out, &e);
687
- break;
680
+ e.type = FixnumCode;
681
+ out->w_start(out, &e);
682
+ dump_num(out, obj);
683
+ e.indent = -1;
684
+ out->w_end(out, &e);
685
+ break;
688
686
  case T_FLOAT:
689
- e.type = FloatCode;
690
- cnt = snprintf(value_buf, sizeof(value_buf), "%0.16g", rb_num2dbl(obj));
691
- out->w_start(out, &e);
692
- dump_value(out, value_buf, cnt);
693
- e.indent = -1;
694
- out->w_end(out, &e);
695
- break;
696
- case T_STRING:
697
- {
698
- const char *str;
699
-
700
- if (0 != out->circ_cache && check_circular(out, obj, &e)) {
701
- break;
702
- }
703
- str = StringValuePtr(obj);
704
- cnt = (int)RSTRING_LEN(obj);
687
+ e.type = FloatCode;
688
+ cnt = snprintf(value_buf, sizeof(value_buf), "%0.16g", rb_num2dbl(obj));
689
+ out->w_start(out, &e);
690
+ dump_value(out, value_buf, cnt);
691
+ e.indent = -1;
692
+ out->w_end(out, &e);
693
+ break;
694
+ case T_STRING: {
695
+ const char *str;
696
+
697
+ if (0 != out->circ_cache && check_circular(out, obj, &e)) {
698
+ break;
699
+ }
700
+ str = StringValuePtr(obj);
701
+ cnt = (int)RSTRING_LEN(obj);
705
702
  #if USE_B64
706
- if (is_xml_friendly((uchar*)str, cnt)) {
707
- e.type = StringCode;
708
- out->w_start(out, &e);
709
- dump_str_value(out, str, cnt, '<');
710
- e.indent = -1;
711
- out->w_end(out, &e);
712
- } else {
713
- ulong size = b64_size(cnt);
714
- char *b64 = ALLOCA_N(char, size + 1);
715
-
716
- e.type = String64Code;
717
- to_base64((uchar*)str, cnt, b64);
718
- out->w_start(out, &e);
719
- dump_value(out, b64, size);
720
- e.indent = -1;
721
- out->w_end(out, &e);
722
- }
703
+ if (is_xml_friendly((uchar *)str, cnt)) {
704
+ e.type = StringCode;
705
+ out->w_start(out, &e);
706
+ dump_str_value(out, str, cnt, '<');
707
+ e.indent = -1;
708
+ out->w_end(out, &e);
709
+ } else {
710
+ ulong size = b64_size(cnt);
711
+ char *b64 = ALLOCA_N(char, size + 1);
712
+
713
+ e.type = String64Code;
714
+ to_base64((uchar *)str, cnt, b64);
715
+ out->w_start(out, &e);
716
+ dump_value(out, b64, size);
717
+ e.indent = -1;
718
+ out->w_end(out, &e);
719
+ }
723
720
  #else
724
- e.type = StringCode;
725
- out->w_start(out, &e);
726
- dump_str_value(out, str, cnt, xml_element_chars);
727
- e.indent = -1;
728
- out->w_end(out, &e);
721
+ e.type = StringCode;
722
+ out->w_start(out, &e);
723
+ dump_str_value(out, str, cnt, xml_element_chars);
724
+ e.indent = -1;
725
+ out->w_end(out, &e);
729
726
  #endif
730
- break;
727
+ break;
731
728
  }
732
- case T_SYMBOL:
733
- {
734
- const char *sym = rb_id2name(SYM2ID(obj));
729
+ case T_SYMBOL: {
730
+ const char *sym = rb_id2name(SYM2ID(obj));
735
731
 
736
- cnt = (int)strlen(sym);
732
+ cnt = (int)strlen(sym);
737
733
  #if USE_B64
738
- if (is_xml_friendly((uchar*)sym, cnt)) {
739
- e.type = SymbolCode;
740
- out->w_start(out, &e);
741
- dump_str_value(out, sym, cnt, '<');
742
- e.indent = -1;
743
- out->w_end(out, &e);
744
- } else {
745
- ulong size = b64_size(cnt);
746
- char *b64 = ALLOCA_N(char, size + 1);
747
-
748
- e.type = Symbol64Code;
749
- to_base64((uchar*)sym, cnt, b64);
750
- out->w_start(out, &e);
751
- dump_value(out, b64, size);
752
- e.indent = -1;
753
- out->w_end(out, &e);
754
- }
734
+ if (is_xml_friendly((uchar *)sym, cnt)) {
735
+ e.type = SymbolCode;
736
+ out->w_start(out, &e);
737
+ dump_str_value(out, sym, cnt, '<');
738
+ e.indent = -1;
739
+ out->w_end(out, &e);
740
+ } else {
741
+ ulong size = b64_size(cnt);
742
+ char *b64 = ALLOCA_N(char, size + 1);
743
+
744
+ e.type = Symbol64Code;
745
+ to_base64((uchar *)sym, cnt, b64);
746
+ out->w_start(out, &e);
747
+ dump_value(out, b64, size);
748
+ e.indent = -1;
749
+ out->w_end(out, &e);
750
+ }
755
751
  #else
756
- e.type = SymbolCode;
757
- out->w_start(out, &e);
758
- dump_str_value(out, sym, cnt, xml_element_chars);
759
- e.indent = -1;
760
- out->w_end(out, &e);
752
+ e.type = SymbolCode;
753
+ out->w_start(out, &e);
754
+ dump_str_value(out, sym, cnt, xml_element_chars);
755
+ e.indent = -1;
756
+ out->w_end(out, &e);
761
757
  #endif
762
- break;
763
- }
764
- case T_DATA:
765
- {
766
- VALUE clas;
767
-
768
- clas = rb_obj_class(obj);
769
- if (rb_cTime == clas) {
770
- e.type = TimeCode;
771
- out->w_start(out, &e);
772
- out->w_time(out, obj);
773
- e.indent = -1;
774
- out->w_end(out, &e);
775
- } else {
776
- const char *classname = rb_class2name(clas);
777
-
778
- if (0 == strcmp("Date", classname)) {
779
- e.type = DateCode;
780
- out->w_start(out, &e);
781
- dump_date(out, obj);
782
- e.indent = -1;
783
- out->w_end(out, &e);
784
- } else if (0 == strcmp("BigDecimal", classname)) {
785
- volatile VALUE rs = rb_funcall(obj, ox_to_s_id, 0);
786
-
787
- e.type = BigDecimalCode;
788
- out->w_start(out, &e);
789
- dump_value(out, StringValuePtr(rs), RSTRING_LEN(rs));
790
- e.indent = -1;
791
- out->w_end(out, &e);
792
- } else {
793
- if (StrictEffort == out->opts->effort) {
794
- rb_raise(rb_eNotImpError, "Failed to dump T_DATA %s\n", classname);
795
- } else {
796
- e.type = NilClassCode;
797
- e.closed = 1;
798
- out->w_start(out, &e);
799
- }
800
- }
801
- }
802
- break;
803
- }
804
- case T_STRUCT:
805
- {
758
+ break;
759
+ }
760
+ case T_DATA: {
761
+ VALUE clas;
762
+
763
+ clas = rb_obj_class(obj);
764
+ if (rb_cTime == clas) {
765
+ e.type = TimeCode;
766
+ out->w_start(out, &e);
767
+ out->w_time(out, obj);
768
+ e.indent = -1;
769
+ out->w_end(out, &e);
770
+ } else {
771
+ const char *classname = rb_class2name(clas);
772
+
773
+ if (0 == strcmp("Date", classname)) {
774
+ e.type = DateCode;
775
+ out->w_start(out, &e);
776
+ dump_date(out, obj);
777
+ e.indent = -1;
778
+ out->w_end(out, &e);
779
+ } else if (0 == strcmp("BigDecimal", classname)) {
780
+ volatile VALUE rs = rb_funcall(obj, ox_to_s_id, 0);
781
+
782
+ e.type = BigDecimalCode;
783
+ out->w_start(out, &e);
784
+ dump_value(out, StringValuePtr(rs), RSTRING_LEN(rs));
785
+ e.indent = -1;
786
+ out->w_end(out, &e);
787
+ } else {
788
+ if (StrictEffort == out->opts->effort) {
789
+ rb_raise(rb_eNotImpError, "Failed to dump T_DATA %s\n", classname);
790
+ } else {
791
+ e.type = NilClassCode;
792
+ e.closed = 1;
793
+ out->w_start(out, &e);
794
+ }
795
+ }
796
+ }
797
+ break;
798
+ }
799
+ case T_STRUCT: {
806
800
  #ifdef RSTRUCT_GET
807
- VALUE clas;
808
-
809
- if (0 != out->circ_cache && check_circular(out, obj, &e)) {
810
- break;
811
- }
812
- clas = rb_obj_class(obj);
813
- if (rb_cRange == clas) {
814
- VALUE beg = RSTRUCT_GET(obj, 0);
815
- VALUE end = RSTRUCT_GET(obj, 1);
816
- VALUE excl = RSTRUCT_GET(obj, 2);
817
- int d2 = depth + 1;
818
-
819
- e.type = RangeCode; e.clas.len = 5; e.clas.str = "Range";
820
- out->w_start(out, &e);
821
- dump_obj(ox_beg_id, beg, d2, out);
822
- dump_obj(ox_end_id, end, d2, out);
823
- dump_obj(ox_excl_id, excl, d2, out);
824
- out->w_end(out, &e);
825
- } else {
826
- char num_buf[16];
827
- int d2 = depth + 1;
801
+ VALUE clas;
802
+
803
+ if (0 != out->circ_cache && check_circular(out, obj, &e)) {
804
+ break;
805
+ }
806
+ clas = rb_obj_class(obj);
807
+ if (rb_cRange == clas) {
808
+ VALUE beg = RSTRUCT_GET(obj, 0);
809
+ VALUE end = RSTRUCT_GET(obj, 1);
810
+ VALUE excl = RSTRUCT_GET(obj, 2);
811
+ int d2 = depth + 1;
812
+
813
+ e.type = RangeCode;
814
+ e.clas.len = 5;
815
+ e.clas.str = "Range";
816
+ out->w_start(out, &e);
817
+ dump_obj(ox_beg_id, beg, d2, out);
818
+ dump_obj(ox_end_id, end, d2, out);
819
+ dump_obj(ox_excl_id, excl, d2, out);
820
+ out->w_end(out, &e);
821
+ } else {
822
+ char num_buf[16];
823
+ int d2 = depth + 1;
828
824
  #ifdef RUBY_INTEGER_UNIFICATION
829
- long i;
830
- long cnt = NUM2LONG(rb_struct_size(obj));
831
- #else // UNIFY_FIXNUM_AND_INTEGER
832
- int i;
833
- int cnt = (int)RSTRUCT_LEN(obj);
834
- #endif // UNIFY_FIXNUM_AND_INTEGER
835
- e.type = StructCode;
836
- e.clas.str = rb_class2name(clas);
837
- e.clas.len = strlen(e.clas.str);
838
- out->w_start(out, &e);
839
-
840
- for (i = 0; i < cnt; i++) {
841
- VALUE v = RSTRUCT_GET(obj, (int)(i));
842
- dump_obj(rb_intern(ulong2str(i, num_buf + sizeof(num_buf) - 1)), v, d2, out);
843
- }
844
- out->w_end(out, &e);
845
- }
825
+ long i;
826
+ long cnt = NUM2LONG(rb_struct_size(obj));
827
+ #else // UNIFY_FIXNUM_AND_INTEGER
828
+ int i;
829
+ int cnt = (int)RSTRUCT_LEN(obj);
830
+ #endif // UNIFY_FIXNUM_AND_INTEGER
831
+ e.type = StructCode;
832
+ e.clas.str = rb_class2name(clas);
833
+ e.clas.len = strlen(e.clas.str);
834
+ out->w_start(out, &e);
835
+
836
+ for (i = 0; i < cnt; i++) {
837
+ VALUE v = RSTRUCT_GET(obj, (int)(i));
838
+ dump_obj(rb_intern(ulong2str(i, num_buf + sizeof(num_buf) - 1)), v, d2, out);
839
+ }
840
+ out->w_end(out, &e);
841
+ }
846
842
  #else
847
- e.type = NilClassCode;
848
- e.closed = 1;
849
- out->w_start(out, &e);
843
+ e.type = NilClassCode;
844
+ e.closed = 1;
845
+ out->w_start(out, &e);
850
846
  #endif
851
- break;
852
- }
853
- case T_OBJECT:
854
- {
855
- VALUE clas;
856
-
857
- if (0 != out->circ_cache && check_circular(out, obj, &e)) {
858
- break;
859
- }
860
- clas = rb_obj_class(obj);
861
- e.clas.str = rb_class2name(clas);
862
- e.clas.len = strlen(e.clas.str);
863
- if (ox_document_clas == clas) {
864
- e.type = RawCode;
865
- out->w_start(out, &e);
866
- dump_gen_doc(obj, depth + 1, out);
867
- out->w_end(out, &e);
868
- } else if (ox_element_clas == clas) {
869
- e.type = RawCode;
870
- out->w_start(out, &e);
871
- dump_gen_element(obj, depth + 1, out);
872
- out->w_end(out, &e);
873
- } else { /* Object */
847
+ break;
848
+ }
849
+ case T_OBJECT: {
850
+ VALUE clas;
851
+
852
+ if (0 != out->circ_cache && check_circular(out, obj, &e)) {
853
+ break;
854
+ }
855
+ clas = rb_obj_class(obj);
856
+ e.clas.str = rb_class2name(clas);
857
+ e.clas.len = strlen(e.clas.str);
858
+ if (ox_document_clas == clas) {
859
+ e.type = RawCode;
860
+ out->w_start(out, &e);
861
+ dump_gen_doc(obj, depth + 1, out);
862
+ out->w_end(out, &e);
863
+ } else if (ox_element_clas == clas) {
864
+ e.type = RawCode;
865
+ out->w_start(out, &e);
866
+ dump_gen_element(obj, depth + 1, out);
867
+ out->w_end(out, &e);
868
+ } else { /* Object */
874
869
  #if HAVE_RB_IVAR_FOREACH
875
- e.type = (Qtrue == rb_obj_is_kind_of(obj, rb_eException)) ? ExceptionCode : ObjectCode;
876
- cnt = (int)rb_ivar_count(obj);
877
- e.closed = (0 >= cnt);
878
- out->w_start(out, &e);
879
- if (0 < cnt) {
880
- unsigned int od = out->depth;
881
-
882
- out->depth = depth + 1;
883
- rb_ivar_foreach(obj, dump_var, (VALUE)out);
884
- out->depth = od;
885
- out->w_end(out, &e);
886
- }
870
+ e.type = (Qtrue == rb_obj_is_kind_of(obj, rb_eException)) ? ExceptionCode : ObjectCode;
871
+ cnt = (int)rb_ivar_count(obj);
872
+ e.closed = (0 >= cnt);
873
+ out->w_start(out, &e);
874
+ if (0 < cnt) {
875
+ unsigned int od = out->depth;
876
+
877
+ out->depth = depth + 1;
878
+ rb_ivar_foreach(obj, dump_var, (VALUE)out);
879
+ out->depth = od;
880
+ out->w_end(out, &e);
881
+ }
887
882
  #else
888
- volatile VALUE vars = rb_obj_instance_variables(obj);
889
- //volatile VALUE vars = rb_funcall2(obj, rb_intern("instance_variables"), 0, 0);
890
-
891
- e.type = (Qtrue == rb_obj_is_kind_of(obj, rb_eException)) ? ExceptionCode : ObjectCode;
892
- cnt = (int)RARRAY_LEN(vars);
893
- e.closed = (0 >= cnt);
894
- out->w_start(out, &e);
895
- if (0 < cnt) {
896
- const VALUE *np = RARRAY_PTR(vars);
897
- ID vid;
898
- unsigned int od = out->depth;
899
- int i;
900
-
901
- out->depth = depth + 1;
902
- for (i = cnt; 0 < i; i--, np++) {
903
- vid = rb_to_id(*np);
904
- dump_var(vid, rb_ivar_get(obj, vid), out);
905
- }
906
- out->depth = od;
907
- out->w_end(out, &e);
908
- }
883
+ volatile VALUE vars = rb_obj_instance_variables(obj);
884
+ // volatile VALUE vars = rb_funcall2(obj, rb_intern("instance_variables"), 0, 0);
885
+
886
+ e.type = (Qtrue == rb_obj_is_kind_of(obj, rb_eException)) ? ExceptionCode : ObjectCode;
887
+ cnt = (int)RARRAY_LEN(vars);
888
+ e.closed = (0 >= cnt);
889
+ out->w_start(out, &e);
890
+ if (0 < cnt) {
891
+ const VALUE *np = RARRAY_PTR(vars);
892
+ ID vid;
893
+ unsigned int od = out->depth;
894
+ int i;
895
+
896
+ out->depth = depth + 1;
897
+ for (i = cnt; 0 < i; i--, np++) {
898
+ vid = rb_to_id(*np);
899
+ dump_var(vid, rb_ivar_get(obj, vid), out);
900
+ }
901
+ out->depth = od;
902
+ out->w_end(out, &e);
903
+ }
909
904
  #endif
910
- }
911
- break;
905
+ }
906
+ break;
912
907
  }
913
- case T_REGEXP:
914
- {
915
- volatile VALUE rs = rb_funcall2(obj, ox_inspect_id, 0, 0);
916
- const char *s = StringValuePtr(rs);
908
+ case T_REGEXP: {
909
+ volatile VALUE rs = rb_funcall2(obj, ox_inspect_id, 0, 0);
910
+ const char *s = StringValuePtr(rs);
917
911
 
918
- cnt = (int)RSTRING_LEN(rs);
919
- e.type = RegexpCode;
920
- out->w_start(out, &e);
912
+ cnt = (int)RSTRING_LEN(rs);
913
+ e.type = RegexpCode;
914
+ out->w_start(out, &e);
921
915
  #if USE_B64
922
- if (is_xml_friendly((uchar*)s, cnt)) {
923
- /*dump_value(out, "/", 1); */
924
- dump_str_value(out, s, cnt, '<');
925
- } else {
926
- ulong size = b64_size(cnt);
927
- char *b64 = ALLOCA_N(char, size + 1);
928
-
929
- to_base64((uchar*)s, cnt, b64);
930
- dump_value(out, b64, size);
931
- }
916
+ if (is_xml_friendly((uchar *)s, cnt)) {
917
+ /*dump_value(out, "/", 1); */
918
+ dump_str_value(out, s, cnt, '<');
919
+ } else {
920
+ ulong size = b64_size(cnt);
921
+ char *b64 = ALLOCA_N(char, size + 1);
922
+
923
+ to_base64((uchar *)s, cnt, b64);
924
+ dump_value(out, b64, size);
925
+ }
932
926
  #else
933
- dump_str_value(out, s, cnt, xml_element_chars);
927
+ dump_str_value(out, s, cnt, xml_element_chars);
934
928
  #endif
935
- e.indent = -1;
936
- out->w_end(out, &e);
937
- break;
929
+ e.indent = -1;
930
+ out->w_end(out, &e);
931
+ break;
938
932
  }
939
- case T_BIGNUM:
940
- {
941
- volatile VALUE rs = rb_big2str(obj, 10);
933
+ case T_BIGNUM: {
934
+ volatile VALUE rs = rb_big2str(obj, 10);
942
935
 
943
- e.type = BignumCode;
944
- out->w_start(out, &e);
945
- dump_value(out, StringValuePtr(rs), RSTRING_LEN(rs));
946
- e.indent = -1;
947
- out->w_end(out, &e);
948
- break;
936
+ e.type = BignumCode;
937
+ out->w_start(out, &e);
938
+ dump_value(out, StringValuePtr(rs), RSTRING_LEN(rs));
939
+ e.indent = -1;
940
+ out->w_end(out, &e);
941
+ break;
949
942
  }
950
943
  #ifdef T_COMPLEX
951
- case T_COMPLEX:
952
- e.type = ComplexCode;
953
- out->w_start(out, &e);
944
+ case T_COMPLEX: e.type = ComplexCode; out->w_start(out, &e);
954
945
  #ifdef RCOMPLEX
955
- dump_obj(0, RCOMPLEX(obj)->real, depth + 1, out);
956
- dump_obj(0, RCOMPLEX(obj)->imag, depth + 1, out);
946
+ dump_obj(0, RCOMPLEX(obj)->real, depth + 1, out);
947
+ dump_obj(0, RCOMPLEX(obj)->imag, depth + 1, out);
957
948
  #else
958
- dump_obj(0, rb_funcall2(obj, rb_intern("real"), 0, 0), depth + 1, out);
959
- dump_obj(0, rb_funcall2(obj, rb_intern("imag"), 0, 0), depth + 1, out);
949
+ dump_obj(0, rb_funcall2(obj, rb_intern("real"), 0, 0), depth + 1, out);
950
+ dump_obj(0, rb_funcall2(obj, rb_intern("imag"), 0, 0), depth + 1, out);
960
951
  #endif
961
- out->w_end(out, &e);
962
- break;
952
+ out->w_end(out, &e);
953
+ break;
963
954
  #endif
964
955
  #ifdef T_RATIONAL
965
- case T_RATIONAL:
966
- e.type = RationalCode;
967
- out->w_start(out, &e);
956
+ case T_RATIONAL: e.type = RationalCode; out->w_start(out, &e);
968
957
  #ifdef RRATIONAL
969
- dump_obj(0, RRATIONAL(obj)->num, depth + 1, out);
970
- dump_obj(0, RRATIONAL(obj)->den, depth + 1, out);
958
+ dump_obj(0, RRATIONAL(obj)->num, depth + 1, out);
959
+ dump_obj(0, RRATIONAL(obj)->den, depth + 1, out);
971
960
  #else
972
- dump_obj(0, rb_funcall2(obj, rb_intern("numerator"), 0, 0), depth + 1, out);
973
- dump_obj(0, rb_funcall2(obj, rb_intern("denominator"), 0, 0), depth + 1, out);
961
+ dump_obj(0, rb_funcall2(obj, rb_intern("numerator"), 0, 0), depth + 1, out);
962
+ dump_obj(0, rb_funcall2(obj, rb_intern("denominator"), 0, 0), depth + 1, out);
974
963
  #endif
975
- out->w_end(out, &e);
976
- break;
964
+ out->w_end(out, &e);
965
+ break;
977
966
  #endif
978
- case T_CLASS:
979
- {
980
- e.type = ClassCode;
981
- e.clas.str = rb_class2name(obj);
982
- e.clas.len = strlen(e.clas.str);
983
- e.closed = 1;
984
- out->w_start(out, &e);
985
- break;
967
+ case T_CLASS: {
968
+ e.type = ClassCode;
969
+ e.clas.str = rb_class2name(obj);
970
+ e.clas.len = strlen(e.clas.str);
971
+ e.closed = 1;
972
+ out->w_start(out, &e);
973
+ break;
986
974
  }
987
975
  default:
988
- if (StrictEffort == out->opts->effort) {
989
- rb_raise(rb_eNotImpError, "Failed to dump %s Object (%02x)\n",
990
- rb_obj_classname(obj), rb_type(obj));
991
- } else {
992
- e.type = NilClassCode;
993
- e.closed = 1;
994
- out->w_start(out, &e);
995
- }
996
- break;
976
+ if (StrictEffort == out->opts->effort) {
977
+ rb_raise(rb_eNotImpError, "Failed to dump %s Object (%02x)\n", rb_obj_classname(obj), rb_type(obj));
978
+ } else {
979
+ e.type = NilClassCode;
980
+ e.closed = 1;
981
+ out->w_start(out, &e);
982
+ }
983
+ break;
997
984
  }
998
985
  out->obj = prev_obj;
999
986
  }
1000
987
 
1001
- static int
1002
- dump_var(ID key, VALUE value, VALUE ov) {
1003
- Out out = (Out)ov;
988
+ static int dump_var(ID key, VALUE value, VALUE ov) {
989
+ Out out = (Out)ov;
1004
990
 
1005
991
  if (T_DATA == rb_type(value) && key == ox_mesg_id) {
1006
- /* There is a secret recipe that keeps Exception mesg attributes as a
1007
- * T_DATA until it is needed. The safe way around this hack is to call
1008
- * the message() method and use the returned string as the
1009
- * message. Not pretty but it solves the most common use of this
1010
- * hack. If there are others they will have to be handled one at a
1011
- * time.
1012
- */
1013
- value = rb_funcall(out->obj, ox_message_id, 0);
992
+ /* There is a secret recipe that keeps Exception mesg attributes as a
993
+ * T_DATA until it is needed. The safe way around this hack is to call
994
+ * the message() method and use the returned string as the
995
+ * message. Not pretty but it solves the most common use of this
996
+ * hack. If there are others they will have to be handled one at a
997
+ * time.
998
+ */
999
+ value = rb_funcall(out->obj, ox_message_id, 0);
1014
1000
  }
1015
1001
  dump_obj(key, value, out->depth, out);
1016
1002
 
1017
1003
  return ST_CONTINUE;
1018
1004
  }
1019
1005
 
1020
- static int
1021
- dump_hash(VALUE key, VALUE value, VALUE ov) {
1022
- Out out = (Out)ov;
1006
+ static int dump_hash(VALUE key, VALUE value, VALUE ov) {
1007
+ Out out = (Out)ov;
1023
1008
 
1024
1009
  dump_obj(0, key, out->depth, out);
1025
1010
  dump_obj(0, value, out->depth, out);
@@ -1027,199 +1012,190 @@ dump_hash(VALUE key, VALUE value, VALUE ov) {
1027
1012
  return ST_CONTINUE;
1028
1013
  }
1029
1014
 
1030
- static void
1031
- dump_gen_doc(VALUE obj, int depth, Out out) {
1032
- volatile VALUE attrs = rb_attr_get(obj, ox_attributes_id);
1033
- volatile VALUE nodes = rb_attr_get(obj, ox_nodes_id);
1015
+ static void dump_gen_doc(VALUE obj, int depth, Out out) {
1016
+ volatile VALUE attrs = rb_attr_get(obj, ox_attributes_id);
1017
+ volatile VALUE nodes = rb_attr_get(obj, ox_nodes_id);
1034
1018
 
1035
1019
  if ('\0' == *out->opts->encoding && Qnil != attrs) {
1036
- volatile VALUE renc = rb_hash_lookup(attrs, ox_encoding_sym);
1020
+ volatile VALUE renc = rb_hash_lookup(attrs, ox_encoding_sym);
1037
1021
 
1038
- if (Qnil != renc) {
1039
- const char *enc = StringValuePtr(renc);
1022
+ if (Qnil != renc) {
1023
+ const char *enc = StringValuePtr(renc);
1040
1024
 
1041
- strncpy(out->opts->encoding, enc, sizeof(out->opts->encoding) - 1);
1042
- }
1025
+ strncpy(out->opts->encoding, enc, sizeof(out->opts->encoding) - 1);
1026
+ }
1043
1027
  }
1044
1028
  if (Yes == out->opts->with_xml) {
1045
- if (0 < out->opts->margin_len) {
1046
- dump_value(out, out->opts->margin, out->opts->margin_len);
1047
- }
1048
- dump_value(out, "<?xml", 5);
1049
- if (Qnil != attrs) {
1050
- rb_hash_foreach(attrs, dump_gen_attr, (VALUE)out);
1051
- }
1052
- dump_value(out, "?>", 2);
1029
+ if (0 < out->opts->margin_len) {
1030
+ dump_value(out, out->opts->margin, out->opts->margin_len);
1031
+ }
1032
+ dump_value(out, "<?xml", 5);
1033
+ if (Qnil != attrs) {
1034
+ rb_hash_foreach(attrs, dump_gen_attr, (VALUE)out);
1035
+ }
1036
+ dump_value(out, "?>", 2);
1053
1037
  }
1054
1038
  if (Yes == out->opts->with_instruct) {
1055
- if (out->buf < out->cur) {
1056
- dump_value(out, "\n", 1);
1057
- }
1058
- if (0 < out->opts->margin_len) {
1059
- dump_value(out, out->opts->margin, out->opts->margin_len);
1060
- }
1061
- dump_value(out, "<?ox version=\"1.0\" mode=\"generic\"?>", 35);
1039
+ if (out->buf < out->cur) {
1040
+ dump_value(out, "\n", 1);
1041
+ }
1042
+ if (0 < out->opts->margin_len) {
1043
+ dump_value(out, out->opts->margin, out->opts->margin_len);
1044
+ }
1045
+ dump_value(out, "<?ox version=\"1.0\" mode=\"generic\"?>", 35);
1062
1046
  }
1063
1047
  if (Qnil != nodes) {
1064
- dump_gen_nodes(nodes, depth, out);
1048
+ dump_gen_nodes(nodes, depth, out);
1065
1049
  }
1066
1050
  }
1067
1051
 
1068
- static void
1069
- dump_gen_element(VALUE obj, int depth, Out out) {
1070
- volatile VALUE rname = rb_attr_get(obj, ox_at_value_id);
1071
- volatile VALUE attrs = rb_attr_get(obj, ox_attributes_id);
1072
- volatile VALUE nodes = rb_attr_get(obj, ox_nodes_id);
1073
- const char *name = StringValuePtr(rname);
1074
- long nlen = RSTRING_LEN(rname);
1075
- size_t size;
1076
- int indent;
1052
+ static void dump_gen_element(VALUE obj, int depth, Out out) {
1053
+ volatile VALUE rname = rb_attr_get(obj, ox_at_value_id);
1054
+ volatile VALUE attrs = rb_attr_get(obj, ox_attributes_id);
1055
+ volatile VALUE nodes = rb_attr_get(obj, ox_nodes_id);
1056
+ const char *name = StringValuePtr(rname);
1057
+ long nlen = RSTRING_LEN(rname);
1058
+ size_t size;
1059
+ int indent;
1077
1060
 
1078
1061
  if (0 > out->indent) {
1079
- indent = -1;
1062
+ indent = -1;
1080
1063
  } else if (0 == out->indent) {
1081
- indent = 0;
1064
+ indent = 0;
1082
1065
  } else {
1083
- indent = depth * out->indent;
1066
+ indent = depth * out->indent;
1084
1067
  }
1085
1068
  size = indent + 4 + nlen + out->opts->margin_len;
1086
1069
  if (out->end - out->cur <= (long)size) {
1087
- grow(out, size);
1070
+ grow(out, size);
1088
1071
  }
1089
1072
  if (0 == depth && 0 < out->opts->margin_len && 0 < out->indent) {
1090
- memcpy(out->cur, out->opts->margin, out->opts->margin_len);
1091
- out->cur += out->opts->margin_len;
1073
+ memcpy(out->cur, out->opts->margin, out->opts->margin_len);
1074
+ out->cur += out->opts->margin_len;
1092
1075
  }
1093
1076
  fill_indent(out, indent);
1094
1077
  *out->cur++ = '<';
1095
1078
  fill_value(out, name, nlen);
1096
1079
  if (Qnil != attrs) {
1097
- rb_hash_foreach(attrs, dump_gen_attr, (VALUE)out);
1080
+ rb_hash_foreach(attrs, dump_gen_attr, (VALUE)out);
1098
1081
  }
1099
1082
  if (Qnil != nodes && 0 < RARRAY_LEN(nodes)) {
1100
- int do_indent;
1101
-
1102
- *out->cur++ = '>';
1103
- do_indent = dump_gen_nodes(nodes, depth, out);
1104
- if (out->end - out->cur <= (long)size) {
1105
- grow(out, size);
1106
- }
1107
- if (do_indent) {
1108
- fill_indent(out, indent);
1109
- }
1110
- *out->cur++ = '<';
1111
- *out->cur++ = '/';
1112
- fill_value(out, name, nlen);
1083
+ int do_indent;
1084
+
1085
+ *out->cur++ = '>';
1086
+ do_indent = dump_gen_nodes(nodes, depth, out);
1087
+ if (out->end - out->cur <= (long)size) {
1088
+ grow(out, size);
1089
+ }
1090
+ if (do_indent) {
1091
+ fill_indent(out, indent);
1092
+ }
1093
+ *out->cur++ = '<';
1094
+ *out->cur++ = '/';
1095
+ fill_value(out, name, nlen);
1113
1096
  } else if (out->opts->no_empty) {
1114
- *out->cur++ = '>';
1115
- *out->cur++ = '<';
1116
- *out->cur++ = '/';
1117
- fill_value(out, name, nlen);
1097
+ *out->cur++ = '>';
1098
+ *out->cur++ = '<';
1099
+ *out->cur++ = '/';
1100
+ fill_value(out, name, nlen);
1118
1101
  } else {
1119
- *out->cur++ = '/';
1102
+ *out->cur++ = '/';
1120
1103
  }
1121
1104
  *out->cur++ = '>';
1122
- *out->cur = '\0';
1105
+ *out->cur = '\0';
1123
1106
  }
1124
1107
 
1125
- static void
1126
- dump_gen_instruct(VALUE obj, int depth, Out out) {
1127
- volatile VALUE rname = rb_attr_get(obj, ox_at_value_id);
1128
- volatile VALUE attrs = rb_attr_get(obj, ox_attributes_id);
1129
- volatile VALUE rcontent = rb_attr_get(obj, ox_at_content_id);
1130
- const char *name = StringValuePtr(rname);
1131
- const char *content = 0;
1132
- long nlen = RSTRING_LEN(rname);
1133
- long clen = 0;
1134
- size_t size;
1108
+ static void dump_gen_instruct(VALUE obj, int depth, Out out) {
1109
+ volatile VALUE rname = rb_attr_get(obj, ox_at_value_id);
1110
+ volatile VALUE attrs = rb_attr_get(obj, ox_attributes_id);
1111
+ volatile VALUE rcontent = rb_attr_get(obj, ox_at_content_id);
1112
+ const char *name = StringValuePtr(rname);
1113
+ const char *content = 0;
1114
+ long nlen = RSTRING_LEN(rname);
1115
+ long clen = 0;
1116
+ size_t size;
1135
1117
 
1136
1118
  if (T_STRING == rb_type(rcontent)) {
1137
- content = StringValuePtr(rcontent);
1138
- clen = RSTRING_LEN(rcontent);
1139
- size = 4 + nlen + clen;
1119
+ content = StringValuePtr(rcontent);
1120
+ clen = RSTRING_LEN(rcontent);
1121
+ size = 4 + nlen + clen;
1140
1122
  } else {
1141
- size = 4 + nlen;
1123
+ size = 4 + nlen;
1142
1124
  }
1143
1125
  if (out->end - out->cur <= (long)size) {
1144
- grow(out, size);
1126
+ grow(out, size);
1145
1127
  }
1146
1128
  *out->cur++ = '<';
1147
1129
  *out->cur++ = '?';
1148
1130
  fill_value(out, name, nlen);
1149
1131
  if (0 != content) {
1150
- fill_value(out, content, clen);
1132
+ fill_value(out, content, clen);
1151
1133
  } else if (Qnil != attrs) {
1152
- rb_hash_foreach(attrs, dump_gen_attr, (VALUE)out);
1134
+ rb_hash_foreach(attrs, dump_gen_attr, (VALUE)out);
1153
1135
  }
1154
1136
  *out->cur++ = '?';
1155
1137
  *out->cur++ = '>';
1156
- *out->cur = '\0';
1138
+ *out->cur = '\0';
1157
1139
  }
1158
1140
 
1159
- static int
1160
- dump_gen_nodes(VALUE obj, int depth, Out out) {
1161
- long cnt = RARRAY_LEN(obj);
1162
- int indent_needed = 1;
1141
+ static int dump_gen_nodes(VALUE obj, int depth, Out out) {
1142
+ long cnt = RARRAY_LEN(obj);
1143
+ int indent_needed = 1;
1163
1144
 
1164
1145
  if (0 < cnt) {
1165
- const VALUE *np = RARRAY_PTR(obj);
1166
- VALUE clas;
1167
- int d2 = depth + 1;
1168
-
1169
- if (MAX_DEPTH < depth) {
1170
- rb_raise(rb_eSysStackError, "maximum depth exceeded");
1171
- }
1172
- for (; 0 < cnt; cnt--, np++) {
1173
- clas = rb_obj_class(*np);
1174
- if (ox_element_clas == clas) {
1175
- dump_gen_element(*np, d2, out);
1176
- } else if (ox_instruct_clas == clas) {
1177
- dump_gen_instruct(*np, d2, out);
1178
- indent_needed = (1 == cnt) ? 0 : 1;
1179
- } else if (rb_cString == clas) {
1180
- dump_str_value(out, StringValuePtr(*(VALUE*)np), RSTRING_LEN(*np), xml_element_chars);
1181
- indent_needed = (1 == cnt) ? 0 : 1;
1182
- } else if (ox_comment_clas == clas) {
1183
- dump_gen_val_node(*np, d2, "<!-- ", 5, " -->", 4, out);
1184
- } else if (ox_raw_clas == clas) {
1185
- dump_gen_val_node(*np, d2, "", 0, "", 0, out);
1186
- } else if (ox_cdata_clas == clas) {
1187
- dump_gen_val_node(*np, d2, "<![CDATA[", 9, "]]>", 3, out);
1188
- } else if (ox_doctype_clas == clas) {
1189
- dump_gen_val_node(*np, d2, "<!DOCTYPE ", 10, ">", 1, out);
1190
- } else {
1191
- rb_raise(rb_eTypeError, "Unexpected class, %s, while dumping generic XML\n", rb_class2name(clas));
1192
- }
1193
- }
1146
+ const VALUE *np = RARRAY_PTR(obj);
1147
+ VALUE clas;
1148
+ int d2 = depth + 1;
1149
+
1150
+ if (MAX_DEPTH < depth) {
1151
+ rb_raise(rb_eSysStackError, "maximum depth exceeded");
1152
+ }
1153
+ for (; 0 < cnt; cnt--, np++) {
1154
+ clas = rb_obj_class(*np);
1155
+ if (ox_element_clas == clas) {
1156
+ dump_gen_element(*np, d2, out);
1157
+ } else if (ox_instruct_clas == clas) {
1158
+ dump_gen_instruct(*np, d2, out);
1159
+ indent_needed = (1 == cnt) ? 0 : 1;
1160
+ } else if (rb_cString == clas) {
1161
+ dump_str_value(out, StringValuePtr(*(VALUE *)np), RSTRING_LEN(*np), xml_element_chars);
1162
+ indent_needed = (1 == cnt) ? 0 : 1;
1163
+ } else if (ox_comment_clas == clas) {
1164
+ dump_gen_val_node(*np, d2, "<!-- ", 5, " -->", 4, out);
1165
+ } else if (ox_raw_clas == clas) {
1166
+ dump_gen_val_node(*np, d2, "", 0, "", 0, out);
1167
+ } else if (ox_cdata_clas == clas) {
1168
+ dump_gen_val_node(*np, d2, "<![CDATA[", 9, "]]>", 3, out);
1169
+ } else if (ox_doctype_clas == clas) {
1170
+ dump_gen_val_node(*np, d2, "<!DOCTYPE ", 10, ">", 1, out);
1171
+ } else {
1172
+ rb_raise(rb_eTypeError, "Unexpected class, %s, while dumping generic XML\n", rb_class2name(clas));
1173
+ }
1174
+ }
1194
1175
  }
1195
1176
  return indent_needed;
1196
1177
  }
1197
1178
 
1198
- static int
1199
- dump_gen_attr(VALUE key, VALUE value, VALUE ov) {
1200
- Out out = (Out)ov;
1179
+ static int dump_gen_attr(VALUE key, VALUE value, VALUE ov) {
1180
+ Out out = (Out)ov;
1201
1181
 
1202
- const char *ks;
1203
- size_t klen;
1204
- size_t size;
1182
+ const char *ks;
1183
+ size_t klen;
1184
+ size_t size;
1205
1185
 
1206
1186
  switch (rb_type(key)) {
1207
- case T_SYMBOL:
1208
- ks = rb_id2name(SYM2ID(key));
1209
- break;
1210
- case T_STRING:
1211
- ks = StringValuePtr(key);
1212
- break;
1187
+ case T_SYMBOL: ks = rb_id2name(SYM2ID(key)); break;
1188
+ case T_STRING: ks = StringValuePtr(key); break;
1213
1189
  default:
1214
- key = rb_String(key);
1215
- ks = StringValuePtr(key);
1216
- break;
1190
+ key = rb_String(key);
1191
+ ks = StringValuePtr(key);
1192
+ break;
1217
1193
  }
1218
- klen = strlen(ks);
1194
+ klen = strlen(ks);
1219
1195
  value = rb_String(value);
1220
- size = 4 + klen + RSTRING_LEN(value);
1196
+ size = 4 + klen + RSTRING_LEN(value);
1221
1197
  if (out->end - out->cur <= (long)size) {
1222
- grow(out, size);
1198
+ grow(out, size);
1223
1199
  }
1224
1200
  *out->cur++ = ' ';
1225
1201
  fill_value(out, ks, klen);
@@ -1232,30 +1208,28 @@ dump_gen_attr(VALUE key, VALUE value, VALUE ov) {
1232
1208
  }
1233
1209
 
1234
1210
  static void
1235
- dump_gen_val_node(VALUE obj, int depth,
1236
- const char *pre, size_t plen,
1237
- const char *suf, size_t slen, Out out) {
1238
- volatile VALUE v = rb_attr_get(obj, ox_at_value_id);
1239
- const char *val;
1240
- size_t vlen;
1241
- size_t size;
1242
- int indent;
1211
+ dump_gen_val_node(VALUE obj, int depth, const char *pre, size_t plen, const char *suf, size_t slen, Out out) {
1212
+ volatile VALUE v = rb_attr_get(obj, ox_at_value_id);
1213
+ const char *val;
1214
+ size_t vlen;
1215
+ size_t size;
1216
+ int indent;
1243
1217
 
1244
1218
  if (T_STRING != rb_type(v)) {
1245
- return;
1219
+ return;
1246
1220
  }
1247
- val = StringValuePtr(v);
1221
+ val = StringValuePtr(v);
1248
1222
  vlen = RSTRING_LEN(v);
1249
1223
  if (0 > out->indent) {
1250
- indent = -1;
1224
+ indent = -1;
1251
1225
  } else if (0 == out->indent) {
1252
- indent = 0;
1226
+ indent = 0;
1253
1227
  } else {
1254
- indent = depth * out->indent;
1228
+ indent = depth * out->indent;
1255
1229
  }
1256
1230
  size = indent + plen + slen + vlen + out->opts->margin_len;
1257
1231
  if (out->end - out->cur <= (long)size) {
1258
- grow(out, size);
1232
+ grow(out, size);
1259
1233
  }
1260
1234
  fill_indent(out, indent);
1261
1235
  fill_value(out, pre, plen);
@@ -1264,63 +1238,60 @@ dump_gen_val_node(VALUE obj, int depth,
1264
1238
  *out->cur = '\0';
1265
1239
  }
1266
1240
 
1267
- static void
1268
- dump_obj_to_xml(VALUE obj, Options copts, Out out) {
1269
- VALUE clas = rb_obj_class(obj);
1241
+ static void dump_obj_to_xml(VALUE obj, Options copts, Out out) {
1242
+ VALUE clas = rb_obj_class(obj);
1270
1243
 
1271
- out->w_time = (Yes == copts->xsd_date) ? dump_time_xsd : dump_time_thin;
1272
- out->buf = ALLOC_N(char, 65336);
1273
- out->end = out->buf + 65325; /* 10 less than end plus extra for possible errors */
1274
- out->cur = out->buf;
1244
+ out->w_time = (Yes == copts->xsd_date) ? dump_time_xsd : dump_time_thin;
1245
+ out->buf = ALLOC_N(char, 65336);
1246
+ out->end = out->buf + 65325; /* 10 less than end plus extra for possible errors */
1247
+ out->cur = out->buf;
1275
1248
  out->circ_cache = 0;
1276
- out->circ_cnt = 0;
1277
- out->opts = copts;
1278
- out->obj = obj;
1279
- *out->cur = '\0';
1249
+ out->circ_cnt = 0;
1250
+ out->opts = copts;
1251
+ out->obj = obj;
1252
+ *out->cur = '\0';
1280
1253
  if (Yes == copts->circular) {
1281
- ox_cache8_new(&out->circ_cache);
1254
+ ox_cache8_new(&out->circ_cache);
1282
1255
  }
1283
1256
  out->indent = copts->indent;
1284
1257
 
1285
1258
  if (ox_document_clas == clas) {
1286
- dump_gen_doc(obj, -1, out);
1259
+ dump_gen_doc(obj, -1, out);
1287
1260
  } else if (ox_element_clas == clas) {
1288
- dump_gen_element(obj, 0, out);
1261
+ dump_gen_element(obj, 0, out);
1289
1262
  } else {
1290
- out->w_start = dump_start;
1291
- out->w_end = dump_end;
1292
- dump_first_obj(obj, out);
1263
+ out->w_start = dump_start;
1264
+ out->w_end = dump_end;
1265
+ dump_first_obj(obj, out);
1293
1266
  }
1294
1267
  if (0 <= out->indent) {
1295
- dump_value(out, "\n", 1);
1268
+ dump_value(out, "\n", 1);
1296
1269
  }
1297
1270
  if (Yes == copts->circular) {
1298
- ox_cache8_delete(out->circ_cache);
1271
+ ox_cache8_delete(out->circ_cache);
1299
1272
  }
1300
1273
  }
1301
1274
 
1302
- char*
1303
- ox_write_obj_to_str(VALUE obj, Options copts) {
1275
+ char *ox_write_obj_to_str(VALUE obj, Options copts) {
1304
1276
  struct _out out;
1305
1277
 
1306
1278
  dump_obj_to_xml(obj, copts, &out);
1307
1279
  return out.buf;
1308
1280
  }
1309
1281
 
1310
- void
1311
- ox_write_obj_to_file(VALUE obj, const char *path, Options copts) {
1282
+ void ox_write_obj_to_file(VALUE obj, const char *path, Options copts) {
1312
1283
  struct _out out;
1313
- size_t size;
1314
- FILE *f;
1284
+ size_t size;
1285
+ FILE *f;
1315
1286
 
1316
1287
  dump_obj_to_xml(obj, copts, &out);
1317
1288
  size = out.cur - out.buf;
1318
1289
  if (0 == (f = fopen(path, "w"))) {
1319
- rb_raise(rb_eIOError, "%s\n", strerror(errno));
1290
+ rb_raise(rb_eIOError, "%s\n", strerror(errno));
1320
1291
  }
1321
1292
  if (size != fwrite(out.buf, 1, size, f)) {
1322
- int err = ferror(f);
1323
- rb_raise(rb_eIOError, "Write failed. [%d:%s]\n", err, strerror(err));
1293
+ int err = ferror(f);
1294
+ rb_raise(rb_eIOError, "Write failed. [%d:%s]\n", err, strerror(err));
1324
1295
  }
1325
1296
  xfree(out.buf);
1326
1297
  fclose(f);