ox 1.5.8 → 1.5.9
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.
- data/README.md +11 -3
- data/ext/ox/base64.c +16 -16
- data/ext/ox/base64.h +3 -4
- data/ext/ox/cache.c +18 -8
- data/ext/ox/cache8.c +2 -2
- data/ext/ox/cache8_test.c +1 -1
- data/ext/ox/cache_test.c +3 -3
- data/ext/ox/dump.c +38 -33
- data/ext/ox/extconf.rb +4 -2
- data/ext/ox/gen_load.c +8 -8
- data/ext/ox/obj_load.c +17 -17
- data/ext/ox/ox.c +15 -15
- data/ext/ox/ox.h +16 -16
- data/ext/ox/parse.c +31 -31
- data/ext/ox/sax.c +38 -39
- data/lib/ox/version.rb +1 -1
- metadata +2 -2
data/README.md
CHANGED
@@ -4,6 +4,10 @@ A fast XML parser and Object marshaller as a Ruby gem.
|
|
4
4
|
## <a name="installation">Installation</a>
|
5
5
|
gem install ox
|
6
6
|
|
7
|
+
## <a name="documentation">Documentation</a>
|
8
|
+
|
9
|
+
*Documentation*: http://www.ohler.com/ox
|
10
|
+
|
7
11
|
## <a name="source">Source</a>
|
8
12
|
|
9
13
|
*GitHub* *repo*: https://github.com/ohler55/ox
|
@@ -12,7 +16,7 @@ A fast XML parser and Object marshaller as a Ruby gem.
|
|
12
16
|
|
13
17
|
## <a name="follow">Follow @oxgem on Twitter</a>
|
14
18
|
|
15
|
-
[Follow @
|
19
|
+
[Follow @peterohler on Twitter](http://twitter.com/#!/peterohler) for announcements and news about the Ox gem.
|
16
20
|
|
17
21
|
## <a name="build_status">Build Status</a>
|
18
22
|
|
@@ -30,9 +34,13 @@ A fast XML parser and Object marshaller as a Ruby gem.
|
|
30
34
|
|
31
35
|
## <a name="release">Release Notes</a>
|
32
36
|
|
33
|
-
### Release 1.5.
|
37
|
+
### Release 1.5.9
|
38
|
+
|
39
|
+
- Merged a fix by edanaher that allows special characters in attribute values
|
40
|
+
|
41
|
+
- Changed all comments to old C style to get code to compile with Ruby 2.0.0.
|
34
42
|
|
35
|
-
-
|
43
|
+
- Other changes to time handling for 2.0.0.
|
36
44
|
|
37
45
|
## <a name="description">Description</a>
|
38
46
|
|
data/ext/ox/base64.c
CHANGED
@@ -35,8 +35,8 @@
|
|
35
35
|
|
36
36
|
static char digits[] = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/";
|
37
37
|
|
38
|
-
|
39
|
-
static
|
38
|
+
/* invalid or terminating characters are set to 'X' or \x58 */
|
39
|
+
static uchar s_digits[256] = "\
|
40
40
|
\x58\x58\x58\x58\x58\x58\x58\x58\x58\x58\x58\x58\x58\x58\x58\x58\
|
41
41
|
\x58\x58\x58\x58\x58\x58\x58\x58\x58\x58\x58\x58\x58\x58\x58\x58\
|
42
42
|
\x58\x58\x58\x58\x58\x58\x58\x58\x58\x58\x58\x3E\x58\x58\x58\x3F\
|
@@ -55,20 +55,20 @@ static u_char s_digits[256] = "\
|
|
55
55
|
\x58\x58\x58\x58\x58\x58\x58\x58\x58\x58\x58\x58\x58\x58\x58\x58";
|
56
56
|
|
57
57
|
void
|
58
|
-
to_base64(const
|
59
|
-
const
|
60
|
-
int
|
61
|
-
|
58
|
+
to_base64(const uchar *src, int len, char *b64) {
|
59
|
+
const uchar *end3;
|
60
|
+
int len3 = len % 3;
|
61
|
+
uchar b1, b2, b3;
|
62
62
|
|
63
63
|
end3 = src + (len - len3);
|
64
64
|
while (src < end3) {
|
65
65
|
b1 = *src++;
|
66
66
|
b2 = *src++;
|
67
67
|
b3 = *src++;
|
68
|
-
*b64++ = digits[(
|
69
|
-
*b64++ = digits[(
|
70
|
-
*b64++ = digits[(
|
71
|
-
*b64++ = digits[(
|
68
|
+
*b64++ = digits[(uchar)(b1 >> 2)];
|
69
|
+
*b64++ = digits[(uchar)(((b1 & 0x03) << 4) | (b2 >> 4))];
|
70
|
+
*b64++ = digits[(uchar)(((b2 & 0x0F) << 2) | (b3 >> 6))];
|
71
|
+
*b64++ = digits[(uchar)(b3 & 0x3F)];
|
72
72
|
}
|
73
73
|
if (1 == len3) {
|
74
74
|
b1 = *src++;
|
@@ -108,16 +108,16 @@ b64_orig_size(const char *text) {
|
|
108
108
|
}
|
109
109
|
|
110
110
|
void
|
111
|
-
from_base64(const char *b64,
|
112
|
-
|
111
|
+
from_base64(const char *b64, uchar *str) {
|
112
|
+
uchar b0, b1, b2, b3;
|
113
113
|
|
114
114
|
while (1) {
|
115
|
-
if ('X' == (b0 = s_digits[(
|
116
|
-
if ('X' == (b1 = s_digits[(
|
115
|
+
if ('X' == (b0 = s_digits[(uchar)*b64++])) { break; }
|
116
|
+
if ('X' == (b1 = s_digits[(uchar)*b64++])) { break; }
|
117
117
|
*str++ = (b0 << 2) | ((b1 >> 4) & 0x03);
|
118
|
-
if ('X' == (b2 = s_digits[(
|
118
|
+
if ('X' == (b2 = s_digits[(uchar)*b64++])) { break; }
|
119
119
|
*str++ = (b1 << 4) | ((b2 >> 2) & 0x0F);
|
120
|
-
if ('X' == (b3 = s_digits[(
|
120
|
+
if ('X' == (b3 = s_digits[(uchar)*b64++])) { break; }
|
121
121
|
*str++ = (b2 << 6) | b3;
|
122
122
|
}
|
123
123
|
*str = '\0';
|
data/ext/ox/base64.h
CHANGED
@@ -31,14 +31,13 @@
|
|
31
31
|
#ifndef __BASE64_H__
|
32
32
|
#define __BASE64_H__
|
33
33
|
|
34
|
-
|
35
|
-
|
34
|
+
typedef unsigned char uchar;
|
36
35
|
|
37
36
|
#define b64_size(len) ((len + 2) / 3 * 4)
|
38
37
|
|
39
38
|
extern unsigned long b64_orig_size(const char *text);
|
40
39
|
|
41
|
-
extern void to_base64(const
|
42
|
-
extern void from_base64(const char *b64,
|
40
|
+
extern void to_base64(const uchar *src, int len, char *b64);
|
41
|
+
extern void from_base64(const char *b64, uchar *str);
|
43
42
|
|
44
43
|
#endif /* __BASE64_H__ */
|
data/ext/ox/cache.c
CHANGED
@@ -32,18 +32,28 @@
|
|
32
32
|
#include <errno.h>
|
33
33
|
#include <stdio.h>
|
34
34
|
#include <string.h>
|
35
|
+
#include <strings.h>
|
35
36
|
#include <stdarg.h>
|
36
37
|
|
37
38
|
#include "cache.h"
|
38
39
|
|
39
40
|
struct _Cache {
|
40
|
-
char *key;
|
41
|
+
char *key; /* only set if the node has a value, and it is not an exact match */
|
41
42
|
VALUE value;
|
42
43
|
struct _Cache *slots[16];
|
43
44
|
};
|
44
45
|
|
45
46
|
static void slot_print(Cache cache, unsigned int depth);
|
46
47
|
|
48
|
+
static char* dupstr(const char *s) {
|
49
|
+
size_t len = strlen(s);
|
50
|
+
char *d = ALLOC_N(char, len + 1);
|
51
|
+
|
52
|
+
memcpy(d, s, len);
|
53
|
+
|
54
|
+
return d;
|
55
|
+
}
|
56
|
+
|
47
57
|
void
|
48
58
|
ox_cache_new(Cache *cache) {
|
49
59
|
*cache = ALLOC(struct _Cache);
|
@@ -58,16 +68,16 @@ ox_cache_get(Cache cache, const char *key, VALUE **slot) {
|
|
58
68
|
Cache *cp;
|
59
69
|
|
60
70
|
for (; '\0' != *k; k++) {
|
61
|
-
cp = cache->slots + (unsigned int)(*k >> 4);
|
71
|
+
cp = cache->slots + (unsigned int)(*k >> 4); /* upper 4 bits */
|
62
72
|
if (0 == *cp) {
|
63
73
|
ox_cache_new(cp);
|
64
74
|
}
|
65
75
|
cache = *cp;
|
66
|
-
cp = cache->slots + (unsigned int)(*k & 0x0F);
|
76
|
+
cp = cache->slots + (unsigned int)(*k & 0x0F); /* lower 4 bits */
|
67
77
|
if (0 == *cp) {
|
68
78
|
ox_cache_new(cp);
|
69
79
|
cache = *cp;
|
70
|
-
cache->key = ('\0' == *(k + 1)) ? 0 :
|
80
|
+
cache->key = ('\0' == *(k + 1)) ? 0 : dupstr(key);
|
71
81
|
break;
|
72
82
|
} else {
|
73
83
|
cache = *cp;
|
@@ -78,8 +88,8 @@ ox_cache_get(Cache cache, const char *key, VALUE **slot) {
|
|
78
88
|
break;
|
79
89
|
} else {
|
80
90
|
Cache *cp2 = cp;
|
81
|
-
|
82
|
-
|
91
|
+
|
92
|
+
/* if value was set along with the key then there are no slots filled yet */
|
83
93
|
cp2 = (*cp2)->slots + (*ck >> 4);
|
84
94
|
ox_cache_new(cp2);
|
85
95
|
cp2 = (*cp2)->slots + (*ck & 0x0F);
|
@@ -103,7 +113,7 @@ ox_cache_get(Cache cache, const char *key, VALUE **slot) {
|
|
103
113
|
|
104
114
|
void
|
105
115
|
ox_cache_print(Cache cache) {
|
106
|
-
|
116
|
+
/*printf("-------------------------------------------\n");*/
|
107
117
|
slot_print(cache, 0);
|
108
118
|
}
|
109
119
|
|
@@ -120,7 +130,7 @@ slot_print(Cache c, unsigned int depth) {
|
|
120
130
|
indent[depth] = '\0';
|
121
131
|
for (i = 0, cp = c->slots; i < 16; i++, cp++) {
|
122
132
|
if (0 == *cp) {
|
123
|
-
|
133
|
+
/*printf("%s%02u:\n", indent, i);*/
|
124
134
|
} else {
|
125
135
|
if (0 == (*cp)->key && Qundef == (*cp)->value) {
|
126
136
|
printf("%s%02u:\n", indent, i);
|
data/ext/ox/cache8.c
CHANGED
@@ -75,7 +75,7 @@ ox_cache8_get(Cache8 cache, VALUE key, slot_t **slot) {
|
|
75
75
|
|
76
76
|
void
|
77
77
|
ox_cache8_print(Cache8 cache) {
|
78
|
-
|
78
|
+
/*printf("-------------------------------------------\n"); */
|
79
79
|
slot_print(cache, 0, 0);
|
80
80
|
}
|
81
81
|
|
@@ -88,7 +88,7 @@ slot_print(Cache8 c, VALUE key, unsigned int depth) {
|
|
88
88
|
for (i = 0, cp = c->slots; i < SLOT_CNT; i++, cp++) {
|
89
89
|
if (0 != *cp) {
|
90
90
|
k = (key << BITS) | i;
|
91
|
-
|
91
|
+
/*printf("*** key: 0x%016lx depth: %u i: %u\n", k, depth, i); */
|
92
92
|
if (DEPTH - 1 == depth) {
|
93
93
|
printf("0x%016lx: %4lu\n", k, (unsigned long)*cp);
|
94
94
|
} else {
|
data/ext/ox/cache8_test.c
CHANGED
data/ext/ox/cache_test.c
CHANGED
@@ -52,9 +52,9 @@ ox_cache_test() {
|
|
52
52
|
v = ox_cache_get(c, *d, &slot);
|
53
53
|
if (Qundef == v) {
|
54
54
|
if (0 == slot) {
|
55
|
-
|
55
|
+
/*printf("*** failed to get a slot for %s\n", *d); */
|
56
56
|
} else {
|
57
|
-
|
57
|
+
/*printf("*** added '%s' to cache\n", *d); */
|
58
58
|
v = ID2SYM(rb_intern(*d));
|
59
59
|
*slot = v;
|
60
60
|
}
|
@@ -63,7 +63,7 @@ ox_cache_test() {
|
|
63
63
|
|
64
64
|
printf("*** get on '%s' returned '%s' (%s)\n", *d, StringValuePtr(rs), rb_class2name(rb_obj_class(v)));
|
65
65
|
}
|
66
|
-
|
66
|
+
/*ox_cache_print(c); */
|
67
67
|
}
|
68
68
|
ox_cache_print(c);
|
69
69
|
}
|
data/ext/ox/dump.c
CHANGED
@@ -51,7 +51,7 @@ typedef struct _Element {
|
|
51
51
|
struct _Str clas;
|
52
52
|
struct _Str attr;
|
53
53
|
unsigned long id;
|
54
|
-
int indent;
|
54
|
+
int indent; /* < 0 indicates no \n */
|
55
55
|
int closed;
|
56
56
|
char type;
|
57
57
|
} *Element;
|
@@ -66,7 +66,7 @@ typedef struct _Out {
|
|
66
66
|
Cache8 circ_cache;
|
67
67
|
unsigned long circ_cnt;
|
68
68
|
int indent;
|
69
|
-
int depth;
|
69
|
+
int depth; /* used by dumpHash */
|
70
70
|
Options opts;
|
71
71
|
VALUE obj;
|
72
72
|
} *Out;
|
@@ -97,7 +97,7 @@ static void dump_time_thin(Out out, VALUE obj);
|
|
97
97
|
static void dump_time_xsd(Out out, VALUE obj);
|
98
98
|
static int dump_hash(VALUE key, VALUE value, Out out);
|
99
99
|
|
100
|
-
static int is_xml_friendly(const
|
100
|
+
static int is_xml_friendly(const uchar *str, int len);
|
101
101
|
|
102
102
|
static const char hex_chars[17] = "0123456789abcdef";
|
103
103
|
|
@@ -112,7 +112,7 @@ static char xml_friendly_chars[256] = "\
|
|
112
112
|
11111111111111111111111111111111";
|
113
113
|
|
114
114
|
inline static int
|
115
|
-
is_xml_friendly(const
|
115
|
+
is_xml_friendly(const uchar *str, int len) {
|
116
116
|
for (; 0 < len; str++, len--) {
|
117
117
|
if ('1' != xml_friendly_chars[*str]) {
|
118
118
|
return 0;
|
@@ -122,7 +122,7 @@ is_xml_friendly(const u_char *str, int len) {
|
|
122
122
|
}
|
123
123
|
|
124
124
|
inline static size_t
|
125
|
-
xml_str_len(const
|
125
|
+
xml_str_len(const uchar *str, size_t len) {
|
126
126
|
size_t size = 0;
|
127
127
|
|
128
128
|
for (; 0 < len; str++, len--) {
|
@@ -132,8 +132,8 @@ xml_str_len(const u_char *str, size_t len) {
|
|
132
132
|
}
|
133
133
|
|
134
134
|
inline static void
|
135
|
-
dump_hex(
|
136
|
-
|
135
|
+
dump_hex(uchar c, Out out) {
|
136
|
+
uchar d = (c >> 4) & 0x0F;
|
137
137
|
|
138
138
|
*out->cur++ = hex_chars[d];
|
139
139
|
d = c & 0x0F;
|
@@ -152,12 +152,12 @@ obj_class_code(VALUE obj) {
|
|
152
152
|
case T_FALSE: return FalseClassCode;
|
153
153
|
case T_FIXNUM: return FixnumCode;
|
154
154
|
case T_FLOAT: return FloatCode;
|
155
|
-
case T_STRING: return (is_xml_friendly((
|
155
|
+
case T_STRING: return (is_xml_friendly((uchar*)StringValuePtr(obj), (int)RSTRING_LEN(obj))) ? StringCode : String64Code;
|
156
156
|
case T_SYMBOL:
|
157
157
|
{
|
158
158
|
const char *sym = rb_id2name(SYM2ID(obj));
|
159
159
|
|
160
|
-
return (is_xml_friendly((
|
160
|
+
return (is_xml_friendly((uchar*)sym, (int)strlen(sym))) ? SymbolCode : Symbol64Code;
|
161
161
|
}
|
162
162
|
case T_DATA: return (rb_cTime == clas) ? TimeCode : ((ox_date_class == clas) ? DateCode : 0);
|
163
163
|
case T_STRUCT: return (rb_cRange == clas) ? RangeCode : StructCode;
|
@@ -258,7 +258,7 @@ grow(Out out, size_t len) {
|
|
258
258
|
if (size <= len * 2 + pos) {
|
259
259
|
size += len;
|
260
260
|
}
|
261
|
-
REALLOC_N(out->buf, char, size + 10);
|
261
|
+
REALLOC_N(out->buf, char, size + 10); /* 10 extra for terminator character plus extra (paranoid) */
|
262
262
|
out->end = out->buf + size;
|
263
263
|
out->cur = out->buf + pos;
|
264
264
|
}
|
@@ -267,14 +267,14 @@ static void
|
|
267
267
|
dump_start(Out out, Element e) {
|
268
268
|
size_t size = e->indent + 4;
|
269
269
|
|
270
|
-
if (0 < e->attr.len) {
|
270
|
+
if (0 < e->attr.len) { /* a="attr" */
|
271
271
|
size += e->attr.len + 5;
|
272
272
|
}
|
273
|
-
if (0 < e->clas.len) {
|
273
|
+
if (0 < e->clas.len) { /* c="class" */
|
274
274
|
size += e->clas.len + 5;
|
275
275
|
}
|
276
|
-
if (0 < e->id) {
|
277
|
-
size += 24;
|
276
|
+
if (0 < e->id) { /* i="id" */
|
277
|
+
size += 24; /* over estimate, 19 digits */
|
278
278
|
}
|
279
279
|
if (out->end - out->cur <= (long)size) {
|
280
280
|
grow(out, size);
|
@@ -337,13 +337,13 @@ dump_value(Out out, const char *value, size_t size) {
|
|
337
337
|
|
338
338
|
inline static void
|
339
339
|
dump_str_value(Out out, const char *value, size_t size) {
|
340
|
-
size_t xsize = xml_str_len((const
|
340
|
+
size_t xsize = xml_str_len((const uchar*)value, size);
|
341
341
|
|
342
342
|
if (out->end - out->cur <= (long)xsize) {
|
343
343
|
grow(out, xsize);
|
344
344
|
}
|
345
345
|
for (; '\0' != *value; value++) {
|
346
|
-
if ('1' == xml_friendly_chars[(
|
346
|
+
if ('1' == xml_friendly_chars[(uchar)*value]) {
|
347
347
|
*out->cur++ = *value;
|
348
348
|
} else {
|
349
349
|
*out->cur++ = '&';
|
@@ -501,8 +501,9 @@ dump_time_xsd(Out out, VALUE obj) {
|
|
501
501
|
if (out->end - out->cur <= 33) {
|
502
502
|
grow(out, 33);
|
503
503
|
}
|
504
|
-
|
504
|
+
/* 2010-07-09T10:47:45.895826+09:00 */
|
505
505
|
tm = localtime(&sec);
|
506
|
+
#if HAS_TM_GMTOFF
|
506
507
|
if (0 > tm->tm_gmtoff) {
|
507
508
|
tzsign = '-';
|
508
509
|
tzhour = (int)(tm->tm_gmtoff / -3600);
|
@@ -511,7 +512,11 @@ dump_time_xsd(Out out, VALUE obj) {
|
|
511
512
|
tzhour = (int)(tm->tm_gmtoff / 3600);
|
512
513
|
tzmin = (int)(tm->tm_gmtoff / 60) - (tzhour * 60);
|
513
514
|
}
|
514
|
-
|
515
|
+
#else
|
516
|
+
tzhour = 0;
|
517
|
+
tzmin = 0;
|
518
|
+
#endif
|
519
|
+
/* TBD replace with more efficient printer */
|
515
520
|
out->cur += sprintf(out->cur, "%04d-%02d-%02dT%02d:%02d:%02d.%06ld%c%02d:%02d",
|
516
521
|
tm->tm_year + 1900, tm->tm_mon + 1, tm->tm_mday,
|
517
522
|
tm->tm_hour, tm->tm_min, tm->tm_sec, nsec / 1000,
|
@@ -555,7 +560,7 @@ dump_obj(ID aid, VALUE obj, unsigned int depth, Out out) {
|
|
555
560
|
|
556
561
|
out->obj = obj;
|
557
562
|
if (0 == aid) {
|
558
|
-
|
563
|
+
/*e.attr.str = 0; */
|
559
564
|
e.attr.len = 0;
|
560
565
|
} else {
|
561
566
|
e.attr.str = rb_id2name(aid);
|
@@ -635,7 +640,7 @@ dump_obj(ID aid, VALUE obj, unsigned int depth, Out out) {
|
|
635
640
|
break;
|
636
641
|
case T_FLOAT:
|
637
642
|
e.type = FloatCode;
|
638
|
-
cnt = sprintf(value_buf, "%0.16g", rb_num2dbl(obj));
|
643
|
+
cnt = sprintf(value_buf, "%0.16g", rb_num2dbl(obj)); /* used sprintf due to bug in snprintf */
|
639
644
|
out->w_start(out, &e);
|
640
645
|
dump_value(out, value_buf, cnt);
|
641
646
|
e.indent = -1;
|
@@ -651,7 +656,7 @@ dump_obj(ID aid, VALUE obj, unsigned int depth, Out out) {
|
|
651
656
|
str = StringValuePtr(obj);
|
652
657
|
cnt = (int)RSTRING_LEN(obj);
|
653
658
|
#if USE_B64
|
654
|
-
if (is_xml_friendly((
|
659
|
+
if (is_xml_friendly((uchar*)str, cnt)) {
|
655
660
|
e.type = StringCode;
|
656
661
|
out->w_start(out, &e);
|
657
662
|
dump_str_value(out, str, cnt);
|
@@ -662,7 +667,7 @@ dump_obj(ID aid, VALUE obj, unsigned int depth, Out out) {
|
|
662
667
|
char *b64 = ALLOCA_N(char, size + 1);
|
663
668
|
|
664
669
|
e.type = String64Code;
|
665
|
-
to_base64((
|
670
|
+
to_base64((uchar*)str, cnt, b64);
|
666
671
|
out->w_start(out, &e);
|
667
672
|
dump_value(out, b64, size);
|
668
673
|
e.indent = -1;
|
@@ -683,7 +688,7 @@ dump_obj(ID aid, VALUE obj, unsigned int depth, Out out) {
|
|
683
688
|
|
684
689
|
cnt = (int)strlen(sym);
|
685
690
|
#if USE_B64
|
686
|
-
if (is_xml_friendly((
|
691
|
+
if (is_xml_friendly((uchar*)sym, cnt)) {
|
687
692
|
e.type = SymbolCode;
|
688
693
|
out->w_start(out, &e);
|
689
694
|
dump_str_value(out, sym, cnt);
|
@@ -694,7 +699,7 @@ dump_obj(ID aid, VALUE obj, unsigned int depth, Out out) {
|
|
694
699
|
char *b64 = ALLOCA_N(char, size + 1);
|
695
700
|
|
696
701
|
e.type = Symbol64Code;
|
697
|
-
to_base64((
|
702
|
+
to_base64((uchar*)sym, cnt, b64);
|
698
703
|
out->w_start(out, &e);
|
699
704
|
dump_value(out, b64, size);
|
700
705
|
e.indent = -1;
|
@@ -805,7 +810,7 @@ dump_obj(ID aid, VALUE obj, unsigned int depth, Out out) {
|
|
805
810
|
out->w_start(out, &e);
|
806
811
|
dump_gen_element(obj, depth + 1, out);
|
807
812
|
out->w_end(out, &e);
|
808
|
-
} else {
|
813
|
+
} else { /* Object */
|
809
814
|
#if HAS_IVAR_HELPERS
|
810
815
|
e.type = (Qtrue == rb_obj_is_kind_of(obj, rb_eException)) ? ExceptionCode : ObjectCode;
|
811
816
|
cnt = (int)rb_ivar_count(obj);
|
@@ -820,10 +825,10 @@ dump_obj(ID aid, VALUE obj, unsigned int depth, Out out) {
|
|
820
825
|
out->w_end(out, &e);
|
821
826
|
}
|
822
827
|
#else
|
823
|
-
|
824
|
-
|
828
|
+
/*VALUE vars = rb_obj_instance_variables(obj); */
|
829
|
+
/*#else */
|
825
830
|
VALUE vars = rb_funcall2(obj, rb_intern("instance_variables"), 0, 0);
|
826
|
-
|
831
|
+
/*#endif */
|
827
832
|
e.type = (Qtrue == rb_obj_is_kind_of(obj, rb_eException)) ? ExceptionCode : ObjectCode;
|
828
833
|
cnt = (int)RARRAY_LEN(vars);
|
829
834
|
e.closed = (0 >= cnt);
|
@@ -862,14 +867,14 @@ dump_obj(ID aid, VALUE obj, unsigned int depth, Out out) {
|
|
862
867
|
e.type = RegexpCode;
|
863
868
|
out->w_start(out, &e);
|
864
869
|
#if USE_B64
|
865
|
-
if (is_xml_friendly((
|
866
|
-
|
870
|
+
if (is_xml_friendly((uchar*)s, cnt)) {
|
871
|
+
/*dump_value(out, "/", 1); */
|
867
872
|
dump_str_value(out, s, cnt);
|
868
873
|
} else {
|
869
874
|
ulong size = b64_size(cnt);
|
870
875
|
char *b64 = ALLOCA_N(char, size + 1);
|
871
876
|
|
872
|
-
to_base64((
|
877
|
+
to_base64((uchar*)s, cnt, b64);
|
873
878
|
dump_value(out, b64, size);
|
874
879
|
}
|
875
880
|
#else
|
@@ -1103,7 +1108,7 @@ dump_gen_attr(VALUE key, VALUE value, Out out) {
|
|
1103
1108
|
fill_value(out, ks, klen);
|
1104
1109
|
*out->cur++ = '=';
|
1105
1110
|
*out->cur++ = '"';
|
1106
|
-
|
1111
|
+
dump_str_value(out, StringValuePtr(value), RSTRING_LEN(value));
|
1107
1112
|
*out->cur++ = '"';
|
1108
1113
|
|
1109
1114
|
return ST_CONTINUE;
|
@@ -1148,7 +1153,7 @@ dump_obj_to_xml(VALUE obj, Options copts, Out out) {
|
|
1148
1153
|
|
1149
1154
|
out->w_time = (Yes == copts->xsd_date) ? dump_time_xsd : dump_time_thin;
|
1150
1155
|
out->buf = ALLOC_N(char, 65336);
|
1151
|
-
out->end = out->buf + 65325;
|
1156
|
+
out->end = out->buf + 65325; /* 10 less than end plus extra for possible errors */
|
1152
1157
|
out->cur = out->buf;
|
1153
1158
|
out->circ_cache = 0;
|
1154
1159
|
out->circ_cnt = 0;
|