leptris 1.1.0 → 1.2.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: ec7aed2502125d89ff790ecd754cab242aec563ee58c45ceaf7e86cac4e96f85
4
- data.tar.gz: 6e9a72b02fc76907143756992afa7866415912bbe5fa9282d1800974cfde8b74
3
+ metadata.gz: 28a6d0b01b14207e6a928eead2f38f84bf2dda03b9c7ae4a3c6bcc3163f2760d
4
+ data.tar.gz: e23962a817090c8707dc691fe58276f25da7075e1b0b64bb1fa39774cd113d4e
5
5
  SHA512:
6
- metadata.gz: 1e2a587372714a54f60e560bd175885f09fa3dd5ec3c0d620715c58e152f36651606e63770000f1a7c5162590299328967942093a96a45f9cac923db2c86d369
7
- data.tar.gz: 60aee00fff31eeba0e89a4b5d4affdf93dff22e5080db1093d17b05e6b029d94608f7934f5ec9c1c4eed3b7bfb3d905adb47f8e51ecc0645f8d52cb3e51da453
6
+ metadata.gz: 83e9f30fd09ded2f909d651423db46be8a6baca9f39f310e9b8c3632f5fd7cd5627d193cd57c80d6191a2c00145858b87d9454a72df12e96a28fbd928864a663
7
+ data.tar.gz: 5991c97a7ea5b8a3462c62492fd70808f4094d2758525ce2ec6ac47a9ffe61bb318c71d1999c95081e5e48ce10cc98d9e671ea8c52400c3a90b01e4f9a5b3ce1
data/CHANGELOG.md CHANGED
@@ -5,6 +5,88 @@ All notable changes to Leptris will be documented in this file.
5
5
  The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/),
6
6
  and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html).
7
7
 
