leptris 1.9.239.0 → 1.9.240.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 +4 -4
- data/lib/leptris/vendor/arm64-darwin/libleptris.dylib +0 -0
- data/lib/leptris/vendor/x86_64-linux-musl/libleptris.so +0 -0
- data/lib/leptris/version.rb +1 -1
- data/lib/leptris/xml/ffi.rb +31 -1
- data/lib/leptris/xml/sax/records.rb +134 -0
- data/lib/leptris/xml/sax.rb +1 -0
- metadata +2 -1
checksums.yaml
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
---
|
|
2
2
|
SHA256:
|
|
3
|
-
metadata.gz:
|
|
4
|
-
data.tar.gz:
|
|
3
|
+
metadata.gz: 91e18b7955af279de38382142b10d20f972c5d8fb1ceb02216efdcae5b572e8d
|
|
4
|
+
data.tar.gz: f30f6e5564aac12de9a5a074be4ebd706bb6fba196911fbbd752229507763b0a
|
|
5
5
|
SHA512:
|
|
6
|
-
metadata.gz:
|
|
7
|
-
data.tar.gz:
|
|
6
|
+
metadata.gz: 3cc5846626e6feac81081470224e77a47da5e6094c4d57c7444d2135837aea33cdb799d34437cd717f0a4f7ae28f9df2abd0f8a3772d204693b4c27871bc4d2f
|
|
7
|
+
data.tar.gz: fa24557f80e5182058a320a7cf87fae1644f324750a767c971aa0a836afe2fd611fc610b0f4e57d34a862b6eabe689b13c146b8db5a98fe25f37c68dfbbee882
|
|
Binary file
|
|
Binary file
|
data/lib/leptris/version.rb
CHANGED
data/lib/leptris/xml/ffi.rb
CHANGED
|
@@ -232,6 +232,32 @@ module Leptris
|
|
|
232
232
|
SAX_EVENT_END_PREFIX = 9
|
|
233
233
|
SAX_EVENT_ERROR = 10
|
|
234
234
|
|
|
235
|
+
# LeptrisSaxRecord (sax.h, #1298): one element or text record;
|
|
236
|
+
# tree as parent/next_sib record indices, strings (off,len)
|
|
237
|
+
# views into the records buffer. 10 x uint32 + uint8.
|
|
238
|
+
class SaxRecord < ::FFI::Struct
|
|
239
|
+
layout :kind, :uint32,
|
|
240
|
+
:parent, :uint32, :next_sib, :uint32,
|
|
241
|
+
:off, :uint32, :len, :uint32,
|
|
242
|
+
:line, :uint32, :start_tag_end, :uint32,
|
|
243
|
+
:elem_end, :uint32, :attr_first, :uint32,
|
|
244
|
+
:attr_count, :uint32,
|
|
245
|
+
:self_closing, :uint8
|
|
246
|
+
end
|
|
247
|
+
|
|
248
|
+
SAX_REC_ELEMENT = 0
|
|
249
|
+
SAX_REC_TEXT = 1
|
|
250
|
+
SAX_REC_NO_INDEX = 0xFFFFFFFF
|
|
251
|
+
|
|
252
|
+
# LeptrisSaxAttr: flat attribute table entry — qname + raw
|
|
253
|
+
# value views, value_has_ws = literal \t/\n/\r present (the
|
|
254
|
+
# CONSUMER applies 3.3.3 normalization). 4 x uint32 + uint8.
|
|
255
|
+
class SaxAttr < ::FFI::Struct
|
|
256
|
+
layout :name_off, :uint32, :name_len, :uint32,
|
|
257
|
+
:value_off, :uint32, :value_len, :uint32,
|
|
258
|
+
:value_has_ws, :uint8
|
|
259
|
+
end
|
|
260
|
+
|
|
235
261
|
ITERPARSE_TOP_LEVEL = 0
|
|
236
262
|
ITERPARSE_FULL_DOCUMENT = 1
|
|
237
263
|
|
|
@@ -1049,7 +1075,10 @@ attach_function :leptris_parse_string,
|
|
|
1049
1075
|
attach_function :leptris_sax_records_data, [:pointer], :pointer
|
|
1050
1076
|
attach_function :leptris_sax_records_attrs,
|
|
1051
1077
|
[:pointer, :pointer], :pointer
|
|
1052
|
-
|
|
1078
|
+
# :pointer, NOT UTF8_STRING — the buffer carries embedded NULs
|
|
1079
|
+
# between views; a C string read would truncate at the first.
|
|
1080
|
+
# Views materialize via Pointer#get_string(off, len).
|
|
1081
|
+
attach_function :leptris_sax_records_buffer, [:pointer], :pointer
|
|
1053
1082
|
attach_function :leptris_sax_records_free, [:pointer], :void
|
|
1054
1083
|
# XSLT 1.0 engine (libleptris 1.9.1): compile once, apply many.
|
|
1055
1084
|
# XQuery 1.0 core (libleptris 1.9.64-1.9.66): orchestration
|
|
@@ -1284,6 +1313,7 @@ attach_function :leptris_parse_string,
|
|
|
1284
1313
|
LEPTRIS_ERROR_NOT_FOUND = -6
|
|
1285
1314
|
LEPTRIS_ERROR_IO = -7
|
|
1286
1315
|
LEPTRIS_ERROR_NOT_IMPLEMENTED = -8
|
|
1316
|
+
LEPTRIS_ERROR_NOT_SUPPORTED = -9
|
|
1287
1317
|
|
|
1288
1318
|
XPATH_NODESET = 0
|
|
1289
1319
|
XPATH_BOOLEAN = 1
|
|
@@ -0,0 +1,134 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
# Bulk SAX records (leptris#1298, engine leptris_sax_records_parse,
|
|
4
|
+
# 1.9.223+): ONE crossing drains the whole document into a flat
|
|
5
|
+
# record table — elements and text runs in document order, the tree
|
|
6
|
+
# as parent/next-sibling record indices, attributes an index range
|
|
7
|
+
# into a flat table, every string an (off,len) view into one
|
|
8
|
+
# NUL-padded buffer. The engine mints zero per-event strings; hosts
|
|
9
|
+
# materialize only what they consume (name/value String = one
|
|
10
|
+
# get_string each).
|
|
11
|
+
#
|
|
12
|
+
# Coverage: the interleaved lane's scannable subset — elements, text,
|
|
13
|
+
# attributes; well-formed entity-free documents without comments/
|
|
14
|
+
# PIs/CDATA/DOCTYPE/xmlns. Outside the subset .open answers nil
|
|
15
|
+
# (LEPTRIS_ERROR_NOT_SUPPORTED, zero allocation) and callers fall
|
|
16
|
+
# back to the callback Recorder; correctness is bit-identical.
|
|
17
|
+
#
|
|
18
|
+
# Field columns materialize once per drain via
|
|
19
|
+
# Pointer#read_array_of_uint32 (no Ruby object per record); the
|
|
20
|
+
# self_closing flag rides a separate uint8 column because it shares
|
|
21
|
+
# its struct tail with padding.
|
|
22
|
+
class Leptris::XML::SAX::Records
|
|
23
|
+
KIND_ELEMENT = Leptris::XML::FFI::SAX_REC_ELEMENT
|
|
24
|
+
KIND_TEXT = Leptris::XML::FFI::SAX_REC_TEXT
|
|
25
|
+
|
|
26
|
+
REC = Leptris::XML::FFI::SaxRecord
|
|
27
|
+
ATTR = Leptris::XML::FFI::SaxAttr
|
|
28
|
+
REC_U32 = REC.size / 4
|
|
29
|
+
ATTR_U32 = ATTR.size / 4
|
|
30
|
+
|
|
31
|
+
attr_reader :count, :attr_count
|
|
32
|
+
|
|
33
|
+
# Drains xml into a table. Returns nil unless the document drained
|
|
34
|
+
# cleanly — outside the scannable subset (NOT_SUPPORTED, zero
|
|
35
|
+
# allocation) OR malformed (the callback path reports parse errors
|
|
36
|
+
# with position) — callers fall back to the callback Recorder in
|
|
37
|
+
# every nil case; correctness is bit-identical.
|
|
38
|
+
def self.open(xml)
|
|
39
|
+
xml = xml.to_s
|
|
40
|
+
out = ::FFI::MemoryPointer.new(:pointer)
|
|
41
|
+
status = Leptris::XML::FFI.leptris_sax_records_parse(
|
|
42
|
+
xml, xml.bytesize, 0, out
|
|
43
|
+
)
|
|
44
|
+
return nil unless status == Leptris::XML::FFI::LEPTRIS_OK
|
|
45
|
+
|
|
46
|
+
new(out.read_pointer)
|
|
47
|
+
end
|
|
48
|
+
|
|
49
|
+
# Block form: the table dies at the end of the block — every view
|
|
50
|
+
# dies with it, so materialize inside.
|
|
51
|
+
def self.parse(xml)
|
|
52
|
+
table = open(xml)
|
|
53
|
+
return nil unless table
|
|
54
|
+
|
|
55
|
+
begin
|
|
56
|
+
yield table
|
|
57
|
+
ensure
|
|
58
|
+
table.free
|
|
59
|
+
end
|
|
60
|
+
end
|
|
61
|
+
|
|
62
|
+
def initialize(ptr)
|
|
63
|
+
@ptr = ptr
|
|
64
|
+
@count = Leptris::XML::FFI.leptris_sax_records_count(@ptr)
|
|
65
|
+
recs = Leptris::XML::FFI.leptris_sax_records_data(@ptr)
|
|
66
|
+
attr_out = ::FFI::MemoryPointer.new(:pointer)
|
|
67
|
+
attrs = Leptris::XML::FFI.leptris_sax_records_attrs(@ptr, attr_out)
|
|
68
|
+
@attr_count = attr_out.read_uint64
|
|
69
|
+
@buf = Leptris::XML::FFI.leptris_sax_records_buffer(@ptr)
|
|
70
|
+
# Whole-table single reads: no Ruby object per record. The u32
|
|
71
|
+
# columns stride by struct size; the flags (self_closing /
|
|
72
|
+
# value_has_ws) are u8 tails read per-byte off their layout
|
|
73
|
+
# offset — endian-safe.
|
|
74
|
+
@rec_u32 = recs.read_array_of_uint32(@count * REC_U32)
|
|
75
|
+
@rec_flag = recs.read_array_of_uint8(@count * REC.size)
|
|
76
|
+
@attr_u32 = attrs.read_array_of_uint32(@attr_count * ATTR_U32)
|
|
77
|
+
@attr_flag = attrs.read_array_of_uint8(@attr_count * ATTR.size)
|
|
78
|
+
@rec_flag_off = REC.offset_of(:self_closing)
|
|
79
|
+
@attr_flag_off = ATTR.offset_of(:value_has_ws)
|
|
80
|
+
end
|
|
81
|
+
|
|
82
|
+
def free
|
|
83
|
+
return if @ptr.nil?
|
|
84
|
+
|
|
85
|
+
Leptris::XML::FFI.leptris_sax_records_free(@ptr)
|
|
86
|
+
@ptr = nil
|
|
87
|
+
end
|
|
88
|
+
|
|
89
|
+
def kind(i)
|
|
90
|
+
@rec_u32[i * REC_U32]
|
|
91
|
+
end
|
|
92
|
+
|
|
93
|
+
# Parent record index (0xFFFFFFFF for document-level records).
|
|
94
|
+
def parent(i)
|
|
95
|
+
@rec_u32[i * REC_U32 + 1]
|
|
96
|
+
end
|
|
97
|
+
|
|
98
|
+
# Element name or text content — ONE String per call, UTF-8.
|
|
99
|
+
def view(i)
|
|
100
|
+
base = i * REC_U32
|
|
101
|
+
@buf.get_string(@rec_u32[base + 3], @rec_u32[base + 4])
|
|
102
|
+
.force_encoding(Encoding::UTF_8)
|
|
103
|
+
end
|
|
104
|
+
|
|
105
|
+
def self_closing?(i)
|
|
106
|
+
@rec_flag[i * REC.size + @rec_flag_off] != 0
|
|
107
|
+
end
|
|
108
|
+
|
|
109
|
+
def attr_first(i)
|
|
110
|
+
@rec_u32[i * REC_U32 + 8]
|
|
111
|
+
end
|
|
112
|
+
|
|
113
|
+
def attr_count_of(i)
|
|
114
|
+
@rec_u32[i * REC_U32 + 9]
|
|
115
|
+
end
|
|
116
|
+
|
|
117
|
+
def attr_name(k)
|
|
118
|
+
@buf.get_string(@attr_u32[k * ATTR_U32],
|
|
119
|
+
@attr_u32[k * ATTR_U32 + 1])
|
|
120
|
+
.force_encoding(Encoding::UTF_8)
|
|
121
|
+
end
|
|
122
|
+
|
|
123
|
+
def attr_value(k)
|
|
124
|
+
@buf.get_string(@attr_u32[k * ATTR_U32 + 2],
|
|
125
|
+
@attr_u32[k * ATTR_U32 + 3])
|
|
126
|
+
.force_encoding(Encoding::UTF_8)
|
|
127
|
+
end
|
|
128
|
+
|
|
129
|
+
# Literal \t/\n/\r in the raw value — the consumer applies
|
|
130
|
+
# XML 1.0 §3.3.3 (map each break byte to a space).
|
|
131
|
+
def attr_value_has_ws?(k)
|
|
132
|
+
@attr_flag[k * ATTR.size + @attr_flag_off] != 0
|
|
133
|
+
end
|
|
134
|
+
end
|
data/lib/leptris/xml/sax.rb
CHANGED
metadata
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
|
2
2
|
name: leptris
|
|
3
3
|
version: !ruby/object:Gem::Version
|
|
4
|
-
version: 1.9.
|
|
4
|
+
version: 1.9.240.0
|
|
5
5
|
platform: ruby
|
|
6
6
|
authors:
|
|
7
7
|
- Ribose Inc.
|
|
@@ -197,6 +197,7 @@ files:
|
|
|
197
197
|
- lib/leptris/xml/sax/dom_dispatch.rb
|
|
198
198
|
- lib/leptris/xml/sax/parser.rb
|
|
199
199
|
- lib/leptris/xml/sax/recorder.rb
|
|
200
|
+
- lib/leptris/xml/sax/records.rb
|
|
200
201
|
- lib/leptris/xml/schematron.rb
|
|
201
202
|
- lib/leptris/xml/searchable.rb
|
|
202
203
|
- lib/leptris/xml/serialization.rb
|