ox-bundlecachetest 2.14.23

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.
Files changed (55) hide show
  1. checksums.yaml +7 -0
  2. data/CHANGELOG.md +751 -0
  3. data/LICENSE +21 -0
  4. data/README.md +351 -0
  5. data/ext/ox/attr.h +78 -0
  6. data/ext/ox/base64.c +105 -0
  7. data/ext/ox/base64.h +18 -0
  8. data/ext/ox/buf.h +162 -0
  9. data/ext/ox/builder.c +948 -0
  10. data/ext/ox/cache.c +351 -0
  11. data/ext/ox/cache.h +21 -0
  12. data/ext/ox/cache8.c +106 -0
  13. data/ext/ox/cache8.h +23 -0
  14. data/ext/ox/dump.c +1260 -0
  15. data/ext/ox/err.c +46 -0
  16. data/ext/ox/err.h +36 -0
  17. data/ext/ox/extconf.rb +47 -0
  18. data/ext/ox/gen_load.c +342 -0
  19. data/ext/ox/hash_load.c +309 -0
  20. data/ext/ox/helper.h +84 -0
  21. data/ext/ox/intern.c +157 -0
  22. data/ext/ox/intern.h +25 -0
  23. data/ext/ox/obj_load.c +809 -0
  24. data/ext/ox/ox.c +1649 -0
  25. data/ext/ox/ox.h +245 -0
  26. data/ext/ox/parse.c +1197 -0
  27. data/ext/ox/sax.c +1570 -0
  28. data/ext/ox/sax.h +69 -0
  29. data/ext/ox/sax_as.c +270 -0
  30. data/ext/ox/sax_buf.c +209 -0
  31. data/ext/ox/sax_buf.h +204 -0
  32. data/ext/ox/sax_hint.c +207 -0
  33. data/ext/ox/sax_hint.h +40 -0
  34. data/ext/ox/sax_stack.h +113 -0
  35. data/ext/ox/slotcache.c +158 -0
  36. data/ext/ox/slotcache.h +19 -0
  37. data/ext/ox/special.c +390 -0
  38. data/ext/ox/special.h +14 -0
  39. data/ext/ox/type.h +39 -0
  40. data/lib/ox/bag.rb +103 -0
  41. data/lib/ox/cdata.rb +10 -0
  42. data/lib/ox/comment.rb +11 -0
  43. data/lib/ox/doctype.rb +11 -0
  44. data/lib/ox/document.rb +28 -0
  45. data/lib/ox/element.rb +464 -0
  46. data/lib/ox/error.rb +25 -0
  47. data/lib/ox/hasattrs.rb +54 -0
  48. data/lib/ox/instruct.rb +34 -0
  49. data/lib/ox/node.rb +23 -0
  50. data/lib/ox/raw.rb +12 -0
  51. data/lib/ox/sax.rb +97 -0
  52. data/lib/ox/version.rb +4 -0
  53. data/lib/ox/xmlrpc_adapter.rb +33 -0
  54. data/lib/ox.rb +79 -0
  55. metadata +128 -0
