string_bits 0.2.0 → 0.2.1

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.
Files changed (3) hide show
  1. checksums.yaml +4 -4
  2. data/ext/string_bits/string_bits.c +81 -46
  3. metadata +1 -1
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 88122353506d55eaecdcdccc56fb8c1d6e07bc7eae76b46c01cdc98890395653
4
- data.tar.gz: 2fade95ae4b0f862d6a9b96884a9fec2faf5916859b8a5251f3fd4ad567bf40d
3
+ metadata.gz: e6202692ddb08678e3c0c07f9f2e1f15a85982fbe172e9d1e986559cc954efbe
4
+ data.tar.gz: a23c8747fec6bdbb82565bd299851be0d6c2f5150e148b5b6ce5b1c1b356c1c1
5
5
  SHA512:
6
- metadata.gz: 8fb4e9b166f936c1525fdfc86044baa1619caae3c80c067191b92c58adec30274c6a52fa1e488c95d3e213dcdce5b2de4bbbbb31ed56d65b26a81f28165cb2fb
7
- data.tar.gz: e8b09ea3c141ac04dfbf2b44ce747e0c8122eb5f25ba96b7acad94e85952d10e7f4cdf010aad2a848d9c620654fe30d6b3f200c492e10e1f0325b3056635568c
6
+ metadata.gz: ce535ad3b8066edce1c3f132cfad48b3e958d6252a42bee210a7bd5ef8962c235383cab7bae0d79a1d600ab937a9d7197ec08590962884af8b8b2bdc92b3cffb
7
+ data.tar.gz: 05dd0dd9327fa659a171cb5645a792a5442ec09e47564c64d8e635ca54bfcdef3ef67f8e9e44f1282bd17fdd557874bea96495a03abb85ea6bd3c905678ba35b
@@ -2,10 +2,40 @@
2
2
  #include "ruby/encoding.h"
3
3
 
4
4
  #include <limits.h> /* CHAR_BIT */
5
- #include <stdint.h> /* uint64_t, UINT64_MAX */
5
+ #include <stdint.h> /* uint64_t, UINT64_MAX, int64_t, intptr_t */
6
+ #include <inttypes.h> /* PRIdPTR (ssize_t via intptr_t), PRId64 */
6
7
  #include <string.h> /* memcpy */
7
8
  #include <sys/types.h> /* ssize_t (Ruby typedefs it on Windows) */
8
9
 
10
+ /* Whole-string bit length, computed in 64 bits.
11
+ *
12
+ * RSTRING_LEN returns a pointer-width signed length, so `RSTRING_LEN(s) * 8`
13
+ * overflows a signed 32-bit ssize_t once a string reaches 2**28 bytes (256 MiB)
14
+ * on an ILP32 build, corrupting every bounds check that compares a bit offset
15
+ * against it. Valid bit indices are confined to the Fixnum range and always fit
16
+ * ssize_t, so only this whole-string bit length needs the wider type: computing
17
+ * it in int64_t keeps the bounds checks correct on 32-bit without changing the
18
+ * public pointer-width bit-index contract (see Discussion.md, "Error behavior
19
+ * for out-of-range bit indices").
20
+ *
21
+ * Porting to Ruby Core:
22
+ * 1. Core String lengths are `long` (RSTRING_LEN), which is pointer-width,
23
+ * so `RSTRING_LEN(str) * 8` overflows on ILP32 for strings >= 256 MiB
24
+ * exactly as it does for ssize_t here. Keep the whole-string bit length
25
+ * in a 64-bit intermediate at every bounds check; do not hold it in a
26
+ * `long`. Reuse this macro (or an equivalent inline) rather than open-
27
+ * coding `len * 8`.
28
+ * 2. Keep the public bit-index type pointer-width and keep rejecting
29
+ * out-of-range positions with ArgumentError (see the cross-reference
30
+ * above). Only this internal length is widened, so the contract that
31
+ * core inherits is unchanged.
32
+ * 3. The error-message format specifiers below (<inttypes.h>: (intptr_t)
33
+ * with PRIdPTR for bit offsets, PRId64 for this widened length) exist
34
+ * only because this length is wider than the offsets. In core, follow
35
+ * the local convention for formatting `long` offsets and pick a 64-bit
36
+ * specifier for the widened length accordingly. */
37
+ #define SB_BIT_LEN(byte_len) ((int64_t)(byte_len) * 8)
38
+
9
39
  /* popcount ----------------------------------------------------------------- */
