ox 2.14.4 → 2.14.8

Sign up to get free protection for your applications and to get access to all the features.
data/ext/ox/sax.h CHANGED
@@ -8,46 +8,60 @@
8
8
 
9
9
  #include <stdbool.h>
10
10
 
11
+ #include "ox.h"
11
12
  #include "sax_buf.h"
12
- #include "sax_has.h"
13
- #include "sax_stack.h"
14
13
  #include "sax_hint.h"
15
- #include "ox.h"
14
+ #include "sax_stack.h"
16
15
 
17
16
  typedef struct _saxOptions {
18
- int symbolize;
19
- int convert_special;
20
- int smart;
21
- SkipMode skip;
22
- char strip_ns[64];
23
- Hints hints;
24
- } *SaxOptions;
17
+ int symbolize;
18
+ int convert_special;
19
+ int smart;
20
+ SkipMode skip;
21
+ char strip_ns[64];
22
+ Hints hints;
23
+ } * SaxOptions;
25
24
 
26
25
  typedef struct _saxDrive {
27
- struct _buf buf;
28
- struct _nStack stack; /* element name stack */
29
- VALUE handler;
30
- VALUE value_obj;
31
- struct _saxOptions options;
32
- int err;
33
- int blocked;
34
- bool abort;
35
- struct _has has;
36
- #if HAVE_RB_ENC_ASSOCIATE
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
+
37
44
  rb_encoding *encoding;
38
- #else
39
- const char *encoding;
40
- #endif
41
- } *SaxDrive;
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;
42
56
 
43
- extern void ox_collapse_return(char *str);
44
- extern void ox_sax_parse(VALUE handler, VALUE io, SaxOptions options);
45
- extern void ox_sax_drive_cleanup(SaxDrive dr);
46
- extern void ox_sax_drive_error(SaxDrive dr, const char *msg);
47
- extern int ox_sax_collapse_special(SaxDrive dr, char *str, long pos, long line, long col);
57
+ extern void ox_collapse_return(char *str);
58
+ extern void ox_sax_parse(VALUE handler, VALUE io, SaxOptions options);
59
+ extern void ox_sax_drive_cleanup(SaxDrive dr);
60
+ extern void ox_sax_drive_error(SaxDrive dr, const char *msg);
61
+ extern int ox_sax_collapse_special(SaxDrive dr, char *str, long pos, long line, long col);
48
62
 
49
- extern VALUE ox_sax_value_class;
63
+ extern VALUE ox_sax_value_class;
50
64
 
51
- extern VALUE str2sym(SaxDrive dr, const char *str, const char **strp);
65
+ extern VALUE str2sym(SaxDrive dr, const char *str, size_t len, const char **strp);
52
66
 
53
67
  #endif /* OX_SAX_H */
data/ext/ox/sax_as.c CHANGED
@@ -43,7 +43,7 @@ parse_double_time(const char *text) {
43
43
  for (; text - dot <= 9; text++) {
44
44
  v2 *= 10;
45
45
  }
46
- #if HAS_NANO_TIME
46
+ #if HAVE_RB_TIME_NANO_NEW
47
47
  return rb_time_nano_new(v, v2);
48
48
  #else
49
49
  return rb_time_new(v, v2 / 1000);
@@ -103,7 +103,7 @@ parse_xsd_time(const char *text) {
103
103
  tm.tm_hour = (int)cargs[3];
104
104
  tm.tm_min = (int)cargs[4];
105
105
  tm.tm_sec = (int)cargs[5];
106
- #if HAS_NANO_TIME
106
+ #if HAVE_RB_TIME_NANO_NEW
107
107
  return rb_time_nano_new(mktime(&tm), cargs[6]);
108
108
  #else
109
109
  return rb_time_new(mktime(&tm), cargs[6] / 1000);
@@ -136,11 +136,9 @@ sax_value_as_s(VALUE self) {
136
136
  break;
137
137
  }
138
138
  rs = rb_str_new2(dr->buf.str);
139
- #if HAVE_RB_ENC_ASSOCIATE
140
139
  if (0 != dr->encoding) {
141
140
  rb_enc_associate(rs, dr->encoding);
142
141
  }
143
- #endif
144
142
  return rs;
145
143
  }
146
144
 
@@ -155,7 +153,7 @@ sax_value_as_sym(VALUE self) {
155
153
  if ('\0' == *dr->buf.str) {
156
154
  return Qnil;
157
155
  }
158
- return str2sym(dr, dr->buf.str, 0);
156
+ return str2sym(dr, dr->buf.str, strlen(dr->buf.str), 0);
159
157
  }
160
158
 
161
159
  /* call-seq: as_f()
data/ext/ox/sax_buf.c CHANGED
@@ -194,30 +194,21 @@ read_from_fd(Buf buf) {
194
194
  return 0;
195
195
  }
196
196
 
197
- static char*
198
- ox_stpncpy(char *dest, const char *src, size_t n) {
199
- size_t cnt = strlen(src) + 1;
200
-
201
- if (n < cnt) {
202
- cnt = n;
203
- }
204
- strncpy(dest, src, cnt);
205
-
206
- return dest + cnt - 1;
207
- }
208
-
209
-
210
197
  static int
211
198
  read_from_str(Buf buf) {
212
199
  size_t max = buf->end - buf->tail - 1;
213
200
  char *s;
214
- long cnt;
201
+ size_t cnt;
215
202
 
216
203
  if ('\0' == *buf->in.str) {
217
- /* done */
218
204
  return -1;
219
205
  }
