ox 2.11.0 → 2.12.0

Sign up to get free protection for your applications and to get access to all the features.
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__ */