Class: BitPack

Inherits:
Object
  • Object
show all
Defined in:
lib/bitpack.rb,
ext/bitpack_ext.c

Class Method Summary collapse

Instance Method Summary collapse

Class Method Details

.from_bytes(string) ⇒ a new BitPack object

Creates a new BitPack object that is initialzed with the contents of string.

Example

>> bp = BitPack.from_bytes("ruby")
=> 01110010011101010110001001111001
>> 4.times { p bp.read_bits(8).chr }
"r"
"u"
"b"
"y"
=> 4

Returns:



59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
# File 'ext/bitpack_ext.c', line 59

static VALUE bp_from_bytes(VALUE class, VALUE bytes_str)
{
    VALUE          bp_obj;
    VALUE          str;;
    bitpack_t      bp;

    str = StringValue(bytes_str);

    bp = bitpack_init_from_bytes((unsigned char *)RSTRING(str)->ptr, RSTRING(str)->len);

    if (bp == NULL) {
        rb_raise(bp_exceptions[BITPACK_ERR_MALLOC_FAILED], "malloc() failed");
    }

    bp_obj = Data_Wrap_Struct(class, 0, bitpack_destroy, bp);

    return bp_obj;
}

.newa new BitPack object .new(n) ⇒ a new BitPack object

Creates a new BitPack object. The number of bytes used internally to store the bit string can optionally be set to n.

Overloads:



20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
# File 'ext/bitpack_ext.c', line 20

static VALUE bp_new(int argc, VALUE *argv, VALUE class)
{
    VALUE     bp_obj;
    bitpack_t bp;

    if (argc == 0) {
        bp = bitpack_init_default();
    }
    else {
        bp = bitpack_init(NUM2ULONG(argv[0]));
    }

    if (bp == NULL) {
        rb_raise(bp_exceptions[BITPACK_ERR_MALLOC_FAILED], "malloc() failed");
    }

    bp_obj = Data_Wrap_Struct(class, 0, bitpack_destroy, bp);

    return bp_obj;
}

Instance Method Details

#get(i) ⇒ 0, 1

Access the value of the bit at index i.

Returns:

  • (0, 1)


225
226
227
228
229
230
231
232
233
234
235
236
237
238
# File 'ext/bitpack_ext.c', line 225

static VALUE bp_get(VALUE self, VALUE index)
{
    bitpack_t     bp;
    unsigned char bit;

    Data_Get_Struct(self, struct _bitpack_t, bp);

    if (!bitpack_get(bp, NUM2ULONG(index), &bit)) {
        rb_raise(bp_exceptions[bitpack_get_error(bp)],
                bitpack_get_error_str(bp));
    }

    return INT2FIX(bit);
}

#[]=(a, b, c = nil) ⇒ Object

Element Assignment. Sets the bit at index, or the range of bits indicated by the Range object range, or the range specified by index and length.

:call-seq:

bp[index] = value             -> value
bp[range] = value             -> value
bp[index, length] = value     -> value

Example

>> bp[0] = 1
=> 1
>> bp[1] = 0
=> 0
>> bp[2] = 1
=> 1
>> bp.to_bin
=> "101"
>> bp[0..7] = 0xff
=> 255
>> bp.to_bin
=> "11111111"
>> bp[8, 16] = 0xf0f0
=> 61680
>> bp.to_bin
=> "111111111111000011110000"


30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
# File 'lib/bitpack.rb', line 30

def []=(a, b, c = nil)
  if c.nil?
    # only two arguments, so it must be one of the following formats:
    #   bp[index] = value
    #   bp[range] = value
    if a.kind_of? Integer
      self.set_bits(b, 1, a)
    elsif a.kind_of? Range
      if a.exclude_end?
        self.set_bits(b, a.end - a.begin, a.begin)
      else
        self.set_bits(b, a.end - a.begin + 1, a.begin)
      end
    else
      raise ArgumentError, "index must be an Integer or Range"
    end
  else
    # this must the following format:
    #   bp[index, length] = value
    self.set_bits(c, b, a)
  end
