leptris 1.9.209.0 → 1.9.209.1

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: 700c8b243ae83bca888161a3db72b2e3c6304023c2d6876716d63cbc77046469
4
- data.tar.gz: 3f5e149db82b4dd010e7a485650321bc752d74ee198e06b5711736781eca3281
3
+ metadata.gz: c7f9ee6f6fa740c91bbb444f605bd68fcae043d8184f220774e89b749eb521fc
4
+ data.tar.gz: b22ed76f401235b0731cbeeeec011655a07ffd189e02a25dd675659fd076798f
5
5
  SHA512:
6
- metadata.gz: 87f6bfc69bcabf29bef4721bddc2947311ba021146912be96f34d043123611f0bc5230fc027855d897d42b7979ff7bed97d0b6df749bcaaf9f7b62cc642c6d26
7
- data.tar.gz: 022fa14f46227d54e5966be7f0b90da028a2ff4bed14e4c2f2f4e26343a4a684c43770637077ab31657efb6c7a63af357285558cc4d25550156c55742c39f83a
6
+ metadata.gz: a9bd90a1a9d941ad5814a13dd659213de9ab86e21e38a8064b681d6d127fe91c935ba5635a2b2e4938699769aca76953e8bcb4db42fee893eef5ab6f55166cb3
7
+ data.tar.gz: f261d4206b02aefa6bfbc57866da62f82c627059fba9fdbab640178e3e7ab6cf19272b6590f20587e50efe170872368930ce5f117d604f1c9c225746643d3cf9
@@ -1932,6 +1932,32 @@ static void walk_rows_impl(void *node, int depth, VALUE out)
1932
1932
  }
1933
1933
  }
1934
1934
 
1935
+ /* ---- Attribute pairs (leptris-ruby#278) --------------------------
1936
+ * Read-only attribute listing as a flat [name, value, ...] array —
1937
+ * names interned (they repeat across documents), values fresh
1938
+ * UTF-8 strings, document order, duplicates included, NO Attr
1939
+ * objects minted. One crossing per element; the walk-hot shape for
1940
+ * consumers that only read name/value. Mutation and per-attribute
1941
+ * namespace resolution stay on attribute_nodes. */
1942
+ static VALUE nf_attribute_pairs(VALUE self, VALUE document, VALUE addr)
1943
+ {
1944
+ (void)self;
1945
+ (void)document;
1946
+ void *node = (void *)(uintptr_t)NUM2ULL(addr);
1947
+ VALUE out = rb_ary_new();
1948
+ if (f_node_type(node) != WS_NODE_ELEMENT) return out;
1949
+
1950
+ for (void *a = f_attr_first(node); a; a = f_attr_next(a)) {
1951
+ const char *an = f_attr_name(a);
1952
+ const char *av = f_attr_value(node, a);
1953
+ rb_ary_push(out, an ? rb_enc_interned_str(an, strlen(an),
1954
+ rb_utf8_encoding())
1955
+ : Qnil);
1956
+ rb_ary_push(out, av ? rb_utf8_str_new_cstr(av) : Qnil);
1957
+ }
1958
+ return out;
1959
+ }
1960
+
1935
1961
  static VALUE nf_snapshot_rows(VALUE self, VALUE document, VALUE addr)
1936
1962
  {
1937
1963
  (void)self;
@@ -2606,6 +2632,8 @@ void Init_native(void)
2606
2632
  nf_snapshot_subtree, 2);
2607
2633
  rb_define_module_function(m_native, "snapshot_rows",
2608
2634
  nf_snapshot_rows, 2);
2635
+ rb_define_module_function(m_native, "attribute_pairs",
2636
+ nf_attribute_pairs, 2);
2609
2637
  rb_define_module_function(m_native, "plan_structs",
2610
2638
  nf_plan_structs, 3);
2611
2639
  rb_define_module_function(m_native, "doc_handle_attach",
@@ -1,5 +1,5 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  module Leptris
4
- VERSION = "1.9.209.0"
4
+ VERSION = "1.9.209.1"
5
5
  end
@@ -284,6 +284,31 @@ class Leptris::XML::Element < Leptris::XML::Node
284
284
  result
285
285
  end
286
286
 
287
+ # Read-only attribute listing as [name, value] pairs — no Attr
288
+ # objects. Names are interned frozen strings (shared across
289
+ # documents; dup before mutating), values fresh UTF-8 strings.
290
+ # Document order, duplicates included. One C crossing per element
291
+ # on the native layer (leptris-ruby#278) — the walk-hot shape for
292
+ # consumers that only read name/value. Mutation and per-attribute
293
+ # namespace resolution stay on attribute_nodes.
294
+ def attribute_pairs
295
+ ensure_alive!
296
+ return @attribute_pairs if memo_hit?(@attribute_pairs_version)
297
+ result = if @c_address && @document &&
298
+ defined?(::Leptris::XML::Native) &&
299
+ ::Leptris::XML::Native.respond_to?(:attribute_pairs)
300
+ ::Leptris::XML::Native.attribute_pairs(@document, @c_address)
301
+ .each_slice(2).to_a
302
+ else
303
+ each_attribute.to_a.map { |a| [a.name, a.value] }
304
+ end
305
+ if @document
306
+ @attribute_pairs = result
307
+ @attribute_pairs_version = @document.version
308
+ end
309
+ result
310
+ end
311
+
287
312
  def attribute_nodes
288
313
  return @attribute_nodes if memo_hit?(@attribute_nodes_version)
289
314
  result = each_attribute.to_a
@@ -46,6 +46,12 @@ class Leptris::XML::Iterparse
46
46
  xml = xml_or_io.is_a?(String) ? xml_or_io : xml_or_io.read
47
47
  iterator = new(Leptris::XML::FFI.leptris_iterparse_new_ex(
48
48
  xml, xml.bytesize, mode_code(mode)))
49
+ # leptris_iterparse_new_ex retains the buffer and reads it
50
+ # lazily in bounded slices (#1207-class): without this
51
+ # reference the input String is collectable the moment parse
52
+ # returns, and the iterator walks freed memory — attribute
53
+ # reads intermittently come back nil (#279)
54
+ iterator.keepalive_input(xml)
49
55
  return iterator unless block
50
56
  begin
51
57
  iterator.run(&block)
@@ -78,9 +84,17 @@ class Leptris::XML::Iterparse
78
84
  def initialize(handle)
79
85
  raise Leptris::XML::ParseError, "leptris_iterparse_new failed" if handle.null?
80
86
  @handle = handle
87
+ @input_keepalive = nil
81
88
  @scope = Leptris::XML::IterationScope.new(handle)
82
89
  end
83
90
 
91
+ # Pins the input buffer for the iterator's lifetime (see
92
+ # self.parse). Public but internal — not part of the API.
93
+ def keepalive_input(buffer)
94
+ @input_keepalive = buffer
95
+ self
96
+ end
97
+
84
98
  # Yields completed elements until the document is exhausted or the
85
99
  # parse fails (see #error). Does not free the iterator — the block
86
100
  # form of .parse/.parse_file does, or call #free explicitly.
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: leptris
3
3
  version: !ruby/object:Gem::Version
4
- version: 1.9.209.0
4
+ version: 1.9.209.1
5
5
  platform: ruby
6
6
  authors:
7
7
  - Ribose Inc.