220
- s = ox_stpncpy(buf->tail, buf->in.str, max);
206
+ cnt = strlen(buf->in.str) + 1;
207
+ if (max < cnt) {
208
+ cnt = max;
209
+ }
210
+ strncpy(buf->tail, buf->in.str, cnt);
211
+ s = buf->tail + cnt - 1;
221
212
  *s = '\0';
222
213
  cnt = s - buf->tail;
223
214
  buf->in.str += cnt;
@@ -0,0 +1,158 @@
1
+ /* slotcache.c
2
+ * Copyright (c) 2011, Peter Ohler
3
+ * All rights reserved.
4
+ */
5
+
6
+ #include "slotcache.h"
7
+
8
+ #include <errno.h>
9
+ #include <stdarg.h>
10
+ #include <stdint.h>
11
+ #include <stdio.h>
12
+ #include <stdlib.h>
13
+ #include <string.h>
14
+ #include <strings.h>
15
+
16
+ struct _slotCache {
17
+ /* The key is a length byte followed by the key as a string. If the key is longer than 254 characters then the
18
+ length is 255. The key can be for a premature value and in that case the length byte is greater than the length
19
+ of the key. */
20
+ char *key;
21
+ VALUE value;
22
+ struct _slotCache *slots[16];
23
+ };
24
+
25
+ static void slot_print(SlotCache cache, unsigned int depth);
26
+
27
+ static char *form_key(const char *s) {
28
+ size_t len = strlen(s);
29
+ char *d = ALLOC_N(char, len + 2);
30
+
31
+ *(uint8_t *)d = (255 <= len) ? 255 : len;
32
+ memcpy(d + 1, s, len + 1);
33
+
34
+ return d;
35
+ }
36
+
37
+ void slot_cache_new(SlotCache *cache) {
38
+ *cache = ALLOC(struct _slotCache);
39
+ (*cache)->key = 0;
40
+ (*cache)->value = Qundef;
41
+ memset((*cache)->slots, 0, sizeof((*cache)->slots));
42
+ }
43
+
44
+ VALUE
45
+ slot_cache_get(SlotCache cache, const char *key, VALUE **slot, const char **keyp) {
46
+ unsigned char *k = (unsigned char *)key;
47
+ SlotCache *cp;
48
+
49
+ for (; '\0' != *k; k++) {
50
+ cp = cache->slots + (unsigned int)(*k >> 4); /* upper 4 bits */
51
+ if (0 == *cp) {
52
+ slot_cache_new(cp);
53
+ }
54
+ cache = *cp;
55
+ cp = cache->slots + (unsigned int)(*k & 0x0F); /* lower 4 bits */
56
+ if (0 == *cp) { /* nothing on this tree so set key and value as a premature key/value pair */
57
+ slot_cache_new(cp);
58
+ cache = *cp;
59
+ cache->key = form_key(key);
60
+ break;
61
+ } else {
62
+ int depth = (int)(k - (unsigned char *)key + 1);
63
+
64
+ cache = *cp;
65
+
66
+ if ('\0' == *(k + 1)) { /* exact match */
67
+ if (0 == cache->key) { /* nothing in this spot so take it */
68
+ cache->key = form_key(key);
69
+ break;
70
+ } else if ((depth == *cache->key || 255 < depth) && 0 == strcmp(key, cache->key + 1)) { /* match */
71
+ break;
72
+ } else { /* have to move the current premature key/value deeper */
73
+ unsigned char *ck = (unsigned char *)(cache->key + depth + 1);
74
+ SlotCache orig = *cp;
75
+
76
+ cp = (*cp)->slots + (*ck >> 4);
77
+ slot_cache_new(cp);
78
+ cp = (*cp)->slots + (*ck & 0x0F);
79
+ slot_cache_new(cp);
80
+ (*cp)->key = cache->key;
81
+ (*cp)->value = cache->value;
82
+ orig->key = form_key(key);
83
+ orig->value = Qundef;
84
+ }
85
+ } else { /* not exact match but on the path */
86
+ if (0 != cache->key) { /* there is a key/value here already */
87
+ if (depth == *cache->key || (255 <= depth && 0 == strncmp(cache->key, key, depth) &&
88
+ '\0' == cache->key[depth])) { /* key belongs here */
89
+ continue;
90
+ } else {
91
+ unsigned char *ck = (unsigned char *)(cache->key + depth + 1);
92
+ SlotCache orig = *cp;
93
+
94
+ cp = (*cp)->slots + (*ck >> 4);
95
+ slot_cache_new(cp);
96
+ cp = (*cp)->slots + (*ck & 0x0F);
97
+ slot_cache_new(cp);
98
+ (*cp)->key = cache->key;
99
+ (*cp)->value = cache->value;
100
+ orig->key = 0;
101
+ orig->value = Qundef;
102
+ }
103
+ }
104
+ }
105
+ }
106
+ }
107
+ *slot = &cache->value;
108
+ if (0 != keyp) {
109
+ if (0 == cache->key) {
110
+ printf("*** Error: failed to set the key for '%s'\n", key);
111
+ *keyp = 0;
112
+ } else {
113
+ *keyp = cache->key + 1;
114
+ }
115
+ }
116
+ return cache->value;
117
+ }
118
+
119
+ void slot_cache_print(SlotCache cache) {
120
+ /*printf("-------------------------------------------\n");*/
121
+ slot_print(cache, 0);
122
+ }
123
+
124
+ static void slot_print(SlotCache c, unsigned int depth) {
125
+ char indent[256];
126
+ SlotCache *cp;
127
+ unsigned int i;
128
+
129
+ if (sizeof(indent) - 1 < depth) {
130
+ depth = ((int)sizeof(indent) - 1);
131
+ }
132
+ memset(indent, ' ', depth);
133
+ indent[depth] = '\0';
134
+ for (i = 0, cp = c->slots; i < 16; i++, cp++) {
135
+ if (0 == *cp) {
136
+ /*printf("%s%02u:\n", indent, i);*/
137
+ } else {
138
+ if (0 == (*cp)->key && Qundef == (*cp)->value) {
139
+ printf("%s%02u:\n", indent, i);
140
+ } else {
141
+ const char *vs;
142
+ const char *clas;
143
+
144
+ if (Qundef == (*cp)->value) {
145
+ vs = "undefined";
146
+ clas = "";
147
+ } else {
148
+ VALUE rs = rb_funcall2((*cp)->value, rb_intern("to_s"), 0, 0);
149
+
150
+ vs = StringValuePtr(rs);
151
+ clas = rb_class2name(rb_obj_class((*cp)->value));
152
+ }
153
+ printf("%s%02u: %s = %s (%s)\n", indent, i, (*cp)->key, vs, clas);
154
+ }
155
+ slot_print(*cp, depth + 2);
156
+ }
157
+ }
158
+ }
@@ -0,0 +1,19 @@
1
+ /* slotcache.h
2
+ * Copyright (c) 2011, Peter Ohler
3
+ * All rights reserved.
4
+ */
5
+
6
+ #ifndef SLOT_CACHE_H
7
+ #define SLOT_CACHE_H
8
+
9
+ #include "ruby.h"
10
+
11
+ typedef struct _slotCache *SlotCache;
12
+
13
+ extern void slot_cache_new(SlotCache *cache);
14
+
15
+ extern VALUE slot_cache_get(SlotCache cache, const char *key, VALUE **slot, const char **keyp);
16
+
17
+ extern void slot_cache_print(SlotCache cache);
18
+
19
+ #endif /* SLOT_CACHE_H */
data/lib/ox/version.rb CHANGED
@@ -1,5 +1,5 @@
1
1
 
