tinybits 0.7.0 → 0.8.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 CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: b85036300ef1fdcc8e58f52bbdcbb97608de1e114b8a60e219d6a4c7916e03dd
4
- data.tar.gz: b3cfb9ec09f09c2df38c0cfb984f5e43e22a3324b18b27e534374180d8f14bcf
3
+ metadata.gz: 8c60cd0920984c872762a71f597b65c2c9712791ea0b3e8a54a20282536f8a6e
4
+ data.tar.gz: 40d72eea34b0e6c07f6747955edca46dfed52a9a624f8e19d2e93ae8a7f6dfa6
5
5
  SHA512:
6
- metadata.gz: c087b9799699c49e67f84bf3677511778691b951773279c6153b20f8f4c92de3ff0b34cfd2e07e4f62e8f85098dcb2135e433a15be5e544f254f5304ba4a8634
7
- data.tar.gz: cf6abb1686f1cbd6eb5cd6bfb03a5ef808fec12200c2ed699f93298a7339a94baaefdc0bf31427e731089e8e48bef359988f55f3cc2ccfc2379fcdbdb1683754
6
+ metadata.gz: 1a4086aa883b8af346ff003b3b414aea443fd56caff4f1da6730cf974365886ae78eceb84c1d37d9d4aea026121cafc0eb5febb4ee3c1ff03e48dc0b646fb203
7
+ data.tar.gz: 063a02e5715833da64c75fd54e6a353e3d6cf89b61d704085edd3791a6b31131398174b3d27e5e1189fd1e0137644aed2358a26e0b2576b717f8775b5a951c0b
@@ -1,6 +1,6 @@
1
1
  /**
2
2
  * TinyBits Amalgamated Header
3
- * Generated on: Tue May 13 11:39:13 PM CEST 2025
3
+ * Generated on: Fri 30 Oct 2026 12:29:55 PM CET
4
4
  */
5
5
 
6
6
  #ifndef TINY_BITS_H