10
40
  /*
11
41
  * Porting to Ruby Core:
@@ -227,7 +257,7 @@ check_bit_index(VALUE self, VALUE n, int lsb_first)
227
257
  rb_raise(rb_eTypeError, "bit index must be an integer");
228
258
  }
229
259
  ssize_t idx = integer_to_bit_idx(n);
230
- ssize_t size = RSTRING_LEN(self) * 8;
260
+ int64_t size = SB_BIT_LEN(RSTRING_LEN(self));
231
261
  if (idx < 0 || idx >= size) {
232
262
  rb_raise(rb_eIndexError, "bit index out of range");
233
263
  }
@@ -302,10 +332,10 @@ sb_range_validate_endpoints(VALUE range)
302
332
  }
303
333
 
304
334
  static inline VALUE
305
- sb_range_beg_len(VALUE range, ssize_t *begp, ssize_t *lenp, ssize_t len, int err)
335
+ sb_range_beg_len(VALUE range, ssize_t *begp, ssize_t *lenp, int64_t len, int err)
306
336
  {
307
337
  long lbeg = 0, llen = 0;
308
- long clipped = (len > (ssize_t)LONG_MAX) ? LONG_MAX : (long)len;
338
+ long clipped = (len > (int64_t)LONG_MAX) ? LONG_MAX : (long)len;
309
339
  struct sb_range_args args = { range, &lbeg, &llen, clipped, err };
310
340
  int state = 0;
311
341
  VALUE result = rb_protect(sb_range_beg_len_call, (VALUE)&args, &state);
@@ -389,7 +419,7 @@ rb_str_bit_at(int argc, VALUE *argv, VALUE self)
389
419
  if (bit_offset < 0) {
390
420
  rb_raise(rb_eIndexError, "bit index out of range");
391
421
  }
392
- ssize_t size = RSTRING_LEN(self) * 8;
422
+ int64_t size = SB_BIT_LEN(RSTRING_LEN(self));
393
423
  if (size <= bit_offset) {
394
424
  return Qnil;
395
425
  }
@@ -457,9 +487,9 @@ count_set_bits_range(const unsigned char *str, ssize_t total_bytes,
457
487
  ssize_t start, ssize_t length)
458
488
  {
459
489
  if (length <= 0) return 0;
460
- ssize_t total_bits = total_bytes * 8;
490
+ int64_t total_bits = SB_BIT_LEN(total_bytes);
461
491
  if (start >= total_bits) return 0;
462
- if (start + length > total_bits) length = total_bits - start;
492
+ if (start + length > total_bits) length = (ssize_t)(total_bits - start);
463
493
 
464
494
  ssize_t byte_start = start >> 3;
465
495
  int bit_lo = (int)(start & 7);
@@ -494,9 +524,9 @@ count_set_bits_range_msb(const unsigned char *str, ssize_t total_bytes,
494
524
  ssize_t start, ssize_t length)
495
525
  {
496
526
  if (length <= 0) return 0;
497
- ssize_t total_bits = total_bytes * 8;
527
+ int64_t total_bits = SB_BIT_LEN(total_bytes);
498
528
  if (start >= total_bits) return 0;
499
- if (start + length > total_bits) length = total_bits - start;
529
+ if (start + length > total_bits) length = (ssize_t)(total_bits - start);
500
530
 
501
531
  ssize_t byte_start = start >> 3;
502
532
  int s_bit = (int)(start & 7); /* MSB-first within-byte start index */
@@ -543,7 +573,7 @@ rb_str_bit_count(int argc, VALUE *argv, VALUE self)
543
573
  return SSIZET2NUM(count_set_bits(str, src_len));
544
574
 
545
575
  int lsb_first = parse_lsb_first_opt(opts);
546
- ssize_t total_bits = src_len * 8;
576
+ int64_t total_bits = SB_BIT_LEN(src_len);
547
577
  ssize_t bit_offset, bit_length;
548
578
 
