ox 2.14.14 → 2.14.17
Sign up to get free protection for your applications and to get access to all the features.
- 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
|