ox 2.14.14 → 2.14.17

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