ox 2.14.12 → 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 +30 -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 +62 -35
- 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 +69 -41
- 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,16 +761,19 @@ CB:
|
|
761
761
|
* code.
|
762
762
|
*/
|
763
763
|
static char read_element_start(SaxDrive dr) {
|
764
|
-
const char *ename =
|
765
|
-
|
764
|
+
const char *ename = NULL;
|
765
|
+
char ebuf[128];
|
766
|
+
size_t nlen;
|
767
|
+
volatile VALUE name = Qnil;
|
766
768
|
char c;
|
767
|
-
int closed;
|
768
769
|
long pos = (long)(dr->buf.pos);
|
769
770
|
long line = (long)(dr->buf.line);
|
770
771
|
long col = (long)(dr->buf.col);
|
771
772
|
Hint h = NULL;
|
772
773
|
int stackless = 0;
|
773
774
|
Nv parent = stack_peek(&dr->stack);
|
775
|
+
bool closed;
|
776
|
+
bool efree = false;
|
774
777
|
|
775
778
|
if ('\0' == (c = read_name_token(dr))) {
|
776
779
|
return '\0';
|
@@ -790,6 +793,7 @@ static char read_element_start(SaxDrive dr) {
|
|
790
793
|
0 == strcasecmp("html", dr->buf.str)) {
|
791
794
|
dr->options.hints = ox_hints_html();
|
792
795
|
}
|
796
|
+
nlen = dr->buf.tail - dr->buf.str - 1;
|
793
797
|
if (NULL != dr->options.hints) {
|
794
798
|
hint_clear_empty(dr);
|
795
799
|
h = ox_hint_find(dr->options.hints, dr->buf.str);
|
@@ -810,7 +814,7 @@ static char read_element_start(SaxDrive dr) {
|
|
810
814
|
if (rb_respond_to(dr->handler, ox_abort_id)) {
|
811
815
|
VALUE args[1];
|
812
816
|
|
813
|
-
args[0] = str2sym(dr, dr->buf.str,
|
817
|
+
args[0] = str2sym(dr, dr->buf.str, nlen, NULL);
|
814
818
|
rb_funcall2(dr->handler, ox_abort_id, 1, args);
|
815
819
|
}
|
816
820
|
dr->abort = true;
|
@@ -825,7 +829,7 @@ static char read_element_start(SaxDrive dr) {
|
|
825
829
|
if (0 != top_nv) {
|
826
830
|
char msg[256];
|
827
831
|
|
828
|
-
if (!h->nest && NestOverlay != h->overlay &&
|
832
|
+
if (!h->nest && NestOverlay != h->overlay && nv_same_name(top_nv, h->name, true)) {
|
829
833
|
snprintf(msg,
|
830
834
|
sizeof(msg) - 1,
|
831
835
|
"%s%s can not be nested in a %s document, closing previous.",
|
@@ -842,7 +846,7 @@ static char read_element_start(SaxDrive dr) {
|
|
842
846
|
int ok = 0;
|
843
847
|
|
844
848
|
for (p = h->parents; 0 != *p; p++) {
|
845
|
-
if (
|
849
|
+
if (nv_same_name(top_nv, *p, true)) {
|
846
850
|
ok = 1;
|
847
851
|
break;
|
848
852
|
}
|
@@ -853,7 +857,7 @@ static char read_element_start(SaxDrive dr) {
|
|
853
857
|
"%s%s can not be a child of a %s in a %s document.",
|
854
858
|
INV_ELEMENT,
|
855
859
|
h->name,
|
856
|
-
top_nv
|
860
|
+
nv_name(top_nv),
|
857
861
|
dr->options.hints->name);
|
858
862
|
ox_sax_drive_error(dr, msg);
|
859
863
|
}
|
@@ -861,7 +865,17 @@ static char read_element_start(SaxDrive dr) {
|
|
861
865
|
}
|
862
866
|
}
|
863
867
|
}
|
864
|
-
name = str2sym(dr, dr->buf.str,
|
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
|
+
}
|
865
879
|
if (dr->has_start_element && 0 >= dr->blocked &&
|
866
880
|
(NULL == h || ActiveOverlay == h->overlay || NestOverlay == h->overlay)) {
|
867
881
|
VALUE args[1];
|
@@ -873,9 +887,9 @@ static char read_element_start(SaxDrive dr) {
|
|
873
887
|
rb_funcall2(dr->handler, ox_start_element_id, 1, args);
|
874
888
|
}
|
875
889
|
if ('/' == c) {
|
876
|
-
closed =
|
890
|
+
closed = true;
|
877
891
|
} else if ('>' == c) {
|
878
|
-
closed =
|
892
|
+
closed = false;
|
879
893
|
} else {
|
880
894
|
buf_protect(&dr->buf);
|
881
895
|
c = read_attrs(dr, c, '/', '>', 0, 0, h);
|
@@ -894,7 +908,7 @@ static char read_element_start(SaxDrive dr) {
|
|
894
908
|
} else if (stackless) {
|
895
909
|
end_element_cb(dr, name, pos, line, col, h);
|
896
910
|
} else if (NULL != h && h->jump) {
|
897
|
-
stack_push(&dr->stack, ename, name, h);
|
911
|
+
stack_push(&dr->stack, ename, nlen, name, h);
|
898
912
|
if ('>' != c) {
|
899
913
|
ox_sax_drive_error(dr, WRONG_CHAR "element not closed");
|
900
914
|
return c;
|
@@ -902,13 +916,16 @@ static char read_element_start(SaxDrive dr) {
|
|
902
916
|
read_jump(dr, h->name);
|
903
917
|
return '<';
|
904
918
|
} else {
|
905
|
-
stack_push(&dr->stack, ename, name, h);
|
919
|
+
stack_push(&dr->stack, ename, nlen, name, h);
|
920
|
+
}
|
921
|
+
if (efree) {
|
922
|
+
free((char *)ename);
|
906
923
|
}
|
907
924
|
if ('>' != c) {
|
908
925
|
ox_sax_drive_error(dr, WRONG_CHAR "element not closed");
|
909
926
|
return c;
|
910
927
|
}
|
911
|
-
dr->buf.str =
|
928
|
+
dr->buf.str = NULL;
|
912
929
|
|
913
930
|
return buf_get(&dr->buf);
|
914
931
|
}
|
@@ -917,7 +934,7 @@ static Nv stack_rev_find(SaxDrive dr, const char *name) {
|
|
917
934
|
Nv nv;
|
918
935
|
|
919
936
|
for (nv = dr->stack.tail - 1; dr->stack.head <= nv; nv--) {
|
920
|
-
if (
|
937
|
+
if (nv_same_name(nv, name, dr->options.smart)) {
|
921
938
|
return nv;
|
922
939
|
}
|
923
940
|
}
|
@@ -942,7 +959,7 @@ static char read_element_end(SaxDrive dr) {
|
|
942
959
|
// c should be > and current is one past so read another char
|
943
960
|
c = buf_get(&dr->buf);
|
944
961
|
nv = stack_peek(&dr->stack);
|
945
|
-
if (0 != nv &&
|
962
|
+
if (0 != nv && nv_same_name(nv, dr->buf.str, dr->options.smart)) {
|
946
963
|
name = nv->val;
|
947
964
|
h = nv->hint;
|
948
965
|
stack_pop(&dr->stack);
|
@@ -995,7 +1012,7 @@ static char read_element_end(SaxDrive dr) {
|
|
995
1012
|
"%selement '%s' close does not match '%s' open",
|
996
1013
|
EL_MISMATCH,
|
997
1014
|
dr->buf.str,
|
998
|
-
nv
|
1015
|
+
nv_name(nv));
|
999
1016
|
ox_sax_drive_error_at(dr, msg, pos, line, col);
|
1000
1017
|
for (nv = stack_pop(&dr->stack); match < nv; nv = stack_pop(&dr->stack)) {
|
1001
1018
|
end_element_cb(dr, nv->val, pos, line, col, nv->hint);
|
@@ -1202,6 +1219,7 @@ static char read_attrs(SaxDrive dr, char c, char termc, char term2, int is_xml,
|
|
1202
1219
|
c = buf_next_non_white(&dr->buf);
|
1203
1220
|
}
|
1204
1221
|
if ('=' != c) {
|
1222
|
+
// TBD allow in smart mode
|
1205
1223
|
if (eq_req) {
|
1206
1224
|
dr->err = 1;
|
1207
1225
|
return c;
|
@@ -1213,7 +1231,7 @@ static char read_attrs(SaxDrive dr, char c, char termc, char term2, int is_xml,
|
|
1213
1231
|
pos = dr->buf.pos + 1;
|
1214
1232
|
line = dr->buf.line;
|
1215
1233
|
col = dr->buf.col + 1;
|
1216
|
-
c = read_quoted_value(dr);
|
1234
|
+
c = read_quoted_value(dr, '?' == termc);
|
1217
1235
|
attr_value = dr->buf.str;
|
1218
1236
|
|
1219
1237
|
if (is_encoding) {
|
@@ -1280,10 +1298,11 @@ static char read_name_token(SaxDrive dr) {
|
|
1280
1298
|
return '\0';
|
1281
1299
|
}
|
1282
1300
|
|
1283
|
-
/* The character after the quote or if there is no quote, the character after
|
1284
|
-
*
|
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.
|
1285
1304
|
*/
|
1286
|
-
static char read_quoted_value(SaxDrive dr) {
|
1305
|
+
static char read_quoted_value(SaxDrive dr, bool inst) {
|
1287
1306
|
char c;
|
1288
1307
|
|
1289
1308
|
c = buf_get(&dr->buf);
|
@@ -1307,19 +1326,27 @@ static char read_quoted_value(SaxDrive dr) {
|
|
1307
1326
|
}
|
1308
1327
|
// not quoted, look for something that terminates the string
|
1309
1328
|
dr->buf.str = dr->buf.tail - 1;
|
1310
|
-
|
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
|
+
}
|
1311
1333
|
while ('\0' != (c = buf_get(&dr->buf))) {
|
1312
1334
|
switch (c) {
|
1313
1335
|
case ' ':
|
1314
1336
|
// case '/':
|
1315
1337
|
case '>':
|
1316
|
-
case '?': // for instructions
|
1317
1338
|
case '\t':
|
1318
1339
|
case '\n':
|
1319
1340
|
case '\r':
|
1320
1341
|
*(dr->buf.tail - 1) = '\0'; /* terminate value */
|
1321
1342
|
// dr->buf.tail is in the correct position, one after the word terminator
|
1322
1343
|
return c;
|
1344
|
+
case '?': // for instructions
|
1345
|
+
if (inst) {
|
1346
|
+
*(dr->buf.tail - 1) = '\0'; /* terminate value */
|
1347
|
+
return c;
|
1348
|
+
}
|
1349
|
+
break;
|
1323
1350
|
default: break;
|
1324
1351
|
}
|
1325
1352
|
}
|
@@ -1463,18 +1490,18 @@ int ox_sax_collapse_special(SaxDrive dr, char *str, long pos, long line, long co
|
|
1463
1490
|
break;
|
1464
1491
|
}
|
1465
1492
|
case '\r':
|
1466
|
-
|
1493
|
+
s++;
|
1467
1494
|
if ('\n' == *s) {
|
1468
|
-
|
1469
|
-
|
1470
|
-
|
1471
|
-
|
1495
|
+
continue;
|
1496
|
+
}
|
1497
|
+
line++;
|
1498
|
+
col = 1;
|
1472
1499
|
*b++ = '\n';
|
1473
|
-
|
1474
|
-
|
1475
|
-
|
1476
|
-
|
1477
|
-
|
1500
|
+
break;
|
1501
|
+
case '\n':
|
1502
|
+
line++;
|
1503
|
+
col = 0;
|
1504
|
+
// fall through
|
1478
1505
|
default:
|
1479
1506
|
col++;
|
1480
1507
|
*b++ = *s++;
|
@@ -1510,7 +1537,7 @@ static Nv hint_try_close(SaxDrive dr, const char *name) {
|
|
1510
1537
|
return 0;
|
1511
1538
|
}
|
1512
1539
|
for (nv = stack_peek(&dr->stack); 0 != nv; nv = stack_peek(&dr->stack)) {
|
1513
|
-
if (
|
1540
|
+
if (nv_same_name(nv, name, true)) {
|
1514
1541
|
stack_pop(&dr->stack);
|
1515
1542
|
return nv;
|
1516
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
|