moxml 0.5.48 → 0.5.50
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/lib/moxml/adapter/base.rb +8 -0
- data/lib/moxml/adapter/leptris.rb +110 -15
- data/lib/moxml/node.rb +13 -0
- data/lib/moxml/version.rb +1 -1
- metadata +2 -2
checksums.yaml
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
---
|
|
2
2
|
SHA256:
|
|
3
|
-
metadata.gz:
|
|
4
|
-
data.tar.gz:
|
|
3
|
+
metadata.gz: '0188508b255f1adb8c622a2965a91352c7ffc63afd79d53796ad48c708d479eb'
|
|
4
|
+
data.tar.gz: 16f4ce7dfbd8a335dfd535bca051288f8a5645a273d7aea9be8fa2d245073482
|
|
5
5
|
SHA512:
|
|
6
|
-
metadata.gz:
|
|
7
|
-
data.tar.gz:
|
|
6
|
+
metadata.gz: 13d1a513fecc2d4e23ee833929b05b2c93d77b4567623246f22f4ddb8f3461a2661f69a1cc73b091b08ab6474b40f929ecf4272ba54112f313ba936598761b81
|
|
7
|
+
data.tar.gz: 76ef5828a376dd566c1945a8655e71fe5d8a68f7a8a007a1260855a05ebcec442034712370e3e9decc5d07490ea2f9ce534b49c5c036df41e6b291868698927f
|
data/lib/moxml/adapter/base.rb
CHANGED
|
@@ -141,6 +141,14 @@ module Moxml
|
|
|
141
141
|
nil
|
|
142
142
|
end
|
|
143
143
|
|
|
144
|
+
# Subtree walk capability: an adapter with a C-side pre-order
|
|
145
|
+
# traversal (leptris >= 1.9.174.6 visit) walks descendants in
|
|
146
|
+
# one dispatch; nil keeps the recursive children walk. Self
|
|
147
|
+
# is not yielded (each_node semantics).
|
|
148
|
+
def walk_descendants(_native, _context)
|
|
149
|
+
nil
|
|
150
|
+
end
|
|
151
|
+
|
|
144
152
|
def same_node?(one, other)
|
|
145
153
|
one == other
|
|
146
154
|
end
|
|
@@ -159,21 +159,116 @@ module Moxml
|
|
|
159
159
|
# 3-4 Ruby frames collapse to the module call over the C
|
|
160
160
|
# method. @native is self; every adapter method that accepts
|
|
161
161
|
# a native already handles NativeNode receivers.
|
|
162
|
-
#
|
|
163
|
-
#
|
|
164
|
-
#
|
|
165
|
-
#
|
|
166
|
-
#
|
|
167
|
-
# pipeline
|
|
168
|
-
#
|
|
169
|
-
#
|
|
170
|
-
#
|
|
171
|
-
# (
|
|
172
|
-
|
|
173
|
-
|
|
174
|
-
|
|
175
|
-
|
|
176
|
-
|
|
162
|
+
# Identity mode v2 (#230): wrapper classes SUBCLASS the
|
|
163
|
+
# TypedData native and include the contract modules, and
|
|
164
|
+
# NativeNode.from honors its receiver (klass-injection,
|
|
165
|
+
# 1.9.174.4+): the C wrap mints our class directly — no
|
|
166
|
+
# Ruby-level extend (the v1 extend mint regressed the
|
|
167
|
+
# pipeline 4x; this is the same TypedData wrap the base
|
|
168
|
+
# mint pays). @native is self; the adapter's C-surface
|
|
169
|
+
# bind_calls accept these receivers (they are NativeNode
|
|
170
|
+
# instances). The hot bare reads super into the C methods
|
|
171
|
+
# (exact-name = the bare-name contract).
|
|
172
|
+
module Identity
|
|
173
|
+
ELEMENT = Class.new(::Leptris::XML::NativeNode) do
|
|
174
|
+
include ::Moxml::Node
|
|
175
|
+
include ::Moxml::Element
|
|
176
|
+
end
|
|
177
|
+
TEXT = Class.new(::Leptris::XML::NativeNode) do
|
|
178
|
+
include ::Moxml::Node
|
|
179
|
+
include ::Moxml::Text
|
|
180
|
+
end
|
|
181
|
+
CDATA = Class.new(::Leptris::XML::NativeNode) do
|
|
182
|
+
include ::Moxml::Node
|
|
183
|
+
include ::Moxml::Cdata
|
|
184
|
+
end
|
|
185
|
+
COMMENT = Class.new(::Leptris::XML::NativeNode) do
|
|
186
|
+
include ::Moxml::Node
|
|
187
|
+
include ::Moxml::Comment
|
|
188
|
+
end
|
|
189
|
+
PROCESSING_INSTRUCTION = Class.new(::Leptris::XML::NativeNode) do
|
|
190
|
+
include ::Moxml::Node
|
|
191
|
+
include ::Moxml::ProcessingInstruction
|
|
192
|
+
end
|
|
193
|
+
|
|
194
|
+
TYPES = {
|
|
195
|
+
element: ELEMENT,
|
|
196
|
+
text: TEXT,
|
|
197
|
+
cdata: CDATA,
|
|
198
|
+
comment: COMMENT,
|
|
199
|
+
processing_instruction: PROCESSING_INSTRUCTION,
|
|
200
|
+
}.freeze
|
|
201
|
+
|
|
202
|
+
module Reads
|
|
203
|
+
# The C methods sit BELOW the contract modules in the
|
|
204
|
+
# ancestry (NativeNode is the superclass), so super
|
|
205
|
+
# from here would run the contract implementation and
|
|
206
|
+
# ADD frames. bind_call reaches the C surface
|
|
207
|
+
# directly; prefixed names take the contract path.
|
|
208
|
+
ELEMENT_CONTRACT_READ =
|
|
209
|
+
::Moxml::ElementBehavior.instance_method(:[])
|
|
210
|
+
|
|
211
|
+
def [](key)
|
|
212
|
+
if key.is_a?(String) && !key.include?(":")
|
|
213
|
+
value = NN_ATTRIBUTE.bind_call(self, key)
|
|
214
|
+
return value unless value.is_a?(String) && entity_bearing?
|
|
215
|
+
|
|
216
|
+
return ::Moxml::Adapter::Leptris.restore_entities(value)
|
|
217
|
+
end
|
|
218
|
+
|
|
219
|
+
ELEMENT_CONTRACT_READ.bind_call(self, key)
|
|
220
|
+
end
|
|
221
|
+
|
|
222
|
+
def text
|
|
223
|
+
value = NN_CONTENT.bind_call(self)
|
|
224
|
+
value.is_a?(String) && entity_bearing? ? ::Moxml::Adapter::Leptris.restore_entities(value) : value
|
|
225
|
+
end
|
|
226
|
+
end
|
|
227
|
+
ELEMENT.include(Reads)
|
|
228
|
+
TEXT.include(Reads)
|
|
229
|
+
end
|
|
230
|
+
|
|
231
|
+
NATIVE_IDENTITY =
|
|
232
|
+
NATIVE_MUTATIONS_COHERENT &&
|
|
233
|
+
Gem::Version.new(::Leptris::VERSION) >= Gem::Version.new("1.9.174.4")
|
|
234
|
+
|
|
235
|
+
def wrap_native(node, type, _context)
|
|
236
|
+
return nil unless NATIVE_IDENTITY &&
|
|
237
|
+
node.is_a?(::Leptris::XML::NativeNode)
|
|
238
|
+
|
|
239
|
+
# from() registers in the shared address-keyed native
|
|
240
|
+
# cache, so later canonical/bulk mints hand OUR instance
|
|
241
|
+
# back — a native already carrying the contract IS the
|
|
242
|
+
# wrapper; minting again would loop per access.
|
|
243
|
+
return node if node.is_a?(::Moxml::Node)
|
|
244
|
+
|
|
245
|
+
klass = Identity::TYPES[type]
|
|
246
|
+
return nil unless klass
|
|
247
|
+
|
|
248
|
+
doc = doc_for(node)
|
|
249
|
+
return nil unless doc
|
|
250
|
+
|
|
251
|
+
klass.from(doc, node)
|
|
252
|
+
end
|
|
253
|
+
|
|
254
|
+
NATIVE_C_WALK =
|
|
255
|
+
defined?(::Leptris::XML::NativeNode) &&
|
|
256
|
+
Gem::Version.new(::Leptris::VERSION) >= Gem::Version.new("1.9.174.6")
|
|
257
|
+
|
|
258
|
+
# One C visit walk (TODO.perf/27: post-order/abort state in
|
|
259
|
+
# the C callback, rb_yield direct — no FFI closure per
|
|
260
|
+
# node) instead of per-level children walks. Pre-order via
|
|
261
|
+
# entering; depth 0 is the receiver and stays unyielded.
|
|
262
|
+
def walk_descendants(native, context)
|
|
263
|
+
return nil unless NATIVE_C_WALK
|
|
264
|
+
|
|
265
|
+
root = to_binding(native)
|
|
266
|
+
return nil unless root.is_a?(::Leptris::XML::Element) ||
|
|
267
|
+
root.is_a?(::Leptris::XML::Document)
|
|
268
|
+
|
|
269
|
+
root.visit do |node, entering, depth|
|
|
270
|
+
yield Moxml::Node.wrap(node, context) if entering && depth.positive?
|
|
271
|
+
end
|
|
177
272
|
end
|
|
178
273
|
|
|
179
274
|
def record_native_doc(root_native, doc)
|
data/lib/moxml/node.rb
CHANGED
|
@@ -278,6 +278,19 @@ module Moxml
|
|
|
278
278
|
# Recursively yield all descendant nodes
|
|
279
279
|
# Used by XPath descendant-or-self and descendant axes
|
|
280
280
|
def each_node(&block)
|
|
281
|
+
unless block
|
|
282
|
+
# Eager materialization: the leptris C-side walk rb_yields
|
|
283
|
+
# from the C callback and segfaults across fiber-suspended
|
|
284
|
+
# enumerator frames, so the no-block form never enters it.
|
|
285
|
+
nodes = []
|
|
286
|
+
each_node { |node| nodes << node }
|
|
287
|
+
return nodes.each
|
|
288
|
+
end
|
|
289
|
+
|
|
290
|
+
# Adapters with a C-side subtree walk take it in one
|
|
291
|
+
# dispatch; the recursive children walk stays the fallback.
|
|
292
|
+
return if adapter.walk_descendants(@native, context, &block)
|
|
293
|
+
|
|
281
294
|
children.each do |child|
|
|
282
295
|
yield child
|
|
283
296
|
child.each_node(&block)
|
data/lib/moxml/version.rb
CHANGED
metadata
CHANGED
|
@@ -1,14 +1,14 @@
|
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
|
2
2
|
name: moxml
|
|
3
3
|
version: !ruby/object:Gem::Version
|
|
4
|
-
version: 0.5.
|
|
4
|
+
version: 0.5.50
|
|
5
5
|
platform: ruby
|
|
6
6
|
authors:
|
|
7
7
|
- Ribose Inc.
|
|
8
8
|
autorequire:
|
|
9
9
|
bindir: exe
|
|
10
10
|
cert_chain: []
|
|
11
|
-
date: 2026-09-
|
|
11
|
+
date: 2026-09-16 00:00:00.000000000 Z
|
|
12
12
|
dependencies: []
|
|
13
13
|
description: |
|
|
14
14
|
Moxml is a unified XML manipulation library that provides a common API
|