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 CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA1:
3
- metadata.gz: 31bc59694575361e4f784ffc8eb8b37fdbb08057
4
- data.tar.gz: 9332c70a159d96aa167cc738ac0a0e5bbb2ff6e9
3
+ metadata.gz: 1a2fc7c5c778f642b52fcf67698d66ef22980334
4
+ data.tar.gz: 36104a1aef0a7fdcf025ce033ebc614cde934ed7
5
5
  SHA512:
6
- metadata.gz: 8ee7dccef40d6141d12b1d8eee8a5b92e5d0ad4b04a0c253086c4c333961da1894eb6a450031bf6e4476f6d62c0fb4392793786ae9fdcc2dd84db7597ac8b2bf
7
- data.tar.gz: 22bed155c466594191d54ac1ed6db28d6a442c54b03836bf94378590af164fc2d2f67713d44ecd4cfedad1c2aec3bb06df5ca029eff746753b2f8715e2f6f8c9
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.0
37
+ ### Release 2.0.1
38
38
 
39
- - The SAX parser went through a significant re-write. The options have changed. It is now 15% faster on large files and
40
- much better at recovering from errors. So much so that the tolerant option was removed and is now the default and
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
- - HTML is now supported with the SAX parser. The parser knows some tags like \<br\> or \<img\> do not have to be
47
- closed. Other hints as to how to parse and when to raise errors are also included. The parser does it's best to
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
- - Added symbolize option to the sax parser. This option, if set to false will use strings instead of symbols for
51
- element and attribute names.
45
+ - Reduced stack use in a several places to improve fiber support.
52
46
 
53
- - A contrib directory was added for people to submit useful bits of code that can be used with Ox. The first
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
- require 'ox'
102
-
103
- class Sample
104
- attr_accessor :a, :b, :c
105
-
106
- def initialize(a, b, c)
107
- @a = a
108
- @b = b
109
- @c = c
110
- end
111
- end
112
-
113
- # Create Object
114
- obj = Sample.new(1, "bee", ['x', :y, 7.0])
115
- # Now dump the Object to an XML String.
116
- xml = Ox.dump(obj)
117
- # Convert the object back into a Sample Object.
118
- obj2 = Ox.parse_obj(xml)
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
- require 'ox'
125
-
126
- doc = Ox::Document.new(:version => '1.0')
127
-
128
- top = Ox::Element.new('top')
129
- top[:name] = 'sample'
130
- doc << top
131
-
132
- mid = Ox::Element.new('middle')
133
- mid[:name] = 'second'
134
- top << mid
135
-
136
- bot = Ox::Element.new('bottom')
137
- bot[:name] = 'third'
138
- mid << bot
139
-
140
- xml = Ox.dump(doc)
141
-
142
- # xml =
143
- # <top name="sample">
144
- # <middle name="second">
145
- # <bottom name="third"/>
146
- # </middle>
147
- # </top>
148
-
149
- doc2 = Ox.parse(xml)
150
- puts "Same? #{doc == doc2}"
151
- # true
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
- require 'stringio'
158
- require 'ox'
159
-
160
- class Sample < ::Ox::Sax
161
- def start_element(name); puts "start: #{name}"; end
162
- def end_element(name); puts "end: #{name}"; end
163
- def attr(name, value); puts " #{name} => #{value}"; end
164
- def text(value); puts "text #{value}"; end
165
- end
166
-
167
- io = StringIO.new(%{
168
- <top name="sample">
169
- <middle name="second">
170
- <bottom name="third"/>
171
- </middle>
172
- </top>
173
- })
174
-
175
- handler = Sample.new()
176
- Ox.sax_parse(handler, io)
177
- # outputs
178
- # start: top
179
- # name => sample
180
- # start: middle
181
- # name => second
182
- # start: bottom
183
- # name => third
184
- # end: bottom
185
- # end: middle
186
- # end: top
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
- <i>123</i>
235
-
226
+ ```xml
227
+ <i>123</i>
228
+ ```
236
229
  An Array has sub-elements and is encoded similar to this example.
237
-
238
- <a>
239
- <i>1</i>
240
- <s>abc</s>
241
- </a>
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
- <h>
248
- <i>1</i>
249
- <s>one</s>
250
- <i>2</i>
251
- <s>two</s>
252
- </h>
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
+ }