8
+ ## [1.2.0] - 2026-08-23
9
+
10
+ Lockstep with libleptris 1.2.0.
11
+
12
+ ### Added
13
+
14
+ - `Leptris::XML::Document.create` — empty document with its own memory
15
+ pool (backs `leptris_document_create`); elements are created against
16
+ it via the factories and attached with `root=`.
17
+ - `Document#root=` — attach an element as the document root
18
+ (`leptris_document_set_root`). Companion to the moxml Leptris
19
+ adapter (lutaml/moxml#96).
20
+ - `Attr#to_xml` — serialized `name="value"` form with the five XML
21
+ special characters escaped.
22
+
23
+ ### Fixed
24
+
25
+ - `Node#text` / `#inner_text` now dispatch to `#content` instead of
26
+ aliasing the base implementation — the alias snapshot meant subclass
27
+ overrides (`Text#content`, `Comment#content`, …) were never seen
28
+ through `text`.
29
+ - `Element#namespace` carries the element's own prefix, so consumers
30
+ can distinguish `{"p" => "urn:p"}` from the default namespace.
31
+ - CI/Rakefile pin libleptris v1.2.0, whose fixes resolve leptris#477
32
+ (mixed-nodeset kinds, `node_name`/`node_value` on non-element
33
+ entries, and `//node()` now including the context root). NodeSet
34
+ keeps its per-index fallback for the still-under-copying batch
35
+ accessor.
36
+
37
+ ### Unbound v1.2.0 surface (follow-up)
38
+
39
+ Namespace-bound XPath (`leptris_xpath_ns_set_*`, `leptris_xpath_eval_ns`)
40
+ and error introspection (`leptris_error_message`, `leptris_last_error`).
41
+
42
+ ## [1.1.1] - 2026-08-22
43
+
44
+ ### Added
45
+
46
+ - **Precompiled platform gems** (emf2svg-ruby model): `rake compile`
47
+ vendors libleptris into `lib/`, and `rake gem:native:<platform>`
48
+ builds binary gems for x86_64/aarch64-linux (incl. musl, via Alpine
49
+ containers), x64-mingw32/ucrt + aarch64-mingw-ucrt, and
50
+ x86_64/arm64-darwin. `gem install leptris` resolves the platform
51
+ gem and works with no system libleptris and no env vars — the FFI
52
+ search order prefers the vendored library. The pure-Ruby gem
53
+ remains the fallback for other setups.
54
+ - `Element#prefix` — the element's own namespace prefix (nil-safe).
55
+ - `Element#each_attribute` — Enumerator over the v1.1.0
56
+ attribute-iteration face; `attributes`/`attribute_nodes`/`keys`/
57
+ `values` now use it (O(n) vs the O(n^2) index-re-walk API).
58
+ - Bindings for the v1.1.0 public surface: attribute-iteration face,
59
+ mixed-nodeset API (`xpath_result_node_kind/get_node/node_name/
60
+ node_value` + kind constants), `leptris_serialize_document`,
61
+ `leptris_document_get_dtd`, `leptris_element_prefix`,
62
+ `leptris_xpath_register_function` (Ruby sugar deferred until the
63
+ callback return-string ownership is verified).
64
+ - `NodeSet` fetches via `get_node` (all node kinds) instead of the
65
+ elements-only `result_get`.
66
+
67
+ ### Changed
68
+
69
+ - `release.yml` is standalone again, building the 8-platform matrix
70
+ plus musl containers and publishing all gems via OIDC trusted
71
+ publishing. Requires the rubygems.org trusted publisher to be
72
+ re-pointed at this workflow (filename `release.yml`, no
73
+ reusable-workflow fields).
74
+ - CI builds libleptris via `rake compile` (single version pin in the
75
+ Rakefile) instead of an inline cmake script.
76
+
77
+ ### Fixed
78
+
79
+ - Removes the resurrected `c14n.rb` (its deletion was lost in a
80
+ rebase-merge; nothing referenced it).
81
+
82
+ ### Known issues
83
+
84
+ - Mixed-kind XPath results misreport node types upstream
85
+ (leptris#477: enum-space collision; `node_name`/`node_value`
86
+ crash on text entries). Specs assert only the correct surface;
87
+ `NodeSet` carries a per-index fallback for the under-copying batch
88
+ accessor.
89
+
8
90
  ## [1.1.0] - 2026-08-22
9
91
 
10
92
  Lockstep with libleptris 1.1.0.
data/README.adoc CHANGED
@@ -397,7 +397,7 @@ bundle exec rspec spec/xml/xpath_spec.rb:42 # one example by line
397
397
  bundle exec rubocop # lint
398
398
  ----
399
399
 
400
- CI pins libleptris to a released tag (currently v1.1.0) and builds it
400
+ CI pins libleptris to a released tag (currently v1.1.1) and builds it
401
401
  from source on each runner; see `.github/workflows/build.yml`.
402
402
 
403
403
  == License
data/Rakefile CHANGED
@@ -4,4 +4,95 @@ require "bundler/gem_tasks"
4
4
  require "rspec/core/rake_task"
5
5
 
6
6
  RSpec::Core::RakeTask.new(:spec)
7
+
8
+ # Pin for `rake compile` and the platform-gem builds. Keep in lockstep
9
+ # with .github/workflows/build.yml (which calls `rake compile`) and the
10
+ # CHANGELOG when libleptris releases.
11
+ LIBLEPTRIS_VERSION = "1.2.0"
12
+
13
+ CMAKE_FLAGS = %w[
14
+ -DCMAKE_BUILD_TYPE=Release
15
+ -DLEPTRIS_BUILD_SHARED=ON
16
+ -DLEPTRIS_BUILD_STATIC=OFF
17
+ -DBUILD_TESTING=OFF
18
+ -DLEPTRIS_BUILD_CLI=OFF
19
+ -DLEPTRIS_BUILD_BENCHMARKS=OFF
20
+ -DLEPTRIS_BUILD_MAN_PAGES=OFF
21
+ -DLEPTRIS_ENABLE_UTF8PROC=OFF
22
+ -DLEPTRIS_ENABLE_ICONV=OFF
23
+ ].freeze
24
+
25
+ desc "Build libleptris #{LIBLEPTRIS_VERSION} from its release tarball into lib/"
26
+ task :compile do
27
+ version = ENV.fetch("LIBLEPTRIS_VERSION", LIBLEPTRIS_VERSION)
28
+ build = File.expand_path("tmp/libleptris-#{version}", __dir__)
29
+ rm_rf(build)
30
+ mkdir_p(build)
31
+ url = "https://api.github.com/repos/leptris/leptris/tarball/v#{version}"
32
+ sh "curl -sL #{url} | tar xz -C #{build} --strip-components=1"
33
+ sh "cmake -B #{build}/build -S #{build} #{CMAKE_FLAGS.join(' ')}"
34
+ sh "cmake --build #{build}/build --config Release -j 4"
35
+ # Windows names the shared library leptris.dll (no "lib" prefix);
36
+ # vendoring under the uniform libleptris.* name keeps the FFI
37
+ # search order simple.
38
+ lib = Dir.glob("#{build}/build/**/libleptris.{dylib,so}").first ||
39
+ Dir.glob("#{build}/build/**/leptris.dll").first
40
+ raise "libleptris shared library not found after build" unless lib
41
+ ext = File.extname(lib)
42
+ cp(lib, "lib/libleptris#{ext}")
43
+ puts "Vendored #{File.basename(lib)} as lib/libleptris#{ext}"
44
+ end
45
+
46
+ task spec: :compile unless ENV.key?("LEPTRIS_LIB_PATH")
47
+
7
48
  task default: :spec
49
+
50
+ require "rubygems/package_task"
51
+
52
+ desc "Build the pure-Ruby gem"
53
+ task "gem:native:any" do
54
+ sh "rake platform:any gem"
55
+ end
56
+
57
+ desc "Define the gem task to build the pure-Ruby gem"
58
+ task "platform:any" do
59
+ spec = Gem::Specification::load("leptris.gemspec").dup
60
+ task = Gem::PackageTask.new(spec)
61
+ task.define
62
+ end
63
+
64
+ platforms = [
65
+ "x64-mingw32",
66
+ "x64-mingw-ucrt",
67
+ "aarch64-mingw-ucrt",
68
+ "x86_64-linux",
69
+ "x86_64-linux-musl",
70
+ "aarch64-linux",
71
+ "aarch64-linux-musl",
72
+ "x86_64-darwin",
73
+ "arm64-darwin",
74
+ ]
75
+
76
+ platforms.each do |platform|
77
+ desc "Build pre-compiled gem for the #{platform} platform"
78
+ task "gem:native:#{platform}" do
79
+ sh "rake compile platform:#{platform} gem"
80
+ end
81
+
82
+ desc "Define the gem task to build on the #{platform} platform (binary gem)"
83
+ task "platform:#{platform}" do
84
+ spec = Gem::Specification::load("leptris.gemspec").dup
85
+ spec.platform = Gem::Platform.new(platform)
86
+ spec.files += Dir.glob("lib/libleptris.{dll,so,dylib}")
87
+ task = Gem::PackageTask.new(spec)
88
+ task.define
89
+ end
90
+ end
91
+
92
+ require "rake/clean"
93
+
94
+ CLOBBER.include("pkg")
95
+ CLEAN.include("tmp",
96
+ "lib/libleptris.dll",
97
+ "lib/libleptris.dylib",
98
+ "lib/libleptris.so")
@@ -1,5 +1,5 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  module Leptris
4
- VERSION = "1.1.0"
4
+ VERSION = "1.2.0"
5
5
  end
@@ -1,10 +1,8 @@
1
1
  # frozen_string_literal: true
2
2
 
3
- # Lightweight attribute wrapper. libleptris v0.4.4 doesn't expose per-attribute
4
- # pointers (no LeptrisAttribute accessors in the public API), so an Attr is a
5
- # (name, value, parent_element) triple. Mutation goes through the parent
6
- # element via #[]. Once upstream adds attribute-level accessors, this can
7
- # become a pointer-backed wrapper.
3
+ # Lightweight attribute wrapper: a (name, value, parent_element) triple
4
+ # materialized from the attribute-iteration face. Mutation goes through
5
+ # the parent element via #[].
8
6
 
9
7
  class Leptris::XML::Attr
10
8
  attr_reader :name, :value, :element
@@ -31,6 +29,17 @@ class Leptris::XML::Attr
31
29
  def to_s; @value; end
32
30
  def to_str; @value; end
33
31
 
32
+ # Serialized attribute form: name="value" with the five XML special
33
+ # characters escaped in the value.
34
+ def to_xml
35
+ escaped = @value.to_s.gsub("&", "&amp;")
36
+ .gsub("<", "&lt;")
37
+ .gsub(">", "&gt;")
38
+ .gsub('"', "&quot;")
39
+ .gsub("'", "&apos;")
40
+ "#{@name}=\"#{escaped}\""
41
+ end
42
+
34
43
  def ==(other)
35
44
  other.is_a?(Leptris::XML::Attr) &&
36
45
  @name == other.name && @value == other.value &&
@@ -66,6 +66,16 @@ class Leptris::XML::Document
66
66
  wrap(raw)
67
67
  end
68
68
 
69
+ # Create an empty document (no root element) backed by its own memory
70
+ # pool. Elements for the tree are created against it via
71
+ # #create_element and friends, then attached with #root=.
72
+ def self.create
73
+ raw = Leptris::XML::FFI.leptris_document_create
74
+ raise Leptris::XML::Error,
75
+ "leptris_document_create failed" if raw.null?
76
+ wrap(raw)
77
+ end
78
+
69
79
  # Convert a raw LeptrisDocument pointer into a Ruby Document with safe
70
80
  # GC lifetime management. The finalizer captures the raw address
71
81
  # integer (not the Document or Pointer object — those would prevent
@@ -107,6 +117,17 @@ class Leptris::XML::Document
107
117
  Leptris::XML::Node.wrap(ptr, self)
108
118
  end
109
119
 
120
+ # Attach +element+ as the document's root element. The element must
121
+ # have been created against this document and must not already have
122
+ # a parent. Any previous root is left detached (still owned by the
123
+ # document's pool until #free).
124
+ def root=(element)
125
+ raise Leptris::XML::UseAfterFreeError if @freed.state == :freed
126
+ Leptris::XML::FFI.check_status(
127
+ Leptris::XML::FFI.leptris_document_set_root(@c_ptr, element.c_ptr))
128
+ element
129
+ end
130
+
110
131
  def create_element(name)
111
132
  ptr = Leptris::XML::FFI.leptris_element_create(@c_ptr, name)
112
133
  raise Leptris::XML::Error, "leptris_element_create failed" if ptr.null?
@@ -48,34 +48,43 @@ class Leptris::XML::Element < Leptris::XML::Node
48
48
  end
49
49
  alias_method :delete, :remove_attribute
50
50
 
51
+ # Iterates the element's attributes via the v1.1.0 linked-list face
52
+ # (one FFI call per attribute; the name_at/value_at indexing API
53
+ # re-walks the list per index, making it O(n^2) per element).
54
+ def each_attribute
55
+ return enum_for(:each_attribute) unless block_given?
56
+ attr = Leptris::XML::FFI.leptris_element_first_attribute(@c_ptr)
57
+ until attr.nil? || attr.null?
58
+ name = Leptris::XML::FFI.leptris_attribute_get_name(attr)
59
+ value = Leptris::XML::FFI.leptris_attribute_get_value(@c_ptr, attr)
60
+ yield Leptris::XML::Attr.new(name, value, self)
61
+ attr = Leptris::XML::FFI.leptris_attribute_next(attr)
62
+ end
63
+ self
64
+ end
65
+
51
66
  def keys
52
- count = Leptris::XML::FFI.leptris_element_attribute_count(@c_ptr)
53
- count.times.map { |i| Leptris::XML::FFI.leptris_element_attribute_name_at(@c_ptr, i) }
67
+ each_attribute.to_a.map(&:name)
54
68
  end
55
69
 
56
70
  def values
57
- count = Leptris::XML::FFI.leptris_element_attribute_count(@c_ptr)
58
- count.times.map { |i| Leptris::XML::FFI.leptris_element_attribute_value_at(@c_ptr, i) }
71
+ each_attribute.to_a.map(&:value)
59
72
  end
60
73
 
61
74
  def attributes
62
- count = Leptris::XML::FFI.leptris_element_attribute_count(@c_ptr)
63
75
  result = {}
64
- count.times do |i|
65
- name = Leptris::XML::FFI.leptris_element_attribute_name_at(@c_ptr, i)
66
- value = Leptris::XML::FFI.leptris_element_attribute_value_at(@c_ptr, i)
67
- result[name] = Leptris::XML::Attr.new(name, value, self)
68
- end
76
+ each_attribute { |attr| result[attr.name] = attr }
69
77
  result
70
78
  end
71
79
 
72
80
  def attribute_nodes
73
- count = Leptris::XML::FFI.leptris_element_attribute_count(@c_ptr)
74
- count.times.map do |i|
75
- name = Leptris::XML::FFI.leptris_element_attribute_name_at(@c_ptr, i)
76
- value = Leptris::XML::FFI.leptris_element_attribute_value_at(@c_ptr, i)
77
- Leptris::XML::Attr.new(name, value, self)
78
- end
81
+ each_attribute.to_a
82
+ end
83
+
84
+ # The element's own namespace prefix (e.g. "foo" for <foo:child/>),
85
+ # or nil when the element has none.
86
+ def prefix
87
+ Leptris::XML::FFI.leptris_element_prefix(@c_ptr)
79
88
  end
80
89
 
81
90
  def prepend_child(node)
@@ -182,7 +191,12 @@ class Leptris::XML::Element < Leptris::XML::Node
182
191
  def namespace
183
192
  uri = Leptris::XML::FFI.leptris_element_namespace(@c_ptr)
184
193
  return nil if uri.nil? || uri.empty?
185
- Leptris::XML::Namespace.new(self, uri)
194
+ # The resolved namespace is reached via this element's own prefix,
195
+ # so carry it through: consumers that distinguish
196
+ # {"p" => "urn:p"} from the default {"nil => "urn:p"} need it.
197
+ prefix = Leptris::XML::FFI.leptris_element_prefix(@c_ptr)
198
+ prefix = nil if prefix.nil? || prefix.empty?
199
+ Leptris::XML::Namespace.new(self, uri, prefix: prefix)
186
200
  end
187
201
 
188
202
  def namespace_definitions
@@ -11,6 +11,7 @@ module Leptris
11
11
  ENV["LEPTRIS_LIB_PATH"],
12
12
  File.expand_path("../../libleptris.dylib", __dir__),
13
13
  File.expand_path("../../libleptris.so", __dir__),
14
+ File.expand_path("../../libleptris.dll", __dir__),
14
15
  "/usr/local/lib/libleptris.dylib",
15
16
  "/usr/local/lib/libleptris.so",
16
17
  "leptris",
@@ -65,6 +66,10 @@ module Leptris
65
66
  [:string, :pointer], :pointer
66
67
  attach_function :leptris_document_free,
67
68
  [:leptris_document], :void
69
+ attach_function :leptris_document_create,
70
+ [], :leptris_document
71
+ attach_function :leptris_document_set_root,
72
+ [:leptris_document, :leptris_element], :leptris_status
68
73
  attach_function :leptris_document_root,
69
74
  [:leptris_document], :leptris_element
70
75
  attach_function :leptris_document_encoding,
@@ -186,6 +191,16 @@ module Leptris
186
191
  [:leptris_element, :string, :int], :int
187
192
  attach_function :leptris_element_has_attribute,
188
193
  [:leptris_element, :string], :int
194
+ attach_function :leptris_element_first_attribute,
195
+ [:leptris_element], :leptris_attribute
196
+ attach_function :leptris_attribute_next,
197
+ [:leptris_attribute], :leptris_attribute
198
+ attach_function :leptris_attribute_get_name,
199
+ [:leptris_attribute], :string
200
+ attach_function :leptris_attribute_get_value,
201
+ [:leptris_element, :leptris_attribute], :string
202
+ attach_function :leptris_element_prefix,
203
+ [:leptris_element], :string
189
204
  attach_function :leptris_element_attribute_count,
190
205
  [:leptris_element], :size_t
191
206
  attach_function :leptris_element_attribute_name_at,
@@ -310,6 +325,22 @@ module Leptris
310
325
  [:leptris_xpath_result], :size_t
311
326
  attach_function :leptris_xpath_result_get,
312
327
  [:leptris_xpath_result, :size_t], :leptris_element
328
+ # Mixed nodesets (v1.1.0): unlike result_get (elements only),
329
+ # get_node returns the node whatever its kind; node_kind reports
330
+ # which (element / synthetic attribute / text / other).
331
+ attach_function :leptris_xpath_result_node_kind,
332
+ [:leptris_xpath_result, :size_t], :int
333
+ attach_function :leptris_xpath_result_get_node,
334
+ [:leptris_xpath_result, :size_t], :leptris_node_ref
335
+ attach_function :leptris_xpath_result_node_name,
336
+ [:leptris_xpath_result, :size_t], :string
337
+ attach_function :leptris_xpath_result_node_value,
338
+ [:leptris_xpath_result, :size_t], :string
339
+ # Document-scoped custom XPath functions. The callback receives
340
+ # (const char* const* args, int argc, void* user_data) and returns
341
+ # a heap string the library frees.
342
+ attach_function :leptris_xpath_register_function,
343
+ [:leptris_document, :string, :pointer, :pointer], :leptris_status
313
344
  attach_function :leptris_xpath_result_get_nodes,
314
345
  [:leptris_xpath_result, :pointer, :size_t], :size_t
315
346
  attach_function :leptris_xpath_result_boolean,
@@ -347,6 +378,12 @@ module Leptris
347
378
 
348
379
  attach_function :leptris_document_serialize,
349
380
  [:leptris_document, :pointer], :pointer
381
+ # Legacy simple serializer, declared retroactively in v1.1.0.
382
+ # Prefer leptris_document_serialize; bound for API completeness.
383
+ attach_function :leptris_serialize_document,
384
+ [:leptris_document], :pointer
385
+ attach_function :leptris_document_get_dtd,
386
+ [:leptris_document], :pointer
350
387
  attach_function :leptris_element_serialize,
351
388
  [:leptris_element, :pointer], :pointer
352
389
  attach_function :leptris_document_save_file,
@@ -398,6 +435,11 @@ module Leptris
398
435
  XPATH_NUMBER = 2
399
436
  XPATH_STRING = 3
400
437
 
438
+ XPATH_NODE_ELEMENT = 0
439
+ XPATH_NODE_ATTRIBUTE = 1
440
+ XPATH_NODE_TEXT = 2
441
+ XPATH_NODE_OTHER = 3
442
+
401
443
  NODE_ELEMENT = 0
402
444
  NODE_TEXT = 1
403
445
  NODE_COMMENT = 2
@@ -45,8 +45,17 @@ class Leptris::XML::Node
45
45
  def content
46
46
  raise NotImplementedError, "#{self.class}#content not implemented"
47
47
  end
48
- alias_method :text, :content
49
- alias_method :inner_text, :content
48
+
49
+ # Dispatching defs, not alias_method: an alias snapshots this base
50
+ # #content (the raise), so subclass overrides would never be seen
51
+ # through the alias. A plain method resolves #content per-call.
52
+ def text
53
+ content
54
+ end
55
+
56
+ def inner_text
57
+ content
58
+ end
50
59
 
51
60
  def type
52
61
  Leptris::XML::FFI.leptris_node_get_type(@c_ptr)
@@ -52,7 +52,7 @@ class Leptris::XML::NodeSet
52
52
  def [](idx)
53
53
  if @result_ptr
54
54
  return nil if idx < 0 || idx >= length
55
- ptr = Leptris::XML::FFI.leptris_xpath_result_get(@result_ptr, idx)
55
+ ptr = Leptris::XML::FFI.leptris_xpath_result_get_node(@result_ptr, idx)
56
56
  return nil if ptr.null?
57
57
  Leptris::XML::Node.wrap(ptr, @document)
58
58
  else
@@ -77,6 +77,13 @@ class Leptris::XML::NodeSet
77
77
  next if ptr.null?
78
78
  yield Leptris::XML::Node.wrap(ptr, @document)
79
79
  end
80
+ # The batch accessor under-copies mixed-kind results (upstream
81
+ # leptris#477); fall back to per-index fetch for the remainder.
82
+ (copied...n).each do |i|
83
+ ptr = Leptris::XML::FFI.leptris_xpath_result_get_node(@result_ptr, i)
84
+ next if ptr.null?
85
+ yield Leptris::XML::Node.wrap(ptr, @document)
86
+ end
80
87
  ensure
81
88
  buf.free
82
89
  end
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: leptris
3
3
  version: !ruby/object:Gem::Version
4
- version: 1.1.0
4
+ version: 1.2.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - Ribose Inc.
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2026-08-22 00:00:00.000000000 Z
11
+ date: 2026-08-23 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: ffi
@@ -112,7 +112,6 @@ files:
112
112
  - lib/leptris/version.rb
113
113
  - lib/leptris/xml.rb
114
114
  - lib/leptris/xml/attr.rb
115
- - lib/leptris/xml/c14n.rb
116
115
  - lib/leptris/xml/c_string_array.rb
117
116
  - lib/leptris/xml/cdata.rb
118
117
  - lib/leptris/xml/comment.rb
@@ -1,23 +0,0 @@
1
- # frozen_string_literal: true
2
-
3
- module Leptris
4
- module XML
5
- # @api private
6
- #
7
- # Builds a NULL-terminated `const char**` from a Ruby array of strings,
8
- # suitable for passing to leptris_c14n_canonicalize_ex's
9
- # `inclusive_ns_prefixes` argument. Returns [pointer, anchor] where
10
- # anchor is the underlying MemoryPointer that the caller must keep
11
- # alive (e.g. via local variable) for the duration of the FFI call.
12
- def self.c14n_build_ns_pointer(inclusive_namespaces)
13
- return [nil, nil] if inclusive_namespaces.nil? || inclusive_namespaces.empty?
14
- strs = Array(inclusive_namespaces).map(&:to_s)
15
- ptr_size = ::FFI.type_size(:pointer)
16
- buffer = ::FFI::MemoryPointer.new(:pointer, strs.size + 1)
17
- anchors = strs.map { |s| ::FFI::MemoryPointer.from_string(s) }
18
- anchors.each_with_index { |p, i| buffer.put_pointer(i * ptr_size, p) }
19
- buffer.put_pointer(strs.size * ptr_size, nil)
20
- [buffer, anchors]
21
- end
22
- end
23
- end