549
579
  if (rb_obj_is_kind_of(v0, rb_cRange)) {
@@ -590,7 +620,7 @@ rb_str_bit_count(int argc, VALUE *argv, VALUE self)
590
620
  static void
591
621
  emit_bits(const unsigned char *str, ssize_t len, int lsb_first, ssize_t start_offset, VALUE ary)
592
622
  {
593
- if (start_offset >= len * 8) return;
623
+ if (start_offset >= SB_BIT_LEN(len)) return;
594
624
 
595
625
  #define SB_EMIT(v) \
596
626
  do { VALUE _b = (v); \
@@ -652,7 +682,8 @@ rb_str_bits(int argc, VALUE *argv, VALUE self)
652
682
  return self;
653
683
  }
654
684
 
655
- ssize_t nbits = (start_offset >= len * 8) ? 0 : (len * 8 - start_offset);
685
+ int64_t total_bits = SB_BIT_LEN(len);
686
+ ssize_t nbits = (start_offset >= total_bits) ? 0 : (ssize_t)(total_bits - start_offset);
656
687
  VALUE ary = rb_ary_new_capa(nbits);
657
688
  emit_bits(str, len, lsb_first, start_offset, ary);
658
689
  return ary;
@@ -690,7 +721,7 @@ static void
690
721
  emit_bit_offsets(const unsigned char *str, ssize_t len, int target, int lsb_first,
691
722
  ssize_t start_offset, VALUE ary)
692
723
  {
693
- if (start_offset >= len * 8) return;
724
+ if (start_offset >= SB_BIT_LEN(len)) return;
694
725
 
695
726
  #define SB_EMIT(pos_val) \
696
727
  do { VALUE _p = (pos_val); \
@@ -803,7 +834,7 @@ rb_str_bit_offsets(int argc, VALUE *argv, VALUE self)
803
834
  /* Pre-size the Array using popcount to avoid repeated reallocation.
804
835
  * For target=0 the expected count is (len * 8 - popcount). */
805
836
  ssize_t set_count = count_set_bits(str, len);
806
- ssize_t count = (target == 1) ? set_count : (len * 8 - set_count);
837
+ ssize_t count = (target == 1) ? set_count : (ssize_t)(SB_BIT_LEN(len) - set_count);
807
838
  VALUE ary = rb_ary_new_capa(count);
808
839
  emit_bit_offsets(str, len, target, lsb_first, start_offset, ary);
809
840
  return ary;
@@ -908,7 +939,7 @@ static VALUE
908
939
  rb_str_bit_slice(int argc, VALUE *argv, VALUE self)
909
940
  {
910
941
  ssize_t src_len = RSTRING_LEN(self);
911
- ssize_t total_bits = src_len * 8;
942
+ int64_t total_bits = SB_BIT_LEN(src_len);
912
943
  ssize_t bit_offset, bit_length;
913
944
  VALUE v0, v1, opts;
914
945
  int n_pos = rb_scan_args(argc, argv, "11:", &v0, &v1, &opts);
@@ -943,8 +974,8 @@ rb_str_bit_slice(int argc, VALUE *argv, VALUE self)
943
974
  }
944
975
 
945
976
  if (bit_offset > total_bits) return Qnil;
946
- ssize_t available = total_bits - bit_offset;
947
- if (bit_length > available) bit_length = available;
977
+ int64_t available = total_bits - bit_offset;
978
+ if (bit_length > available) bit_length = (ssize_t)available;
948
979
 
949
980
  if (bit_length == 0) return rb_str_new("", 0);
950
981
 
@@ -1022,7 +1053,7 @@ rb_str_mutate_bits(int argc, VALUE *argv, VALUE self, enum sb_mutation_op op)
1022
1053
  if (bit_length < 0)
1023
1054
  rb_raise(rb_eArgError, "bit_length must be non-negative");
1024
1055
  if (bit_length == 0) return self;
1025
- ssize_t total_bits = RSTRING_LEN(self) * 8;
1056
+ int64_t total_bits = SB_BIT_LEN(RSTRING_LEN(self));
1026
1057
  if (bit_offset >= total_bits || bit_offset + bit_length > total_bits)
1027
1058
  rb_raise(rb_eIndexError, "bit range out of range");
1028
1059
  for (ssize_t logical = bit_offset; logical < bit_offset + bit_length; logical++) {
@@ -1042,7 +1073,7 @@ rb_str_mutate_bits(int argc, VALUE *argv, VALUE self, enum sb_mutation_op op)
1042
1073
 
1043
1074
  if (rb_obj_is_kind_of(target, rb_cRange)) {
1044
1075
  sb_range_validate_endpoints(target);
1045
- ssize_t total_bits = RSTRING_LEN(self) * 8;
1076
+ int64_t total_bits = SB_BIT_LEN(RSTRING_LEN(self));
1046
1077
  ssize_t beg, len;
1047
1078
 
1048
1079
  /* err=0 returns Qnil for out-of-range begin (after negative normalization);
@@ -1336,7 +1367,7 @@ rb_str_each_bit_field(int argc, VALUE *argv, VALUE self)
1336
1367
  rb_raise(rb_eArgError, "bitlen must be positive");
1337
1368
  }
1338
1369
  if (bl > 64) {
1339
- rb_raise(rb_eArgError, "bitlen must be <= 64 (got %ld)", bl);
1370
+ rb_raise(rb_eArgError, "bitlen must be <= 64 (got %" PRIdPTR ")", (intptr_t)bl);
1340
1371
  }
1341
1372
  bitlens[f] = bl;
1342
1373
  step += bl;
@@ -1345,8 +1376,8 @@ rb_str_each_bit_field(int argc, VALUE *argv, VALUE self)
1345
1376
  int lsb_first = parse_lsb_first_opt(opts);
1346
1377
 
1347
1378
  ssize_t src_len = RSTRING_LEN(self);
1348
- ssize_t total_bits = src_len * 8;
1349
- ssize_t iterations = total_bits / step;
1379
+ int64_t total_bits = SB_BIT_LEN(src_len);
1380
+ ssize_t iterations = (ssize_t)(total_bits / step);
1350
1381
 
1351
1382
  VALUE *field_vals = ALLOCA_N(VALUE, num_fields);
1352
1383
 
@@ -1390,7 +1421,7 @@ rb_str_bit_fields(int argc, VALUE *argv, VALUE self)
1390
1421
  rb_raise(rb_eArgError, "bitlen must be positive");
1391
1422
  }
1392
1423
  if (bl > 64) {
1393
- rb_raise(rb_eArgError, "bitlen must be <= 64 (got %ld)", bl);
1424
+ rb_raise(rb_eArgError, "bitlen must be <= 64 (got %" PRIdPTR ")", (intptr_t)bl);
1394
1425
  }
1395
1426
  bitlens[f] = bl;
1396
1427
  step += bl;
@@ -1399,8 +1430,8 @@ rb_str_bit_fields(int argc, VALUE *argv, VALUE self)
1399
1430
  int lsb_first = parse_lsb_first_opt(opts);
1400
1431
 
1401
1432
  ssize_t src_len = RSTRING_LEN(self);
1402
- ssize_t total_bits = src_len * 8;
1403
- ssize_t iterations = total_bits / step;
1433
+ int64_t total_bits = SB_BIT_LEN(src_len);
1434
+ ssize_t iterations = (ssize_t)(total_bits / step);
1404
1435
 
1405
1436
  int have_block = rb_block_given_p();
1406
1437
  VALUE result = have_block ? Qnil : rb_ary_new_capa(iterations);
@@ -1444,7 +1475,7 @@ rb_str_bit_fields(int argc, VALUE *argv, VALUE self)
1444
1475
  static ssize_t
1445
1476
  count_run_lsb(const unsigned char *src, ssize_t src_len, ssize_t bit_offset, int target)
1446
1477
  {
1447
- ssize_t max_run = src_len * 8 - bit_offset;
1478
+ int64_t max_run = SB_BIT_LEN(src_len) - bit_offset;
1448
1479
  ssize_t byte_idx = bit_offset >> 3;
1449
1480
  int bit_off = bit_offset & 7;
1450
1481
  ssize_t count = 0;
@@ -1461,7 +1492,7 @@ count_run_lsb(const unsigned char *src, ssize_t src_len, ssize_t bit_offset, int
1461
1492
  count += run;
1462
1493
  byte_idx++;
1463
1494
  if (run < remaining)
1464
- return count < max_run ? count : max_run;
1495
+ return (ssize_t)(count < max_run ? count : max_run);
1465
1496
  }
1466
1497
 
1467
1498
  #if SB_LITTLE_ENDIAN
@@ -1475,7 +1506,7 @@ count_run_lsb(const unsigned char *src, ssize_t src_len, ssize_t bit_offset, int
1475
1506
  byte_idx += 8;
1476
1507
  } else {
1477
1508
  count += sb_ctzll(~word);
1478
- return count < max_run ? count : max_run;
1509
+ return (ssize_t)(count < max_run ? count : max_run);
1479
1510
  }
1480
1511
  }
1481
1512
  #endif
@@ -1490,11 +1521,11 @@ count_run_lsb(const unsigned char *src, ssize_t src_len, ssize_t bit_offset, int
1490
1521
  byte_idx++;
1491
1522
  } else {
1492
1523
  count += sb_ctz8(~b);
1493
- return count < max_run ? count : max_run;
1524
+ return (ssize_t)(count < max_run ? count : max_run);
1494
1525
  }
1495
1526
  }
1496
1527
 
1497
- return count < max_run ? count : max_run;
1528
+ return (ssize_t)(count < max_run ? count : max_run);
1498
1529
  }
1499
1530
 
1500
1531
  /* Return the length of the consecutive run of `bit` starting at pos, or nil. */
@@ -1512,7 +1543,7 @@ rb_str_bit_run_count(int argc, VALUE *argv, VALUE self)
1512
1543
  int target = parse_bit_target(bit_val);
1513
1544
  ssize_t bit_offset = integer_to_bit_idx(bit_offset_v);
1514
1545
  ssize_t src_len = RSTRING_LEN(self);
1515
- if (bit_offset < 0 || bit_offset >= src_len * 8) return Qnil;
1546
+ if (bit_offset < 0 || bit_offset >= SB_BIT_LEN(src_len)) return Qnil;
1516
1547
 
1517
1548
  const unsigned char *src = (const unsigned char *)RSTRING_PTR(self);
1518
1549
  if (lsb_first) {
@@ -1523,7 +1554,7 @@ rb_str_bit_run_count(int argc, VALUE *argv, VALUE self)
1523
1554
  if (logical_get_bit(src, bit_offset, 0) != target) return Qnil;
1524
1555
 
1525
1556
  ssize_t run = 1;
1526
- ssize_t total_bits = src_len * 8;
1557
+ int64_t total_bits = SB_BIT_LEN(src_len);
1527
1558
  while (bit_offset + run < total_bits && logical_get_bit(src, bit_offset + run, 0) == target) {
1528
1559
  run++;
1529
1560
  }
@@ -1545,8 +1576,8 @@ static void
1545
1576
  emit_bit_runs(VALUE self, int lsb_first, ssize_t start_offset, VALUE ary)
1546
1577
  {
1547
1578
  ssize_t src_len = RSTRING_LEN(self);
1548
- if (src_len == 0 || start_offset >= src_len * 8) return;
1549
- ssize_t total_bits = src_len * 8;
1579
+ int64_t total_bits = SB_BIT_LEN(src_len);
1580
+ if (src_len == 0 || start_offset >= total_bits) return;
1550
1581
  ssize_t offset = start_offset;
1551
1582
 
1552
1583
  #define SB_EMIT_TRIPLE(bval, oval, lval) \
@@ -1620,7 +1651,7 @@ rb_str_bit_splice(int argc, VALUE *argv, VALUE self)
1620
1651
  ssize_t dst_bit_off, dst_bit_len;
1621
1652
  ssize_t src_bit_off, src_bit_len;
1622
1653
  VALUE str;
1623
- ssize_t dst_total = RSTRING_LEN(self) * 8;
1654
+ int64_t dst_total = SB_BIT_LEN(RSTRING_LEN(self));
1624
1655
  VALUE v0, v1, v2, v3, opts;
1625
1656
 
1626
1657
  int n_pos = rb_scan_args(argc, argv, "22:", &v0, &v1, &v2, &v3, &opts);
@@ -1651,7 +1682,7 @@ rb_str_bit_splice(int argc, VALUE *argv, VALUE self)
1651
1682
  if (!rb_integer_type_p(v2)) {
1652
1683
  rb_raise(rb_eTypeError, "third argument must be an Integer");
1653
1684
  }
1654
- ssize_t src_total = RSTRING_LEN(str) * 8;
1685
+ int64_t src_total = SB_BIT_LEN(RSTRING_LEN(str));
1655
1686
  src_bit_off = integer_to_bit_idx(v2);
1656
1687
  if (src_bit_off < 0) src_bit_off += src_total;
1657
1688
  src_bit_len = dst_bit_len;
@@ -1690,7 +1721,7 @@ rb_str_bit_splice(int argc, VALUE *argv, VALUE self)
1690
1721
  if (dst_bit_off < 0) dst_bit_off += dst_total;
1691
1722
  str = v2;
1692
1723
  Check_Type(str, T_STRING);
1693
- ssize_t src_total = RSTRING_LEN(str) * 8;
1724
+ int64_t src_total = SB_BIT_LEN(RSTRING_LEN(str));
1694
1725
  src_bit_off = integer_to_bit_idx(v3);
1695
1726
  if (src_bit_off < 0) src_bit_off += src_total;
1696
1727
  src_bit_len = dst_bit_len;
@@ -1702,15 +1733,17 @@ rb_str_bit_splice(int argc, VALUE *argv, VALUE self)
1702
1733
 
1703
1734
  if (dst_bit_off < 0 || dst_bit_len < 0 || dst_bit_off + dst_bit_len > dst_total) {
1704
1735
  rb_raise(rb_eIndexError,
1705
- "bit_splice: destination range [%ld, %ld] out of bounds (total %ld bits)",
1706
- dst_bit_off, dst_bit_len, dst_total);
1736
+ "bit_splice: destination range [%" PRIdPTR ", %" PRIdPTR
1737
+ "] out of bounds (total %" PRId64 " bits)",
1738
+ (intptr_t)dst_bit_off, (intptr_t)dst_bit_len, (int64_t)dst_total);
1707
1739
  }
1708
1740
 
1709
- ssize_t src_total_bits = RSTRING_LEN(str) * 8;
1741
+ int64_t src_total_bits = SB_BIT_LEN(RSTRING_LEN(str));
1710
1742
  if (src_bit_off < 0 || src_bit_len < 0 || src_bit_off + src_bit_len > src_total_bits) {
1711
1743
  rb_raise(rb_eIndexError,
1712
- "bit_splice: source range [%ld, %ld] out of bounds (total %ld bits)",
1713
- src_bit_off, src_bit_len, src_total_bits);
1744
+ "bit_splice: source range [%" PRIdPTR ", %" PRIdPTR
1745
+ "] out of bounds (total %" PRId64 " bits)",
1746
+ (intptr_t)src_bit_off, (intptr_t)src_bit_len, (int64_t)src_total_bits);
1714
1747
  }
1715
1748
 
1716
1749
  if (dst_bit_len == 0) return self;
@@ -1840,8 +1873,9 @@ rb_ary_mask(int argc, VALUE *argv, VALUE self)
1840
1873
  ssize_t needed = (ary_len + 7) >> 3;
1841
1874
  if (needed > bmp_len)
1842
1875
  rb_raise(rb_eArgError,
1843
- "bitmap too short: need %ld bytes for %ld elements, got %ld",
1844
- needed, ary_len, bmp_len);
1876
+ "bitmap too short: need %" PRIdPTR " bytes for %" PRIdPTR
1877
+ " elements, got %" PRIdPTR,
1878
+ (intptr_t)needed, (intptr_t)ary_len, (intptr_t)bmp_len);
1845
1879
 
1846
1880
  if (!lsb_first) {
1847
1881
  for (ssize_t i = 0; i < ary_len; i++) {
@@ -1885,8 +1919,9 @@ rb_ary_mask_bang(int argc, VALUE *argv, VALUE self)
1885
1919
  ssize_t needed = (ary_len + 7) >> 3;
1886
1920
  if (needed > bmp_len)
1887
1921
  rb_raise(rb_eArgError,
1888
- "bitmap too short: need %ld bytes for %ld elements, got %ld",
1889
- needed, ary_len, bmp_len);
1922
+ "bitmap too short: need %" PRIdPTR " bytes for %" PRIdPTR
1923
+ " elements, got %" PRIdPTR,
1924
+ (intptr_t)needed, (intptr_t)ary_len, (intptr_t)bmp_len);
1890
1925
 
1891
1926
  if (!lsb_first) {
1892
1927
  for (ssize_t i = 0; i < ary_len; i++) {
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: string_bits
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.2.0
4
+ version: 0.2.1
5
5
  platform: ruby
6
6
  authors:
7
7
  - HASUMI Hitoshi