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 CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 837c0ef02149244d49ab2779216dbafc40c46cf1af3354d6ef35779929176476
4
- data.tar.gz: b749a74dee9e1ff268cf69ca6dfff6edcb5681e2c4abe90a07a10442689cc484
3
+ metadata.gz: 5923d0aee2bea7b543f7aec674879c552846492786d05af0d7fd6447f4e60d3b
4
+ data.tar.gz: b0acca612b1a7624847d0c2399f18b7d122c4d9f41a77deaee23ac96c76d87c2
5
5
  SHA512:
6
- metadata.gz: f18d97d2e7c3087a07983f32b4d1e061e46866e5d17734689e8af68c8c004b669c008cb7321246123b060d44099624e2c039065727886ba146a412a7f8cae166
7
- data.tar.gz: 90f9b3fcc779a2ac25e7a317a3fa17f028c4f9008bb8e57c6dc26693965add3cb116f7e9b250d64038f9928d027ee178f7e633320152202f94a1d896edff6f63
6
+ metadata.gz: 5c9f59561ace452549c579d22f30b3c0101f0ec9e1f3bf302d711aee2844af32c5c575057fb28c60aecff009c7314d4772691c187368517939ec0ed8a48fc74d
7
+ data.tar.gz: 4a13ef2c59d159cb1728751c1ec7eb896df35909fb6434e65d722a8ef96e96a2a95e309852f21daf6de87c41e7ca13b13d19015f5bbaed1b0a0dcca5d14b123c
@@ -4,6 +4,10 @@ All changes to the Ox gem are documented here. Releases follow semantic versioni
4
4
 
5
5
  ## [Unreleased]
6
6
 
7
+ ## [2.12.0] - 2019-12-18
8
+
9
+ - Add `no_empty` option to not allow <xyz/> and use <xyz></xyz> instead.
10
+
7
11
  ## [2.11.0] - 2019-06-14
8
12
 
9
13
  ### 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(:version => '1.0')
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:
@@ -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
- *out->cur++ = '/';
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
  }
@@ -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
- 1, // convert_special
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 &lt; 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);
@@ -123,26 +123,27 @@ typedef struct _circArray {
123
123
  } *CircArray;
124
124
 
125
125
  typedef struct _options {
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 inv_repl[12]; /* max 10 valid characters, first character is the length */
144
- char strip_ns[64]; /* namespace to strip, \0 is no-strip, \* is all, else only matches */
145
- struct _hints *html_hints; /* html hints */
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
  };
@@ -1,5 +1,5 @@
1
1
 
2
2
  module Ox
3
3
  # Current version of the module.
4
- VERSION = '2.11.0'
4
+ VERSION = '2.12.0'
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.11.0
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-06-14 00:00:00.000000000 Z
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.1
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.
@@ -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__ */