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.
- checksums.yaml +4 -4
- data/ext/string_bits/string_bits.c +81 -46
- metadata +1 -1
checksums.yaml
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
---
|
|
2
2
|
SHA256:
|
|
3
|
-
metadata.gz:
|
|
4
|
-
data.tar.gz:
|
|
3
|
+
metadata.gz: e6202692ddb08678e3c0c07f9f2e1f15a85982fbe172e9d1e986559cc954efbe
|
|
4
|
+
data.tar.gz: a23c8747fec6bdbb82565bd299851be0d6c2f5150e148b5b6ce5b1c1b356c1c1
|
|
5
5
|
SHA512:
|
|
6
|
-
metadata.gz:
|
|
7
|
-
data.tar.gz:
|
|
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
|
-
|
|
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,
|
|
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 > (
|
|
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
|
-
|
|
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
|
-
|
|
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
|
-
|
|
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
|
-
|
|
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
|
|
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
|
-
|
|
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
|
|
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
|
|
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
|
-
|
|
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
|
-
|
|
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
|
-
|
|
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
|
-
|
|
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 %
|
|
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
|
-
|
|
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 %
|
|
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
|
-
|
|
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
|
-
|
|
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
|
|
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
|
-
|
|
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
|
-
|
|
1549
|
-
|
|
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
|
-
|
|
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
|
-
|
|
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
|
-
|
|
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 [%
|
|
1706
|
-
|
|
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
|
-
|
|
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 [%
|
|
1713
|
-
|
|
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 %
|
|
1844
|
-
|
|
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 %
|
|
1889
|
-
|
|
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++) {
|