leptris 1.1.0 → 1.1.2
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 +48 -0
- data/README.adoc +1 -1
- data/Rakefile +91 -0
- data/lib/leptris/version.rb +1 -1
- data/lib/leptris/xml/attr.rb +3 -5
- data/lib/leptris/xml/element.rb +25 -16
- data/lib/leptris/xml/ffi.rb +38 -0
- data/lib/leptris/xml/node_set.rb +8 -1
- metadata +2 -3
- data/lib/leptris/xml/c14n.rb +0 -23
checksums.yaml
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
---
|
|
2
2
|
SHA256:
|
|
3
|
-
metadata.gz:
|
|
4
|
-
data.tar.gz:
|
|
3
|
+
metadata.gz: 949fe73711448bd7857072004c75d6201b06829e9eb632124ae922a2fb7ff3f1
|
|
4
|
+
data.tar.gz: 259bbac7ce3e90389cce4f0e79dc979e7bc8ca844caa7745680ba352c010ba86
|
|
5
5
|
SHA512:
|
|
6
|
-
metadata.gz:
|
|
7
|
-
data.tar.gz:
|
|
6
|
+
metadata.gz: cdab285d1fe462fcf7bc66681ebfbe1af74748ae99a8f0eebe1e502dfd72313b4429ac5943a18ebebd5706a308b135c33dfd7e8aab4bd313e383adcd91bb682f
|
|
7
|
+
data.tar.gz: 18240f20ed093b9e6434d0f9036ab93545b6af47237aa5ee72f616f3b10836148a3850fec5332fb2e44f416a53d25523d69f8bc4e4e1bb17c1f1181f16515f98
|
data/CHANGELOG.md
CHANGED
|
@@ -5,6 +5,54 @@ 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.1.1] - 2026-08-22
|
|
9
|
+
|
|
10
|
+
### Added
|
|
11
|
+
|
|
12
|
+
- **Precompiled platform gems** (emf2svg-ruby model): `rake compile`
|
|
13
|
+
vendors libleptris into `lib/`, and `rake gem:native:<platform>`
|
|
14
|
+
builds binary gems for x86_64/aarch64-linux (incl. musl, via Alpine
|
|
15
|
+
containers), x64-mingw32/ucrt + aarch64-mingw-ucrt, and
|
|
16
|
+
x86_64/arm64-darwin. `gem install leptris` resolves the platform
|
|
17
|
+
gem and works with no system libleptris and no env vars — the FFI
|
|
18
|
+
search order prefers the vendored library. The pure-Ruby gem
|
|
19
|
+
remains the fallback for other setups.
|
|
20
|
+
- `Element#prefix` — the element's own namespace prefix (nil-safe).
|
|
21
|
+
- `Element#each_attribute` — Enumerator over the v1.1.0
|
|
22
|
+
attribute-iteration face; `attributes`/`attribute_nodes`/`keys`/
|
|
23
|
+
`values` now use it (O(n) vs the O(n^2) index-re-walk API).
|
|
24
|
+
- Bindings for the v1.1.0 public surface: attribute-iteration face,
|
|
25
|
+
mixed-nodeset API (`xpath_result_node_kind/get_node/node_name/
|
|
26
|
+
node_value` + kind constants), `leptris_serialize_document`,
|
|
27
|
+
`leptris_document_get_dtd`, `leptris_element_prefix`,
|
|
28
|
+
`leptris_xpath_register_function` (Ruby sugar deferred until the
|
|
29
|
+
callback return-string ownership is verified).
|
|
30
|
+
- `NodeSet` fetches via `get_node` (all node kinds) instead of the
|
|
31
|
+
elements-only `result_get`.
|
|
32
|
+
|
|
33
|
+
### Changed
|
|
34
|
+
|
|
35
|
+
- `release.yml` is standalone again, building the 8-platform matrix
|
|
36
|
+
plus musl containers and publishing all gems via OIDC trusted
|
|
37
|
+
publishing. Requires the rubygems.org trusted publisher to be
|
|
38
|
+
re-pointed at this workflow (filename `release.yml`, no
|
|
39
|
+
reusable-workflow fields).
|
|
40
|
+
- CI builds libleptris via `rake compile` (single version pin in the
|
|
41
|
+
Rakefile) instead of an inline cmake script.
|
|
42
|
+
|
|
43
|
+
### Fixed
|
|
44
|
+
|
|
45
|
+
- Removes the resurrected `c14n.rb` (its deletion was lost in a
|
|
46
|
+
rebase-merge; nothing referenced it).
|
|
47
|
+
|
|
48
|
+
### Known issues
|
|
49
|
+
|
|
50
|
+
- Mixed-kind XPath results misreport node types upstream
|
|
51
|
+
(leptris#477: enum-space collision; `node_name`/`node_value`
|
|
52
|
+
crash on text entries). Specs assert only the correct surface;
|
|
53
|
+
`NodeSet` carries a per-index fallback for the under-copying batch
|
|
54
|
+
accessor.
|
|
55
|
+
|
|
8
56
|
## [1.1.0] - 2026-08-22
|
|
9
57
|
|
|
10
58
|
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.
|
|
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.1.1"
|
|
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")
|
data/lib/leptris/version.rb
CHANGED
data/lib/leptris/xml/attr.rb
CHANGED
|
@@ -1,10 +1,8 @@
|
|
|
1
1
|
# frozen_string_literal: true
|
|
2
2
|
|
|
3
|
-
# Lightweight attribute wrapper
|
|
4
|
-
#
|
|
5
|
-
#
|
|
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
|
data/lib/leptris/xml/element.rb
CHANGED
|
@@ -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
|
-
|
|
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
|
-
|
|
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
|
-
|
|
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
|
-
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
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)
|
data/lib/leptris/xml/ffi.rb
CHANGED
|
@@ -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",
|
|
@@ -186,6 +187,16 @@ module Leptris
|
|
|
186
187
|
[:leptris_element, :string, :int], :int
|
|
187
188
|
attach_function :leptris_element_has_attribute,
|
|
188
189
|
[:leptris_element, :string], :int
|
|
190
|
+
attach_function :leptris_element_first_attribute,
|
|
191
|
+
[:leptris_element], :leptris_attribute
|
|
192
|
+
attach_function :leptris_attribute_next,
|
|
193
|
+
[:leptris_attribute], :leptris_attribute
|
|
194
|
+
attach_function :leptris_attribute_get_name,
|
|
195
|
+
[:leptris_attribute], :string
|
|
196
|
+
attach_function :leptris_attribute_get_value,
|
|
197
|
+
[:leptris_element, :leptris_attribute], :string
|
|
198
|
+
attach_function :leptris_element_prefix,
|
|
199
|
+
[:leptris_element], :string
|
|
189
200
|
attach_function :leptris_element_attribute_count,
|
|
190
201
|
[:leptris_element], :size_t
|
|
191
202
|
attach_function :leptris_element_attribute_name_at,
|
|
@@ -310,6 +321,22 @@ module Leptris
|
|
|
310
321
|
[:leptris_xpath_result], :size_t
|
|
311
322
|
attach_function :leptris_xpath_result_get,
|
|
312
323
|
[:leptris_xpath_result, :size_t], :leptris_element
|
|
324
|
+
# Mixed nodesets (v1.1.0): unlike result_get (elements only),
|
|
325
|
+
# get_node returns the node whatever its kind; node_kind reports
|
|
326
|
+
# which (element / synthetic attribute / text / other).
|
|
327
|
+
attach_function :leptris_xpath_result_node_kind,
|
|
328
|
+
[:leptris_xpath_result, :size_t], :int
|
|
329
|
+
attach_function :leptris_xpath_result_get_node,
|
|
330
|
+
[:leptris_xpath_result, :size_t], :leptris_node_ref
|
|
331
|
+
attach_function :leptris_xpath_result_node_name,
|
|
332
|
+
[:leptris_xpath_result, :size_t], :string
|
|
333
|
+
attach_function :leptris_xpath_result_node_value,
|
|
334
|
+
[:leptris_xpath_result, :size_t], :string
|
|
335
|
+
# Document-scoped custom XPath functions. The callback receives
|
|
336
|
+
# (const char* const* args, int argc, void* user_data) and returns
|
|
337
|
+
# a heap string the library frees.
|
|
338
|
+
attach_function :leptris_xpath_register_function,
|
|
339
|
+
[:leptris_document, :string, :pointer, :pointer], :leptris_status
|
|
313
340
|
attach_function :leptris_xpath_result_get_nodes,
|
|
314
341
|
[:leptris_xpath_result, :pointer, :size_t], :size_t
|
|
315
342
|
attach_function :leptris_xpath_result_boolean,
|
|
@@ -347,6 +374,12 @@ module Leptris
|
|
|
347
374
|
|
|
348
375
|
attach_function :leptris_document_serialize,
|
|
349
376
|
[:leptris_document, :pointer], :pointer
|
|
377
|
+
# Legacy simple serializer, declared retroactively in v1.1.0.
|
|
378
|
+
# Prefer leptris_document_serialize; bound for API completeness.
|
|
379
|
+
attach_function :leptris_serialize_document,
|
|
380
|
+
[:leptris_document], :pointer
|
|
381
|
+
attach_function :leptris_document_get_dtd,
|
|
382
|
+
[:leptris_document], :pointer
|
|
350
383
|
attach_function :leptris_element_serialize,
|
|
351
384
|
[:leptris_element, :pointer], :pointer
|
|
352
385
|
attach_function :leptris_document_save_file,
|
|
@@ -398,6 +431,11 @@ module Leptris
|
|
|
398
431
|
XPATH_NUMBER = 2
|
|
399
432
|
XPATH_STRING = 3
|
|
400
433
|
|
|
434
|
+
XPATH_NODE_ELEMENT = 0
|
|
435
|
+
XPATH_NODE_ATTRIBUTE = 1
|
|
436
|
+
XPATH_NODE_TEXT = 2
|
|
437
|
+
XPATH_NODE_OTHER = 3
|
|
438
|
+
|
|
401
439
|
NODE_ELEMENT = 0
|
|
402
440
|
NODE_TEXT = 1
|
|
403
441
|
NODE_COMMENT = 2
|
data/lib/leptris/xml/node_set.rb
CHANGED
|
@@ -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.
|
|
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.
|
|
4
|
+
version: 1.1.2
|
|
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-
|
|
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
|
data/lib/leptris/xml/c14n.rb
DELETED
|
@@ -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
|