end

#append_bits(value, num_bits) ⇒ Object

Append the Integer value to the end of a BitPack object.

Packs num_bits bits at the end of a BitPack object. The size of the BitPack object is increased by num_bits as a result.

Example

>> bp = BitPack.new
=>
>> bp.append_bits(1, 3)
=> 001
>> bp.append_bits(3, 3)
=> 001011
>> bp.append_bits(7, 3)
=> 001011111


416
417
418
419
420
421
422
423
424
425
426
427
428
# File 'ext/bitpack_ext.c', line 416

static VALUE bp_append_bits(VALUE self, VALUE value, VALUE num_bits)
{
    bitpack_t bp;

    Data_Get_Struct(self, struct _bitpack_t, bp);

    if (!bitpack_append_bits(bp, NUM2ULONG(value), NUM2ULONG(num_bits))) {
        rb_raise(bp_exceptions[bitpack_get_error(bp)],
                bitpack_get_error_str(bp));
    }

    return self;
}

#append_bytes(string) ⇒ Object

Append string to the end of a BitPack object.

Packs string at the end of a BitPack object. The size of the BitPack object is increased by the length of string as a result.

Example

>> bp = BitPack.new
=>
>> bp.append_bytes("bit")
=> 011000100110100101110100
>> bp.append_bytes("pack")
=> 01100010011010010111010001110000011000010110001101101011
>> 7.times { p bp.read_bits(8).chr }
"b"
"i"
"t"
"p"
"a"
"c"
"k"
=> 7


457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
# File 'ext/bitpack_ext.c', line 457

static VALUE bp_append_bytes(VALUE self, VALUE value)
{
    bitpack_t bp;
    VALUE     str;

    Data_Get_Struct(self, struct _bitpack_t, bp);

    str = StringValue(value);

    if (!bitpack_append_bytes(bp, (unsigned char *)RSTRING(str)->ptr,
          RSTRING(str)->len)) {
        rb_raise(bp_exceptions[bitpack_get_error(bp)],
                bitpack_get_error_str(bp));
    }

    return self;
}

#data_sizeInteger

Access the number of bytes of memory currently allocated to this BitPack object.

Returns:

  • (Integer)


103
104
105
106
107
108
109
110
111
112
113
# File 'ext/bitpack_ext.c', line 103

static VALUE bp_data_size(VALUE self)
{
    bitpack_t     bp;
    unsigned long data_size;

    Data_Get_Struct(self, struct _bitpack_t, bp);

    data_size = bitpack_data_size(bp);

    return ULONG2NUM(data_size);
}

#get(i) ⇒ 0, 1

Access the value of the bit at index i.

Returns:

  • (0, 1)


225
226
227
228
229
230
231
232
233
234
235
236
237
238
# File 'ext/bitpack_ext.c', line 225

static VALUE bp_get(VALUE self, VALUE index)
{
    bitpack_t     bp;
    unsigned char bit;

    Data_Get_Struct(self, struct _bitpack_t, bp);

    if (!bitpack_get(bp, NUM2ULONG(index), &bit)) {
        rb_raise(bp_exceptions[bitpack_get_error(bp)],
                bitpack_get_error_str(bp));
    }

    return INT2FIX(bit);
}

#get_bits(num_bits, i) ⇒ Integer

Access the value stored in a range of bits starting at index i.

Unpacks num_bits starting from index i and returns the Integer value.

Example

>> bp = BitPack.new
=>
>> bp.append_bits(1, 4)
=> 0001
>> bp.append_bits(2, 4)
=> 00010010
>> bp.append_bits(3, 4)
=> 000100100011
>> bp.append_bits(4, 4)
=> 0001001000110100
>> bp.get_bits(4, 0)
=> 1
>> bp.get_bits(4, 4)
=> 2
>> bp.get_bits(4, 8)
=> 3
>> bp.get_bits(4, 12)
=> 4

