Module: Leptris::XML::Serialization
- Defined in:
- lib/leptris/xml/serialization.rb
Overview
Owns the SerializeOptions lifecycle and the owned-string read for document and subtree serialization/canonicalization. Document and Element expose one-line methods over this module — the options struct, the encoding anchor, the C call, and the read-and-free all live here.
Class Method Summary collapse
-
.build_options(indent: 0, no_decl: false, encoding: nil) ⇒ Object
Builds a SerializeOptions struct.
-
.canonicalize(ffi_function, c_ptr, version:, mode:, inclusive_namespaces: nil, with_comments: false) ⇒ Object
ffi_functionis a bound FFI function taking (c_ptr, version, mode, ns_ptr, flags): leptris_c14n_canonicalize_ex or leptris_c14n_canonicalize_subtree_ex. -
.to_xml(ffi_function, c_ptr, indent: 0, no_decl: false, encoding: nil) ⇒ Object
ffi_functionis a bound _serialize_into function taking (c_ptr, buf, capacity, out_len, opts): size query with buf=NULL, then one fill into a caller buffer.
Class Method Details
.build_options(indent: 0, no_decl: false, encoding: nil) ⇒ Object
Builds a SerializeOptions struct. Returns [opts, encoding_anchor]; the anchor must stay referenced while opts is in an FFI call.
62 63 64 65 66 67 68 69 70 71 72 |
# File 'lib/leptris/xml/serialization.rb', line 62 def self.(indent: 0, no_decl: false, encoding: nil) opts = Leptris::XML::FFI::SerializeOptions.new opts[:indent] = indent.to_i opts[:xml_declaration] = no_decl ? 0 : 1 encoding_anchor = nil if encoding encoding_anchor = ::FFI::MemoryPointer.from_string(encoding.to_s) opts[:encoding] = encoding_anchor end [opts, encoding_anchor] end |
.canonicalize(ffi_function, c_ptr, version:, mode:, inclusive_namespaces: nil, with_comments: false) ⇒ Object
ffi_function is a bound FFI function taking
(c_ptr, version, mode, ns_ptr, flags): leptris_c14n_canonicalize_ex
or leptris_c14n_canonicalize_subtree_ex.
53 54 55 56 57 58 |
# File 'lib/leptris/xml/serialization.rb', line 53 def self.canonicalize(ffi_function, c_ptr, version:, mode:, inclusive_namespaces: nil, with_comments: false) ns_ptr, _ns_anchor = Leptris::XML::CStringArray.to_c(inclusive_namespaces) str_ptr = ffi_function.call(c_ptr, version, mode, ns_ptr, with_comments ? 1 : 0) Leptris::XML::FFI.read_owned_string(str_ptr) end |
.to_xml(ffi_function, c_ptr, indent: 0, no_decl: false, encoding: nil) ⇒ Object
ffi_function is a bound _serialize_into function taking
(c_ptr, buf, capacity, out_len, opts): size query with buf=NULL,
then one fill into a caller buffer. Since libleptris 1.9.0 the
pair reuses a single serialization through a per-document cache
(leptris#541) — no C-side result-string allocation, and repeated
serializations of an unmutated document skip the serialize pass.
27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 |
# File 'lib/leptris/xml/serialization.rb', line 27 def self.to_xml(ffi_function, c_ptr, indent: 0, no_decl: false, encoding: nil) opts = if indent.to_i.zero? && !no_decl && encoding.nil? DEFAULT_OPTIONS else opts, _encoding_anchor = ( indent: indent, no_decl: no_decl, encoding: encoding) opts end need = ffi_function.call(c_ptr, nil, 0, nil, opts.pointer) return "" if need.zero? buf = ::FFI::MemoryPointer.new(:char, need) begin ffi_function.call(c_ptr, buf, need, nil, opts.pointer) # The buffer holds exactly the serialization + NUL; XML output # is NUL-free, so a bounded read_string is exact. (Avoids the # out_len param — no portable size_t read exists on Pointer.) buf.read_string ensure buf.free end end |