ox 2.14.14 → 2.14.17
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +4 -4
- data/CHANGELOG.md +18 -0
- data/README.md +1 -1
- data/ext/ox/attr.h +33 -39
- data/ext/ox/base64.c +48 -42
- data/ext/ox/base64.h +4 -4
- data/ext/ox/buf.h +80 -86
- data/ext/ox/builder.c +377 -456
- data/ext/ox/cache.c +2 -2
- data/ext/ox/cache8.c +37 -40
- data/ext/ox/cache8.h +7 -7
- data/ext/ox/dump.c +811 -889
- data/ext/ox/err.c +16 -13
- data/ext/ox/err.h +11 -12
- data/ext/ox/extconf.rb +5 -10
- data/ext/ox/gen_load.c +135 -139
- data/ext/ox/hash_load.c +130 -148
- data/ext/ox/helper.h +32 -39
- data/ext/ox/intern.c +1 -2
- data/ext/ox/obj_load.c +586 -662
- data/ext/ox/ox.c +93 -132
- data/ext/ox/ox.h +5 -10
- data/ext/ox/parse.c +836 -874
- data/ext/ox/sax.c +56 -31
- data/ext/ox/sax.h +2 -2
- data/ext/ox/sax_as.c +78 -102
- data/ext/ox/sax_buf.c +85 -94
- data/ext/ox/sax_buf.h +101 -120
- data/ext/ox/sax_hint.c +175 -184
- data/ext/ox/sax_hint.h +19 -19
- data/ext/ox/sax_stack.h +59 -45
- data/ext/ox/slotcache.c +3 -3
- data/ext/ox/slotcache.h +4 -4
- data/ext/ox/special.c +320 -327
- data/ext/ox/special.h +2 -2
- data/ext/ox/type.h +19 -19
- data/lib/ox/bag.rb +13 -9
- data/lib/ox/cdata.rb +0 -2
- data/lib/ox/comment.rb +0 -2
- data/lib/ox/doctype.rb +0 -2
- data/lib/ox/document.rb +3 -5
- data/lib/ox/element.rb +41 -26
- data/lib/ox/error.rb +0 -3
- data/lib/ox/hasattrs.rb +7 -8
- data/lib/ox/instruct.rb +4 -6
- data/lib/ox/node.rb +3 -4
- data/lib/ox/raw.rb +0 -2
- data/lib/ox/sax.rb +20 -36
- data/lib/ox/version.rb +1 -2
- data/lib/ox/xmlrpc_adapter.rb +5 -6
- data/lib/ox.rb +15 -16
- metadata +27 -6
data/ext/ox/sax.c
CHANGED
@@ -55,7 +55,7 @@ static char read_text(SaxDrive dr);
|
|
55
55
|
static char read_jump(SaxDrive dr, const char *pat);
|
56
56
|
static char read_attrs(SaxDrive dr, char c, char termc, char term2, int is_xml, int eq_req, Hint h);
|
57
57
|
static char read_name_token(SaxDrive dr);
|
58
|
-
static char read_quoted_value(SaxDrive dr);
|
58
|
+
static char read_quoted_value(SaxDrive dr, bool inst);
|
59
59
|
|
60
60
|
static void hint_clear_empty(SaxDrive dr);
|
61
61
|
static Nv hint_try_close(SaxDrive dr, const char *name);
|
@@ -469,7 +469,7 @@ DONE:
|
|
469
469
|
Nv sp;
|
470
470
|
|
471
471
|
for (sp = dr->stack.tail - 1; dr->stack.head <= sp; sp--) {
|
472
|
-
snprintf(msg, sizeof(msg) - 1, "%selement '%s' not closed", EL_MISMATCH, sp
|
472
|
+
snprintf(msg, sizeof(msg) - 1, "%selement '%s' not closed", EL_MISMATCH, nv_name(sp));
|
473
473
|
ox_sax_drive_error_at(dr, msg, dr->buf.pos, dr->buf.line, dr->buf.col);
|
474
474
|
end_element_cb(dr, sp->val, dr->buf.pos, dr->buf.line, dr->buf.col, sp->hint);
|
475
475
|
}
|
@@ -761,17 +761,19 @@ CB:
|
|
761
761
|
* code.
|
762
762
|
*/
|
763
763
|
static char read_element_start(SaxDrive dr) {
|
764
|
-
const char *ename =
|
764
|
+
const char *ename = NULL;
|
765
|
+
char ebuf[128];
|
765
766
|
size_t nlen;
|
766
|
-
volatile VALUE name
|
767
|
+
volatile VALUE name = Qnil;
|
767
768
|
char c;
|
768
|
-
int closed;
|
769
769
|
long pos = (long)(dr->buf.pos);
|
770
770
|
long line = (long)(dr->buf.line);
|
771
771
|
long col = (long)(dr->buf.col);
|
772
772
|
Hint h = NULL;
|
773
773
|
int stackless = 0;
|
774
774
|
Nv parent = stack_peek(&dr->stack);
|
775
|
+
bool closed;
|
776
|
+
bool efree = false;
|
775
777
|
|
776
778
|
if ('\0' == (c = read_name_token(dr))) {
|
777
779
|
return '\0';
|
@@ -827,7 +829,7 @@ static char read_element_start(SaxDrive dr) {
|
|
827
829
|
if (0 != top_nv) {
|
828
830
|
char msg[256];
|
829
831
|
|
830
|
-
if (!h->nest && NestOverlay != h->overlay &&
|
832
|
+
if (!h->nest && NestOverlay != h->overlay && nv_same_name(top_nv, h->name, true)) {
|
831
833
|
snprintf(msg,
|
832
834
|
sizeof(msg) - 1,
|
833
835
|
"%s%s can not be nested in a %s document, closing previous.",
|
@@ -844,7 +846,7 @@ static char read_element_start(SaxDrive dr) {
|
|
844
846
|
int ok = 0;
|
845
847
|
|
846
848
|
for (p = h->parents; 0 != *p; p++) {
|
847
|
-
if (
|
849
|
+
if (nv_same_name(top_nv, *p, true)) {
|
848
850
|
ok = 1;
|
849
851
|
break;
|
850
852
|
}
|
@@ -855,7 +857,7 @@ static char read_element_start(SaxDrive dr) {
|
|
855
857
|
"%s%s can not be a child of a %s in a %s document.",
|
856
858
|
INV_ELEMENT,
|
857
859
|
h->name,
|
858
|
-
top_nv
|
860
|
+
nv_name(top_nv),
|
859
861
|
dr->options.hints->name);
|
860
862
|
ox_sax_drive_error(dr, msg);
|
861
863
|
}
|
@@ -864,6 +866,16 @@ static char read_element_start(SaxDrive dr) {
|
|
864
866
|
}
|
865
867
|
}
|
866
868
|
name = str2sym(dr, dr->buf.str, nlen, &ename);
|
869
|
+
if (NULL == ename) {
|
870
|
+
if (sizeof(ebuf) <= nlen) {
|
871
|
+
ename = ox_strndup(dr->buf.str, nlen);
|
872
|
+
efree = true;
|
873
|
+
} else {
|
874
|
+
memcpy(ebuf, dr->buf.str, nlen);
|
875
|
+
ebuf[nlen] = '\0';
|
876
|
+
ename = ebuf;
|
877
|
+
}
|
878
|
+
}
|
867
879
|
if (dr->has_start_element && 0 >= dr->blocked &&
|
868
880
|
(NULL == h || ActiveOverlay == h->overlay || NestOverlay == h->overlay)) {
|
869
881
|
VALUE args[1];
|
@@ -875,9 +887,9 @@ static char read_element_start(SaxDrive dr) {
|
|
875
887
|
rb_funcall2(dr->handler, ox_start_element_id, 1, args);
|
876
888
|
}
|
877
889
|
if ('/' == c) {
|
878
|
-
closed =
|
890
|
+
closed = true;
|
879
891
|
} else if ('>' == c) {
|
880
|
-
closed =
|
892
|
+
closed = false;
|
881
893
|
} else {
|
882
894
|
buf_protect(&dr->buf);
|
883
895
|
c = read_attrs(dr, c, '/', '>', 0, 0, h);
|
@@ -906,11 +918,14 @@ static char read_element_start(SaxDrive dr) {
|
|
906
918
|
} else {
|
907
919
|
stack_push(&dr->stack, ename, nlen, name, h);
|
908
920
|
}
|
921
|
+
if (efree) {
|
922
|
+
free((char *)ename);
|
923
|
+
}
|
909
924
|
if ('>' != c) {
|
910
925
|
ox_sax_drive_error(dr, WRONG_CHAR "element not closed");
|
911
926
|
return c;
|
912
927
|
}
|
913
|
-
dr->buf.str =
|
928
|
+
dr->buf.str = NULL;
|
914
929
|
|
915
930
|
return buf_get(&dr->buf);
|
916
931
|
}
|
@@ -919,7 +934,7 @@ static Nv stack_rev_find(SaxDrive dr, const char *name) {
|
|
919
934
|
Nv nv;
|
920
935
|
|
921
936
|
for (nv = dr->stack.tail - 1; dr->stack.head <= nv; nv--) {
|
922
|
-
if (
|
937
|
+
if (nv_same_name(nv, name, dr->options.smart)) {
|
923
938
|
return nv;
|
924
939
|
}
|
925
940
|
}
|
@@ -944,7 +959,7 @@ static char read_element_end(SaxDrive dr) {
|
|
944
959
|
// c should be > and current is one past so read another char
|
945
960
|
c = buf_get(&dr->buf);
|
946
961
|
nv = stack_peek(&dr->stack);
|
947
|
-
if (0 != nv &&
|
962
|
+
if (0 != nv && nv_same_name(nv, dr->buf.str, dr->options.smart)) {
|
948
963
|
name = nv->val;
|
949
964
|
h = nv->hint;
|
950
965
|
stack_pop(&dr->stack);
|
@@ -997,7 +1012,7 @@ static char read_element_end(SaxDrive dr) {
|
|
997
1012
|
"%selement '%s' close does not match '%s' open",
|
998
1013
|
EL_MISMATCH,
|
999
1014
|
dr->buf.str,
|
1000
|
-
nv
|
1015
|
+
nv_name(nv));
|
1001
1016
|
ox_sax_drive_error_at(dr, msg, pos, line, col);
|
1002
1017
|
for (nv = stack_pop(&dr->stack); match < nv; nv = stack_pop(&dr->stack)) {
|
1003
1018
|
end_element_cb(dr, nv->val, pos, line, col, nv->hint);
|
@@ -1204,6 +1219,7 @@ static char read_attrs(SaxDrive dr, char c, char termc, char term2, int is_xml,
|
|
1204
1219
|
c = buf_next_non_white(&dr->buf);
|
1205
1220
|
}
|
1206
1221
|
if ('=' != c) {
|
1222
|
+
// TBD allow in smart mode
|
1207
1223
|
if (eq_req) {
|
1208
1224
|
dr->err = 1;
|
1209
1225
|
return c;
|
@@ -1215,7 +1231,7 @@ static char read_attrs(SaxDrive dr, char c, char termc, char term2, int is_xml,
|
|
1215
1231
|
pos = dr->buf.pos + 1;
|
1216
1232
|
line = dr->buf.line;
|
1217
1233
|
col = dr->buf.col + 1;
|
1218
|
-
c = read_quoted_value(dr);
|
1234
|
+
c = read_quoted_value(dr, '?' == termc);
|
1219
1235
|
attr_value = dr->buf.str;
|
1220
1236
|
|
1221
1237
|
if (is_encoding) {
|
@@ -1282,10 +1298,11 @@ static char read_name_token(SaxDrive dr) {
|
|
1282
1298
|
return '\0';
|
1283
1299
|
}
|
1284
1300
|
|
1285
|
-
/* The character after the quote or if there is no quote, the character after
|
1286
|
-
*
|
1301
|
+
/* The character after the quote or if there is no quote, the character after
|
1302
|
+
* the word is returned. dr->buf.tail is one past that. dr->buf.str will point
|
1303
|
+
* to the token which will be '\0' terminated.
|
1287
1304
|
*/
|
1288
|
-
static char read_quoted_value(SaxDrive dr) {
|
1305
|
+
static char read_quoted_value(SaxDrive dr, bool inst) {
|
1289
1306
|
char c;
|
1290
1307
|
|
1291
1308
|
c = buf_get(&dr->buf);
|
@@ -1309,19 +1326,27 @@ static char read_quoted_value(SaxDrive dr) {
|
|
1309
1326
|
}
|
1310
1327
|
// not quoted, look for something that terminates the string
|
1311
1328
|
dr->buf.str = dr->buf.tail - 1;
|
1312
|
-
|
1329
|
+
// TBD if smart or html then no error
|
1330
|
+
if (!(dr->options.smart && ox_hints_html() != dr->options.hints)) {
|
1331
|
+
ox_sax_drive_error(dr, WRONG_CHAR "attribute value not in quotes");
|
1332
|
+
}
|
1313
1333
|
while ('\0' != (c = buf_get(&dr->buf))) {
|
1314
1334
|
switch (c) {
|
1315
1335
|
case ' ':
|
1316
1336
|
// case '/':
|
1317
1337
|
case '>':
|
1318
|
-
case '?': // for instructions
|
1319
1338
|
case '\t':
|
1320
1339
|
case '\n':
|
1321
1340
|
case '\r':
|
1322
1341
|
*(dr->buf.tail - 1) = '\0'; /* terminate value */
|
1323
1342
|
// dr->buf.tail is in the correct position, one after the word terminator
|
1324
1343
|
return c;
|
1344
|
+
case '?': // for instructions
|
1345
|
+
if (inst) {
|
1346
|
+
*(dr->buf.tail - 1) = '\0'; /* terminate value */
|
1347
|
+
return c;
|
1348
|
+
}
|
1349
|
+
break;
|
1325
1350
|
default: break;
|
1326
1351
|
}
|
1327
1352
|
}
|
@@ -1465,18 +1490,18 @@ int ox_sax_collapse_special(SaxDrive dr, char *str, long pos, long line, long co
|
|
1465
1490
|
break;
|
1466
1491
|
}
|
1467
1492
|
case '\r':
|
1468
|
-
|
1493
|
+
s++;
|
1469
1494
|
if ('\n' == *s) {
|
1470
|
-
|
1471
|
-
|
1472
|
-
|
1473
|
-
|
1495
|
+
continue;
|
1496
|
+
}
|
1497
|
+
line++;
|
1498
|
+
col = 1;
|
1474
1499
|
*b++ = '\n';
|
1475
|
-
|
1476
|
-
|
1477
|
-
|
1478
|
-
|
1479
|
-
|
1500
|
+
break;
|
1501
|
+
case '\n':
|
1502
|
+
line++;
|
1503
|
+
col = 0;
|
1504
|
+
// fall through
|
1480
1505
|
default:
|
1481
1506
|
col++;
|
1482
1507
|
*b++ = *s++;
|
@@ -1512,7 +1537,7 @@ static Nv hint_try_close(SaxDrive dr, const char *name) {
|
|
1512
1537
|
return 0;
|
1513
1538
|
}
|
1514
1539
|
for (nv = stack_peek(&dr->stack); 0 != nv; nv = stack_peek(&dr->stack)) {
|
1515
|
-
if (
|
1540
|
+
if (nv_same_name(nv, name, true)) {
|
1516
1541
|
stack_pop(&dr->stack);
|
1517
1542
|
return nv;
|
1518
1543
|
}
|
data/ext/ox/sax.h
CHANGED
@@ -20,7 +20,7 @@ typedef struct _saxOptions {
|
|
20
20
|
SkipMode skip;
|
21
21
|
char strip_ns[64];
|
22
22
|
Hints hints;
|
23
|
-
} *
|
23
|
+
} *SaxOptions;
|
24
24
|
|
25
25
|
typedef struct _saxDrive {
|
26
26
|
struct _buf buf;
|
@@ -52,7 +52,7 @@ typedef struct _saxDrive {
|
|
52
52
|
bool has_start_element;
|
53
53
|
bool has_end_element;
|
54
54
|
|
55
|
-
} *
|
55
|
+
} *SaxDrive;
|
56
56
|
|
57
57
|
extern void ox_collapse_return(char *str);
|
58
58
|
extern void ox_sax_parse(VALUE handler, VALUE io, SaxOptions options);
|
data/ext/ox/sax_as.c
CHANGED
@@ -3,27 +3,26 @@
|
|
3
3
|
* All rights reserved.
|
4
4
|
*/
|
5
5
|
|
6
|
-
#include <stdlib.h>
|
7
6
|
#include <errno.h>
|
8
7
|
#include <stdio.h>
|
8
|
+
#include <stdlib.h>
|
9
9
|
#include <strings.h>
|
10
10
|
#include <sys/types.h>
|
11
11
|
#if HAVE_SYS_UIO_H
|
12
12
|
#include <sys/uio.h>
|
13
13
|
#endif
|
14
|
-
#include <unistd.h>
|
15
14
|
#include <time.h>
|
15
|
+
#include <unistd.h>
|
16
16
|
|
17
|
+
#include "ox.h"
|
17
18
|
#include "ruby.h"
|
18
19
|
#include "ruby/version.h"
|
19
|
-
#include "ox.h"
|
20
20
|
#include "sax.h"
|
21
21
|
|
22
|
-
static VALUE
|
23
|
-
|
24
|
-
long
|
25
|
-
|
26
|
-
const char *dot = 0;
|
22
|
+
static VALUE parse_double_time(const char *text) {
|
23
|
+
long v = 0;
|
24
|
+
long v2 = 0;
|
25
|
+
const char *dot = 0;
|
27
26
|
char c;
|
28
27
|
|
29
28
|
for (; '.' != *text; text++) {
|
@@ -44,101 +43,86 @@ parse_double_time(const char *text) {
|
|
44
43
|
for (; text - dot <= 9; text++) {
|
45
44
|
v2 *= 10;
|
46
45
|
}
|
47
|
-
#if HAVE_RB_TIME_NANO_NEW
|
48
46
|
return rb_time_nano_new(v, v2);
|
49
|
-
#else
|
50
|
-
return rb_time_new(v, v2 / 1000);
|
51
|
-
#endif
|
52
47
|
}
|
53
48
|
|
54
49
|
typedef struct _tp {
|
55
|
-
int
|
56
|
-
char
|
57
|
-
char
|
50
|
+
int cnt;
|
51
|
+
char end;
|
52
|
+
char alt;
|
58
53
|
} *Tp;
|
59
54
|
|
60
|
-
static VALUE
|
61
|
-
|
62
|
-
long
|
63
|
-
long
|
64
|
-
|
65
|
-
|
66
|
-
|
67
|
-
|
68
|
-
|
69
|
-
|
70
|
-
|
71
|
-
|
72
|
-
|
73
|
-
|
74
|
-
|
75
|
-
|
76
|
-
|
77
|
-
|
78
|
-
struct tm tm;
|
55
|
+
static VALUE parse_xsd_time(const char *text) {
|
56
|
+
long cargs[10];
|
57
|
+
long *cp = cargs;
|
58
|
+
long v;
|
59
|
+
int i;
|
60
|
+
char c = '\0';
|
61
|
+
struct _tp tpa[10] = {{4, '-', '-'},
|
62
|
+
{2, '-', '-'},
|
63
|
+
{2, 'T', ' '},
|
64
|
+
{2, ':', ':'},
|
65
|
+
{2, ':', ':'},
|
66
|
+
{2, '.', '.'},
|
67
|
+
{9, '+', '-'},
|
68
|
+
{2, ':', ':'},
|
69
|
+
{2, '\0', '\0'},
|
70
|
+
{0, '\0', '\0'}};
|
71
|
+
Tp tp = tpa;
|
72
|
+
struct tm tm;
|
79
73
|
|
80
74
|
memset(cargs, 0, sizeof(cargs));
|
81
75
|
for (; 0 != tp->cnt; tp++) {
|
82
|
-
for (i = tp->cnt, v = 0; 0 < i
|
76
|
+
for (i = tp->cnt, v = 0; 0 < i; text++, i--) {
|
83
77
|
c = *text;
|
84
78
|
if (c < '0' || '9' < c) {
|
85
79
|
if ('\0' == c || tp->end == c || tp->alt == c) {
|
86
80
|
break;
|
87
81
|
}
|
88
|
-
|
82
|
+
return Qnil;
|
89
83
|
}
|
90
84
|
v = 10 * v + (long)(c - '0');
|
91
85
|
}
|
92
|
-
|
93
|
-
|
94
|
-
|
86
|
+
if ('\0' == c) {
|
87
|
+
break;
|
88
|
+
}
|
95
89
|
c = *text++;
|
96
90
|
if (tp->end != c && tp->alt != c) {
|
97
|
-
|
91
|
+
return Qnil;
|
98
92
|
}
|
99
93
|
*cp++ = v;
|
100
94
|
}
|
101
95
|
tm.tm_year = (int)cargs[0] - 1900;
|
102
|
-
tm.tm_mon
|
96
|
+
tm.tm_mon = (int)cargs[1] - 1;
|
103
97
|
tm.tm_mday = (int)cargs[2];
|
104
98
|
tm.tm_hour = (int)cargs[3];
|
105
|
-
tm.tm_min
|
106
|
-
tm.tm_sec
|
107
|
-
#if HAVE_RB_TIME_NANO_NEW
|
99
|
+
tm.tm_min = (int)cargs[4];
|
100
|
+
tm.tm_sec = (int)cargs[5];
|
108
101
|
return rb_time_nano_new(mktime(&tm), cargs[6]);
|
109
|
-
#else
|
110
|
-
return rb_time_new(mktime(&tm), cargs[6] / 1000);
|
111
|
-
#endif
|
112
102
|
}
|
113
103
|
|
114
104
|
/* call-seq: as_s()
|
115
105
|
*
|
116
106
|
* *return* value as an String.
|
117
107
|
*/
|
118
|
-
static VALUE
|
119
|
-
|
120
|
-
|
121
|
-
VALUE rs;
|
108
|
+
static VALUE sax_value_as_s(VALUE self) {
|
109
|
+
SaxDrive dr = DATA_PTR(self);
|
110
|
+
VALUE rs;
|
122
111
|
|
123
112
|
if ('\0' == *dr->buf.str) {
|
124
|
-
|
113
|
+
return Qnil;
|
125
114
|
}
|
126
115
|
if (dr->options.convert_special) {
|
127
|
-
|
116
|
+
ox_sax_collapse_special(dr, dr->buf.str, dr->buf.pos, dr->buf.line, dr->buf.col);
|
128
117
|
}
|
129
118
|
switch (dr->options.skip) {
|
130
|
-
case CrSkip:
|
131
|
-
|
132
|
-
|
133
|
-
case SpcSkip:
|
134
|
-
buf_collapse_white(dr->buf.str);
|
135
|
-
break;
|
136
|
-
default:
|
137
|
-
break;
|
119
|
+
case CrSkip: buf_collapse_return(dr->buf.str); break;
|
120
|
+
case SpcSkip: buf_collapse_white(dr->buf.str); break;
|
121
|
+
default: break;
|
138
122
|
}
|
139
123
|
rs = rb_str_new2(dr->buf.str);
|
140
124
|
if (0 != dr->encoding) {
|
141
|
-
|
125
|
+
rb_enc_associate(rs, dr->encoding);
|
142
126
|
}
|
143
127
|
return rs;
|
144
128
|
}
|
@@ -147,12 +131,11 @@ sax_value_as_s(VALUE self) {
|
|
147
131
|
*
|
148
132
|
* *return* value as an Symbol.
|
149
133
|
*/
|
150
|
-
static VALUE
|
151
|
-
|
152
|
-
SaxDrive dr = DATA_PTR(self);
|
134
|
+
static VALUE sax_value_as_sym(VALUE self) {
|
135
|
+
SaxDrive dr = DATA_PTR(self);
|
153
136
|
|
154
137
|
if ('\0' == *dr->buf.str) {
|
155
|
-
|
138
|
+
return Qnil;
|
156
139
|
}
|
157
140
|
return str2sym(dr, dr->buf.str, strlen(dr->buf.str), 0);
|
158
141
|
}
|
@@ -161,12 +144,11 @@ sax_value_as_sym(VALUE self) {
|
|
161
144
|
*
|
162
145
|
* *return* value as an Float.
|
163
146
|
*/
|
164
|
-
static VALUE
|
165
|
-
|
166
|
-
SaxDrive dr = DATA_PTR(self);
|
147
|
+
static VALUE sax_value_as_f(VALUE self) {
|
148
|
+
SaxDrive dr = DATA_PTR(self);
|
167
149
|
|
168
150
|
if ('\0' == *dr->buf.str) {
|
169
|
-
|
151
|
+
return Qnil;
|
170
152
|
}
|
171
153
|
return rb_float_new(strtod(dr->buf.str, 0));
|
172
154
|
}
|
@@ -175,31 +157,30 @@ sax_value_as_f(VALUE self) {
|
|
175
157
|
*
|
176
158
|
* *return* value as an Fixnum.
|
177
159
|
*/
|
178
|
-
static VALUE
|
179
|
-
|
180
|
-
|
181
|
-
|
182
|
-
|
183
|
-
int neg = 0;
|
160
|
+
static VALUE sax_value_as_i(VALUE self) {
|
161
|
+
SaxDrive dr = DATA_PTR(self);
|
162
|
+
const char *s = dr->buf.str;
|
163
|
+
long n = 0;
|
164
|
+
int neg = 0;
|
184
165
|
|
185
166
|
if ('\0' == *s) {
|
186
|
-
|
167
|
+
return Qnil;
|
187
168
|
}
|
188
169
|
if ('-' == *s) {
|
189
|
-
|
190
|
-
|
170
|
+
neg = 1;
|
171
|
+
s++;
|
191
172
|
} else if ('+' == *s) {
|
192
|
-
|
173
|
+
s++;
|
193
174
|
}
|
194
175
|
for (; '\0' != *s; s++) {
|
195
|
-
|
196
|
-
|
197
|
-
|
198
|
-
|
199
|
-
|
176
|
+
if ('0' <= *s && *s <= '9') {
|
177
|
+
n = n * 10 + (*s - '0');
|
178
|
+
} else {
|
179
|
+
rb_raise(ox_arg_error_class, "Not a valid Fixnum.\n");
|
180
|
+
}
|
200
181
|
}
|
201
182
|
if (neg) {
|
202
|
-
|
183
|
+
n = -n;
|
203
184
|
}
|
204
185
|
return LONG2NUM(n);
|
205
186
|
}
|
@@ -208,22 +189,20 @@ sax_value_as_i(VALUE self) {
|
|
208
189
|
*
|
209
190
|
* *return* value as an Time.
|
210
191
|
*/
|
211
|
-
static VALUE
|
212
|
-
|
213
|
-
|
214
|
-
const char *str = dr->buf.str;
|
192
|
+
static VALUE sax_value_as_time(VALUE self) {
|
193
|
+
SaxDrive dr = DATA_PTR(self);
|
194
|
+
const char *str = dr->buf.str;
|
215
195
|
VALUE t;
|
216
196
|
|
217
197
|
if ('\0' == *str) {
|
218
|
-
|
198
|
+
return Qnil;
|
219
199
|
}
|
220
|
-
if (Qnil == (t = parse_double_time(str)) &&
|
221
|
-
|
222
|
-
VALUE args[1];
|
200
|
+
if (Qnil == (t = parse_double_time(str)) && Qnil == (t = parse_xsd_time(str))) {
|
201
|
+
VALUE args[1];
|
223
202
|
|
224
203
|
/*printf("**** time parse\n"); */
|
225
204
|
*args = rb_str_new2(str);
|
226
|
-
t
|
205
|
+
t = rb_funcall2(ox_time_class, ox_parse_id, 1, args);
|
227
206
|
}
|
228
207
|
return t;
|
229
208
|
}
|
@@ -232,8 +211,7 @@ sax_value_as_time(VALUE self) {
|
|
232
211
|
*
|
233
212
|
* *return* value as an boolean.
|
234
213
|
*/
|
235
|
-
static VALUE
|
236
|
-
sax_value_as_bool(VALUE self) {
|
214
|
+
static VALUE sax_value_as_bool(VALUE self) {
|
237
215
|
return (0 == strcasecmp("true", ((SaxDrive)DATA_PTR(self))->buf.str)) ? Qtrue : Qfalse;
|
238
216
|
}
|
239
217
|
|
@@ -241,8 +219,7 @@ sax_value_as_bool(VALUE self) {
|
|
241
219
|
*
|
242
220
|
* *return* true if the value is empty.
|
243
221
|
*/
|
244
|
-
static VALUE
|
245
|
-
sax_value_empty(VALUE self) {
|
222
|
+
static VALUE sax_value_empty(VALUE self) {
|
246
223
|
return ('\0' == *((SaxDrive)DATA_PTR(self))->buf.str) ? Qtrue : Qfalse;
|
247
224
|
}
|
248
225
|
|
@@ -251,15 +228,14 @@ sax_value_empty(VALUE self) {
|
|
251
228
|
* Values in the SAX callbacks. They can be converted to various different
|
252
229
|
* types. with the _as_x()_ methods.
|
253
230
|
*/
|
254
|
-
void
|
255
|
-
ox_sax_define() {
|
231
|
+
void ox_sax_define() {
|
256
232
|
#if 0
|
257
233
|
ox = rb_define_module("Ox");
|
258
234
|
#if RUBY_API_VERSION_CODE >= 30200
|
259
235
|
sax_module = rb_define_class_under(ox, "Sax", rb_cObject);
|
260
236
|
#endif
|
261
237
|
#endif
|
262
|
-
VALUE
|
238
|
+
VALUE sax_module = rb_const_get_at(Ox, rb_intern("Sax"));
|
263
239
|
|
264
240
|
ox_sax_value_class = rb_define_class_under(sax_module, "Value", rb_cObject);
|
265
241
|
#if RUBY_API_VERSION_CODE >= 30200
|