Returns:

  • (Integer)


345
346
347
348
349
350
351
352
353
354
355
356
357
358
# File 'ext/bitpack_ext.c', line 345

static VALUE bp_get_bits(VALUE self, VALUE num_bits, VALUE index)
{
    bitpack_t     bp;
    unsigned long value;

    Data_Get_Struct(self, struct _bitpack_t, bp);

    if (!bitpack_get_bits(bp, NUM2ULONG(num_bits), NUM2ULONG(index), &value)) {
        rb_raise(bp_exceptions[bitpack_get_error(bp)],
                bitpack_get_error_str(bp));
    }

    return ULONG2NUM(value);
}

#get_bytes(num_bytes, i) ⇒ String

Access the value stored in a range of bytes starting at index i.

Unpacks num_bytes starting from bit index i and returns the String value.

Example

>> bp =  BitPack.from_bytes("foobar")
=> 011001100110111101101111011000100110000101110010
>> bp.get_bytes(3, 24)
=> "bar"

Returns:

  • (String)


376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
# File 'ext/bitpack_ext.c', line 376

static VALUE bp_get_bytes(VALUE self, VALUE num_bytes, VALUE index)
{
    bitpack_t      bp;
    unsigned char *bytes;
    VALUE          str;

    Data_Get_Struct(self, struct _bitpack_t, bp);

    if (!bitpack_get_bytes(bp, NUM2ULONG(num_bytes), NUM2ULONG(index), &bytes)) {
        rb_raise(bp_exceptions[bitpack_get_error(bp)],
                bitpack_get_error_str(bp));
    }

    str = rb_str_new((char *)bytes, NUM2ULONG(num_bytes));

    free(bytes);

    return str;
}

#off(i) ⇒ Object

Unsets the bit at index i. If i is greater than the current size of the BitPack object, then the size is expanded and the current append position is set to this index.



205
206
207
208
209
210
211
212
213
214
215
216
217
# File 'ext/bitpack_ext.c', line 205

static VALUE bp_off(VALUE self, VALUE index)
{
    bitpack_t bp;

    Data_Get_Struct(self, struct _bitpack_t, bp);

    if (!bitpack_off(bp, NUM2ULONG(index))) {
        rb_raise(bp_exceptions[bitpack_get_error(bp)],
                bitpack_get_error_str(bp));
    }

    return self;
}

#on(i) ⇒ Object

Sets the bit at index i. If i is greater than the current size of the BitPack object, then the size is expanded and the current append position is set to this index.

Example

>> bp = BitPack.new
=>
>> bp.on(0)
=> 1
>> bp.on(2)
=> 101
>> bp.on(7)
=> 10100001
>> bp.on(6)
=> 10100011


183
184
185
186
187
188
189
190
191
192
193
194
195
# File 'ext/bitpack_ext.c', line 183

static VALUE bp_on(VALUE self, VALUE index)
{
    bitpack_t bp;

    Data_Get_Struct(self, struct _bitpack_t, bp);

    if (!bitpack_on(bp, NUM2ULONG(index))) {
        rb_raise(bp_exceptions[bitpack_get_error(bp)],
                bitpack_get_error_str(bp));
    }

    return self;
}

#read_bits(num_bits) ⇒ Integer

Access the value of a range of bits at the current read position.

