teptris 0.2.8-aarch64-linux → 0.2.12-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: e714f116aa622dd650b4ac56a5e141bf386d91e10dc207fa892987edbf0eefb0
4
- data.tar.gz: 15a3479572c120f1e14679ba9f65b5a5dbf0635f370c8f705241cefb806fcf05
3
+ metadata.gz: 0f2fba1e77b4a112c8659bd5242d0011fe9799655578d8d8de331bbd01cd8d93
4
+ data.tar.gz: 46763b0a790127f1a2f0838fe5c14b9ae1628eeda5fe6e77529505eabfbf360e
5
5
  SHA512:
6
- metadata.gz: da97d70889b02a3a863ef22504b8f8b1506523bb908e2488198bb7700fd137acdb3b3598507ad1951d647e7ae36a994cbcc8c4f7e25d6087da6be35a46dbbca5
7
- data.tar.gz: eb47412826da027c2f82f18c7fe966389748d8e2eaea9bb30cd34d1bdaed2a5de426d8c072c2b2266f4e0bb1aeef6c2f75c703782f8b13b937637bd9f09b1753
6
+ metadata.gz: 83ec919a0cc274e8047ba8d0edbe11a21705dc6cc33c03be4fee2df1ce0a266d5e404e2372b5b34f19cec8aa852ed5bf3eda5f63a26710b0289c7a4beeb139f1
7
+ data.tar.gz: 4f9441a279cd7ad347dc46bc577b74183113e3304314392cf5fb9df709157d315cd93263eedb40cb1b97c0ceadddb0ccb648da8cb8187c24d8f51ad024ade666
data/lib/libteptris.so CHANGED
Binary file
data/lib/teptris/toml.rb CHANGED
@@ -56,241 +56,7 @@ module Teptris
56
56
  end
57
57
 
58
58
  def dump(obj)