@@ -1108,7 +1108,7 @@ static inline enum tiny_bits_type _unpack_blob(tiny_bits_unpacker *decoder, uint
1108
1108
  read = decode_varint(decoder->buffer, decoder->size, pos, &len);
1109
1109
  if(read == 0) return TINY_BITS_ERROR;
1110
1110
  if((pos + read + len) > decoder->size) return TINY_BITS_ERROR;
1111
- value->str_blob_val.data = (const char *)decoder->buffer + pos;
1111
+ value->str_blob_val.data = (const char *)decoder->buffer + pos + read;
1112
1112
  value->str_blob_val.length = len;
1113
1113
  decoder->current_pos = pos + read + len;
1114
1114
  return TINY_BITS_BLOB;
@@ -27,7 +27,7 @@ VALUE rb_cUnpacker;
27
27
  static VALUE rb_packer_alloc(VALUE klass);
28
28
  static VALUE rb_packer_init(VALUE self);
29
29
  static VALUE rb_unpacker_alloc(VALUE klass);
30
- static VALUE rb_unpacker_init(VALUE self);
30
+ static VALUE rb_unpacker_init(int argc, VALUE* argv, VALUE self);
31
31
  static VALUE rb_pack(VALUE self, VALUE obj);
32
32
  static VALUE rb_unpack(VALUE self, VALUE buffer);
33
33
 
@@ -112,6 +112,8 @@ static VALUE rb_packer_init(VALUE self) {
112
112
  static inline int pack_ruby_object_recursive(tiny_bits_packer* packer, VALUE obj, VALUE context) {
113
113
  switch (TYPE(obj)) {
114
114
  case T_STRING: {
115
+ if (ENCODING_GET_INLINED(obj) == rb_ascii8bit_encindex())
116
+ return pack_blob(packer, RSTRING_PTR(obj), RSTRING_LEN(obj));
115
117
  return pack_str(packer, RSTRING_PTR(obj), RSTRING_LEN(obj));
116
118
  }
117
119
  case T_HASH: {
@@ -134,6 +136,14 @@ static inline int pack_ruby_object_recursive(tiny_bits_packer* packer, VALUE obj
134
136
  int64_t val = NUM2LONG(obj); // Assumes fits in int64_t
135
137
  return pack_int(packer, val);
136
138
  }
139
+ case T_BIGNUM: {
140
+ // within int64: a Bignum only past the Fixnum range (2**62)
141
+ if (rb_absint_numwords(obj, 63, NULL) > 1) {
142
+ rb_warn("Integer out of the int64 range encountered during packing");
143
+ return 0;
144
+ }
145
+ return pack_int(packer, (int64_t)NUM2LL(obj));
146
+ }
137
147
  case T_FLOAT: {
138
148
  double val = NUM2DBL(obj);
139
149
  return pack_double(packer, val);
@@ -288,6 +298,7 @@ static VALUE rb_reset(VALUE self){
288
298
  // Unpacker structure
289
299
  typedef struct {
290
300
  tiny_bits_unpacker* unpacker;
301
+ int symbolize_keys; // map keys that are strings come back as symbols
291
302
  //size_t strings_index;
292
303
  //VALUE ruby_strings[TB_HASH_CACHE_SIZE];
293
304
  } UnpackerData;
@@ -316,6 +327,7 @@ static const rb_data_type_t unpacker_data_type = {
316
327
  static VALUE rb_unpacker_alloc(VALUE klass) {
317
328
  UnpackerData* unpacker_data = ALLOC(UnpackerData);
318
329
  unpacker_data->unpacker = NULL;
330
+ unpacker_data->symbolize_keys = 0;
319
331
  return TypedData_Wrap_Struct(klass, &unpacker_data_type, unpacker_data);
320
332
  }
321
333
 
@@ -324,12 +336,19 @@ static VALUE rb_unpacker_alloc(VALUE klass) {
324
336
  *
325
337
  * Initializes a new Unpacker.
326
338
  *
339
+ * @param symbolize_keys [Boolean] unpack hash keys that are strings as symbols (default false)
327
340
  * @return [Unpacker] The initialized unpacker object.
328
341
  */
329
- static VALUE rb_unpacker_init(VALUE self) {
342
+ static VALUE rb_unpacker_init(int argc, VALUE* argv, VALUE self) {
330
343
  UnpackerData* unpacker_data;
331
344
  TypedData_Get_Struct(self, UnpackerData, &unpacker_data_type, unpacker_data);
332
345
 
346
+ VALUE opts = Qnil;
347
+ rb_scan_args(argc, argv, ":", &opts);
348
+ if (!NIL_P(opts)) {
349
+ unpacker_data->symbolize_keys = RTEST(rb_hash_lookup(opts, ID2SYM(rb_intern("symbolize_keys"))));
350
+ }
351
+
333
352
  unpacker_data->unpacker = tiny_bits_unpacker_create();
334
353
  if (!unpacker_data->unpacker) {
335
354
  rb_raise(rb_eRuntimeError, "Failed to initialize unpacker");
@@ -376,6 +395,12 @@ static VALUE unpack_ruby_object(VALUE strings, UnpackerData* unpacker_data, size
376
395
  return DBL2NUM(value.double_val);
377
396
  case TINY_BITS_INT:
378
397
  return LONG2NUM(value.int_val);
398
+ case TINY_BITS_NAN:
399
+ return DBL2NUM(NAN);
400
+ case TINY_BITS_INF:
401
+ return DBL2NUM(INFINITY);
402
+ case TINY_BITS_N_INF:
403
+ return DBL2NUM(-INFINITY);
379
404
  case TINY_BITS_NULL:
380
405
  return Qnil;
381
406
  case TINY_BITS_TRUE:
@@ -396,6 +421,7 @@ static VALUE unpack_ruby_object(VALUE strings, UnpackerData* unpacker_data, size
396
421
  for (size_t i = 0; i < value.length; i++) {
397
422
  VALUE key = unpack_ruby_object(strings, unpacker_data, 0);
398
423
  if (key == Qundef) return Qundef; // Error
424
+ if (unpacker_data->symbolize_keys && RB_TYPE_P(key, T_STRING)) key = rb_str_intern(key);
399
425
  VALUE val = unpack_ruby_object(strings, unpacker_data, 0);
400
426
  if (val == Qundef) return Qundef; // Error
401
427
  rb_hash_aset(hash, key, val);
@@ -566,7 +592,7 @@ void Init_tinybits_ext(void) {
566
592
  rb_define_method(rb_cPacker, "reset", rb_reset, 0);
567
593
 
568
594
  rb_define_alloc_func(rb_cUnpacker, rb_unpacker_alloc);
569
- rb_define_method(rb_cUnpacker, "initialize", rb_unpacker_init, 0);
595
+ rb_define_method(rb_cUnpacker, "initialize", rb_unpacker_init, -1);
570
596
  rb_define_method(rb_cUnpacker, "unpack", rb_unpack, 1);
571
597
  rb_define_alias(rb_cUnpacker, "load", "unpack");
572
598
  rb_define_alias(rb_cUnpacker, "decode", "unpack");
@@ -2,9 +2,11 @@ module TinyBits
2
2
 
3
3
  class DUnpacker
4
4
 
5
- def initialize(dict)
5
+ # @param dict [[String]] the dictionary the packer used (order is significant).
6
+ # @param symbolize_keys [Boolean] unpack hash keys that are strings as symbols.
7
+ def initialize(dict, symbolize_keys: false)
6
8
  @dict = Packer.new.pack(dict.collect{|a| a.to_s })
7
- @unpacker = Unpacker.new
9
+ @unpacker = Unpacker.new(symbolize_keys: symbolize_keys)
8
10
  @dict_popped = false
9
11
  end
10
12
 
@@ -1,3 +1,3 @@
1
1
  module TinyBits
2
- VERSION = '0.7.0'.freeze
2
+ VERSION = '0.8.0'.freeze
3
3
  end
data/lib/tinybits.rb CHANGED
@@ -20,15 +20,16 @@ module TinyBits
20
20
 
21
21
  # unpacks an object from a binary string
22
22
  # @param buffer [String] The Ruby string holding the packed buffer.
23
+ # @param symbolize_keys [Boolean] unpack hash keys that are strings as symbols.
23
24
  # @return [Object] The unpacked Ruby Object (all strings within the object will be frozen).
24
25
  # @raise [RuntimeError] If unpacking fails due to unsupported types or malformed data.
25
26
  # this is a convinience interface, a better way is to instantiate a TinyBits::Unpacker
26
27
  # object and use its #unpack method
27
- def self.unpack(buffer, dict = nil)
28
+ def self.unpack(buffer, dict = nil, symbolize_keys: false)
28
29
  if dict
29
- DUnpacker.new(dict).unpack(buffer)
30
+ DUnpacker.new(dict, symbolize_keys: symbolize_keys).unpack(buffer)
30
31
  else
31
- Unpacker.new.unpack(buffer)
32
+ Unpacker.new(symbolize_keys: symbolize_keys).unpack(buffer)
32
33
  end
33
34
  end
34
35
  end
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: tinybits
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.7.0
4
+ version: 0.8.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - Mohamed Hassan
@@ -44,7 +44,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
44
44
  - !ruby/object:Gem::Version
45
45
  version: '0'
46
46
  requirements: []
47
- rubygems_version: 4.0.11
47
+ rubygems_version: 4.0.23
48
48
  specification_version: 4
49
49
  summary: Very fast and compact serialization for Ruby!
50
50
  test_files: []