Unpacks num_bits bits starting at the current read position (see Bitpack#read_pos) and returns the integer value. The current read position is advanced by num_bits bits.

Example

>> bp = BitPack.from_bytes("ruby")
=> 01110010011101010110001001111001
>> 4.times { p bp.read_bits(8).chr }
"r"
"u"
"b"
"y"
=> 4

Returns:

  • (Integer)


496
497
498
499
500
501
502
503
504
505
506
507
508
509
# File 'ext/bitpack_ext.c', line 496

static VALUE bp_read_bits(VALUE self, VALUE num_bits)
{
    bitpack_t     bp;
    unsigned long value;

    Data_Get_Struct(self, struct _bitpack_t, bp);

    if (!bitpack_read_bits(bp, NUM2ULONG(num_bits), &value)) {
        rb_raise(bp_exceptions[bitpack_get_error(bp)],
                bitpack_get_error_str(bp));
    }

    return ULONG2NUM(value);
}

#read_bytes(num_bytes) ⇒ String

Access the value of a range of bytes at the current read position.

Unpacks num_bytes bytes starting at the current read position (see Bitpack#read_pos) and returns the String value. The current read position is advanced by num_bytes * 8 bits.

Example

>> bp = BitPack.from_bytes("foobar")
=> 011001100110111101101111011000100110000101110010
>> bp.read_bytes(3)
=> "foo"
>> bp.read_bytes(3)
=> "bar"

Returns:

  • (String)


530
531
532
533
534
535
536
537
538
539
540
541
542
543
544
545
546
547
548
# File 'ext/bitpack_ext.c', line 530

static VALUE bp_read_bytes(VALUE self, VALUE num_bytes)
{
    bitpack_t      bp;
    unsigned char *value;
    VALUE          str;

    Data_Get_Struct(self, struct _bitpack_t, bp);

    if (!bitpack_read_bytes(bp, NUM2ULONG(num_bytes), &value)) {
        rb_raise(bp_exceptions[bitpack_get_error(bp)],
                bitpack_get_error_str(bp));
    }

    str = rb_str_new((char *)value, NUM2ULONG(num_bytes));

    free(value);

    return str;
}

#read_posInteger

Access the current read position of this BitPack object.

Example

>> bp = BitPack.from_bytes("test")
=> 01110100011001010111001101110100
>> bp.read_pos
=> 0
>> bp.read_bits(8)
=> 116
>> bp.read_pos
=> 8

Returns:

  • (Integer)


132
133
134
135
136
137
138
139
140
141
142
# File 'ext/bitpack_ext.c', line 132

static VALUE bp_read_pos(VALUE self)
{
    bitpack_t     bp;
    unsigned long read_pos;

    Data_Get_Struct(self, struct _bitpack_t, bp);

    read_pos = bitpack_read_pos(bp);

    return ULONG2NUM(read_pos);
}

#reset_read_posObject

Reset the current read position to the beginning of this BitPack object.



151
152
153
154
155
156
157
158
159
160
# File 'ext/bitpack_ext.c', line 151

static VALUE bp_reset_read_pos(VALUE self)
{
    bitpack_t bp;

    Data_Get_Struct(self, struct _bitpack_t, bp);

    bitpack_reset_read_pos(bp);

    return self;
}

#set_bits(value, num_bits, i) ⇒ self

Sets the specified range of bits in a BitPack object.

Packs the Integer value into num_bits bits starting at index i. The number of bits required to represent value is checked against the size of the range. If i + num_bits is greater than the current size of the BitPack, then the size is adjusted appropriately.

Example

>> bp = BitPack.new
=>
>> bp.set_bits(0xff, 8, 0)
=> 11111111
>> bp.set_bits(0xaa, 8, 8)
=> 1111111110101010

Returns:

  • (self)


261
262
263
264
265
266
267
268
269
270
271
272
273
# File 'ext/bitpack_ext.c', line 261

static VALUE bp_set_bits(VALUE self, VALUE value, VALUE num_bits, VALUE index)
{
    bitpack_t bp;

    Data_Get_Struct(self, struct _bitpack_t, bp);

    if (!bitpack_set_bits(bp, NUM2ULONG(value), NUM2ULONG(num_bits), NUM2ULONG(index))) {
        rb_raise(bp_exceptions[bitpack_get_error(bp)],
                bitpack_get_error_str(bp));
    }

    return self;
}

#set_bytes(string, i) ⇒ Object

Sets the specified range of bytes in a BitPack object.

Packs string into the BitPack object starting at index i. The size of the BitPack object is adjusted appropriately if necessary.

Example

>> bp = BitPack.new
=>
>> bp.set_bytes("ruby", 0)
=> 01110010011101010110001001111001
>> 4.times { p bp.read_bits(8).chr }
"r"
"u"
"b"
"y"
=> 4


297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
# File 'ext/bitpack_ext.c', line 297

static VALUE bp_set_bytes(VALUE self, VALUE bytes, VALUE index)
{
    bitpack_t bp;
    VALUE     str;

    Data_Get_Struct(self, struct _bitpack_t, bp);

    str = StringValue(bytes);

    if (!bitpack_set_bytes(bp, (unsigned char *)RSTRING(str)->ptr,
          RSTRING(str)->len, NUM2ULONG(index))) {
        rb_raise(bp_exceptions[bitpack_get_error(bp)],
                bitpack_get_error_str(bp));
    }

    return self;
}

#sizeInteger

Access the current size of the BitPack object in bits.

Returns:

  • (Integer)


84
85
86
87
88
89
90
91
92
93
94
# File 'ext/bitpack_ext.c', line 84

static VALUE bp_size(VALUE self)
{
    bitpack_t     bp;
    unsigned long size;

    Data_Get_Struct(self, struct _bitpack_t, bp);

    size = bitpack_size(bp);

    return ULONG2NUM(size);
}

#to_binString

Converts the BitPack object to a string of 1s and 0s.

Returns:

  • (String)


556
557
558
559
560
561
562
563
564
565
566
567
568
569
570
571
572
573
574
# File 'ext/bitpack_ext.c', line 556

static VALUE bp_to_bin(VALUE self)
{
    bitpack_t  bp;
    char      *s;
    VALUE      str;

    Data_Get_Struct(self, struct _bitpack_t, bp);

    if (!bitpack_to_bin(bp, &s)) {
        rb_raise(bp_exceptions[bitpack_get_error(bp)],
                bitpack_get_error_str(bp));
    }

    str = rb_str_new2(s);

    free(s);

    return str;
}

#to_bytesString

Converts the BitPack object to a string of bytes. If the current size of the BitPack object is not a multiple of 8, the last byte in the returned String will be padded with the appropriate number of 0 bits.

Example

>> bp = BitPack.new
=>
>> bp.append_bits(?r, 8)
=> 01110010
>> bp.append_bits(?u, 8)
=> 0111001001110101
>> bp.append_bits(?b, 8)
=> 011100100111010101100010
>> bp.append_bits(?y, 8)
=> 01110010011101010110001001111001
>> bp.to_bytes
=> "ruby"

Returns:

  • (String)


600
601
602
603
604
605
606
607
608
609
610
611
612
613
614
615
616
617
618
619
# File 'ext/bitpack_ext.c', line 600

static VALUE bp_to_bytes(VALUE self)
{
    bitpack_t      bp;
    unsigned char *s;
    unsigned long  num_bytes;
    VALUE          str;

    Data_Get_Struct(self, struct _bitpack_t, bp);

    if (!bitpack_to_bytes(bp, &s, &num_bytes)) {
        rb_raise(bp_exceptions[bitpack_get_error(bp)],
                bitpack_get_error_str(bp));
    }

    str = rb_str_new((char *)s, num_bytes);

    free(s);

    return str;
}

#to_binString

Converts the BitPack object to a string of 1s and 0s.

Returns:

  • (String)


556
557
558
559
560
561
562
563
564
565
566
567
568
569
570
571
572
573
574
# File 'ext/bitpack_ext.c', line 556

static VALUE bp_to_bin(VALUE self)
{
    bitpack_t  bp;
    char      *s;
    VALUE      str;

    Data_Get_Struct(self, struct _bitpack_t, bp);

    if (!bitpack_to_bin(bp, &s)) {
        rb_raise(bp_exceptions[bitpack_get_error(bp)],
                bitpack_get_error_str(bp));
    }

    str = rb_str_new2(s);

    free(s);

    return str;
}