yeptris 0.6.7.4-aarch64-linux → 0.6.7.5-aarch64-linux

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 CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 38fd217a7686b96f7665ef834d28df3a2d7cdce411f4dcfb29988d57537586c7
4
- data.tar.gz: 11ac5624a27aafc4254506f63118ecbe919c8f1cfb6466d8b2b342ef43ca38be
3
+ metadata.gz: 0b7d5fc414b1459a5bd7507b2cc3f4dc308efd75010d82f132bd7da078c3e999
4
+ data.tar.gz: a27ba76d7a111dd8902ff058e1a26cadd05c3cfa921034bcab70bbad48deff0f
5
5
  SHA512:
6
- metadata.gz: a2d5d2f45d7dd6ad25e2e491f5fac8df7ccce2ffd7312ae2302ee49369749b7ee502519a4616d0c69a7365302f4ca349eafc60b0ea45e6c160f709c53f519e82
7
- data.tar.gz: 863a0a4e29c2a60f157560881070172f209acd9e001b727d9aeeb70c1f1ec106e1bb5e7a816f1798c841cdc79016674dd8fdf5add5698235439d51c535446e15
6
+ metadata.gz: 86c23e8e229b87eff443d7e2be1cc16ad57b07a80b8edf5feb7a757e4b611aff34822c78eca5548c72e7eb42a1895f3023b4a50948147e654cb119003ad21a57
7
+ data.tar.gz: 75ef4719add9a892912352792c0fd8e28347a079ccfee167b1520082d77c1d7a17d83baa593024d2c1b03d8ff0e2d9881f85e6dd1ec56dd00a8606fa25dcaf6f
@@ -0,0 +1,114 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Yeptris
4
+ # CBOR (RFC 8949) over the same FFI document the rest of the
5
+ # binding rides (TODO.cbor/04). Decode materializes through the
6
+ # Psych-compatible path; encode builds the tree with YAMLTree and
7
+ # hands the document to the C encoder — plain data only (aliases
8
+ # and non-decimal tag text are unencodable by the C contract).
9
+ #
10
+ # Representation notes inherited from the decoder: integers beyond
11
+ # int64 and bignums materialize as their shortest-double text, byte
12
+ # strings as tag-chained text — CBOR's JSON-data-model mapping.
13
+ module CBOR
14
+ STRICT = (1 << 0) # decode: reject non-minimal arguments
15
+ CANONICAL = (1 << 1) # encode: s4.2.1 core deterministic profile
16
+
17
+ class Error < Yeptris::Error; end
18
+ class UnencodableError < Error; end
19
+
20
+ module_function
21
+
22
+ def available?
23
+ defined?(::Yeptris::FFI::CBOR_EX) && ::Yeptris::FFI::CBOR_EX
24
+ end
25
+
26
+ def load(data, strict: false)
27
+ raise Error, "libyeptris has no CBOR support" unless available?
28
+
29
+ doc_ptr = ::Yeptris::FFI.yeptris_cbor_decode(data, data.bytesize, strict ? STRICT : 0, nil)
30
+ raise ParseError, ::Yeptris::FFI.last_error_message if doc_ptr.null?
31
+
32
+ # the wrapper's finalizer also frees — its idempotent #free is
33
+ # the ONLY release path (a raw double free corrupts the heap)
34
+ doc = ::Yeptris::Document.new(doc_ptr)
35
+ doc.root.to_ruby
36
+ ensure
37
+ doc&.free
38
+ end
39
+
40
+ def load_sequence(data, strict: false)
41
+ raise Error, "libyeptris has no CBOR support" unless available?
42
+
43
+ items = []
44
+ receiver = ::FFI::Function.new(:int, %i[pointer pointer size_t]) do |_ctx, item, _index|
45
+ # the callback owns the item; materialize then free in place
46
+ # (through the wrapper — the finalizer frees too)
47
+ doc = ::Yeptris::Document.new(item)
48
+ items << doc.root&.to_ruby
49
+ doc.free
50
+ 0
51
+ end
52
+ st = ::Yeptris::FFI.yeptris_cbor_decode_sequence(
53
+ data, data.bytesize, strict ? STRICT : 0, receiver, nil, nil
54
+ )
55
+ raise ParseError, ::Yeptris::FFI.last_error_message if st.zero? && !data.empty?
56
+
57
+ items
58
+ end
59
+
60
+ def dump(obj, canonical: true)
61
+ docs = build_documents([obj])
62
+ begin
63
+ encode_one(docs[0], canonical)
64
+ ensure
65
+ docs.each(&:free)
66
+ end
67
+ end
68
+
69
+ def dump_sequence(objects, canonical: true)
70
+ docs = build_documents(objects)
71
+ begin
72
+ opts = canonical ? CANONICAL : 0
73
+ arr = ::FFI::MemoryPointer.new(:pointer, docs.size)
74
+ arr.write_array_of_pointer(docs.map(&:c_ptr))
75
+ len_ptr = ::FFI::MemoryPointer.new(:size_t)
76
+ take_buffer(
77
+ ::Yeptris::FFI.yeptris_cbor_encode_sequence(arr, docs.size, opts, len_ptr),
78
+ len_ptr
79
+ )
80
+ ensure
81
+ docs.each(&:free)
82
+ end
83
+ end
84
+
85
+ # -- internals ----------------------------------------------------
86
+
87
+ def build_documents(objects)
88
+ # ONE document per object: a visitor's tree is a single
89
+ # document and push sets its root — reuse would overwrite
90
+ objects.map do |obj|
91
+ visitor = ::Yeptris::Psych::Visitors::YAMLTree.new
92
+ visitor.push(obj)
93
+ visitor.document
94
+ end
95
+ end
96
+
97
+ def encode_one(doc, canonical)
98
+ opts = canonical ? CANONICAL : 0
99
+ len_ptr = ::FFI::MemoryPointer.new(:size_t)
100
+ take_buffer(::Yeptris::FFI.yeptris_cbor_encode(doc.c_ptr, opts, len_ptr), len_ptr)
101
+ end
102
+
103
+ # The encode convenience contract: a malloc'd buffer plus its
104
+ # byte length — binary data, freed through the library's own free.
105
+ def take_buffer(ptr, len_ptr)
106
+ raise UnencodableError, ::Yeptris::FFI.last_error_message if ptr.null?
107
+
108
+ len = len_ptr.read_uint64
109
+ ptr.read_bytes(len).force_encoding(Encoding::BINARY)
110
+ ensure
111
+ ::Yeptris::FFI.yeptris_free(ptr) if ptr && !ptr.null?
112
+ end
113
+ end
114
+ end
data/lib/yeptris/ffi.rb CHANGED
@@ -230,17 +230,45 @@ module Yeptris
230
230
  false
