ox 2.0.11 → 2.0.12
Sign up to get free protection for your applications and to get access to all the features.
Potentially problematic release.
This version of ox might be problematic. Click here for more details.
- checksums.yaml +4 -4
- data/README.md +2 -2
- data/ext/ox/dump.c +548 -568
- data/ext/ox/extconf.rb +2 -1
- data/ext/ox/sax.c +0 -14
- data/ext/ox/sax_buf.c +14 -1
- data/lib/ox/version.rb +1 -1
- metadata +2 -2
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 7bc14be25d8676f147ec3bf997dfc6464c5a1ac9
|
4
|
+
data.tar.gz: e5662578d75a1a1af039467666d75c427815b89b
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 44e1578e1ac977a53591611069645e39dbadc906067a892ff52a197f2e7d2e8c798cb4320d7352203790519f8851e45f413f41eda5eb1a5da30e25d03c09be33
|
7
|
+
data.tar.gz: 4454ffacc01df4a78fff994fa31b8fc152bff30efebdde48da72c472f82d4a13a23411cd85100146187474ac6eaedb9e71f34a195e64df635b19d9e40c047a69
|
data/README.md
CHANGED
@@ -34,9 +34,9 @@ A fast XML parser and Object marshaller as a Ruby gem.
|
|
34
34
|
|
35
35
|
## <a name="release">Release Notes</a>
|
36
36
|
|
37
|
-
### Release 2.0.
|
37
|
+
### Release 2.0.12
|
38
38
|
|
39
|
-
-
|
39
|
+
- Fixed problem compiling with latest version of Rubinius.
|
40
40
|
|
41
41
|
## <a name="description">Description</a>
|
42
42
|
|
data/ext/ox/dump.c
CHANGED
@@ -41,69 +41,69 @@
|
|
41
41
|
#define USE_B64 0
|
42
42
|
#define MAX_DEPTH 1000
|
43
43
|
|
44
|
-
typedef unsigned long
|
44
|
+
typedef unsigned long ulong;
|
45
45
|
|
46
46
|
typedef struct _Str {
|
47
|
-
const char
|
48
|
-
size_t
|
47
|
+
const char *str;
|
48
|
+
size_t len;
|
49
49
|
} *Str;
|
50
50
|
|
51
51
|
typedef struct _Element {
|
52
|
-
struct _Str
|
53
|
-
struct _Str
|
54
|
-
unsigned long
|
55
|
-
int
|
56
|
-
int
|
57
|
-
char
|
52
|
+
struct _Str clas;
|
53
|
+
struct _Str attr;
|
54
|
+
unsigned long id;
|
55
|
+
int indent; /* < 0 indicates no \n */
|
56
|
+
int closed;
|
57
|
+
char type;
|
58
58
|
} *Element;
|
59
59
|
|
60
60
|
typedef struct _Out {
|
61
|
-
void
|
62
|
-
void
|
63
|
-
void
|
64
|
-
char
|
65
|
-
char
|
66
|
-
char
|
67
|
-
Cache8
|
68
|
-
unsigned long
|
69
|
-
int
|
70
|
-
int
|
71
|
-
Options
|
61
|
+
void (*w_start)(struct _Out *out, Element e);
|
62
|
+
void (*w_end)(struct _Out *out, Element e);
|
63
|
+
void (*w_time)(struct _Out *out, VALUE obj);
|
64
|
+
char *buf;
|
65
|
+
char *end;
|
66
|
+
char *cur;
|
67
|
+
Cache8 circ_cache;
|
68
|
+
unsigned long circ_cnt;
|
69
|
+
int indent;
|
70
|
+
int depth; /* used by dumpHash */
|
71
|
+
Options opts;
|
72
72
|
VALUE obj;
|
73
73
|
} *Out;
|
74
74
|
|
75
|
-
static void
|
75
|
+
static void dump_obj_to_xml(VALUE obj, Options copts, Out out);
|
76
76
|
|
77
|
-
static void
|
78
|
-
static void
|
79
|
-
static void
|
80
|
-
static void
|
77
|
+
static void dump_first_obj(VALUE obj, Out out);
|
78
|
+
static void dump_obj(ID aid, VALUE obj, int depth, Out out);
|
79
|
+
static void dump_gen_doc(VALUE obj, int depth, Out out);
|
80
|
+
static void dump_gen_element(VALUE obj, int depth, Out out);
|
81
81
|
static void dump_gen_instruct(VALUE obj, int depth, Out out);
|
82
|
-
static int
|
83
|
-
static int
|
84
|
-
static void
|
85
|
-
|
86
|
-
|
82
|
+
static int dump_gen_attr(VALUE key, VALUE value, Out out);
|
83
|
+
static int dump_gen_nodes(VALUE obj, int depth, Out out);
|
84
|
+
static void dump_gen_val_node(VALUE obj, int depth,
|
85
|
+
const char *pre, size_t plen,
|
86
|
+
const char *suf, size_t slen, Out out);
|
87
87
|
|
88
|
-
static void
|
89
|
-
static void
|
88
|
+
static void dump_start(Out out, Element e);
|
89
|
+
static void dump_end(Out out, Element e);
|
90
90
|
|
91
|
-
static void
|
91
|
+
static void grow(Out out, size_t len);
|
92
92
|
|
93
|
-
static void
|
94
|
-
static void
|
95
|
-
static int
|
96
|
-
static void
|
97
|
-
static void
|
98
|
-
static void
|
99
|
-
static void
|
100
|
-
static int
|
93
|
+
static void dump_value(Out out, const char *value, size_t size);
|
94
|
+
static void dump_str_value(Out out, const char *value, size_t size);
|
95
|
+
static int dump_var(ID key, VALUE value, Out out);
|
96
|
+
static void dump_num(Out out, VALUE obj);
|
97
|
+
static void dump_date(Out out, VALUE obj);
|
98
|
+
static void dump_time_thin(Out out, VALUE obj);
|
99
|
+
static void dump_time_xsd(Out out, VALUE obj);
|
100
|
+
static int dump_hash(VALUE key, VALUE value, Out out);
|
101
101
|
|
102
|
-
static int
|
102
|
+
static int is_xml_friendly(const uchar *str, int len);
|
103
103
|
|
104
104
|
static const char hex_chars[17] = "0123456789abcdef";
|
105
105
|
|
106
|
-
static char
|
106
|
+
static char xml_friendly_chars[257] = "\
|
107
107
|
88888888811881888888888888888888\
|
108
108
|
11611156111111111111111111114141\
|
109
109
|
11111111111111111111111111111111\
|
@@ -116,9 +116,9 @@ static char xml_friendly_chars[257] = "\
|
|
116
116
|
inline static int
|
117
117
|
is_xml_friendly(const uchar *str, int len) {
|
118
118
|
for (; 0 < len; str++, len--) {
|
119
|
-
|
120
|
-
|
121
|
-
|
119
|
+
if ('1' != xml_friendly_chars[*str]) {
|
120
|
+
return 0;
|
121
|
+
}
|
122
122
|
}
|
123
123
|
return 1;
|
124
124
|
}
|
@@ -147,55 +147,55 @@ obj_class_code(VALUE obj) {
|
|
147
147
|
VALUE clas = rb_obj_class(obj);
|
148
148
|
|
149
149
|
switch (rb_type(obj)) {
|
150
|
-
case T_NIL:
|
151
|
-
case T_ARRAY:
|
152
|
-
case T_HASH:
|
153
|
-
case T_TRUE:
|
154
|
-
case T_FALSE:
|
155
|
-
case T_FIXNUM:
|
156
|
-
case T_FLOAT:
|
157
|
-
case T_STRING:
|
150
|
+
case T_NIL: return NilClassCode;
|
151
|
+
case T_ARRAY: return ArrayCode;
|
152
|
+
case T_HASH: return HashCode;
|
153
|
+
case T_TRUE: return TrueClassCode;
|
154
|
+
case T_FALSE: return FalseClassCode;
|
155
|
+
case T_FIXNUM: return FixnumCode;
|
156
|
+
case T_FLOAT: return FloatCode;
|
157
|
+
case T_STRING: return (is_xml_friendly((uchar*)StringValuePtr(obj), (int)RSTRING_LEN(obj))) ? StringCode : String64Code;
|
158
158
|
case T_SYMBOL:
|
159
159
|
{
|
160
|
-
|
160
|
+
const char *sym = rb_id2name(SYM2ID(obj));
|
161
161
|
|
162
|
-
|
162
|
+
return (is_xml_friendly((uchar*)sym, (int)strlen(sym))) ? SymbolCode : Symbol64Code;
|
163
163
|
}
|
164
|
-
case T_DATA:
|
165
|
-
case T_STRUCT:
|
166
|
-
case T_OBJECT:
|
167
|
-
case T_REGEXP:
|
168
|
-
case T_BIGNUM:
|
164
|
+
case T_DATA: return (rb_cTime == clas) ? TimeCode : ((ox_date_class == clas) ? DateCode : 0);
|
165
|
+
case T_STRUCT: return (rb_cRange == clas) ? RangeCode : StructCode;
|
166
|
+
case T_OBJECT: return (ox_document_clas == clas || ox_element_clas == clas) ? RawCode : ObjectCode;
|
167
|
+
case T_REGEXP: return RegexpCode;
|
168
|
+
case T_BIGNUM: return BignumCode;
|
169
169
|
#ifdef T_COMPLEX
|
170
|
-
case T_COMPLEX:
|
170
|
+
case T_COMPLEX: return ComplexCode;
|
171
171
|
#endif
|
172
172
|
#ifdef T_RATIONAL
|
173
|
-
case T_RATIONAL:
|
173
|
+
case T_RATIONAL: return RationalCode;
|
174
174
|
#endif
|
175
|
-
case T_CLASS:
|
176
|
-
default:
|
175
|
+
case T_CLASS: return ClassCode;
|
176
|
+
default: return 0;
|
177
177
|
}
|
178
178
|
}
|
179
179
|
|
180
180
|
inline static void
|
181
181
|
fill_indent(Out out, int cnt) {
|
182
182
|
if (0 <= cnt) {
|
183
|
-
|
184
|
-
|
185
|
-
|
186
|
-
|
183
|
+
*out->cur++ = '\n';
|
184
|
+
for (; 0 < cnt; cnt--) {
|
185
|
+
*out->cur++ = ' ';
|
186
|
+
}
|
187
187
|
}
|
188
188
|
}
|
189
189
|
|
190
190
|
inline static void
|
191
191
|
fill_value(Out out, const char *value, size_t len) {
|
192
192
|
if (6 < len) {
|
193
|
-
|
194
|
-
|
193
|
+
memcpy(out->cur, value, len);
|
194
|
+
out->cur += len;
|
195
195
|
} else {
|
196
|
-
|
197
|
-
|
198
|
-
|
196
|
+
for (; '\0' != *value; value++) {
|
197
|
+
*out->cur++ = *value;
|
198
|
+
}
|
199
199
|
}
|
200
200
|
}
|
201
201
|
|
@@ -206,23 +206,23 @@ fill_attr(Out out, char name, const char *value, size_t len) {
|
|
206
206
|
*out->cur++ = '=';
|
207
207
|
*out->cur++ = '"';
|
208
208
|
if (6 < len) {
|
209
|
-
|
210
|
-
|
209
|
+
memcpy(out->cur, value, len);
|
210
|
+
out->cur += len;
|
211
211
|
} else {
|
212
|
-
|
213
|
-
|
214
|
-
|
212
|
+
for (; '\0' != *value; value++) {
|
213
|
+
*out->cur++ = *value;
|
214
|
+
}
|
215
215
|
}
|
216
216
|
*out->cur++ = '"';
|
217
217
|
}
|
218
218
|
|
219
219
|
inline static const char*
|
220
220
|
ulong2str(ulong num, char *end) {
|
221
|
-
char
|
221
|
+
char *b;
|
222
222
|
|
223
223
|
*end-- = '\0';
|
224
224
|
for (b = end; 0 < num || b == end; num /= 10, b--) {
|
225
|
-
|
225
|
+
*b = (num % 10) + '0';
|
226
226
|
}
|
227
227
|
b++;
|
228
228
|
|
@@ -236,17 +236,17 @@ check_circular(Out out, VALUE obj, Element e) {
|
|
236
236
|
int result;
|
237
237
|
|
238
238
|
if (0 == (id = ox_cache8_get(out->circ_cache, obj, &slot))) {
|
239
|
-
|
240
|
-
|
241
|
-
|
242
|
-
|
243
|
-
|
239
|
+
out->circ_cnt++;
|
240
|
+
id = out->circ_cnt;
|
241
|
+
*slot = id;
|
242
|
+
e->id = id;
|
243
|
+
result = 0;
|
244
244
|
} else {
|
245
|
-
|
246
|
-
|
247
|
-
|
248
|
-
|
249
|
-
|
245
|
+
e->type = RefCode; e->clas.len = 0; e->clas.str = 0;
|
246
|
+
e->closed = 1;
|
247
|
+
e->id = id;
|
248
|
+
out->w_start(out, e);
|
249
|
+
result = 1;
|
250
250
|
}
|
251
251
|
return result;
|
252
252
|
}
|
@@ -255,10 +255,10 @@ static void
|
|
255
255
|
grow(Out out, size_t len) {
|
256
256
|
size_t size = out->end - out->buf;
|
257
257
|
long pos = out->cur - out->buf;
|
258
|
-
|
258
|
+
|
259
259
|
size *= 2;
|
260
260
|
if (size <= len * 2 + pos) {
|
261
|
-
|
261
|
+
size += len;
|
262
262
|
}
|
263
263
|
REALLOC_N(out->buf, char, size + 10); /* 10 extra for terminator character plus extra (paranoid) */
|
264
264
|
out->end = out->buf + size;
|
@@ -267,40 +267,40 @@ grow(Out out, size_t len) {
|
|
267
267
|
|
268
268
|
static void
|
269
269
|
dump_start(Out out, Element e) {
|
270
|
-
size_t
|
270
|
+
size_t size = e->indent + 4;
|
271
271
|
|
272
272
|
if (0 < e->attr.len) { /* a="attr" */
|
273
|
-
|
273
|
+
size += e->attr.len + 5;
|
274
274
|
}
|
275
275
|
if (0 < e->clas.len) { /* c="class" */
|
276
|
-
|
276
|
+
size += e->clas.len + 5;
|
277
277
|
}
|
278
278
|
if (0 < e->id) { /* i="id" */
|
279
|
-
|
279
|
+
size += 24; /* over estimate, 19 digits */
|
280
280
|
}
|
281
281
|
if (out->end - out->cur <= (long)size) {
|
282
|
-
|
282
|
+
grow(out, size);
|
283
283
|
}
|
284
284
|
if (out->buf < out->cur) {
|
285
|
-
|
285
|
+
fill_indent(out, e->indent);
|
286
286
|
}
|
287
287
|
*out->cur++ = '<';
|
288
288
|
*out->cur++ = e->type;
|
289
289
|
if (0 < e->attr.len) {
|
290
|
-
|
290
|
+
fill_attr(out, 'a', e->attr.str, e->attr.len);
|
291
291
|
}
|
292
292
|
if ((ObjectCode == e->type || ExceptionCode == e->type || StructCode == e->type || ClassCode == e->type) && 0 < e->clas.len) {
|
293
|
-
|
293
|
+
fill_attr(out, 'c', e->clas.str, e->clas.len);
|
294
294
|
}
|
295
295
|
if (0 < e->id) {
|
296
|
-
|
297
|
-
|
298
|
-
|
299
|
-
|
300
|
-
|
296
|
+
char buf[32];
|
297
|
+
char *end = buf + sizeof(buf) - 1;
|
298
|
+
const char *s = ulong2str(e->id, end);
|
299
|
+
|
300
|
+
fill_attr(out, 'i', s, end - s);
|
301
301
|
}
|
302
302
|
if (e->closed) {
|
303
|
-
|
303
|
+
*out->cur++ = '/';
|
304
304
|
}
|
305
305
|
*out->cur++ = '>';
|
306
306
|
*out->cur = '\0';
|
@@ -308,10 +308,10 @@ dump_start(Out out, Element e) {
|
|
308
308
|
|
309
309
|
static void
|
310
310
|
dump_end(Out out, Element e) {
|
311
|
-
size_t
|
311
|
+
size_t size = e->indent + 5;
|
312
312
|
|
313
313
|
if (out->end - out->cur <= (long)size) {
|
314
|
-
|
314
|
+
grow(out, size);
|
315
315
|
}
|
316
316
|
fill_indent(out, e->indent);
|
317
317
|
*out->cur++ = '<';
|
@@ -324,15 +324,15 @@ dump_end(Out out, Element e) {
|
|
324
324
|
inline static void
|
325
325
|
dump_value(Out out, const char *value, size_t size) {
|
326
326
|
if (out->end - out->cur <= (long)size) {
|
327
|
-
|
327
|
+
grow(out, size);
|
328
328
|
}
|
329
329
|
if (6 < size) {
|
330
|
-
|
331
|
-
|
330
|
+
memcpy(out->cur, value, size);
|
331
|
+
out->cur += size;
|
332
332
|
} else {
|
333
|
-
|
334
|
-
|
335
|
-
|
333
|
+
for (; '\0' != *value; value++) {
|
334
|
+
*out->cur++ = *value;
|
335
|
+
}
|
336
336
|
}
|
337
337
|
*out->cur = '\0';
|
338
338
|
}
|
@@ -342,7 +342,7 @@ dump_str_value(Out out, const char *value, size_t size) {
|
|
342
342
|
size_t xsize = xml_str_len((const uchar*)value, size);
|
343
343
|
|
344
344
|
if (out->end - out->cur <= (long)xsize) {
|
345
|
-
|
345
|
+
grow(out, xsize);
|
346
346
|
}
|
347
347
|
for (; '\0' != *value; value++) {
|
348
348
|
if ('1' == xml_friendly_chars[(uchar)*value]) {
|
@@ -391,33 +391,33 @@ dump_str_value(Out out, const char *value, size_t size) {
|
|
391
391
|
|
392
392
|
inline static void
|
393
393
|
dump_num(Out out, VALUE obj) {
|
394
|
-
char
|
395
|
-
char
|
396
|
-
long
|
397
|
-
int
|
394
|
+
char buf[32];
|
395
|
+
char *b = buf + sizeof(buf) - 1;
|
396
|
+
long num = NUM2LONG(obj);
|
397
|
+
int neg = 0;
|
398
398
|
|
399
399
|
if (0 > num) {
|
400
|
-
|
401
|
-
|
400
|
+
neg = 1;
|
401
|
+
num = -num;
|
402
402
|
}
|
403
403
|
*b-- = '\0';
|
404
404
|
if (0 < num) {
|
405
|
-
|
406
|
-
|
407
|
-
|
408
|
-
|
409
|
-
|
410
|
-
|
411
|
-
|
412
|
-
|
405
|
+
for (; 0 < num; num /= 10, b--) {
|
406
|
+
*b = (num % 10) + '0';
|
407
|
+
}
|
408
|
+
if (neg) {
|
409
|
+
*b = '-';
|
410
|
+
} else {
|
411
|
+
b++;
|
412
|
+
}
|
413
413
|
} else {
|
414
|
-
|
414
|
+
*b = '0';
|
415
415
|
}
|
416
416
|
if (out->end - out->cur <= (long)(sizeof(buf) - (b - buf))) {
|
417
|
-
|
417
|
+
grow(out, sizeof(buf) - (b - buf));
|
418
418
|
}
|
419
419
|
for (; '\0' != *b; b++) {
|
420
|
-
|
420
|
+
*out->cur++ = *b;
|
421
421
|
}
|
422
422
|
*out->cur = '\0';
|
423
423
|
}
|
@@ -443,16 +443,16 @@ dump_time_thin(Out out, VALUE obj) {
|
|
443
443
|
|
444
444
|
*b-- = '\0';
|
445
445
|
for (; dot < b; b--, nsec /= 10) {
|
446
|
-
|
446
|
+
*b = '0' + (nsec % 10);
|
447
447
|
}
|
448
448
|
*b-- = '.';
|
449
449
|
for (; 0 < sec; b--, sec /= 10) {
|
450
|
-
|
450
|
+
*b = '0' + (sec % 10);
|
451
451
|
}
|
452
452
|
b++;
|
453
453
|
size = sizeof(buf) - (b - buf) - 1;
|
454
454
|
if (out->end - out->cur <= size) {
|
455
|
-
|
455
|
+
grow(out, size);
|
456
456
|
}
|
457
457
|
memcpy(out->cur, b, size);
|
458
458
|
out->cur += size;
|
@@ -460,14 +460,14 @@ dump_time_thin(Out out, VALUE obj) {
|
|
460
460
|
|
461
461
|
static void
|
462
462
|
dump_date(Out out, VALUE obj) {
|
463
|
-
char
|
464
|
-
char
|
465
|
-
long
|
466
|
-
long
|
463
|
+
char buf[64];
|
464
|
+
char *b = buf + sizeof(buf) - 1;
|
465
|
+
long jd = NUM2LONG(rb_funcall2(obj, ox_jd_id, 0, 0));
|
466
|
+
long size;
|
467
467
|
|
468
468
|
*b-- = '\0';
|
469
469
|
for (; 0 < jd; b--, jd /= 10) {
|
470
|
-
|
470
|
+
*b = '0' + (jd % 10);
|
471
471
|
}
|
472
472
|
b++;
|
473
473
|
if ('\0' == *b) {
|
@@ -476,7 +476,7 @@ dump_date(Out out, VALUE obj) {
|
|
476
476
|
}
|
477
477
|
size = sizeof(buf) - (b - buf) - 1;
|
478
478
|
if (out->end - out->cur <= size) {
|
479
|
-
|
479
|
+
grow(out, size);
|
480
480
|
}
|
481
481
|
memcpy(out->cur, b, size);
|
482
482
|
out->cur += size;
|
@@ -501,18 +501,18 @@ dump_time_xsd(Out out, VALUE obj) {
|
|
501
501
|
char tzsign = '+';
|
502
502
|
|
503
503
|
if (out->end - out->cur <= 33) {
|
504
|
-
|
504
|
+
grow(out, 33);
|
505
505
|
}
|
506
506
|
/* 2010-07-09T10:47:45.895826+09:00 */
|
507
507
|
tm = localtime(&sec);
|
508
508
|
#if HAS_TM_GMTOFF
|
509
509
|
if (0 > tm->tm_gmtoff) {
|
510
|
-
|
511
|
-
|
512
|
-
|
510
|
+
tzsign = '-';
|
511
|
+
tzhour = (int)(tm->tm_gmtoff / -3600);
|
512
|
+
tzmin = (int)(tm->tm_gmtoff / -60) - (tzhour * 60);
|
513
513
|
} else {
|
514
|
-
|
515
|
-
|
514
|
+
tzhour = (int)(tm->tm_gmtoff / 3600);
|
515
|
+
tzmin = (int)(tm->tm_gmtoff / 60) - (tzhour * 60);
|
516
516
|
}
|
517
517
|
#else
|
518
518
|
tzhour = 0;
|
@@ -527,157 +527,157 @@ dump_time_xsd(Out out, VALUE obj) {
|
|
527
527
|
|
528
528
|
static void
|
529
529
|
dump_first_obj(VALUE obj, Out out) {
|
530
|
-
char
|
531
|
-
Options
|
532
|
-
int
|
530
|
+
char buf[128];
|
531
|
+
Options copts = out->opts;
|
532
|
+
int cnt;
|
533
533
|
|
534
534
|
if (Yes == copts->with_xml) {
|
535
|
-
|
536
|
-
|
537
|
-
|
538
|
-
|
539
|
-
|
540
|
-
|
535
|
+
if ('\0' == *copts->encoding) {
|
536
|
+
dump_value(out, "<?xml version=\"1.0\"?>", 21);
|
537
|
+
} else {
|
538
|
+
cnt = sprintf(buf, "<?xml version=\"1.0\" encoding=\"%s\"?>", copts->encoding);
|
539
|
+
dump_value(out, buf, cnt);
|
540
|
+
}
|
541
541
|
}
|
542
542
|
if (Yes == copts->with_instruct) {
|
543
|
-
|
544
|
-
|
545
|
-
|
546
|
-
|
547
|
-
|
543
|
+
cnt = sprintf(buf, "%s<?ox version=\"1.0\" mode=\"object\"%s%s?>",
|
544
|
+
(out->buf < out->cur) ? "\n" : "",
|
545
|
+
(Yes == copts->circular) ? " circular=\"yes\"" : ((No == copts->circular) ? " circular=\"no\"" : ""),
|
546
|
+
(Yes == copts->xsd_date) ? " xsd_date=\"yes\"" : ((No == copts->xsd_date) ? " xsd_date=\"no\"" : ""));
|
547
|
+
dump_value(out, buf, cnt);
|
548
548
|
}
|
549
549
|
if (Yes == copts->with_dtd) {
|
550
|
-
|
551
|
-
|
550
|
+
cnt = sprintf(buf, "%s<!DOCTYPE %c SYSTEM \"ox.dtd\">", (out->buf < out->cur) ? "\n" : "", obj_class_code(obj));
|
551
|
+
dump_value(out, buf, cnt);
|
552
552
|
}
|
553
553
|
dump_obj(0, obj, 0, out);
|
554
554
|
}
|
555
555
|
|
556
556
|
static void
|
557
557
|
dump_obj(ID aid, VALUE obj, int depth, Out out) {
|
558
|
-
struct _Element
|
558
|
+
struct _Element e;
|
559
559
|
VALUE prev_obj = out->obj;
|
560
|
-
char
|
561
|
-
int
|
560
|
+
char value_buf[64];
|
561
|
+
int cnt;
|
562
562
|
|
563
563
|
if (MAX_DEPTH < depth) {
|
564
564
|
rb_raise(rb_eSysStackError, "maximum depth exceeded");
|
565
565
|
}
|
566
566
|
out->obj = obj;
|
567
567
|
if (0 == aid) {
|
568
|
-
|
569
|
-
|
568
|
+
/*e.attr.str = 0; */
|
569
|
+
e.attr.len = 0;
|
570
570
|
} else {
|
571
|
-
|
572
|
-
|
571
|
+
e.attr.str = rb_id2name(aid);
|
572
|
+
e.attr.len = strlen(e.attr.str);
|
573
573
|
}
|
574
574
|
e.closed = 0;
|
575
575
|
if (0 == depth) {
|
576
|
-
|
576
|
+
e.indent = (0 <= out->indent) ? 0 : -1;
|
577
577
|
} else if (0 > out->indent) {
|
578
|
-
|
578
|
+
e.indent = -1;
|
579
579
|
} else if (0 == out->indent) {
|
580
|
-
|
580
|
+
e.indent = 0;
|
581
581
|
} else {
|
582
|
-
|
582
|
+
e.indent = depth * out->indent;
|
583
583
|
}
|
584
584
|
e.id = 0;
|
585
585
|
e.clas.len = 0;
|
586
586
|
e.clas.str = 0;
|
587
587
|
switch (rb_type(obj)) {
|
588
588
|
case T_NIL:
|
589
|
-
|
590
|
-
|
591
|
-
|
592
|
-
|
589
|
+
e.type = NilClassCode;
|
590
|
+
e.closed = 1;
|
591
|
+
out->w_start(out, &e);
|
592
|
+
break;
|
593
593
|
case T_ARRAY:
|
594
|
-
|
595
|
-
|
596
|
-
|
597
|
-
|
598
|
-
|
599
|
-
|
600
|
-
|
601
|
-
|
602
|
-
|
603
|
-
|
604
|
-
|
605
|
-
|
606
|
-
|
607
|
-
|
608
|
-
|
609
|
-
|
610
|
-
|
611
|
-
|
594
|
+
if (0 != out->circ_cache && check_circular(out, obj, &e)) {
|
595
|
+
break;
|
596
|
+
}
|
597
|
+
cnt = (int)RARRAY_LEN(obj);
|
598
|
+
e.type = ArrayCode;
|
599
|
+
e.closed = (0 >= cnt);
|
600
|
+
out->w_start(out, &e);
|
601
|
+
if (!e.closed) {
|
602
|
+
const VALUE *np = RARRAY_PTR(obj);
|
603
|
+
int i;
|
604
|
+
int d2 = depth + 1;
|
605
|
+
|
606
|
+
for (i = cnt; 0 < i; i--, np++) {
|
607
|
+
dump_obj(0, *np, d2, out);
|
608
|
+
}
|
609
|
+
out->w_end(out, &e);
|
610
|
+
}
|
611
|
+
break;
|
612
612
|
case T_HASH:
|
613
|
-
|
614
|
-
|
615
|
-
|
616
|
-
|
617
|
-
|
618
|
-
|
619
|
-
|
620
|
-
|
621
|
-
|
622
|
-
|
623
|
-
|
624
|
-
|
625
|
-
|
626
|
-
|
627
|
-
|
628
|
-
|
613
|
+
if (0 != out->circ_cache && check_circular(out, obj, &e)) {
|
614
|
+
break;
|
615
|
+
}
|
616
|
+
cnt = (int)RHASH_SIZE(obj);
|
617
|
+
e.type = HashCode;
|
618
|
+
e.closed = (0 >= cnt);
|
619
|
+
out->w_start(out, &e);
|
620
|
+
if (0 < cnt) {
|
621
|
+
unsigned int od = out->depth;
|
622
|
+
|
623
|
+
out->depth = depth + 1;
|
624
|
+
rb_hash_foreach(obj, dump_hash, (VALUE)out);
|
625
|
+
out->depth = od;
|
626
|
+
out->w_end(out, &e);
|
627
|
+
}
|
628
|
+
break;
|
629
629
|
case T_TRUE:
|
630
|
-
|
631
|
-
|
632
|
-
|
633
|
-
|
630
|
+
e.type = TrueClassCode;
|
631
|
+
e.closed = 1;
|
632
|
+
out->w_start(out, &e);
|
633
|
+
break;
|
634
634
|
case T_FALSE:
|
635
|
-
|
636
|
-
|
637
|
-
|
638
|
-
|
635
|
+
e.type = FalseClassCode;
|
636
|
+
e.closed = 1;
|
637
|
+
out->w_start(out, &e);
|
638
|
+
break;
|
639
639
|
case T_FIXNUM:
|
640
|
-
|
641
|
-
|
642
|
-
|
643
|
-
|
644
|
-
|
645
|
-
|
640
|
+
e.type = FixnumCode;
|
641
|
+
out->w_start(out, &e);
|
642
|
+
dump_num(out, obj);
|
643
|
+
e.indent = -1;
|
644
|
+
out->w_end(out, &e);
|
645
|
+
break;
|
646
646
|
case T_FLOAT:
|
647
|
-
|
648
|
-
|
649
|
-
|
650
|
-
|
651
|
-
|
652
|
-
|
653
|
-
|
647
|
+
e.type = FloatCode;
|
648
|
+
cnt = sprintf(value_buf, "%0.16g", rb_num2dbl(obj)); /* used sprintf due to bug in snprintf */
|
649
|
+
out->w_start(out, &e);
|
650
|
+
dump_value(out, value_buf, cnt);
|
651
|
+
e.indent = -1;
|
652
|
+
out->w_end(out, &e);
|
653
|
+
break;
|
654
654
|
case T_STRING:
|
655
655
|
{
|
656
|
-
|
656
|
+
const char *str;
|
657
657
|
|
658
|
-
|
659
|
-
|
660
|
-
|
661
|
-
|
662
|
-
|
658
|
+
if (0 != out->circ_cache && check_circular(out, obj, &e)) {
|
659
|
+
break;
|
660
|
+
}
|
661
|
+
str = StringValuePtr(obj);
|
662
|
+
cnt = (int)RSTRING_LEN(obj);
|
663
663
|
#if USE_B64
|
664
|
-
|
665
|
-
|
666
|
-
|
667
|
-
|
668
|
-
|
669
|
-
|
670
|
-
|
671
|
-
|
672
|
-
|
673
|
-
|
674
|
-
|
675
|
-
|
676
|
-
|
677
|
-
|
678
|
-
|
679
|
-
|
680
|
-
|
664
|
+
if (is_xml_friendly((uchar*)str, cnt)) {
|
665
|
+
e.type = StringCode;
|
666
|
+
out->w_start(out, &e);
|
667
|
+
dump_str_value(out, str, cnt);
|
668
|
+
e.indent = -1;
|
669
|
+
out->w_end(out, &e);
|
670
|
+
} else {
|
671
|
+
ulong size = b64_size(cnt);
|
672
|
+
char *b64 = ALLOCA_N(char, size + 1);
|
673
|
+
|
674
|
+
e.type = String64Code;
|
675
|
+
to_base64((uchar*)str, cnt, b64);
|
676
|
+
out->w_start(out, &e);
|
677
|
+
dump_value(out, b64, size);
|
678
|
+
e.indent = -1;
|
679
|
+
out->w_end(out, &e);
|
680
|
+
}
|
681
681
|
#else
|
682
682
|
e.type = StringCode;
|
683
683
|
out->w_start(out, &e);
|
@@ -685,31 +685,31 @@ dump_obj(ID aid, VALUE obj, int depth, Out out) {
|
|
685
685
|
e.indent = -1;
|
686
686
|
out->w_end(out, &e);
|
687
687
|
#endif
|
688
|
-
|
688
|
+
break;
|
689
689
|
}
|
690
690
|
case T_SYMBOL:
|
691
691
|
{
|
692
|
-
|
692
|
+
const char *sym = rb_id2name(SYM2ID(obj));
|
693
693
|
|
694
|
-
|
694
|
+
cnt = (int)strlen(sym);
|
695
695
|
#if USE_B64
|
696
|
-
|
697
|
-
|
698
|
-
|
699
|
-
|
700
|
-
|
701
|
-
|
702
|
-
|
703
|
-
|
704
|
-
|
705
|
-
|
706
|
-
|
707
|
-
|
708
|
-
|
709
|
-
|
710
|
-
|
711
|
-
|
712
|
-
|
696
|
+
if (is_xml_friendly((uchar*)sym, cnt)) {
|
697
|
+
e.type = SymbolCode;
|
698
|
+
out->w_start(out, &e);
|
699
|
+
dump_str_value(out, sym, cnt);
|
700
|
+
e.indent = -1;
|
701
|
+
out->w_end(out, &e);
|
702
|
+
} else {
|
703
|
+
ulong size = b64_size(cnt);
|
704
|
+
char *b64 = ALLOCA_N(char, size + 1);
|
705
|
+
|
706
|
+
e.type = Symbol64Code;
|
707
|
+
to_base64((uchar*)sym, cnt, b64);
|
708
|
+
out->w_start(out, &e);
|
709
|
+
dump_value(out, b64, size);
|
710
|
+
e.indent = -1;
|
711
|
+
out->w_end(out, &e);
|
712
|
+
}
|
713
713
|
#else
|
714
714
|
e.type = SymbolCode;
|
715
715
|
out->w_start(out, &e);
|
@@ -717,19 +717,19 @@ dump_obj(ID aid, VALUE obj, int depth, Out out) {
|
|
717
717
|
e.indent = -1;
|
718
718
|
out->w_end(out, &e);
|
719
719
|
#endif
|
720
|
-
|
720
|
+
break;
|
721
721
|
}
|
722
722
|
case T_DATA:
|
723
723
|
{
|
724
|
-
|
725
|
-
|
726
|
-
|
727
|
-
|
728
|
-
|
729
|
-
|
730
|
-
|
731
|
-
|
732
|
-
|
724
|
+
VALUE clas;
|
725
|
+
|
726
|
+
clas = rb_obj_class(obj);
|
727
|
+
if (rb_cTime == clas) {
|
728
|
+
e.type = TimeCode;
|
729
|
+
out->w_start(out, &e);
|
730
|
+
out->w_time(out, obj);
|
731
|
+
e.indent = -1;
|
732
|
+
out->w_end(out, &e);
|
733
733
|
} else {
|
734
734
|
const char *classname = rb_class2name(clas);
|
735
735
|
|
@@ -740,7 +740,7 @@ dump_obj(ID aid, VALUE obj, int depth, Out out) {
|
|
740
740
|
e.indent = -1;
|
741
741
|
out->w_end(out, &e);
|
742
742
|
} else if (0 == strcmp("BigDecimal", classname)) {
|
743
|
-
VALUE rs = rb_funcall(obj, ox_to_s_id, 0);
|
743
|
+
volatile VALUE rs = rb_funcall(obj, ox_to_s_id, 0);
|
744
744
|
|
745
745
|
e.type = BigDecimalCode;
|
746
746
|
out->w_start(out, &e);
|
@@ -756,217 +756,197 @@ dump_obj(ID aid, VALUE obj, int depth, Out out) {
|
|
756
756
|
out->w_start(out, &e);
|
757
757
|
}
|
758
758
|
}
|
759
|
-
|
760
|
-
|
759
|
+
}
|
760
|
+
break;
|
761
761
|
}
|
762
762
|
case T_STRUCT:
|
763
763
|
{
|
764
764
|
#if HAS_RSTRUCT
|
765
|
-
|
766
|
-
|
767
|
-
|
768
|
-
|
769
|
-
|
770
|
-
|
771
|
-
|
772
|
-
|
773
|
-
|
774
|
-
|
775
|
-
|
776
|
-
|
777
|
-
|
778
|
-
|
779
|
-
|
780
|
-
|
781
|
-
|
782
|
-
|
783
|
-
|
784
|
-
|
785
|
-
|
786
|
-
|
787
|
-
|
788
|
-
|
789
|
-
|
790
|
-
|
791
|
-
|
792
|
-
|
793
|
-
|
794
|
-
|
795
|
-
|
796
|
-
|
797
|
-
|
798
|
-
|
765
|
+
VALUE clas;
|
766
|
+
|
767
|
+
if (0 != out->circ_cache && check_circular(out, obj, &e)) {
|
768
|
+
break;
|
769
|
+
}
|
770
|
+
clas = rb_obj_class(obj);
|
771
|
+
if (rb_cRange == clas) {
|
772
|
+
VALUE beg = RSTRUCT_PTR(obj)[0];
|
773
|
+
VALUE end = RSTRUCT_PTR(obj)[1];
|
774
|
+
VALUE excl = RSTRUCT_PTR(obj)[2];
|
775
|
+
int d2 = depth + 1;
|
776
|
+
|
777
|
+
e.type = RangeCode; e.clas.len = 5; e.clas.str = "Range";
|
778
|
+
out->w_start(out, &e);
|
779
|
+
dump_obj(ox_beg_id, beg, d2, out);
|
780
|
+
dump_obj(ox_end_id, end, d2, out);
|
781
|
+
dump_obj(ox_excl_id, excl, d2, out);
|
782
|
+
out->w_end(out, &e);
|
783
|
+
} else {
|
784
|
+
char num_buf[16];
|
785
|
+
VALUE *vp;
|
786
|
+
int i;
|
787
|
+
int d2 = depth + 1;
|
788
|
+
|
789
|
+
e.type = StructCode;
|
790
|
+
e.clas.str = rb_class2name(clas);
|
791
|
+
e.clas.len = strlen(e.clas.str);
|
792
|
+
out->w_start(out, &e);
|
793
|
+
cnt = (int)RSTRUCT_LEN(obj);
|
794
|
+
for (i = 0, vp = RSTRUCT_PTR(obj); i < cnt; i++, vp++) {
|
795
|
+
dump_obj(rb_intern(ulong2str(i, num_buf + sizeof(num_buf) - 1)), *vp, d2, out);
|
796
|
+
}
|
797
|
+
out->w_end(out, &e);
|
798
|
+
}
|
799
799
|
#else
|
800
|
-
|
801
|
-
|
802
|
-
|
800
|
+
e.type = NilClassCode;
|
801
|
+
e.closed = 1;
|
802
|
+
out->w_start(out, &e);
|
803
803
|
#endif
|
804
|
-
|
804
|
+
break;
|
805
805
|
}
|
806
806
|
case T_OBJECT:
|
807
807
|
{
|
808
|
-
|
809
|
-
|
810
|
-
|
811
|
-
|
812
|
-
|
813
|
-
|
814
|
-
|
815
|
-
|
816
|
-
|
817
|
-
|
818
|
-
|
819
|
-
|
820
|
-
|
821
|
-
|
822
|
-
|
823
|
-
|
824
|
-
|
825
|
-
|
826
|
-
|
808
|
+
VALUE clas;
|
809
|
+
|
810
|
+
if (0 != out->circ_cache && check_circular(out, obj, &e)) {
|
811
|
+
break;
|
812
|
+
}
|
813
|
+
clas = rb_obj_class(obj);
|
814
|
+
e.clas.str = rb_class2name(clas);
|
815
|
+
e.clas.len = strlen(e.clas.str);
|
816
|
+
if (ox_document_clas == clas) {
|
817
|
+
e.type = RawCode;
|
818
|
+
out->w_start(out, &e);
|
819
|
+
dump_gen_doc(obj, depth + 1, out);
|
820
|
+
out->w_end(out, &e);
|
821
|
+
} else if (ox_element_clas == clas) {
|
822
|
+
e.type = RawCode;
|
823
|
+
out->w_start(out, &e);
|
824
|
+
dump_gen_element(obj, depth + 1, out);
|
825
|
+
out->w_end(out, &e);
|
826
|
+
} else { /* Object */
|
827
827
|
#if HAS_IVAR_HELPERS
|
828
|
-
|
829
|
-
|
830
|
-
|
831
|
-
|
832
|
-
|
833
|
-
|
834
|
-
|
835
|
-
|
836
|
-
|
837
|
-
|
838
|
-
|
839
|
-
|
828
|
+
e.type = (Qtrue == rb_obj_is_kind_of(obj, rb_eException)) ? ExceptionCode : ObjectCode;
|
829
|
+
cnt = (int)rb_ivar_count(obj);
|
830
|
+
e.closed = (0 >= cnt);
|
831
|
+
out->w_start(out, &e);
|
832
|
+
if (0 < cnt) {
|
833
|
+
unsigned int od = out->depth;
|
834
|
+
|
835
|
+
out->depth = depth + 1;
|
836
|
+
rb_ivar_foreach(obj, dump_var, (VALUE)out);
|
837
|
+
out->depth = od;
|
838
|
+
out->w_end(out, &e);
|
839
|
+
}
|
840
840
|
#else
|
841
|
-
|
842
|
-
|
843
|
-
|
844
|
-
|
845
|
-
|
846
|
-
|
847
|
-
|
848
|
-
|
849
|
-
|
850
|
-
|
851
|
-
|
852
|
-
|
853
|
-
|
854
|
-
|
855
|
-
|
856
|
-
|
857
|
-
|
858
|
-
|
859
|
-
|
860
|
-
|
861
|
-
|
862
|
-
}
|
841
|
+
volatile VALUE vars = rb_obj_instance_variables(obj);
|
842
|
+
//volatile VALUE vars = rb_funcall2(obj, rb_intern("instance_variables"), 0, 0);
|
843
|
+
|
844
|
+
e.type = (Qtrue == rb_obj_is_kind_of(obj, rb_eException)) ? ExceptionCode : ObjectCode;
|
845
|
+
cnt = (int)RARRAY_LEN(vars);
|
846
|
+
e.closed = (0 >= cnt);
|
847
|
+
out->w_start(out, &e);
|
848
|
+
if (0 < cnt) {
|
849
|
+
const VALUE *np = RARRAY_PTR(vars);
|
850
|
+
ID vid;
|
851
|
+
unsigned int od = out->depth;
|
852
|
+
int i;
|
853
|
+
|
854
|
+
out->depth = depth + 1;
|
855
|
+
for (i = cnt; 0 < i; i--, np++) {
|
856
|
+
vid = rb_to_id(*np);
|
857
|
+
dump_var(vid, rb_ivar_get(obj, vid), out);
|
858
|
+
}
|
859
|
+
out->depth = od;
|
860
|
+
out->w_end(out, &e);
|
861
|
+
}
|
863
862
|
#endif
|
864
|
-
|
865
|
-
|
863
|
+
}
|
864
|
+
break;
|
866
865
|
}
|
867
866
|
case T_REGEXP:
|
868
867
|
{
|
869
|
-
|
870
|
-
|
871
|
-
const char *s = StringValuePtr(rs);
|
868
|
+
volatile VALUE rs = rb_funcall2(obj, ox_inspect_id, 0, 0);
|
869
|
+
const char *s = StringValuePtr(rs);
|
872
870
|
|
873
|
-
|
874
|
-
|
875
|
-
|
876
|
-
int options = rb_reg_options(obj);
|
877
|
-
|
878
|
-
cnt = (int)RREGEXP_SRC_LEN(obj);
|
879
|
-
#endif
|
880
|
-
e.type = RegexpCode;
|
881
|
-
out->w_start(out, &e);
|
871
|
+
cnt = (int)RSTRING_LEN(rs);
|
872
|
+
e.type = RegexpCode;
|
873
|
+
out->w_start(out, &e);
|
882
874
|
#if USE_B64
|
883
|
-
|
884
|
-
|
885
|
-
|
886
|
-
|
887
|
-
|
888
|
-
|
889
|
-
|
890
|
-
|
891
|
-
|
892
|
-
|
875
|
+
if (is_xml_friendly((uchar*)s, cnt)) {
|
876
|
+
/*dump_value(out, "/", 1); */
|
877
|
+
dump_str_value(out, s, cnt);
|
878
|
+
} else {
|
879
|
+
ulong size = b64_size(cnt);
|
880
|
+
char *b64 = ALLOCA_N(char, size + 1);
|
881
|
+
|
882
|
+
to_base64((uchar*)s, cnt, b64);
|
883
|
+
dump_value(out, b64, size);
|
884
|
+
}
|
893
885
|
#else
|
894
886
|
dump_str_value(out, s, cnt);
|
895
887
|
#endif
|
896
|
-
|
897
|
-
|
898
|
-
|
899
|
-
dump_value(out, "m", 1);
|
900
|
-
}
|
901
|
-
if (0 != (ONIG_OPTION_IGNORECASE & options)) {
|
902
|
-
dump_value(out, "i", 1);
|
903
|
-
}
|
904
|
-
if (0 != (ONIG_OPTION_EXTEND & options)) {
|
905
|
-
dump_value(out, "x", 1);
|
906
|
-
}
|
907
|
-
#endif
|
908
|
-
e.indent = -1;
|
909
|
-
out->w_end(out, &e);
|
910
|
-
break;
|
888
|
+
e.indent = -1;
|
889
|
+
out->w_end(out, &e);
|
890
|
+
break;
|
911
891
|
}
|
912
892
|
case T_BIGNUM:
|
913
893
|
{
|
914
|
-
|
915
|
-
|
916
|
-
|
917
|
-
|
918
|
-
|
919
|
-
|
920
|
-
|
921
|
-
|
894
|
+
volatile VALUE rs = rb_big2str(obj, 10);
|
895
|
+
|
896
|
+
e.type = BignumCode;
|
897
|
+
out->w_start(out, &e);
|
898
|
+
dump_value(out, StringValuePtr(rs), RSTRING_LEN(rs));
|
899
|
+
e.indent = -1;
|
900
|
+
out->w_end(out, &e);
|
901
|
+
break;
|
922
902
|
}
|
923
903
|
#ifdef T_COMPLEX
|
924
904
|
case T_COMPLEX:
|
925
|
-
|
926
|
-
|
905
|
+
e.type = ComplexCode;
|
906
|
+
out->w_start(out, &e);
|
927
907
|
#ifdef RCOMPLEX
|
928
|
-
|
929
|
-
|
908
|
+
dump_obj(0, RCOMPLEX(obj)->real, depth + 1, out);
|
909
|
+
dump_obj(0, RCOMPLEX(obj)->imag, depth + 1, out);
|
930
910
|
#else
|
931
|
-
|
932
|
-
|
911
|
+
dump_obj(0, rb_funcall2(obj, rb_intern("real"), 0, 0), depth + 1, out);
|
912
|
+
dump_obj(0, rb_funcall2(obj, rb_intern("imag"), 0, 0), depth + 1, out);
|
933
913
|
#endif
|
934
|
-
|
935
|
-
|
914
|
+
out->w_end(out, &e);
|
915
|
+
break;
|
936
916
|
#endif
|
937
917
|
#ifdef T_RATIONAL
|
938
918
|
case T_RATIONAL:
|
939
|
-
|
940
|
-
|
919
|
+
e.type = RationalCode;
|
920
|
+
out->w_start(out, &e);
|
941
921
|
#ifdef RRATIONAL
|
942
|
-
|
943
|
-
|
922
|
+
dump_obj(0, RRATIONAL(obj)->num, depth + 1, out);
|
923
|
+
dump_obj(0, RRATIONAL(obj)->den, depth + 1, out);
|
944
924
|
#else
|
945
|
-
|
946
|
-
|
925
|
+
dump_obj(0, rb_funcall2(obj, rb_intern("numerator"), 0, 0), depth + 1, out);
|
926
|
+
dump_obj(0, rb_funcall2(obj, rb_intern("denominator"), 0, 0), depth + 1, out);
|
947
927
|
#endif
|
948
|
-
|
949
|
-
|
928
|
+
out->w_end(out, &e);
|
929
|
+
break;
|
950
930
|
#endif
|
951
931
|
case T_CLASS:
|
952
932
|
{
|
953
|
-
|
954
|
-
|
955
|
-
|
956
|
-
|
957
|
-
|
958
|
-
|
933
|
+
e.type = ClassCode;
|
934
|
+
e.clas.str = rb_class2name(obj);
|
935
|
+
e.clas.len = strlen(e.clas.str);
|
936
|
+
e.closed = 1;
|
937
|
+
out->w_start(out, &e);
|
938
|
+
break;
|
959
939
|
}
|
960
940
|
default:
|
961
|
-
|
962
|
-
|
963
|
-
|
964
|
-
|
965
|
-
|
966
|
-
|
967
|
-
|
968
|
-
|
969
|
-
|
941
|
+
if (StrictEffort == out->opts->effort) {
|
942
|
+
rb_raise(rb_eNotImpError, "Failed to dump %s Object (%02x)\n",
|
943
|
+
rb_obj_classname(obj), rb_type(obj));
|
944
|
+
} else {
|
945
|
+
e.type = NilClassCode;
|
946
|
+
e.closed = 1;
|
947
|
+
out->w_start(out, &e);
|
948
|
+
}
|
949
|
+
break;
|
970
950
|
}
|
971
951
|
out->obj = prev_obj;
|
972
952
|
}
|
@@ -974,13 +954,13 @@ dump_obj(ID aid, VALUE obj, int depth, Out out) {
|
|
974
954
|
static int
|
975
955
|
dump_var(ID key, VALUE value, Out out) {
|
976
956
|
if (T_DATA == rb_type(value) && key == ox_mesg_id) {
|
977
|
-
|
978
|
-
|
979
|
-
|
980
|
-
|
981
|
-
|
982
|
-
|
983
|
-
|
957
|
+
/* There is a secret recipe that keeps Exception mesg attributes as a
|
958
|
+
* T_DATA until it is needed. The safe way around this hack is to call
|
959
|
+
* the message() method and use the returned string as the
|
960
|
+
* message. Not pretty but it solves the most common use of this
|
961
|
+
* hack. If there are others they will have to be handled one at a
|
962
|
+
* time.
|
963
|
+
*/
|
984
964
|
value = rb_funcall(out->obj, ox_message_id, 0);
|
985
965
|
}
|
986
966
|
dump_obj(key, value, out->depth, out);
|
@@ -998,80 +978,80 @@ dump_hash(VALUE key, VALUE value, Out out) {
|
|
998
978
|
|
999
979
|
static void
|
1000
980
|
dump_gen_doc(VALUE obj, int depth, Out out) {
|
1001
|
-
VALUE
|
1002
|
-
VALUE
|
981
|
+
volatile VALUE attrs = rb_attr_get(obj, ox_attributes_id);
|
982
|
+
volatile VALUE nodes = rb_attr_get(obj, ox_nodes_id);
|
1003
983
|
|
1004
984
|
if ('\0' == *out->opts->encoding && Qnil != attrs) {
|
1005
|
-
VALUE renc = rb_hash_lookup(attrs, ox_encoding_sym);
|
985
|
+
volatile VALUE renc = rb_hash_lookup(attrs, ox_encoding_sym);
|
1006
986
|
|
1007
|
-
|
1008
|
-
const char
|
987
|
+
if (Qnil != renc) {
|
988
|
+
const char *enc = StringValuePtr(renc);
|
1009
989
|
|
1010
990
|
strncpy(out->opts->encoding, enc, sizeof(out->opts->encoding) - 1);
|
1011
|
-
|
991
|
+
}
|
1012
992
|
}
|
1013
993
|
if (Yes == out->opts->with_xml) {
|
1014
|
-
|
1015
|
-
|
1016
|
-
|
994
|
+
dump_value(out, "<?xml", 5);
|
995
|
+
if (Qnil != attrs) {
|
996
|
+
rb_hash_foreach(attrs, dump_gen_attr, (VALUE)out);
|
1017
997
|
}
|
1018
|
-
|
998
|
+
dump_value(out, "?>", 2);
|
1019
999
|
}
|
1020
1000
|
if (Yes == out->opts->with_instruct) {
|
1021
|
-
|
1022
|
-
|
1023
|
-
|
1024
|
-
|
1025
|
-
|
1001
|
+
if (out->buf < out->cur) {
|
1002
|
+
dump_value(out, "\n<?ox version=\"1.0\" mode=\"generic\"?>", 36);
|
1003
|
+
} else {
|
1004
|
+
dump_value(out, "<?ox version=\"1.0\" mode=\"generic\"?>", 35);
|
1005
|
+
}
|
1026
1006
|
}
|
1027
1007
|
if (Qnil != nodes) {
|
1028
|
-
|
1008
|
+
dump_gen_nodes(nodes, depth, out);
|
1029
1009
|
}
|
1030
1010
|
}
|
1031
1011
|
|
1032
1012
|
static void
|
1033
1013
|
dump_gen_element(VALUE obj, int depth, Out out) {
|
1034
|
-
VALUE
|
1035
|
-
VALUE
|
1036
|
-
VALUE
|
1037
|
-
const char
|
1038
|
-
long
|
1039
|
-
size_t
|
1040
|
-
int
|
1014
|
+
volatile VALUE rname = rb_attr_get(obj, ox_at_value_id);
|
1015
|
+
volatile VALUE attrs = rb_attr_get(obj, ox_attributes_id);
|
1016
|
+
volatile VALUE nodes = rb_attr_get(obj, ox_nodes_id);
|
1017
|
+
const char *name = StringValuePtr(rname);
|
1018
|
+
long nlen = RSTRING_LEN(rname);
|
1019
|
+
size_t size;
|
1020
|
+
int indent;
|
1041
1021
|
|
1042
1022
|
if (0 > out->indent) {
|
1043
|
-
|
1023
|
+
indent = -1;
|
1044
1024
|
} else if (0 == out->indent) {
|
1045
|
-
|
1025
|
+
indent = 0;
|
1046
1026
|
} else {
|
1047
|
-
|
1027
|
+
indent = depth * out->indent;
|
1048
1028
|
}
|
1049
1029
|
size = indent + 4 + nlen;
|
1050
1030
|
if (out->end - out->cur <= (long)size) {
|
1051
|
-
|
1031
|
+
grow(out, size);
|
1052
1032
|
}
|
1053
1033
|
fill_indent(out, indent);
|
1054
1034
|
*out->cur++ = '<';
|
1055
1035
|
fill_value(out, name, nlen);
|
1056
1036
|
if (Qnil != attrs) {
|
1057
|
-
|
1037
|
+
rb_hash_foreach(attrs, dump_gen_attr, (VALUE)out);
|
1058
1038
|
}
|
1059
1039
|
if (Qnil != nodes) {
|
1060
|
-
|
1061
|
-
|
1062
|
-
|
1063
|
-
|
1064
|
-
|
1065
|
-
|
1066
|
-
|
1067
|
-
|
1068
|
-
|
1069
|
-
|
1070
|
-
|
1071
|
-
|
1072
|
-
|
1040
|
+
int do_indent;
|
1041
|
+
|
1042
|
+
*out->cur++ = '>';
|
1043
|
+
do_indent = dump_gen_nodes(nodes, depth, out);
|
1044
|
+
if (out->end - out->cur <= (long)size) {
|
1045
|
+
grow(out, size);
|
1046
|
+
}
|
1047
|
+
if (do_indent) {
|
1048
|
+
fill_indent(out, indent);
|
1049
|
+
}
|
1050
|
+
*out->cur++ = '<';
|
1051
|
+
*out->cur++ = '/';
|
1052
|
+
fill_value(out, name, nlen);
|
1073
1053
|
} else {
|
1074
|
-
|
1054
|
+
*out->cur++ = '/';
|
1075
1055
|
}
|
1076
1056
|
*out->cur++ = '>';
|
1077
1057
|
*out->cur = '\0';
|
@@ -1079,14 +1059,14 @@ dump_gen_element(VALUE obj, int depth, Out out) {
|
|
1079
1059
|
|
1080
1060
|
static void
|
1081
1061
|
dump_gen_instruct(VALUE obj, int depth, Out out) {
|
1082
|
-
VALUE rname = rb_attr_get(obj, ox_at_value_id);
|
1083
|
-
VALUE attrs = rb_attr_get(obj, ox_attributes_id);
|
1084
|
-
VALUE rcontent = rb_attr_get(obj, ox_at_content_id);
|
1085
|
-
const char
|
1086
|
-
const char
|
1087
|
-
long
|
1088
|
-
long
|
1089
|
-
size_t
|
1062
|
+
volatile VALUE rname = rb_attr_get(obj, ox_at_value_id);
|
1063
|
+
volatile VALUE attrs = rb_attr_get(obj, ox_attributes_id);
|
1064
|
+
volatile VALUE rcontent = rb_attr_get(obj, ox_at_content_id);
|
1065
|
+
const char *name = StringValuePtr(rname);
|
1066
|
+
const char *content = 0;
|
1067
|
+
long nlen = RSTRING_LEN(rname);
|
1068
|
+
long clen = 0;
|
1069
|
+
size_t size;
|
1090
1070
|
|
1091
1071
|
if (T_STRING == rb_type(rcontent)) {
|
1092
1072
|
content = StringValuePtr(rcontent);
|
@@ -1096,7 +1076,7 @@ dump_gen_instruct(VALUE obj, int depth, Out out) {
|
|
1096
1076
|
size = 4 + nlen;
|
1097
1077
|
}
|
1098
1078
|
if (out->end - out->cur <= (long)size) {
|
1099
|
-
|
1079
|
+
grow(out, size);
|
1100
1080
|
}
|
1101
1081
|
*out->cur++ = '<';
|
1102
1082
|
*out->cur++ = '?';
|
@@ -1104,7 +1084,7 @@ dump_gen_instruct(VALUE obj, int depth, Out out) {
|
|
1104
1084
|
if (0 != content) {
|
1105
1085
|
fill_value(out, content, clen);
|
1106
1086
|
} else if (Qnil != attrs) {
|
1107
|
-
|
1087
|
+
rb_hash_foreach(attrs, dump_gen_attr, (VALUE)out);
|
1108
1088
|
}
|
1109
1089
|
*out->cur++ = '?';
|
1110
1090
|
*out->cur++ = '>';
|
@@ -1113,37 +1093,37 @@ dump_gen_instruct(VALUE obj, int depth, Out out) {
|
|
1113
1093
|
|
1114
1094
|
static int
|
1115
1095
|
dump_gen_nodes(VALUE obj, int depth, Out out) {
|
1116
|
-
long
|
1117
|
-
int
|
1096
|
+
long cnt = RARRAY_LEN(obj);
|
1097
|
+
int indent_needed = 1;
|
1118
1098
|
|
1119
1099
|
if (0 < cnt) {
|
1120
|
-
|
1121
|
-
|
1122
|
-
|
1100
|
+
const VALUE *np = RARRAY_PTR(obj);
|
1101
|
+
VALUE clas;
|
1102
|
+
int d2 = depth + 1;
|
1123
1103
|
|
1124
1104
|
if (MAX_DEPTH < depth) {
|
1125
1105
|
rb_raise(rb_eSysStackError, "maximum depth exceeded");
|
1126
1106
|
}
|
1127
|
-
|
1128
|
-
|
1129
|
-
|
1130
|
-
|
1107
|
+
for (; 0 < cnt; cnt--, np++) {
|
1108
|
+
clas = rb_obj_class(*np);
|
1109
|
+
if (ox_element_clas == clas) {
|
1110
|
+
dump_gen_element(*np, d2, out);
|
1131
1111
|
} else if (ox_instruct_clas == clas) {
|
1132
|
-
|
1133
|
-
|
1134
|
-
|
1135
|
-
|
1136
|
-
|
1137
|
-
|
1138
|
-
|
1139
|
-
|
1140
|
-
|
1141
|
-
|
1142
|
-
|
1143
|
-
|
1144
|
-
|
1145
|
-
|
1146
|
-
|
1112
|
+
dump_gen_instruct(*np, d2, out);
|
1113
|
+
indent_needed = (1 == cnt) ? 0 : 1;
|
1114
|
+
} else if (rb_cString == clas) {
|
1115
|
+
dump_str_value(out, StringValuePtr(*(VALUE*)np), RSTRING_LEN(*np));
|
1116
|
+
indent_needed = (1 == cnt) ? 0 : 1;
|
1117
|
+
} else if (ox_comment_clas == clas) {
|
1118
|
+
dump_gen_val_node(*np, d2, "<!-- ", 5, " -->", 4, out);
|
1119
|
+
} else if (ox_cdata_clas == clas) {
|
1120
|
+
dump_gen_val_node(*np, d2, "<![CDATA[", 9, "]]>", 3, out);
|
1121
|
+
} else if (ox_doctype_clas == clas) {
|
1122
|
+
dump_gen_val_node(*np, d2, "<!DOCTYPE ", 10, " >", 2, out);
|
1123
|
+
} else {
|
1124
|
+
rb_raise(rb_eTypeError, "Unexpected class, %s, while dumping generic XML\n", rb_class2name(clas));
|
1125
|
+
}
|
1126
|
+
}
|
1147
1127
|
}
|
1148
1128
|
return indent_needed;
|
1149
1129
|
}
|
@@ -1151,8 +1131,8 @@ dump_gen_nodes(VALUE obj, int depth, Out out) {
|
|
1151
1131
|
static int
|
1152
1132
|
dump_gen_attr(VALUE key, VALUE value, Out out) {
|
1153
1133
|
const char *ks;
|
1154
|
-
size_t
|
1155
|
-
size_t
|
1134
|
+
size_t klen;
|
1135
|
+
size_t size;
|
1156
1136
|
|
1157
1137
|
#if HAS_PRIVATE_ENCODING
|
1158
1138
|
// There seems to be a bug in jruby for converting symbols to strings and preserving the encoding. This is a work
|
@@ -1176,7 +1156,7 @@ dump_gen_attr(VALUE key, VALUE value, Out out) {
|
|
1176
1156
|
value = rb_String(value);
|
1177
1157
|
size = 4 + klen + RSTRING_LEN(value);
|
1178
1158
|
if (out->end - out->cur <= (long)size) {
|
1179
|
-
|
1159
|
+
grow(out, size);
|
1180
1160
|
}
|
1181
1161
|
*out->cur++ = ' ';
|
1182
1162
|
fill_value(out, ks, klen);
|
@@ -1190,29 +1170,29 @@ dump_gen_attr(VALUE key, VALUE value, Out out) {
|
|
1190
1170
|
|
1191
1171
|
static void
|
1192
1172
|
dump_gen_val_node(VALUE obj, int depth,
|
1193
|
-
|
1194
|
-
|
1195
|
-
VALUE
|
1196
|
-
const char
|
1197
|
-
size_t
|
1198
|
-
size_t
|
1199
|
-
int
|
1173
|
+
const char *pre, size_t plen,
|
1174
|
+
const char *suf, size_t slen, Out out) {
|
1175
|
+
volatile VALUE v = rb_attr_get(obj, ox_at_value_id);
|
1176
|
+
const char *val;
|
1177
|
+
size_t vlen;
|
1178
|
+
size_t size;
|
1179
|
+
int indent;
|
1200
1180
|
|
1201
1181
|
if (T_STRING != rb_type(v)) {
|
1202
|
-
|
1182
|
+
return;
|
1203
1183
|
}
|
1204
1184
|
val = StringValuePtr(v);
|
1205
1185
|
vlen = RSTRING_LEN(v);
|
1206
1186
|
if (0 > out->indent) {
|
1207
|
-
|
1187
|
+
indent = -1;
|
1208
1188
|
} else if (0 == out->indent) {
|
1209
|
-
|
1189
|
+
indent = 0;
|
1210
1190
|
} else {
|
1211
|
-
|
1191
|
+
indent = depth * out->indent;
|
1212
1192
|
}
|
1213
1193
|
size = indent + plen + slen + vlen;
|
1214
1194
|
if (out->end - out->cur <= (long)size) {
|
1215
|
-
|
1195
|
+
grow(out, size);
|
1216
1196
|
}
|
1217
1197
|
fill_indent(out, indent);
|
1218
1198
|
fill_value(out, pre, plen);
|
@@ -1223,7 +1203,7 @@ dump_gen_val_node(VALUE obj, int depth,
|
|
1223
1203
|
|
1224
1204
|
static void
|
1225
1205
|
dump_obj_to_xml(VALUE obj, Options copts, Out out) {
|
1226
|
-
VALUE
|
1206
|
+
VALUE clas = rb_obj_class(obj);
|
1227
1207
|
|
1228
1208
|
out->w_time = (Yes == copts->xsd_date) ? dump_time_xsd : dump_time_thin;
|
1229
1209
|
out->buf = ALLOC_N(char, 65336);
|
@@ -1234,7 +1214,7 @@ dump_obj_to_xml(VALUE obj, Options copts, Out out) {
|
|
1234
1214
|
out->opts = copts;
|
1235
1215
|
out->obj = obj;
|
1236
1216
|
if (Yes == copts->circular) {
|
1237
|
-
|
1217
|
+
ox_cache8_new(&out->circ_cache);
|
1238
1218
|
}
|
1239
1219
|
out->indent = copts->indent;
|
1240
1220
|
if (ox_document_clas == clas) {
|
@@ -1242,13 +1222,13 @@ dump_obj_to_xml(VALUE obj, Options copts, Out out) {
|
|
1242
1222
|
} else if (ox_element_clas == clas) {
|
1243
1223
|
dump_gen_element(obj, 0, out);
|
1244
1224
|
} else {
|
1245
|
-
|
1246
|
-
|
1247
|
-
|
1225
|
+
out->w_start = dump_start;
|
1226
|
+
out->w_end = dump_end;
|
1227
|
+
dump_first_obj(obj, out);
|
1248
1228
|
}
|
1249
1229
|
dump_value(out, "\n", 1);
|
1250
1230
|
if (Yes == copts->circular) {
|
1251
|
-
|
1231
|
+
ox_cache8_delete(out->circ_cache);
|
1252
1232
|
}
|
1253
1233
|
}
|
1254
1234
|
|
@@ -1263,17 +1243,17 @@ ox_write_obj_to_str(VALUE obj, Options copts) {
|
|
1263
1243
|
void
|
1264
1244
|
ox_write_obj_to_file(VALUE obj, const char *path, Options copts) {
|
1265
1245
|
struct _Out out;
|
1266
|
-
size_t
|
1267
|
-
FILE
|
1246
|
+
size_t size;
|
1247
|
+
FILE *f;
|
1268
1248
|
|
1269
1249
|
dump_obj_to_xml(obj, copts, &out);
|
1270
1250
|
size = out.cur - out.buf;
|
1271
1251
|
if (0 == (f = fopen(path, "w"))) {
|
1272
|
-
|
1252
|
+
rb_raise(rb_eIOError, "%s\n", strerror(errno));
|
1273
1253
|
}
|
1274
1254
|
if (size != fwrite(out.buf, 1, size, f)) {
|
1275
|
-
|
1276
|
-
|
1255
|
+
int err = ferror(f);
|
1256
|
+
rb_raise(rb_eIOError, "Write failed. [%d:%s]\n", err, strerror(err));
|
1277
1257
|
}
|
1278
1258
|
xfree(out.buf);
|
1279
1259
|
fclose(f);
|