2
2
  module Ox
3
3
  # Current version of the module.
4
- VERSION = '2.14.4'
4
+ VERSION = '2.14.8'
5
5
  end
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: ox
3
3
  version: !ruby/object:Gem::Version
4
- version: 2.14.4
4
+ version: 2.14.8
5
5
  platform: ruby
6
6
  authors:
7
7
  - Peter Ohler
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2021-03-19 00:00:00.000000000 Z
11
+ date: 2022-02-09 00:00:00.000000000 Z
12
12
  dependencies: []
13
13
  description: "A fast XML parser and object serializer that uses only standard C lib.\n\nOptimized
14
14
  XML (Ox), as the name implies was written to provide speed optimized\nXML handling.
@@ -41,6 +41,8 @@ files:
41
41
  - ext/ox/gen_load.c
42
42
  - ext/ox/hash_load.c
43
43
  - ext/ox/helper.h
44
+ - ext/ox/intern.c
45
+ - ext/ox/intern.h
44
46
  - ext/ox/obj_load.c
45
47
  - ext/ox/ox.c
46
48
  - ext/ox/ox.h
@@ -50,10 +52,11 @@ files:
50
52
  - ext/ox/sax_as.c
51
53
  - ext/ox/sax_buf.c
52
54
  - ext/ox/sax_buf.h