231
231
  end
232
232
 
233
+ # CBOR (RFC 8949, TODO.cbor): absent on libraries before the
234
+ # codec's release — the CBOR module feature-detects
235
+ CBOR_EX = begin
236
+ attach_function :yeptris_cbor_decode, %i[pointer size_t uint32 yeptris_status_out],
237
+ :yeptris_document
238
+ callback :cbor_item_cb, %i[pointer yeptris_document size_t], :int
239
+ attach_function :yeptris_cbor_decode_sequence,
240
+ %i[pointer size_t uint32 cbor_item_cb pointer yeptris_status_out], :size_t
241
+ attach_function :yeptris_cbor_encode, %i[yeptris_document uint32 pointer], :pointer
242
+ attach_function :yeptris_cbor_encode_sequence,
243
+ %i[pointer size_t uint32 pointer], :pointer
244
+ true
245
+ rescue ::FFI::NotFoundError
246
+ false
247
+ end
248
+
233
249
  # Owned char* results (serialize*): one reader, freed exactly once.
234
250
  # The release goes through yeptris_free (libyeptris's own
235
251
  # allocator-matching free) because ffi's :free attach has no
236
252
  # Windows process-symbol fallback — libyeptris.dll doesn't export
237
253
  # libc free, so resolving :free against it fails on Windows.