59
- raise ArgumentError, "cannot dump #{obj.class}" unless obj.is_a?(Hash)
60
-
61
- out = +""
62
- emit_table(obj, out, nil)
63
- out
64
- end
65
-
66
- private
67
-
68
- def build_parse_error(handle)
69
- line = 0
70
- column = 0
71
- msg = "parse failed"
72
- unless handle.null?
73
- es = Lib::ErrorStruct.new(Lib.teptris_document_error(handle))
74
- line = es[:line]
75
- column = es[:column]
76
- msg = es[:message]
77
- end
78
- ParseError.new(msg, line, column)
79
- end
80
-
81
- # One-bulk-drain load: the C side flattens the whole tree in a
82
- # single crossing; this decoder walks the typed flat buffer.
83
- FLAT_TABLE = 0x01
84
- FLAT_ARRAY = 0x02
85
- FLAT_STRING = 0x03
86
- FLAT_INT = 0x04
87
- FLAT_FLOAT = 0x05
88
- FLAT_FALSE = 0x06
89
- FLAT_TRUE = 0x07
90
- FLAT_DT = 0x08 # ..0x0B: offset, local-datetime, date, local-time
91
-
92
- def load_flat(handle)
93
- bufp = FFI::MemoryPointer.new(:pointer)
94
- lenp = FFI::MemoryPointer.new(:size_t)
95
- st = Lib.teptris_document_flatten(handle, bufp, lenp)
96
- raise Error, "flatten failed" unless st == Teptris::TEPTRIS_OK
97
-
98
- buf = bufp.read_pointer
99
- begin
100
- data = buf.get_bytes(0, lenp.read_uint64)
101
- value, = decode_flat(data, 0)
102
- value
103
- ensure
104
- Lib.teptris_flatten_free(buf)
105
- end
106
- end
107
-
108
- def decode_flat(d, pos)
109
- case d.getbyte(pos)
110
- when FLAT_TABLE
111
- n = d.unpack1("L<", offset: pos + 1)
112
- pos += 5
113
- h = {}
114
- n.times do
115
- kl = d.unpack1("L<", offset: pos)
116
- pos += 4
117
- k = d.byteslice(pos, kl).force_encoding(Encoding::UTF_8)
118
- pos += kl
119
- v, pos = decode_flat(d, pos)
120
- h[k] = v
121
- end
122
- [h, pos]
123
- when FLAT_ARRAY
124
- n = d.unpack1("L<", offset: pos + 1)
125
- pos += 5
126
- a = Array.new(n)
127
- n.times do |i|
128
- a[i], pos = decode_flat(d, pos)
129
- end
130
- [a, pos]
131
- when FLAT_STRING
132
- l = d.unpack1("L<", offset: pos + 1)
133
- pos += 5
134
- [d.byteslice(pos, l).force_encoding(Encoding::UTF_8), pos + l]
135
- when FLAT_INT
136
- [d.unpack1("q<", offset: pos + 1), pos + 9]
137
- when FLAT_FLOAT
138
- [d.unpack1("E", offset: pos + 1), pos + 9]
139
- when FLAT_FALSE then [false, pos + 1]
140
- when FLAT_TRUE then [true, pos + 1]
141
- when FLAT_DT, FLAT_DT + 1, FLAT_DT + 2, FLAT_DT + 3
142
- kind = d.getbyte(pos)
143
- year = d.unpack1("q<", offset: pos + 1)
144
- mon = d.getbyte(pos + 9)
145
- day = d.getbyte(pos + 10)
146
- hour = d.getbyte(pos + 11)
147
- min = d.getbyte(pos + 12)
148
- sec = d.getbyte(pos + 13)
149
- nsec = d.unpack1("L<", offset: pos + 14)
150
- off = d.unpack1("q<", offset: pos + 18)
151
- [flat_datetime(kind, year, mon, day, hour, min, sec, nsec, off),
152
- pos + 26]
153
- else
154
- raise Error, "corrupt flat buffer at #{pos}"
155
- end
156
- end
157
-
158
- def flat_datetime(kind, y, mon, day, hour, min, sec, nsec, off)
159
- return flat_datetime_string(kind, y, mon, day, hour, min, sec, nsec, off) if @mode == 1
160
-
161
- rational = Rational(sec * 1_000_000_000 + nsec, 1_000_000_000)
162
- case kind
163
- when FLAT_DT
164
- check_permitted!(Time)
165
- Time.new(y, mon, day, hour, min, rational, off)
166
- when FLAT_DT + 1
167
- check_permitted!(Time)
168
- Time.local(y, mon, day, hour, min, rational)
169
- when FLAT_DT + 2
170
- check_permitted!(Date)
171
- Date.new(y, mon, day)
172
- else
173
- s = format("%02d:%02d:%02d", hour, min, sec)
174
- s << "." << format("%09d", nsec).sub(/0+\z/, "") if nsec.positive?
175
- s
176
- end
177
- end
178
-
179
- def check_permitted!(klass)
180
- permitted = @permitted
181
- return if permitted.nil? || permitted.include?(klass)
182
-
183
- raise Error,
184
- "value materializes #{klass}, which is not in " \
185
- "permitted_classes (use datetime_policy: :string to keep " \
186
- "datetimes as strings)"
187
- end
188
-
189
- def flat_datetime_string(kind, y, mon, day, hour, min, sec, nsec, off)
190
- case kind
191
- when FLAT_DT + 2 then return format("%04d-%02d-%02d", y, mon, day)
192
- when FLAT_DT + 3 then s = +""
193
- else s = +(format("%04d-%02d-%02dT", y, mon, day))
194
- end
195
- s << format("%02d:%02d:%02d", hour, min, sec)
196
- if nsec.positive?
197
- s << "." << format("%09d", nsec).sub(/0+\z/, "")
198
- end
199
- case kind
200
- when FLAT_DT
201
- off.zero? ? s << "Z" : s << format("%+03d:%02d", off / 3600, (off % 3600).abs / 60)
202
- end
203
- s
204
- end
205
-
206
- # ---- dump -----------------------------------------------------------
207
-
208
- def emit_table(hash, out, prefix)
209
- hash.each do |k, v|
210
- next if table?(v) || aot?(v)
211
-
212
- out << emit_key(k) << " = " << emit_value(v) << "\n"
213
- end
214
- hash.each do |k, v|
215
- next unless table?(v) || aot?(v)
216
-
217
- path = prefix ? "#{prefix}.#{emit_key(k)}" : emit_key(k)
218
- if aot?(v)
219
- v.each do |item|
220
- out << "[[" << path << "]]\n"
221
- emit_table(item, out, path)
222
- end
223
- else
224
- out << "[" << path << "]\n"
225
- emit_table(v, out, path)
226
- end
227
- end
228
- end
229
-
230
- def table?(v)
231
- v.is_a?(Hash)
232
- end
233
-
234
- def aot?(v)
235
- v.is_a?(Array) && !v.empty? && v.all? { |e| e.is_a?(Hash) }
236
- end
237
-
238
- def emit_key(k)
239
- k = k.to_s
240
- if /\A[A-Za-z0-9_-]+\z/.match?(k)
241
- k
242
- elsif !k.include?("'") && !k.each_char.any? { |c| c.ord < 0x20 }
243
- "'#{k}'"
244
- else
245
- "\"#{escape_basic(k)}\""
246
- end
247
- end
248
-
249
- BASIC_ESCAPES = {
250
- "\\" => "\\\\\\\\", # \ -> \\
251
- "\"" => "\\\"", "\b" => "\\b", "\f" => "\\f",
252
- "\n" => "\\n", "\r" => "\\r", "\t" => "\\t"
253
- }.freeze
254
-
255
- def escape_basic(s)
256
- s.gsub(/[\\\"\b\f\n\r\t]/) { |c| BASIC_ESCAPES[c] }
257
- end
258
-
259
- def emit_value(v)
260
- case v
261
- when String
262
- if !v.include?("'") && !v.each_char.any? { |c| c.ord < 0x20 }
263
- "'#{v}'"
264
- else
265
- "\"#{escape_basic(v)}\""
266
- end
267
- when Integer then v.to_s
268
- when Float
269
- return v.to_s if v.finite?
270
-
271
- v.nan? ? "nan" : (v.positive? ? "inf" : "-inf")
272
- when TrueClass then "true"
273
- when FalseClass then "false"
274
- when Time
275
- base = v.strftime("%Y-%m-%dT%H:%M:%S")
276
- frac = v.strftime("%N").sub(/0+\z/, "")
277
- base << "." << frac unless frac.empty?
278
- base << tz(v)
279
- when Date then v.iso8601
280
- when Array then "[#{v.map { |e| emit_value(e) }.join(', ')}]"
281
- when Hash
282
- "{#{v.map { |k, e| "#{emit_key(k)} = #{emit_value(e)}" }.join(', ')}}"
283
- else raise Error, "cannot dump #{v.class}"
284
- end
285
- end
286
-
287
- def tz(time)
288
- off = time.utc_offset
289
- return "Z" if off.zero?
290
-
291
- sign = off.negative? ? "-" : "+"
292
- off = -off if off.negative?
293
- format("%s%02d:%02d", sign, off / 3600, (off % 3600) / 60)
59
+ TeptrisExt.dump(obj)
294
60
  end
295
61
  end
296
62
  end
@@ -1,3 +1,3 @@
1
1
  module Teptris
2
- VERSION = "0.2.8"
2
+ VERSION = "0.2.12"
3
3
  end
data/lib/teptris.rb CHANGED
@@ -3,7 +3,22 @@ require "date"
3
3
  require_relative "teptris/version"
4
4
  require_relative "teptris/error"
5
5
  require_relative "teptris/toml"
6
- require "teptris_ext" # the native extension IS the binding (no fallback)
6
+
7
+ # Windows ucrt rubies name their DLL per minor (x64-ucrt-ruby330.dll), so
8
+ # the mingw gems ship one extension per ruby minor beside a shared
9
+ # libteptris.dll (nokogiri's fat-gem layout). The native extension IS the
10
+ # binding — no fallback, ever.
11
+ begin
12
+ if RUBY_PLATFORM =~ /mingw/
13
+ require "teptris/#{RUBY_VERSION[/\A\d+\.\d+/]}/teptris_ext"
14
+ else
15
+ require "teptris_ext"
16
+ end
17
+ rescue LoadError
18
+ raise LoadError,
19
+ "teptris native extension not available for #{RUBY_PLATFORM} " \
20
+ "ruby #{RUBY_VERSION} (no fallback by design)"
21
+ end
7
22
 
8
23
  module Teptris
9
24
  TEPTRIS_OK = 0
data/lib/teptris_ext.so CHANGED
Binary file
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: teptris
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.2.8
4
+ version: 0.2.12
5
5
  platform: aarch64-linux
6
6
  authors:
7
7
  - teptris contributors
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2026-09-13 00:00:00.000000000 Z
11
+ date: 2026-09-14 00:00:00.000000000 Z
12
12
  dependencies: []
13
13
  description: An FFI binding over libteptris, a C11 TOML 1.0 parser/emitter. API shape
14
14
  mirrors the tomlib gem.