53
- - ext/ox/sax_has.h
54
55
  - ext/ox/sax_hint.c
55
56
  - ext/ox/sax_hint.h
56
57
  - ext/ox/sax_stack.h
58
+ - ext/ox/slotcache.c
59
+ - ext/ox/slotcache.h
57
60
  - ext/ox/special.c
58
61
  - ext/ox/special.h
59
62
  - ext/ox/type.h
@@ -81,9 +84,12 @@ rdoc_options:
81
84
  - "--main"
82
85
  - README.md
83
86
  - "--title"
84
- - Ox Documentation
87
+ - Ox
85
88
  - "--exclude"
86
89
  - extconf.rb
90
+ - lib
91
+ - ext/ox
92
+ - README.md
87
93
  require_paths:
88
94
  - lib
89
95
  - ext
@@ -98,7 +104,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
98
104
  - !ruby/object:Gem::Version
99
105
  version: '0'
100
106
  requirements: []
101
- rubygems_version: 3.2.3
107
+ rubygems_version: 3.3.3
102
108
  signing_key:
103
109
  specification_version: 4
104
110
  summary: A fast XML parser and object serializer.
data/ext/ox/sax_has.h DELETED
@@ -1,53 +0,0 @@
1
- /* sax_has.h
2
- * Copyright (c) 2011, Peter Ohler
3
- * All rights reserved.
4
- */
5
-
6
- #ifndef OX_SAX_HAS_H
7
- #define OX_SAX_HAS_H
8
-
9
- typedef struct _has {
10
- int instruct;
11
- int end_instruct;
12
- int attr;
13
- int attrs_done;
14
- int attr_value;
15
- int doctype;
16
- int comment;
17
- int cdata;
18
- int text;
19
- int value;
20
- int start_element;
21
- int end_element;
22
- int error;
23
- int pos;
24
- int line;
25
- int column;
26
- } *Has;
27
-
28
- inline static int
29
- respond_to(VALUE obj, ID method) {
30
- return rb_respond_to(obj, method);
31
- }
32
-
33
- inline static void
34
- has_init(Has has, VALUE handler) {
35
- has->instruct = respond_to(handler, ox_instruct_id);
36
- has->end_instruct = respond_to(handler, ox_end_instruct_id);
37
- has->attr = respond_to(handler, ox_attr_id);
38
- has->attr_value = respond_to(handler, ox_attr_value_id);
39
- has->attrs_done = respond_to(handler, ox_attrs_done_id);
40
- has->doctype = respond_to(handler, ox_doctype_id);
41
- has->comment = respond_to(handler, ox_comment_id);
42
- has->cdata = respond_to(handler, ox_cdata_id);
43
- has->text = respond_to(handler, ox_text_id);
44
- has->value = respond_to(handler, ox_value_id);
45
- has->start_element = respond_to(handler, ox_start_element_id);
46
- has->end_element = respond_to(handler, ox_end_element_id);
47
- has->error = respond_to(handler, ox_error_id);
48
- has->pos = (Qtrue == rb_ivar_defined(handler, ox_at_pos_id));
49
- has->line = (Qtrue == rb_ivar_defined(handler, ox_at_line_id));
50
- has->column = (Qtrue == rb_ivar_defined(handler, ox_at_column_id));
51
- }
52
-
53
- #endif /* OX_SAX_HAS_H */