238
- begin
254
+ # A raised attach ABORTS this file mid-evaluation — everything
255
+ # after it (NODE_SCALAR and the kind constants below) never
256
+ # defines, and a lazily autoloaded node.rb then dies with
257
+ # 'uninitialized constant' (#138). Every fallback attaches too.
258
+ YEPTRIS_FREE = begin
239
259
  attach_function :yeptris_free, [:pointer], :void
260
+ :direct
240
261
  rescue ::FFI::NotFoundError
241
- # libyeptris < v0.6.6: POSIX resolves :free through the process
242
- # symbol table, so the direct libc attach still works there.
243
- attach_function :yeptris_free, :free, [:pointer], :void
262
+ begin
263
+ # libyeptris < v0.6.6: POSIX resolves :free through the
264
+ # process symbol table, so the libc attach still works there.
265
+ attach_function :yeptris_free, :free, [:pointer], :void
266
+ :libc
267
+ rescue ::FFI::NotFoundError
268
+ # no owned-buffer release on this lib+platform combination;
269
+ # Owned.string leaks instead of killing the whole file
270
+ :none
271
+ end
244
272
  end
245
273
 
246
274
  module Owned
@@ -258,7 +286,7 @@ module Yeptris
258
286
  else
259
287
  ptr.read_string.force_encoding(Encoding::UTF_8)
260
288
  end
261
- ::Yeptris::FFI.yeptris_free(ptr)
289
+ ::Yeptris::FFI.yeptris_free(ptr) if ::Yeptris::FFI::YEPTRIS_FREE != :none
262
290
  s
263
291
  end
264
292
  end
@@ -41,6 +41,12 @@ module Yeptris
41
41
  BuiltDocument.new(@tree)
42
42
  end
43
43
 
44
+ # The raw document (the CBOR encoder consumes the tree
45
+ # directly; #tree wraps it for stdlib's yaml face)
46
+ def document
47
+ @tree
48
+ end
49
+
44
50
  def finish
45
51
  @tree.serialize(explicit_doc_start: true)
46
52
  end
data/lib/yeptris.rb CHANGED
@@ -3,7 +3,7 @@
3
3
  module Yeptris
4
4
  # The gem's version lives in the parent namespace's file — the last
5
5
  # internal require (yeptris/version) retired with it.
6
- VERSION = "0.6.7.4".freeze
6
+ VERSION = "0.6.7.5".freeze
7
7
  # The error hierarchy lives in THIS file (the parent namespace's
8
8
  # own file): nested constants do not trigger a parent-constant
9
9
  # autoload, and the law forbids internal requires — defining the
@@ -44,6 +44,7 @@ module Yeptris
44
44
  autoload :ValueML, "yeptris/valueml"
45
45
  autoload :Psych, "yeptris/psych"
46
46
  autoload :Schema, "yeptris/schema"
47
+ autoload :CBOR, "yeptris/cbor"
47
48
  end
48
49
 
49
50
  # NOTE (the #318 poisoned-process class): the Psych error-name aliases
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: yeptris
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.6.7.4
4
+ version: 0.6.7.5
5
5
  platform: aarch64-linux
6
6
  authors:
7
7
  - Ribose Inc.
@@ -40,6 +40,7 @@ files:
40
40
  - ext/yeptris_native/json_ruby.c
41
41
  - ext/yeptris_native/yeptris_native.c
42
42
  - lib/yeptris.rb
43
+ - lib/yeptris/cbor.rb
43
44
  - lib/yeptris/document.rb
44
45
  - lib/yeptris/ffi.rb
45
46
  - lib/yeptris/json.rb