ox 2.14.12 → 2.14.17

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,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);