ox 2.0.0 → 2.0.1
Sign up to get free protection for your applications and to get access to all the features.
Potentially problematic release.
This version of ox might be problematic. Click here for more details.
- checksums.yaml +4 -4
- data/README.md +121 -128
- data/ext/ox/attr.h +109 -0
- data/ext/ox/err.c +64 -0
- data/ext/ox/err.h +61 -0
- data/ext/ox/gen_load.c +32 -33
- data/ext/ox/helper.h +116 -0
- data/ext/ox/obj_load.c +551 -518
- data/ext/ox/ox.c +43 -20
- data/ext/ox/ox.h +9 -47
- data/ext/ox/parse.c +146 -70
- data/ext/ox/sax.c +19 -1
- data/ext/ox/sax_buf.c +5 -4
- data/ext/ox/sax_has.h +2 -0
- data/ext/ox/sax_stack.h +3 -3
- data/ext/ox/type.h +63 -0
- data/lib/ox/sax.rb +12 -6
- data/lib/ox/version.rb +1 -1
- metadata +8 -4
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 1a2fc7c5c778f642b52fcf67698d66ef22980334
|
4
|
+
data.tar.gz: 36104a1aef0a7fdcf025ce033ebc614cde934ed7
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 4190d2fd9661a40b1fa388f3e736a114d1561d823aa4ba2f17ddea9cca8405a1f0f95fb498d2fdd053ebc1a743f076995003e8e45f7dcf85c072f23848aaa024
|
7
|
+
data.tar.gz: bda2a5979727f68eb5d629f7aa69dc1c0912bb232b7068005b18d27c89dcaf5f74b40fcae07ef08eebd27cd6143ad05dfa8eb4bc71c60bef583c71625ebbb772
|
data/README.md
CHANGED
@@ -34,24 +34,17 @@ A fast XML parser and Object marshaller as a Ruby gem.
|
|
34
34
|
|
35
35
|
## <a name="release">Release Notes</a>
|
36
36
|
|
37
|
-
### Release 2.0.
|
37
|
+
### Release 2.0.1
|
38
38
|
|
39
|
-
-
|
40
|
-
|
41
|
-
only behavior. A smart option was added however. The smart option recognizes a file as an HTML file and will apply a
|
42
|
-
simple set of validation rules that allow the HTML to be parsed more reasonably. Errors will cause callbacks but the
|
43
|
-
parsing continues with the best guess as to how to recover. Rubymaniac has helped with testing and prompted the
|
44
|
-
rewrite to support parsing HTML pages.
|
39
|
+
- Added an attrs_done callback to the sax parser that will be called when all
|
40
|
+
attributes for an element have been read.
|
45
41
|
|
46
|
-
-
|
47
|
-
|
48
|
-
continue parsing even after errors.
|
42
|
+
- Fixed bug in SAX parser where raising an exception in the handler routines
|
43
|
+
would not cleanup. The test put together by griffinmyers was a huge help.
|
49
44
|
|
50
|
-
-
|
51
|
-
element and attribute names.
|
45
|
+
- Reduced stack use in a several places to improve fiber support.
|
52
46
|
|
53
|
-
-
|
54
|
-
contributor is Notezen with a nice way of building XML.
|
47
|
+
- Changed exception handling to assure proper cleanup with new stack minimizing.
|
55
48
|
|
56
49
|
## <a name="description">Description</a>
|
57
50
|
|
@@ -98,92 +91,92 @@ Ox is compatible with Ruby 1.8.7, 1.9.2, JRuby, and RBX.
|
|
98
91
|
### Object Dump Sample:
|
99
92
|
|
100
93
|
```ruby
|
101
|
-
|
102
|
-
|
103
|
-
|
104
|
-
|
105
|
-
|
106
|
-
|
107
|
-
|
108
|
-
|
109
|
-
|
110
|
-
|
111
|
-
|
112
|
-
|
113
|
-
|
114
|
-
|
115
|
-
|
116
|
-
|
117
|
-
|
118
|
-
|
94
|
+
require 'ox'
|
95
|
+
|
96
|
+
class Sample
|
97
|
+
attr_accessor :a, :b, :c
|
98
|
+
|
99
|
+
def initialize(a, b, c)
|
100
|
+
@a = a
|
101
|
+
@b = b
|
102
|
+
@c = c
|
103
|
+
end
|
104
|
+
end
|
105
|
+
|
106
|
+
# Create Object
|
107
|
+
obj = Sample.new(1, "bee", ['x', :y, 7.0])
|
108
|
+
# Now dump the Object to an XML String.
|
109
|
+
xml = Ox.dump(obj)
|
110
|
+
# Convert the object back into a Sample Object.
|
111
|
+
obj2 = Ox.parse_obj(xml)
|
119
112
|
```
|
120
113
|
|
121
114
|
### Generic XML Writing and Parsing:
|
122
115
|
|
123
116
|
```ruby
|
124
|
-
|
125
|
-
|
126
|
-
|
127
|
-
|
128
|
-
|
129
|
-
|
130
|
-
|
131
|
-
|
132
|
-
|
133
|
-
|
134
|
-
|
135
|
-
|
136
|
-
|
137
|
-
|
138
|
-
|
139
|
-
|
140
|
-
|
141
|
-
|
142
|
-
|
143
|
-
|
144
|
-
|
145
|
-
|
146
|
-
|
147
|
-
|
148
|
-
|
149
|
-
|
150
|
-
|
151
|
-
|
117
|
+
require 'ox'
|
118
|
+
|
119
|
+
doc = Ox::Document.new(:version => '1.0')
|
120
|
+
|
121
|
+
top = Ox::Element.new('top')
|
122
|
+
top[:name] = 'sample'
|
123
|
+
doc << top
|
124
|
+
|
125
|
+
mid = Ox::Element.new('middle')
|
126
|
+
mid[:name] = 'second'
|
127
|
+
top << mid
|
128
|
+
|
129
|
+
bot = Ox::Element.new('bottom')
|
130
|
+
bot[:name] = 'third'
|
131
|
+
mid << bot
|
132
|
+
|
133
|
+
xml = Ox.dump(doc)
|
134
|
+
|
135
|
+
# xml =
|
136
|
+
# <top name="sample">
|
137
|
+
# <middle name="second">
|
138
|
+
# <bottom name="third"/>
|
139
|
+
# </middle>
|
140
|
+
# </top>
|
141
|
+
|
142
|
+
doc2 = Ox.parse(xml)
|
143
|
+
puts "Same? #{doc == doc2}"
|
144
|
+
# true
|
152
145
|
```
|
153
146
|
|
154
147
|
### SAX XML Parsing:
|
155
148
|
|
156
149
|
```ruby
|
157
|
-
|
158
|
-
|
159
|
-
|
160
|
-
|
161
|
-
|
162
|
-
|
163
|
-
|
164
|
-
|
165
|
-
|
166
|
-
|
167
|
-
|
168
|
-
|
169
|
-
|
170
|
-
|
171
|
-
|
172
|
-
|
173
|
-
|
174
|
-
|
175
|
-
|
176
|
-
|
177
|
-
|
178
|
-
|
179
|
-
|
180
|
-
|
181
|
-
|
182
|
-
|
183
|
-
|
184
|
-
|
185
|
-
|
186
|
-
|
150
|
+
require 'stringio'
|
151
|
+
require 'ox'
|
152
|
+
|
153
|
+
class Sample < ::Ox::Sax
|
154
|
+
def start_element(name); puts "start: #{name}"; end
|
155
|
+
def end_element(name); puts "end: #{name}"; end
|
156
|
+
def attr(name, value); puts " #{name} => #{value}"; end
|
157
|
+
def text(value); puts "text #{value}"; end
|
158
|
+
end
|
159
|
+
|
160
|
+
io = StringIO.new(%{
|
161
|
+
<top name="sample">
|
162
|
+
<middle name="second">
|
163
|
+
<bottom name="third"/>
|
164
|
+
</middle>
|
165
|
+
</top>
|
166
|
+
})
|
167
|
+
|
168
|
+
handler = Sample.new()
|
169
|
+
Ox.sax_parse(handler, io)
|
170
|
+
# outputs
|
171
|
+
# start: top
|
172
|
+
# name => sample
|
173
|
+
# start: middle
|
174
|
+
# name => second
|
175
|
+
# start: bottom
|
176
|
+
# name => third
|
177
|
+
# end: bottom
|
178
|
+
# end: middle
|
179
|
+
# end: top
|
187
180
|
```
|
188
181
|
|
189
182
|
### Object XML format
|
@@ -196,27 +189,27 @@ necessary.
|
|
196
189
|
|
197
190
|
The type indicator map is:
|
198
191
|
|
199
|
-
- **a** => Array
|
200
|
-
- **b** => Base64
|
201
|
-
- **c** => Class
|
202
|
-
- **f** => Float
|
203
|
-
- **g** => Regexp
|
204
|
-
- **h** => Hash
|
205
|
-
- **i** => Fixnum
|
206
|
-
- **j** => Bignum
|
207
|
-
- **l** => Rational
|
208
|
-
- **m** => Symbol
|
209
|
-
- **n** => FalseClass
|
210
|
-
- **o** => Object
|
211
|
-
- **p** => Ref
|
212
|
-
- **r** => Range
|
213
|
-
- **s** => String
|
214
|
-
- **t** => Time
|
215
|
-
- **u** => Struct
|
216
|
-
- **v** => Complex
|
217
|
-
- **x** => Raw
|
218
|
-
- **y** => TrueClass
|
219
|
-
- **z** => NilClass
|
192
|
+
- **a** => `Array`
|
193
|
+
- **b** => `Base64`
|
194
|
+
- **c** => `Class`
|
195
|
+
- **f** => `Float`
|
196
|
+
- **g** => `Regexp`
|
197
|
+
- **h** => `Hash`
|
198
|
+
- **i** => `Fixnum`
|
199
|
+
- **j** => `Bignum`
|
200
|
+
- **l** => `Rational`
|
201
|
+
- **m** => `Symbol`
|
202
|
+
- **n** => `FalseClass`
|
203
|
+
- **o** => `Object`
|
204
|
+
- **p** => `Ref`
|
205
|
+
- **r** => `Range`
|
206
|
+
- **s** => `String`
|
207
|
+
- **t** => `Time`
|
208
|
+
- **u** => `Struct`
|
209
|
+
- **v** => `Complex`
|
210
|
+
- **x** => `Raw`
|
211
|
+
- **y** => `TrueClass`
|
212
|
+
- **z** => `NilClass`
|
220
213
|
|
221
214
|
If the type is an Object, type 'o' then an attribute named 'c' should be set
|
222
215
|
with the full Class name including the Module names. If the XML element
|
@@ -230,27 +223,27 @@ interpreter.)
|
|
230
223
|
|
231
224
|
Values are encoded as the text portion of an element or in the sub-elements
|
232
225
|
of the principle. For example, a Fixnum is encoded as:
|
233
|
-
|
234
|
-
|
235
|
-
|
226
|
+
```xml
|
227
|
+
<i>123</i>
|
228
|
+
```
|
236
229
|
An Array has sub-elements and is encoded similar to this example.
|
237
|
-
|
238
|
-
|
239
|
-
|
240
|
-
|
241
|
-
|
242
|
-
|
230
|
+
```xml
|
231
|
+
<a>
|
232
|
+
<i>1</i>
|
233
|
+
<s>abc</s>
|
234
|
+
</a>
|
235
|
+
```
|
243
236
|
A Hash is encoded with an even number of elements where the first element is
|
244
237
|
the key and the second is the value. This is repeated for each entry in the
|
245
238
|
Hash. An example is of { 1 => 'one', 2 => 'two' } encoding is:
|
246
|
-
|
247
|
-
|
248
|
-
|
249
|
-
|
250
|
-
|
251
|
-
|
252
|
-
|
253
|
-
|
239
|
+
```xml
|
240
|
+
<h>
|
241
|
+
<i>1</i>
|
242
|
+
<s>one</s>
|
243
|
+
<i>2</i>
|
244
|
+
<s>two</s>
|
245
|
+
</h>
|
246
|
+
```
|
254
247
|
Strings with characters not allowed in XML are base64 encoded amd will be
|
255
248
|
converted back into a String when loaded.
|
256
249
|
|
data/ext/ox/attr.h
ADDED
@@ -0,0 +1,109 @@
|
|
1
|
+
/* attr.h
|
2
|
+
* Copyright (c) 2011, Peter Ohler
|
3
|
+
* All rights reserved.
|
4
|
+
*
|
5
|
+
* Redistribution and use in source and binary forms, with or without
|
6
|
+
* modification, are permitted provided that the following conditions are met:
|
7
|
+
*
|
8
|
+
* - Redistributions of source code must retain the above copyright notice, this
|
9
|
+
* list of conditions and the following disclaimer.
|
10
|
+
*
|
11
|
+
* - Redistributions in binary form must reproduce the above copyright notice,
|
12
|
+
* this list of conditions and the following disclaimer in the documentation
|
13
|
+
* and/or other materials provided with the distribution.
|
14
|
+
*
|
15
|
+
* - Neither the name of Peter Ohler nor the names of its contributors may be
|
16
|
+
* used to endorse or promote products derived from this software without
|
17
|
+
* specific prior written permission.
|
18
|
+
*
|
19
|
+
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
|
20
|
+
* AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
21
|
+
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
|
22
|
+
* DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE
|
23
|
+
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
|
24
|
+
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
|
25
|
+
* SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
|
26
|
+
* CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
|
27
|
+
* OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
|
28
|
+
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
29
|
+
*/
|
30
|
+
|
31
|
+
#ifndef __OX_ATTR_H__
|
32
|
+
#define __OX_ATTR_H__
|
33
|
+
|
34
|
+
#include "ox.h"
|
35
|
+
|
36
|
+
#define ATTR_STACK_INC 8
|
37
|
+
|
38
|
+
typedef struct _Attr {
|
39
|
+
const char *name;
|
40
|
+
const char *value;
|
41
|
+
} *Attr;
|
42
|
+
|
43
|
+
typedef struct _AttrStack {
|
44
|
+
struct _Attr base[ATTR_STACK_INC];
|
45
|
+
Attr head; /* current stack */
|
46
|
+
Attr end; /* stack end */
|
47
|
+
Attr tail; /* pointer to one past last element name on stack */
|
48
|
+
} *AttrStack;
|
49
|
+
|
50
|
+
inline static void
|
51
|
+
attr_stack_init(AttrStack stack) {
|
52
|
+
stack->head = stack->base;
|
53
|
+
stack->end = stack->base + sizeof(stack->base) / sizeof(struct _Attr);
|
54
|
+
stack->tail = stack->head;
|
55
|
+
stack->head->name = 0;
|
56
|
+
}
|
57
|
+
|
58
|
+
inline static int
|
59
|
+
attr_stack_empty(AttrStack stack) {
|
60
|
+
return (stack->head == stack->tail);
|
61
|
+
}
|
62
|
+
|
63
|
+
inline static void
|
64
|
+
attr_stack_cleanup(AttrStack stack) {
|
65
|
+
if (stack->base != stack->head) {
|
66
|
+
xfree(stack->head);
|
67
|
+
stack->head = stack->base;
|
68
|
+
}
|
69
|
+
}
|
70
|
+
|
71
|
+
inline static void
|
72
|
+
attr_stack_push(AttrStack stack, const char *name, const char *value) {
|
73
|
+
if (stack->end <= stack->tail + 1) {
|
74
|
+
size_t len = stack->end - stack->head;
|
75
|
+
size_t toff = stack->tail - stack->head;
|
76
|
+
|
77
|
+
if (stack->base == stack->head) {
|
78
|
+
stack->head = ALLOC_N(struct _Attr, len + ATTR_STACK_INC);
|
79
|
+
memcpy(stack->head, stack->base, sizeof(struct _Attr) * len);
|
80
|
+
} else {
|
81
|
+
REALLOC_N(stack->head, struct _Attr, len + ATTR_STACK_INC);
|
82
|
+
}
|
83
|
+
stack->tail = stack->head + toff;
|
84
|
+
stack->end = stack->head + len + ATTR_STACK_INC;
|
85
|
+
}
|
86
|
+
stack->tail->name = name;
|
87
|
+
stack->tail->value = value;
|
88
|
+
stack->tail++;
|
89
|
+
stack->tail->name = 0; // terminate
|
90
|
+
}
|
91
|
+
|
92
|
+
inline static Attr
|
93
|
+
attr_stack_peek(AttrStack stack) {
|
94
|
+
if (stack->head < stack->tail) {
|
95
|
+
return stack->tail - 1;
|
96
|
+
}
|
97
|
+
return 0;
|
98
|
+
}
|
99
|
+
|
100
|
+
inline static Attr
|
101
|
+
attr_stack_pop(AttrStack stack) {
|
102
|
+
if (stack->head < stack->tail) {
|
103
|
+
stack->tail--;
|
104
|
+
return stack->tail;
|
105
|
+
}
|
106
|
+
return 0;
|
107
|
+
}
|
108
|
+
|
109
|
+
#endif /* __OX_ATTR_H__ */
|
data/ext/ox/err.c
ADDED
@@ -0,0 +1,64 @@
|
|
1
|
+
/* err.c
|
2
|
+
* Copyright (c) 2011, Peter Ohler
|
3
|
+
* All rights reserved.
|
4
|
+
*
|
5
|
+
* Redistribution and use in source and binary forms, with or without
|
6
|
+
* modification, are permitted provided that the following conditions are met:
|
7
|
+
*
|
8
|
+
* - Redistributions of source code must retain the above copyright notice, this
|
9
|
+
* list of conditions and the following disclaimer.
|
10
|
+
*
|
11
|
+
* - Redistributions in binary form must reproduce the above copyright notice,
|
12
|
+
* this list of conditions and the following disclaimer in the documentation
|
13
|
+
* and/or other materials provided with the distribution.
|
14
|
+
*
|
15
|
+
* - Neither the name of Peter Ohler nor the names of its contributors may be
|
16
|
+
* used to endorse or promote products derived from this software without
|
17
|
+
* specific prior written permission.
|
18
|
+
*
|
19
|
+
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
|
20
|
+
* AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
21
|
+
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
|
22
|
+
* DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE
|
23
|
+
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
|
24
|
+
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
|
25
|
+
* SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
|
26
|
+
* CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
|
27
|
+
* OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
|
28
|
+
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
29
|
+
*/
|
30
|
+
|
31
|
+
#include <stdarg.h>
|
32
|
+
|
33
|
+
#include "err.h"
|
34
|
+
|
35
|
+
void
|
36
|
+
ox_err_set(Err e, VALUE clas, const char *format, ...) {
|
37
|
+
va_list ap;
|
38
|
+
|
39
|
+
va_start(ap, format);
|
40
|
+
e->clas = clas;
|
41
|
+
vsnprintf(e->msg, sizeof(e->msg) - 1, format, ap);
|
42
|
+
va_end(ap);
|
43
|
+
}
|
44
|
+
|
45
|
+
void
|
46
|
+
ox_err_raise(Err e) {
|
47
|
+
rb_raise(e->clas, "%s", e->msg);
|
48
|
+
}
|
49
|
+
|
50
|
+
void
|
51
|
+
_ox_err_set_with_location(Err err, const char *msg, const char *xml, const char *current, const char* file, int line) {
|
52
|
+
int xline = 1;
|
53
|
+
int col = 1;
|
54
|
+
|
55
|
+
for (; xml < current && '\n' != *current; current--) {
|
56
|
+
col++;
|
57
|
+
}
|
58
|
+
for (; xml < current; current--) {
|
59
|
+
if ('\n' == *current) {
|
60
|
+
xline++;
|
61
|
+
}
|
62
|
+
}
|
63
|
+
ox_err_set(err, ox_parse_error_class, "%s at line %d, column %d [%s:%d]\n", msg, xline, col, file, line);
|
64
|
+
}
|