data/ext/ox/sax.h ADDED
@@ -0,0 +1,69 @@
1
+ /* sax.h
2
+ * Copyright (c) 2011, Peter Ohler
3
+ * All rights reserved.
4
+ */
5
+
6
+ #ifndef OX_SAX_H
7
+ #define OX_SAX_H
8
+
9
+ #include <stdbool.h>
10
+
11
+ #include "ox.h"
12
+ #include "sax_buf.h"
13
+ #include "sax_hint.h"
14
+ #include "sax_stack.h"
15
+
16
+ typedef struct _saxOptions {
17
+ int symbolize;
18
+ int convert_special;
19
+ int smart;
20
+ SkipMode skip;
21
+ char strip_ns[64];
22
+ Hints hints;
23
+ } *SaxOptions;
24
+
25
+ typedef struct _saxDrive {
26
+ struct _buf buf;
27
+ struct _nStack stack; /* element name stack */
28
+ VALUE handler;
29
+ VALUE value_obj;
30
+ struct _saxOptions options;
31
+ VALUE (*get_name)(const char *name, size_t len, rb_encoding *encoding, const char **namep);
32
+ void (*set_pos)(VALUE handler, long pos);
33
+ void (*set_line)(VALUE handler, long line);
34
+ void (*set_col)(VALUE handler, long col);
35
+ void (*attr_cb)(struct _saxDrive *dr, VALUE name, char *value, long pos, long line, long col);
36
+ void (*attrs_done)(VALUE handler);
37
+ VALUE (*instruct)(struct _saxDrive *dr, const char *target, long pos, long line, long col);
38
+ void (*end_instruct)(struct _saxDrive *dr, VALUE target, long pos, long line, long col);
39
+ void (*doctype)(struct _saxDrive *dr, long pos, long line, long col);
40
+ void (*comment)(struct _saxDrive *dr, long pos, long line, long col);
41
+ void (*cdata)(struct _saxDrive *dr, long pos, long line, long col);
42
+ void (*error)(struct _saxDrive *dr, const char *msg, long pos, long line, long col);
43
+
44
+ rb_encoding *encoding;
45
+ int err;
46
+ int blocked;
47
+ bool abort;
48
+ bool utf8;
49
+ bool want_attr_name;
50
+ bool has_text;
51
+ bool has_value;
52
+ bool has_start_element;
53
+ bool has_end_element;
54
+
55
+ } *SaxDrive;
56
+
57
+ extern const rb_data_type_t ox_sax_value_type;
58
+
59
+ extern void ox_collapse_return(char *str);
60
+ extern void ox_sax_parse(VALUE handler, VALUE io, SaxOptions options);
61
+ extern void ox_sax_drive_cleanup(SaxDrive dr);
62
+ extern void ox_sax_drive_error(SaxDrive dr, const char *msg);
63
+ extern int ox_sax_collapse_special(SaxDrive dr, char *str, long pos, long line, long col);
64
+
65
+ extern VALUE ox_sax_value_class;
66
+
67
+ extern VALUE str2sym(SaxDrive dr, const char *str, size_t len, const char **strp);
68
+
69
+ #endif /* OX_SAX_H */
data/ext/ox/sax_as.c ADDED
@@ -0,0 +1,270 @@
1
+ /* sax_as.c
2
+ * Copyright (c) 2011, Peter Ohler
3
+ * All rights reserved.
4
+ */
5
+
6
+ #include <errno.h>
7
+ #include <stdio.h>
8
+ #include <stdlib.h>
9
+ #include <strings.h>
10
+ #include <sys/types.h>
11
+ #if HAVE_SYS_UIO_H
12
+ #include <sys/uio.h>
13
+ #endif
14
+ #include <time.h>
15
+ #include <unistd.h>
16
+
17
+ #include "ox.h"
18
+ #include "ruby.h"
19
+ #include "ruby/version.h"
20
+ #include "sax.h"
21
+
22
+ static VALUE parse_double_time(const char *text) {
23
+ long v = 0;
24
+ long v2 = 0;
25
+ const char *dot = 0;
26
+ char c;
27
+
28
+ for (; '.' != *text; text++) {
29
+ c = *text;
30
+ if (c < '0' || '9' < c) {
31
+ return Qnil;
32
+ }
33
+ v = 10 * v + (long)(c - '0');
34
+ }
35
+ dot = text++;
36
+ for (; '\0' != *text && text - dot <= 6; text++) {
37
+ c = *text;
38
+ if (c < '0' || '9' < c) {
39
+ return Qnil;
40
+ }
41
+ v2 = 10 * v2 + (long)(c - '0');
42
+ }
43
+ for (; text - dot <= 9; text++) {
44
+ v2 *= 10;
45
+ }
46
+ return rb_time_nano_new(v, v2);
47
+ }
48
+
49
+ typedef struct _tp {
50
+ int cnt;
51
+ char end;
52
+ char alt;
53
+ } *Tp;
54
+
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;
73
+
74
+ memset(cargs, 0, sizeof(cargs));
75
+ for (; 0 != tp->cnt; tp++) {
76
+ for (i = tp->cnt, v = 0; 0 < i; text++, i--) {
77
+ c = *text;
78
+ if (c < '0' || '9' < c) {
79
+ if ('\0' == c || tp->end == c || tp->alt == c) {
80
+ break;
81
+ }
82
+ return Qnil;
83
+ }
84
+ v = 10 * v + (long)(c - '0');
85
+ }
86
+ if ('\0' == c) {
87
+ break;
88
+ }
89
+ c = *text++;
90
+ if (tp->end != c && tp->alt != c) {
91
+ return Qnil;
92
+ }
93
+ *cp++ = v;
94
+ }
95
+ tm.tm_year = (int)cargs[0] - 1900;
96
+ tm.tm_mon = (int)cargs[1] - 1;
97
+ tm.tm_mday = (int)cargs[2];
98
+ tm.tm_hour = (int)cargs[3];
99
+ tm.tm_min = (int)cargs[4];
100
+ tm.tm_sec = (int)cargs[5];
101
+ return rb_time_nano_new(mktime(&tm), cargs[6]);
102
+ }
103
+
104
+ /* call-seq: as_s()
105
+ *
106
+ * *return* value as an String.
107
+ */
108
+ static VALUE sax_value_as_s(VALUE self) {
109
+ SaxDrive dr;
110
+ VALUE rs;
111
+
112
+ TypedData_Get_Struct(self, struct _saxDrive, &ox_sax_value_type, dr);
113
+
114
+ if ('\0' == *dr->buf.str) {
115
+ return Qnil;
116
+ }
117
+ if (dr->options.convert_special) {
118
+ ox_sax_collapse_special(dr, dr->buf.str, dr->buf.pos, dr->buf.line, dr->buf.col);
119
+ }
120
+ switch (dr->options.skip) {
121
+ case CrSkip: buf_collapse_return(dr->buf.str); break;
122
+ case SpcSkip: buf_collapse_white(dr->buf.str); break;
123
+ default: break;
124
+ }
125
+ rs = rb_str_new2(dr->buf.str);
126
+ if (0 != dr->encoding) {
127
+ rb_enc_associate(rs, dr->encoding);
128
+ }
129
+ return rs;
130
+ }
131
+
132
+ /* call-seq: as_sym()
133
+ *
134
+ * *return* value as an Symbol.
135
+ */
136
+ static VALUE sax_value_as_sym(VALUE self) {
137
+ SaxDrive dr;
138
+
139
+ TypedData_Get_Struct(self, struct _saxDrive, &ox_sax_value_type, dr);
140
+
141
+ if ('\0' == *dr->buf.str) {
142
+ return Qnil;
143
+ }
144
+ return str2sym(dr, dr->buf.str, strlen(dr->buf.str), 0);
145
+ }
146
+
147
+ /* call-seq: as_f()
148
+ *
149
+ * *return* value as an Float.
150
+ */
151
+ static VALUE sax_value_as_f(VALUE self) {
152
+ SaxDrive dr;
153
+
154
+ TypedData_Get_Struct(self, struct _saxDrive, &ox_sax_value_type, dr);
155
+
156
+ if ('\0' == *dr->buf.str) {
157
+ return Qnil;
158
+ }
159
+ return rb_float_new(strtod(dr->buf.str, 0));
160
+ }
161
+
162
+ /* call-seq: as_i()
163
+ *
164
+ * *return* value as an Fixnum.
165
+ */
166
+ static VALUE sax_value_as_i(VALUE self) {
167
+ SaxDrive dr;
168
+ const char *s;
169
+ long n = 0;
170
+ int neg = 0;
171
+
172
+ TypedData_Get_Struct(self, struct _saxDrive, &ox_sax_value_type, dr);
173
+ s = dr->buf.str;
174
+
175
+ if ('\0' == *s) {
176
+ return Qnil;
177
+ }
178
+ if ('-' == *s) {
179
+ neg = 1;
180
+ s++;
181
+ } else if ('+' == *s) {
182
+ s++;
183
+ }
184
+ for (; '\0' != *s; s++) {
185
+ if ('0' <= *s && *s <= '9') {
186
+ n = n * 10 + (*s - '0');
187
+ } else {
188
+ rb_raise(ox_arg_error_class, "Not a valid Fixnum.\n");
189
+ }
190
+ }
191
+ if (neg) {
192
+ n = -n;
193
+ }
194
+ return LONG2NUM(n);
195
+ }
196
+
197
+ /* call-seq: as_time()
198
+ *
199
+ * *return* value as an Time.
200
+ */
201
+ static VALUE sax_value_as_time(VALUE self) {
202
+ SaxDrive dr;
203
+ const char *str;
204
+ VALUE t;
205
+
206
+ TypedData_Get_Struct(self, struct _saxDrive, &ox_sax_value_type, dr);
207
+ str = dr->buf.str;
208
+
209
+ if ('\0' == *str) {
210
+ return Qnil;
211
+ }
212
+ if (Qnil == (t = parse_double_time(str)) && Qnil == (t = parse_xsd_time(str))) {
213
+ VALUE args[1];
214
+
215
+ /*printf("**** time parse\n"); */
216
+ *args = rb_str_new2(str);
217
+ t = rb_funcall2(ox_time_class, ox_parse_id, 1, args);
218
+ }
219
+ return t;
220
+ }
221
+
222
+ /* call-seq: as_bool()
223
+ *
224
+ * *return* value as an boolean.
225
+ */
226
+ static VALUE sax_value_as_bool(VALUE self) {
227
+ SaxDrive dr;
228
+
229
+ TypedData_Get_Struct(self, struct _saxDrive, &ox_sax_value_type, dr);
230
+ return (0 == strcasecmp("true", dr->buf.str)) ? Qtrue : Qfalse;
231
+ }
232
+
233
+ /* call-seq: empty()
234
+ *
235
+ * *return* true if the value is empty.
236
+ */
237
+ static VALUE sax_value_empty(VALUE self) {
238
+ SaxDrive dr;
239
+
240
+ TypedData_Get_Struct(self, struct _saxDrive, &ox_sax_value_type, dr);
241
+ return ('\0' == *dr->buf.str) ? Qtrue : Qfalse;
242
+ }
243
+
244
+ /* Document-class: Ox::Sax::Value
245
+ *
246
+ * Values in the SAX callbacks. They can be converted to various different
247
+ * types. with the _as_x()_ methods.
248
+ */
249
+ void ox_sax_define(void) {
250
+ #if 0
251
+ ox = rb_define_module("Ox");
252
+ #if RUBY_API_VERSION_CODE >= 30200
253
+ sax_module = rb_define_class_under(ox, "Sax", rb_cObject);
254
+ #endif
255
+ #endif
256
+ VALUE sax_module = rb_const_get_at(Ox, rb_intern("Sax"));
257
+
258
+ ox_sax_value_class = rb_define_class_under(sax_module, "Value", rb_cObject);
259
+ #if RUBY_API_VERSION_CODE >= 30200
260
+ rb_undef_alloc_func(ox_sax_value_class);
261
+ #endif
262
+
263
+ rb_define_method(ox_sax_value_class, "as_s", sax_value_as_s, 0);
264
+ rb_define_method(ox_sax_value_class, "as_sym", sax_value_as_sym, 0);
265
+ rb_define_method(ox_sax_value_class, "as_i", sax_value_as_i, 0);
266
+ rb_define_method(ox_sax_value_class, "as_f", sax_value_as_f, 0);
267
+ rb_define_method(ox_sax_value_class, "as_time", sax_value_as_time, 0);
268
+ rb_define_method(ox_sax_value_class, "as_bool", sax_value_as_bool, 0);
269
+ rb_define_method(ox_sax_value_class, "empty?", sax_value_empty, 0);
270
+ }
data/ext/ox/sax_buf.c ADDED
@@ -0,0 +1,209 @@
1
+ /* sax_buf.c
2
+ * Copyright (c) 2011, Peter Ohler
3
+ * All rights reserved.
4
+ */
5
+
6
+ #include <errno.h>
7
+ #include <stdio.h>
8
+ #include <stdlib.h>
9
+ #include <strings.h>
10
+ #include <sys/types.h>
11
+ #if HAVE_SYS_UIO_H
12
+ #include <sys/uio.h>
13
+ #endif
14
+ #include <time.h>
15
+ #include <unistd.h>
16
+
17
+ #include "ox.h"
18
+ #include "ruby.h"
19
+ #include "sax.h"
20
+
21
+ #define BUF_PAD 4
22
+
23
+ static VALUE rescue_cb(VALUE rdr, VALUE err);
24
+ static VALUE io_cb(VALUE rdr);
25
+ static VALUE partial_io_cb(VALUE rdr);
26
+ static int read_from_io(Buf buf);
27
+ static int read_from_fd(Buf buf);
28
+ static int read_from_io_partial(Buf buf);
29
+ static int read_from_str(Buf buf);
30
+
31
+ void ox_sax_buf_init(Buf buf, VALUE io) {
32
+ volatile VALUE io_class = rb_obj_class(io);
33
+ VALUE rfd;
34
+
35
+ if (rb_cString == io_class) {
36
+ buf->read_func = read_from_str;
37
+ buf->in.str = StringValuePtr(io);
38
+ } else if (ox_stringio_class == io_class && 0 == FIX2INT(rb_funcall2(io, ox_pos_id, 0, 0))) {
39
+ volatile VALUE s = rb_funcall2(io, ox_string_id, 0, 0);
40
+
41
+ buf->read_func = read_from_str;
42
+ buf->in.str = StringValuePtr(s);
43
+ } else if (rb_cFile == io_class && Qnil != (rfd = rb_funcall(io, ox_fileno_id, 0))) {
44
+ buf->read_func = read_from_fd;
45
+ buf->in.fd = FIX2INT(rfd);
46
+ } else if (rb_respond_to(io, ox_readpartial_id)) {
47
+ buf->read_func = read_from_io_partial;
48
+ buf->in.io = io;
49
+ } else if (rb_respond_to(io, ox_read_id)) {
50
+ buf->read_func = read_from_io;
51
+ buf->in.io = io;
52
+ } else {
53
+ rb_raise(ox_arg_error_class, "sax_parser io argument must respond to readpartial() or read().\n");
54
+ }
55
+ buf->head = buf->base;
56
+ *buf->head = '\0';
57
+ buf->end = buf->head + sizeof(buf->base) - BUF_PAD;
58
+ buf->tail = buf->head;
59
+ buf->read_end = buf->head;
60
+ buf->pro = 0;
61
+ buf->str = 0;
62
+ buf->pos = 0;
63
+ buf->line = 1;
64
+ buf->col = 0;
65
+ buf->pro_pos = 1;
66
+ buf->pro_line = 1;
67
+ buf->pro_col = 0;
68
+ buf->dr = 0;
69
+ }
70
+
71
+ int ox_sax_buf_read(Buf buf) {
72
+ int err;
73
+ size_t shift = 0;
74
+
75
+ // if there is not much room to read into, shift or realloc a larger buffer.
76
+ if (buf->head < buf->tail && 4096 > buf->end - buf->tail) {
77
+ if (0 == buf->pro) {
78
+ shift = buf->tail - buf->head;
79
+ } else {
80
+ shift = buf->pro - buf->head - 1; // leave one character so we cab backup one
81
+ }
82
+ if (0 >= shift) { /* no space left so allocate more */
83
+ char *old = buf->head;
84
+ size_t size = buf->end - buf->head + BUF_PAD;
85
+
86
+ if (buf->head == buf->base) {
87
+ buf->head = ALLOC_N(char, size * 2);
88
+ memcpy(buf->head, old, size);
89
+ } else {
90
+ REALLOC_N(buf->head, char, size * 2);
91
+ }
92
+ buf->end = buf->head + size * 2 - BUF_PAD;
93
+ buf->tail = buf->head + (buf->tail - old);
94
+ buf->read_end = buf->head + (buf->read_end - old);
95
+ if (0 != buf->pro) {
96
+ buf->pro = buf->head + (buf->pro - old);
97
+ }
98
+ if (0 != buf->str) {
99
+ buf->str = buf->head + (buf->str - old);
100
+ }
101
+ } else {
102
+ memmove(buf->head, buf->head + shift, buf->read_end - (buf->head + shift));
103
+ buf->tail -= shift;
104
+ buf->read_end -= shift;
105
+ if (0 != buf->pro) {
106
+ buf->pro -= shift;
107
+ }
108
+ if (0 != buf->str) {
109
+ buf->str -= shift;
110
+ }
111
+ }
112
+ }
113
+ err = buf->read_func(buf);
114
+ *buf->read_end = '\0';
115
+
116
+ return err;
117
+ }
118
+
119
+ static VALUE rescue_cb(VALUE rbuf, VALUE err) {
120
+ VALUE err_class = rb_obj_class(err);
121
+
122
+ if (err_class != rb_eTypeError && err_class != rb_eEOFError) {
123
+ Buf buf = (Buf)rbuf;
124
+
125
+ // ox_sax_drive_cleanup(buf->dr); called after exiting protect
126
+ rb_raise(err, "at line %ld, column %ld\n", (long)buf->line, (long)buf->col);
127
+ }
128
+ return Qfalse;
129
+ }
130
+
131
+ static VALUE partial_io_cb(VALUE rbuf) {
132
+ Buf buf = (Buf)rbuf;
133
+ VALUE args[1];
134
+ VALUE rstr;
135
+ char *str;
136
+ size_t cnt;
137
+
138
+ args[0] = ULONG2NUM(buf->end - buf->tail);
139
+ rstr = rb_funcall2(buf->in.io, ox_readpartial_id, 1, args);
140
+ str = StringValuePtr(rstr);
141
+ cnt = strlen(str);
142
+ // printf("*** read partial %lu bytes, str: '%s'\n", cnt, str);
143
+ strcpy(buf->tail, str);
144
+ buf->read_end = buf->tail + cnt;
145
+
146
+ return Qtrue;
147
+ }
148
+
149
+ static VALUE io_cb(VALUE rbuf) {
150
+ Buf buf = (Buf)rbuf;
151
+ VALUE args[1];
152
+ VALUE rstr;
153
+ char *str;
154
+ size_t cnt;
155
+
156
+ args[0] = ULONG2NUM(buf->end - buf->tail);
157
+ rstr = rb_funcall2(buf->in.io, ox_read_id, 1, args);
158
+ str = StringValuePtr(rstr);
159
+ cnt = strlen(str);
160
+ // printf("*** read %lu bytes, str: '%s'\n", cnt, str);
161
+ strcpy(buf->tail, str);
162
+ buf->read_end = buf->tail + cnt;
163
+
164
+ return Qtrue;
165
+ }
166
+
167
+ static int read_from_io_partial(Buf buf) {
168
+ return (Qfalse == rb_rescue(partial_io_cb, (VALUE)buf, rescue_cb, (VALUE)buf));
169
+ }
170
+
171
+ static int read_from_io(Buf buf) {
172
+ return (Qfalse == rb_rescue(io_cb, (VALUE)buf, rescue_cb, (VALUE)buf));
173
+ }
174
+
175
+ static int read_from_fd(Buf buf) {
176
+ ssize_t cnt;
177
+ size_t max = buf->end - buf->tail;
178
+
179
+ cnt = read(buf->in.fd, buf->tail, max);
180
+ if (cnt < 0) {
181
+ ox_sax_drive_error(buf->dr, "failed to read from file");
182
+ return -1;
183
+ } else if (0 != cnt) {
184
+ buf->read_end = buf->tail + cnt;
185
+ }
186
+ return 0;
187
+ }
188
+
189
+ static int read_from_str(Buf buf) {
190
+ size_t max = buf->end - buf->tail - 1;
191
+ char *s;
192
+ size_t cnt;
193
+
194
+ if ('\0' == *buf->in.str) {
195
+ return -1;
196
+ }
197
+ cnt = strlen(buf->in.str) + 1;
198
+ if (max < cnt) {
199
+ cnt = max;
200
+ }
201
+ memcpy(buf->tail, buf->in.str, cnt);
202
+ s = buf->tail + cnt - 1;
203
+ *s = '\0';
204
+ cnt = s - buf->tail;
205
+ buf->in.str += cnt;
206
+ buf->read_end = buf->tail + cnt;
207
+
208
+ return 0;
209
+ }