moxml 0.5.0 → 0.5.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 +4 -4
- data/lib/moxml/adapter/leptris.rb +23 -2
- data/lib/moxml/adapter/ox.rb +41 -21
- data/lib/moxml/adapter/rexml.rb +9 -5
- data/lib/moxml/version.rb +1 -1
- metadata +1 -1
checksums.yaml
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
---
|
|
2
2
|
SHA256:
|
|
3
|
-
metadata.gz:
|
|
4
|
-
data.tar.gz:
|
|
3
|
+
metadata.gz: ca6fefbf114afcaf13d9c241b4df5081eef1e004019618ca12d31a655d89dd53
|
|
4
|
+
data.tar.gz: d361373f16dafff997d4ca53b5dbc23c332b09331e8f49ef5abed09f526bdea7
|
|
5
5
|
SHA512:
|
|
6
|
-
metadata.gz:
|
|
7
|
-
data.tar.gz:
|
|
6
|
+
metadata.gz: 0a2e61a613511970e4c6945c074a578aefcb12591def797a726bf0959796c43dbf2e71b77509271b1dad15b9f0f1e81f5ec3b8b0af0e384bccad35745bc2dbb6
|
|
7
|
+
data.tar.gz: 183964ef083c888b3b7d58b896a547acf25c0414d997040c10b805b8379088825c2ec996b149aa9e8fe51b6419135d1341d8ebe9c88ddb0656101e25d3291557
|
|
@@ -266,7 +266,13 @@ module Moxml
|
|
|
266
266
|
def split_entity_markers(natives, parent)
|
|
267
267
|
result = []
|
|
268
268
|
natives.each do |child|
|
|
269
|
-
|
|
269
|
+
# FFI Text#content returns a fresh unfrozen BINARY string:
|
|
270
|
+
# retag in place (dup would be a throwaway allocation), but
|
|
271
|
+
# before include? — BINARY.include? with the UTF-8 marker raises
|
|
272
|
+
if child.is_a?(::Leptris::XML::Text)
|
|
273
|
+
content = child.content
|
|
274
|
+
content.force_encoding("UTF-8")
|
|
275
|
+
end
|
|
270
276
|
if content&.include?(Entity::MARKER)
|
|
271
277
|
content.scan(/([^#{Entity::MARKER}]*)(?:#{Entity::MARKER}([\w.:-]+);)?/o) do
|
|
272
278
|
text_part = Regexp.last_match(1)
|
|
@@ -862,8 +868,23 @@ module Moxml
|
|
|
862
868
|
|
|
863
869
|
private
|
|
864
870
|
|
|
871
|
+
# The variable-length \s* gap after \A defeats Onigmo's anchor
|
|
872
|
+
# optimization, forcing a full-buffer scan — 6.5 ms on a 1 MB
|
|
873
|
+
# document without a declaration (the common case). Match a
|
|
874
|
+
# head slice instead; fall back to the full string only when
|
|
875
|
+
# the head is all whitespace (pathological prefixes).
|
|
876
|
+
SOURCE_DECLARATION_RE = /\A\s*<\?xml\b/
|
|
877
|
+
private_constant :SOURCE_DECLARATION_RE
|
|
878
|
+
|
|
865
879
|
def record_source_declaration(native_doc, xml_string)
|
|
866
|
-
|
|
880
|
+
head = xml_string[0, 256]
|
|
881
|
+
had = if head.match?(SOURCE_DECLARATION_RE)
|
|
882
|
+
true
|
|
883
|
+
elsif head.match?(/\A\s*\z/)
|
|
884
|
+
xml_string.match?(SOURCE_DECLARATION_RE)
|
|
885
|
+
else
|
|
886
|
+
false
|
|
887
|
+
end
|
|
867
888
|
attachments.set(native_doc, :had_source_declaration, had)
|
|
868
889
|
end
|
|
869
890
|
|
data/lib/moxml/adapter/ox.rb
CHANGED
|
@@ -717,28 +717,48 @@ module Moxml
|
|
|
717
717
|
# Only documents/elements can contain entity refs or CDATA issues
|
|
718
718
|
return false unless node.is_a?(::Ox::Document) || node.is_a?(::Ox::Element)
|
|
719
719
|
|
|
720
|
-
#
|
|
721
|
-
|
|
722
|
-
|
|
723
|
-
|
|
724
|
-
|
|
725
|
-
|
|
726
|
-
|
|
727
|
-
|
|
728
|
-
|
|
729
|
-
|
|
730
|
-
|
|
731
|
-
|
|
732
|
-
|
|
733
|
-
|
|
734
|
-
|
|
735
|
-
has_cdata =
|
|
736
|
-
if
|
|
737
|
-
attachments.set(
|
|
738
|
-
attachments.set(
|
|
720
|
+
# Element serializes consult the owning document's cached
|
|
721
|
+
# flags — a rescan per call made element to_xml ~30x slower
|
|
722
|
+
# than document to_xml on plain documents.
|
|
723
|
+
scan_root = node
|
|
724
|
+
if node.is_a?(::Ox::Element) && (doc = document(node))
|
|
725
|
+
return true if attachments.get(doc, :has_entity_refs)
|
|
726
|
+
return true if attachments.get(doc, :has_cdata_end_markers)
|
|
727
|
+
return false if attachments.key?(doc, :has_entity_refs) &&
|
|
728
|
+
attachments.key?(doc, :has_cdata_end_markers)
|
|
729
|
+
|
|
730
|
+
scan_root = doc
|
|
731
|
+
end
|
|
732
|
+
|
|
733
|
+
# One merged tree scan instead of two; flags cache on the
|
|
734
|
+
# document either way.
|
|
735
|
+
has_er, has_cdata = tree_scan_custom_needs(scan_root)
|
|
736
|
+
if scan_root.is_a?(::Ox::Document)
|
|
737
|
+
attachments.set(scan_root, :has_entity_refs, has_er)
|
|
738
|
+
attachments.set(scan_root, :has_cdata_end_markers, has_cdata)
|
|
739
|
+
end
|
|
740
|
+
|
|
741
|
+
has_er || has_cdata
|
|
742
|
+
end
|
|
743
|
+
|
|
744
|
+
# Single walk collecting both custom-serialize triggers.
|
|
745
|
+
def tree_scan_custom_needs(node)
|
|
746
|
+
has_er = false
|
|
747
|
+
has_cdata = false
|
|
748
|
+
stack = [node]
|
|
749
|
+
until stack.empty?
|
|
750
|
+
current = stack.pop
|
|
751
|
+
case current
|
|
752
|
+
when ::Moxml::Adapter::CustomizedOx::EntityReference
|
|
753
|
+
has_er = true
|
|
754
|
+
when ::Ox::CData
|
|
755
|
+
has_cdata = true if current.value&.include?("]]>")
|
|
756
|
+
when ::Ox::Element, ::Ox::Document
|
|
757
|
+
current.nodes&.each { |child| stack << child }
|
|
758
|
+
end
|
|
759
|
+
return [true, has_cdata] if has_er
|
|
739
760
|
end
|
|
740
|
-
|
|
741
|
-
has_cdata
|
|
761
|
+
[has_er, has_cdata]
|
|
742
762
|
end
|
|
743
763
|
|
|
744
764
|
def has_declaration?(native_doc, _wrapper)
|
data/lib/moxml/adapter/rexml.rb
CHANGED
|
@@ -186,12 +186,16 @@ module Moxml
|
|
|
186
186
|
# Return all children preserving whitespace text nodes
|
|
187
187
|
result = node.children.dup
|
|
188
188
|
|
|
189
|
-
# Include any EntityReference wrappers stored alongside native
|
|
189
|
+
# Include any EntityReference wrappers stored alongside native
|
|
190
|
+
# children. Native children are identity-unique; only this
|
|
191
|
+
# concat can duplicate (the same wrapper added twice), so the
|
|
192
|
+
# dedupe lives here and the common path stays scan-free.
|
|
190
193
|
entity_refs = attachments.get(node, :entity_refs)
|
|
191
|
-
|
|
192
|
-
|
|
193
|
-
|
|
194
|
-
|
|
194
|
+
if entity_refs
|
|
195
|
+
result.concat(entity_refs).uniq!(&:object_id) || result
|
|
196
|
+
else
|
|
197
|
+
result
|
|
198
|
+
end
|
|
195
199
|
end
|
|
196
200
|
|
|
197
201
|
def parent(node)
|
data/lib/moxml/version.rb
CHANGED