ox 2.11.0 → 2.12.0
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 +4 -0
- data/README.md +24 -7
- data/ext/ox/dump.c +13 -1
- data/ext/ox/ox.c +25 -2
- data/ext/ox/ox.h +23 -22
- data/lib/ox/version.rb +1 -1
- metadata +3 -4
- data/ext/ox/encode.h +0 -26
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 5923d0aee2bea7b543f7aec674879c552846492786d05af0d7fd6447f4e60d3b
|
4
|
+
data.tar.gz: b0acca612b1a7624847d0c2399f18b7d122c4d9f41a77deaee23ac96c76d87c2
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 5c9f59561ace452549c579d22f30b3c0101f0ec9e1f3bf302d711aee2844af32c5c575057fb28c60aecff009c7314d4772691c187368517939ec0ed8a48fc74d
|
7
|
+
data.tar.gz: 4a13ef2c59d159cb1728751c1ec7eb896df35909fb6434e65d722a8ef96e96a2a95e309852f21daf6de87c41e7ca13b13d19015f5bbaed1b0a0dcca5d14b123c
|
data/CHANGELOG.md
CHANGED
data/README.md
CHANGED
@@ -22,7 +22,7 @@ A fast XML parser and Object marshaller as a Ruby gem.
|
|
22
22
|
|
23
23
|
## Support
|
24
24
|
|
25
|
-
[Get supported Ox with a Tidelift Subscription.](https://tidelift.com/subscription/pkg/rubygems-ox?utm_source=rubygems-ox&utm_medium=referral&utm_campaign=readme)
|
25
|
+
[Get supported Ox with a Tidelift Subscription.](https://tidelift.com/subscription/pkg/rubygems-ox?utm_source=rubygems-ox&utm_medium=referral&utm_campaign=readme) Security updates are [supported](https://tidelift.com/security).
|
26
26
|
|
27
27
|
## Links of Interest
|
28
28
|
|
@@ -108,7 +108,13 @@ obj2 = Ox.parse_obj(xml)
|
|
108
108
|
```ruby
|
109
109
|
require 'ox'
|
110
110
|
|
111
|
-
doc = Ox::Document.new
|
111
|
+
doc = Ox::Document.new
|
112
|
+
|
113
|
+
instruct = Ox::Instruct.new(:xml)
|
114
|
+
instruct[:version] = '1.0'
|
115
|
+
instruct[:encoding] = 'UTF-8'
|
116
|
+
instruct[:standalone] = 'yes'
|
117
|
+
doc << instruct
|
112
118
|
|
113
119
|
top = Ox::Element.new('top')
|
114
120
|
top[:name] = 'sample'
|
@@ -120,20 +126,31 @@ top << mid
|
|
120
126
|
|
121
127
|
bot = Ox::Element.new('bottom')
|
122
128
|
bot[:name] = 'third'
|
129
|
+
bot << 'text at bottom'
|
123
130
|
mid << bot
|
124
131
|
|
132
|
+
other_elements = Ox::Element.new('otherElements')
|
133
|
+
other_elements << Ox::CData.new('<sender>John Smith</sender>')
|
134
|
+
other_elements << Ox::Comment.new('Director\'s commentary')
|
135
|
+
# other_elements << Ox::DocType.new('content')
|
136
|
+
other_elements << Ox::Raw.new('<warning>Be carefull with this! Direct inject into XML!</warning>')
|
137
|
+
top << other_elements
|
138
|
+
|
139
|
+
|
125
140
|
xml = Ox.dump(doc)
|
126
141
|
|
127
142
|
# xml =
|
143
|
+
# <?xml version="1.0" encoding="UTF-8" standalone="yes"?>
|
128
144
|
# <top name="sample">
|
129
145
|
# <middle name="second">
|
130
|
-
# <bottom name="third"
|
146
|
+
# <bottom name="third">text at bottom</bottom>
|
131
147
|
# </middle>
|
148
|
+
# <otherElements>
|
149
|
+
# <![CDATA[<sender>John Smith</sender>]]>
|
150
|
+
# <!-- Director's commentary -->
|
151
|
+
# <warning>Be carefull with this! Direct inject into XML!</warning>
|
152
|
+
# </otherElements>
|
132
153
|
# </top>
|
133
|
-
|
134
|
-
doc2 = Ox.parse(xml)
|
135
|
-
puts "Same? #{doc == doc2}"
|
136
|
-
# true
|
137
154
|
```
|
138
155
|
|
139
156
|
### HTML Parsing:
|
data/ext/ox/dump.c
CHANGED
@@ -301,7 +301,14 @@ dump_start(Out out, Element e) {
|
|
301
301
|
fill_attr(out, 'i', s, end - s);
|
302
302
|
}
|
303
303
|
if (e->closed) {
|
304
|
-
|
304
|
+
if (out->opts->no_empty) {
|
305
|
+
*out->cur++ = '>';
|
306
|
+
*out->cur++ = '<';
|
307
|
+
*out->cur++ = '/';
|
308
|
+
*out->cur++ = e->type;
|
309
|
+
} else {
|
310
|
+
*out->cur++ = '/';
|
311
|
+
}
|
305
312
|
}
|
306
313
|
*out->cur++ = '>';
|
307
314
|
*out->cur = '\0';
|
@@ -1105,6 +1112,11 @@ dump_gen_element(VALUE obj, int depth, Out out) {
|
|
1105
1112
|
*out->cur++ = '<';
|
1106
1113
|
*out->cur++ = '/';
|
1107
1114
|
fill_value(out, name, nlen);
|
1115
|
+
} else if (out->opts->no_empty) {
|
1116
|
+
*out->cur++ = '>';
|
1117
|
+
*out->cur++ = '<';
|
1118
|
+
*out->cur++ = '/';
|
1119
|
+
fill_value(out, name, nlen);
|
1108
1120
|
} else {
|
1109
1121
|
*out->cur++ = '/';
|
1110
1122
|
}
|
data/ext/ox/ox.c
CHANGED
@@ -127,6 +127,7 @@ static VALUE limited_sym;
|
|
127
127
|
static VALUE margin_sym;
|
128
128
|
static VALUE mode_sym;
|
129
129
|
static VALUE nest_ok_sym;
|
130
|
+
static VALUE no_empty_sym;
|
130
131
|
static VALUE object_sym;
|
131
132
|
static VALUE off_sym;
|
132
133
|
static VALUE opt_format_sym;
|
@@ -177,8 +178,9 @@ struct _options ox_default_options = {
|
|
177
178
|
Yes, // sym_keys
|
178
179
|
SpcSkip, // skip
|
179
180
|
No, // smart
|
180
|
-
|
181
|
+
true, // convert_special
|
181
182
|
No, // allow_invalid
|
183
|
+
false, // no_empty
|
182
184
|
{ '\0' }, // inv_repl
|
183
185
|
{ '\0' }, // strip_ns
|
184
186
|
NULL, // html_hints
|
@@ -293,6 +295,7 @@ hints_to_overlay(Hints hints) {
|
|
293
295
|
* - _:smart_ [true|false|nil] flag indicating the SAX parser uses hints if available (use with html)
|
294
296
|
* - _:convert_special_ [true|false|nil] flag indicating special characters like < are converted with the SAX parser
|
295
297
|
* - _:invalid_replace_ [nil|String] replacement string for invalid XML characters on dump. nil indicates include anyway as hex. A string, limited to 10 characters will replace the invalid character with the replace.
|
298
|
+
* - _:no_empty_ [true|false|nil] flag indicating there should be no empty elements in a dump
|
296
299
|
* - _:strip_namespace_ [String|true|false] false or "" results in no namespace stripping. A string of "*" or true will strip all namespaces. Any other non-empty string indicates that matching namespaces will be stripped.
|
297
300
|
* - _:overlay_ [Hash] a Hash of keys that match html element names and values that are one of
|
298
301
|
* - _:active_ - make the normal callback for the element
|
@@ -326,6 +329,7 @@ get_def_opts(VALUE self) {
|
|
326
329
|
rb_hash_aset(opts, element_key_mod_sym, ox_default_options.element_key_mod);
|
327
330
|
rb_hash_aset(opts, smart_sym, (Yes == ox_default_options.smart) ? Qtrue : ((No == ox_default_options.smart) ? Qfalse : Qnil));
|
328
331
|
rb_hash_aset(opts, convert_special_sym, (ox_default_options.convert_special) ? Qtrue : Qfalse);
|
332
|
+
rb_hash_aset(opts, no_empty_sym, (ox_default_options.no_empty) ? Qtrue : Qfalse);
|
329
333
|
switch (ox_default_options.mode) {
|
330
334
|
case ObjMode: rb_hash_aset(opts, mode_sym, object_sym); break;
|
331
335
|
case GenMode: rb_hash_aset(opts, mode_sym, generic_sym); break;
|
@@ -542,6 +546,17 @@ set_def_opts(VALUE self, VALUE opts) {
|
|
542
546
|
rb_raise(ox_parse_error_class, ":convert_special must be true or false.\n");
|
543
547
|
}
|
544
548
|
|
549
|
+
v = rb_hash_lookup(opts, no_empty_sym);
|
550
|
+
if (Qnil == v) {
|
551
|
+
// no change
|
552
|
+
} else if (Qtrue == v) {
|
553
|
+
ox_default_options.no_empty = 1;
|
554
|
+
} else if (Qfalse == v) {
|
555
|
+
ox_default_options.no_empty = 0;
|
556
|
+
} else {
|
557
|
+
rb_raise(ox_parse_error_class, ":no_empty must be true or false.\n");
|
558
|
+
}
|
559
|
+
|
545
560
|
v = rb_hash_aref(opts, invalid_replace_sym);
|
546
561
|
if (Qnil == v) {
|
547
562
|
ox_default_options.allow_invalid = Yes;
|
@@ -777,6 +792,9 @@ load(char *xml, size_t len, int argc, VALUE *argv, VALUE self, VALUE encoding, E
|
|
777
792
|
if (Qnil != (v = rb_hash_lookup(h, convert_special_sym))) {
|
778
793
|
options.convert_special = (Qfalse != v);
|
779
794
|
}
|
795
|
+
if (Qnil != (v = rb_hash_lookup(h, no_empty_sym))) {
|
796
|
+
options.no_empty = (Qfalse != v);
|
797
|
+
}
|
780
798
|
|
781
799
|
v = rb_hash_lookup(h, invalid_replace_sym);
|
782
800
|
if (Qnil == v) {
|
@@ -996,7 +1014,7 @@ load_file(int argc, VALUE *argv, VALUE self) {
|
|
996
1014
|
xml = ALLOCA_N(char, len + 1);
|
997
1015
|
}
|
998
1016
|
fseek(f, 0, SEEK_SET);
|
999
|
-
if (len != fread(xml, 1, len, f)) {
|
1017
|
+
if ((size_t)len != fread(xml, 1, len, f)) {
|
1000
1018
|
ox_err_set(&err, rb_eLoadError, "Failed to read %ld bytes from %s.\n", (long)len, path);
|
1001
1019
|
obj = Qnil;
|
1002
1020
|
} else {
|
@@ -1208,6 +1226,9 @@ parse_dump_options(VALUE ropts, Options copts) {
|
|
1208
1226
|
}
|
1209
1227
|
strncpy(copts->encoding, StringValuePtr(v), sizeof(copts->encoding) - 1);
|
1210
1228
|
}
|
1229
|
+
if (Qnil != (v = rb_hash_lookup(ropts, no_empty_sym))) {
|
1230
|
+
copts->no_empty = (v == Qtrue);
|
1231
|
+
}
|
1211
1232
|
if (Qnil != (v = rb_hash_lookup(ropts, effort_sym))) {
|
1212
1233
|
if (auto_define_sym == v) {
|
1213
1234
|
copts->effort = AutoEffort;
|
@@ -1275,6 +1296,7 @@ parse_dump_options(VALUE ropts, Options copts) {
|
|
1275
1296
|
* - +obj+ [Object] Object to serialize as an XML document String
|
1276
1297
|
* - +options+ [Hash] formating options
|
1277
1298
|
* - *:indent* [Fixnum] format expected
|
1299
|
+
* - *:no_empty* [true|false] if true don't output empty elements
|
1278
1300
|
* - *:xsd_date* [true|false] use XSD date format if true, default: false
|
1279
1301
|
* - *:circular* [true|false] allow circular references, default: false
|
1280
1302
|
* - *:strict|:tolerant]* [ :effort effort to use when an undumpable object (e.g., IO) is encountered, default: :strict
|
@@ -1480,6 +1502,7 @@ void Init_ox() {
|
|
1480
1502
|
margin_sym = ID2SYM(rb_intern("margin")); rb_gc_register_address(&margin_sym);
|
1481
1503
|
mode_sym = ID2SYM(rb_intern("mode")); rb_gc_register_address(&mode_sym);
|
1482
1504
|
nest_ok_sym = ID2SYM(rb_intern("nest_ok")); rb_gc_register_address(&nest_ok_sym);
|
1505
|
+
no_empty_sym = ID2SYM(rb_intern("no_empty")); rb_gc_register_address(&no_empty_sym);
|
1483
1506
|
object_sym = ID2SYM(rb_intern("object")); rb_gc_register_address(&object_sym);
|
1484
1507
|
off_sym = ID2SYM(rb_intern("off")); rb_gc_register_address(&off_sym);
|
1485
1508
|
opt_format_sym = ID2SYM(rb_intern("opt_format")); rb_gc_register_address(&opt_format_sym);
|
data/ext/ox/ox.h
CHANGED
@@ -123,26 +123,27 @@ typedef struct _circArray {
|
|
123
123
|
} *CircArray;
|
124
124
|
|
125
125
|
typedef struct _options {
|
126
|
-
char encoding[64];
|
127
|
-
char margin[128];
|
128
|
-
int indent;
|
129
|
-
int trace;
|
130
|
-
char margin_len;
|
131
|
-
char with_dtd;
|
132
|
-
char with_xml;
|
133
|
-
char with_instruct;
|
134
|
-
char circular;
|
135
|
-
char xsd_date;
|
136
|
-
char mode;
|
137
|
-
char effort;
|
138
|
-
char sym_keys;
|
139
|
-
char skip;
|
140
|
-
char smart;
|
141
|
-
char convert_special
|
142
|
-
char allow_invalid;
|
143
|
-
char
|
144
|
-
char
|
145
|
-
|
126
|
+
char encoding[64]; // encoding, stored in the option to avoid GC invalidation in default values
|
127
|
+
char margin[128]; // left margin for dumping
|
128
|
+
int indent; // indention for dump, default 2
|
129
|
+
int trace; // trace level
|
130
|
+
char margin_len; // margin length
|
131
|
+
char with_dtd; // YesNo
|
132
|
+
char with_xml; // YesNo
|
133
|
+
char with_instruct; // YesNo
|
134
|
+
char circular; // YesNo
|
135
|
+
char xsd_date; // YesNo
|
136
|
+
char mode; // LoadMode
|
137
|
+
char effort; // Effort
|
138
|
+
char sym_keys; // symbolize keys
|
139
|
+
char skip; // skip mode
|
140
|
+
char smart; // YesNo sax smart mode
|
141
|
+
char convert_special;// boolean true or false
|
142
|
+
char allow_invalid; // YesNo
|
143
|
+
char no_empty; // boolean - no empty elements when dumping
|
144
|
+
char inv_repl[12]; // max 10 valid characters, first character is the length
|
145
|
+
char strip_ns[64]; // namespace to strip, \0 is no-strip, \* is all, else only matches
|
146
|
+
struct _hints *html_hints; // html hints
|
146
147
|
VALUE attr_key_mod;
|
147
148
|
VALUE element_key_mod;
|
148
149
|
#if HAS_ENCODING_SUPPORT
|
@@ -158,13 +159,13 @@ typedef struct _options {
|
|
158
159
|
struct _pInfo {
|
159
160
|
struct _helperStack helpers;
|
160
161
|
struct _err err;
|
161
|
-
char *str; //buffer being read from
|
162
|
+
char *str; // buffer being read from
|
162
163
|
char *end; // end of original string
|
163
164
|
char *s; // current position in buffer
|
164
165
|
VALUE obj;
|
165
166
|
ParseCallbacks pcb;
|
166
167
|
CircArray circ_array;
|
167
|
-
unsigned long id; //set for text types when cirs_array is set
|
168
|
+
unsigned long id; // set for text types when cirs_array is set
|
168
169
|
Options options;
|
169
170
|
char last; // last character read, rarely set
|
170
171
|
};
|
data/lib/ox/version.rb
CHANGED
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.
|
4
|
+
version: 2.12.0
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Peter Ohler
|
8
8
|
autorequire:
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
|
-
date: 2019-
|
11
|
+
date: 2019-12-18 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
|
14
14
|
\ \nOptimized XML (Ox), as the name implies was written to provide speed
|
@@ -35,7 +35,6 @@ files:
|
|
35
35
|
- ext/ox/cache8.c
|
36
36
|
- ext/ox/cache8.h
|
37
37
|
- ext/ox/dump.c
|
38
|
-
- ext/ox/encode.h
|
39
38
|
- ext/ox/err.c
|
40
39
|
- ext/ox/err.h
|
41
40
|
- ext/ox/extconf.rb
|
@@ -99,7 +98,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
|
|
99
98
|
- !ruby/object:Gem::Version
|
100
99
|
version: '0'
|
101
100
|
requirements: []
|
102
|
-
rubygems_version: 3.0.
|
101
|
+
rubygems_version: 3.0.3
|
103
102
|
signing_key:
|
104
103
|
specification_version: 4
|
105
104
|
summary: A fast XML parser and object serializer.
|
data/ext/ox/encode.h
DELETED
@@ -1,26 +0,0 @@
|
|
1
|
-
/* encode.h
|
2
|
-
* Copyright (c) 2011, Peter Ohler
|
3
|
-
* All rights reserved.
|
4
|
-
*/
|
5
|
-
|
6
|
-
#ifndef __OX_ENCODE_H__
|
7
|
-
#define __OX_ENCODE_H__
|
8
|
-
|
9
|
-
#include "ruby.h"
|
10
|
-
#if HAS_ENCODING_SUPPORT
|
11
|
-
#include "ruby/encoding.h"
|
12
|
-
#endif
|
13
|
-
|
14
|
-
static inline VALUE
|
15
|
-
ox_encode(VALUE rstr) {
|
16
|
-
#if HAS_ENCODING_SUPPORT
|
17
|
-
rb_enc_associate(rstr, ox_utf8_encoding);
|
18
|
-
#else
|
19
|
-
if (Qnil != ox_utf8_encoding) {
|
20
|
-
rstr = rb_funcall(ox_utf8_encoding, ox_iconv_id, 1, rstr);
|
21
|
-
}
|
22
|
-
#endif
|
23
|
-
return rstr;
|
24
|
-
}
|
25
|
-
|
26
|
-
#endif /* __OX_ENCODE_H__ */
|