Class: TypeArray

Inherits:
Object
  • Object
show all
Defined in:
lib/type_array/version.rb,
ext/type_array/type_array.c

Defined Under Namespace

Modules: IOReader, IOWriter

Constant Summary collapse

VERSION =
'0.2'

Class Method Summary collapse

Instance Method Summary collapse

Class Method Details

.new(100) ⇒ Int32Array .new("01234567") ⇒ Int32Array .new(buf, 20) ⇒ Int32Array .new(buf, 0, 20) ⇒ Int32Array .new(buf, 20, 20) ⇒ Int32Array

Creates a new TypeArray instance. ArrayBuffer, data (String) and length constructors are supported.

Examples

buf = ArrayBuffer.new(100)         =>  ArrayBuffer

ary = Int32Array.new(buf, 20)      =>  Int32Array
ary.length                         =>  20
ary.byte_length                    =>  80
ary.byte_offset                    =>  20

ary = Int32Array.new(buf, 0, 20)   =>  Int32Array
ary.length                         =>  20
ary.byte_length                    =>  80
ary.byte_offset                    =>  0

ary = Int32Array.new(buf, 20, 20)  =>  Int32Array
ary.length                         =>  20
ary.byte_length                    =>  80
ary.byte_offset                    =>  20

ary = Int32Array.new("01234567")   =>  Int32Array
ary.byte_length                    =>  8
ary.to_s                           =>  "01234567"

ary = Int32Array.new(100)          =>  Int32Array
ary.length                         =>  100
ary.byte_length                    =>  400

Overloads:



342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
# File 'ext/type_array/type_array.c', line 342

static VALUE rb_type_array_s_new(int argc, VALUE *argv, VALUE klass)
{
    VALUE type_array;
    VALUE obj, byte_offset, length;
    rb_type_array_t *array = NULL;
    unsigned long buffer_length, offset;
    if (klass == rb_cTypeArray) rb_raise(rb_eTypeError, "TypeArray cannot be instantiated directly.");
    rb_scan_args(argc, argv, "12", &obj, &byte_offset, &length);
    type_array = Data_Make_Struct(klass, rb_type_array_t, rb_mark_type_array, rb_free_type_array, array);
    array->size = FIX2ULONG(rb_const_get(klass, rb_intern("BYTES_PER_ELEMENT")));
    array->byte_offset = 0;
    array->length = 0;

    if (klass == rb_cInt8Array) {
        array->aref_fn = rb_type_array_aref_int8;
        array->aset_fn = rb_type_array_aset_int8;
        array->mul_fn = rb_type_array_mul_int8;
        array->plus_fn = rb_type_array_plus_int8;
        array->minus_fn = rb_type_array_minus_int8;
        array->div_fn = rb_type_array_div_int8;
        array->eql_fn = rb_type_array_eql_int8;
    } else if (klass == rb_cUInt8Array) {
        array->aref_fn = rb_type_array_aref_uint8;
        array->aset_fn = rb_type_array_aset_uint8;
        array->mul_fn = rb_type_array_mul_uint8;
        array->plus_fn = rb_type_array_plus_uint8;
        array->minus_fn = rb_type_array_minus_uint8;
        array->div_fn = rb_type_array_div_uint8;
        array->eql_fn = rb_type_array_eql_uint8;
    } else if (klass == rb_cInt16Array) {
        array->aref_fn = rb_type_array_aref_int16;
        array->aset_fn = rb_type_array_aset_int16;
        array->mul_fn = rb_type_array_mul_int16;
        array->plus_fn = rb_type_array_plus_int16;
        array->minus_fn = rb_type_array_minus_int16;
        array->div_fn = rb_type_array_div_int16;
        array->eql_fn = rb_type_array_eql_int16;
    } else if (klass == rb_cUInt16Array) {
        array->aref_fn = rb_type_array_aref_uint16;
        array->aset_fn = rb_type_array_aset_uint16;
        array->mul_fn = rb_type_array_mul_uint16;
        array->plus_fn = rb_type_array_plus_uint16;
        array->minus_fn = rb_type_array_minus_uint16;
        array->div_fn = rb_type_array_div_uint16;
        array->eql_fn = rb_type_array_eql_uint16;
    } else if (klass == rb_cInt32Array) {
        array->aref_fn = rb_type_array_aref_int32;
        array->aset_fn = rb_type_array_aset_int32;
        array->mul_fn = rb_type_array_mul_int32;
        array->plus_fn = rb_type_array_plus_int32;
        array->minus_fn = rb_type_array_minus_int32;
        array->div_fn = rb_type_array_div_int32;
        array->eql_fn = rb_type_array_eql_int32;
    } else if (klass == rb_cUInt32Array) {
        array->aref_fn = rb_type_array_aref_uint32;
        array->aset_fn = rb_type_array_aset_uint32;
        array->mul_fn = rb_type_array_mul_uint32;
        array->plus_fn = rb_type_array_plus_uint32;
        array->minus_fn = rb_type_array_minus_uint32;
        array->div_fn = rb_type_array_div_uint32;
        array->eql_fn = rb_type_array_eql_uint32;
    } else if (klass == rb_cFloat32Array) {
        array->aref_fn = rb_type_array_aref_float32;
        array->aset_fn = rb_type_array_aset_float32;
        array->mul_fn = rb_type_array_mul_float32;
        array->plus_fn = rb_type_array_plus_float32;
        array->minus_fn = rb_type_array_minus_float32;
        array->div_fn = rb_type_array_div_float32;
        array->eql_fn = rb_type_array_eql_float32;
    } else if (klass == rb_cFloat64Array) {
        array->aref_fn = rb_type_array_aref_float64;
        array->aset_fn = rb_type_array_aset_float64;
        array->mul_fn = rb_type_array_mul_float64;
        array->plus_fn = rb_type_array_plus_float64;
        array->minus_fn = rb_type_array_minus_float64;
        array->div_fn = rb_type_array_div_float64;
        array->eql_fn = rb_type_array_eql_float64;
    }

    if (FIXNUM_P(obj)) {
        array->length = FIX2ULONG(obj);
        array->byte_length = (array->length * array->size);
        array->buf = rb_alloc_array_buffer(array->byte_length, NULL);
    } else if (rb_type(obj) == T_STRING) {
        array->byte_length = (unsigned long)RSTRING_LEN(obj);
        array->length = (array->byte_length / array->size);
        ArrayBufferEncode(obj);
        array->buf = rb_alloc_array_buffer(array->byte_length, (void *)RSTRING_PTR(obj));
    } else if (rb_class_of(obj) == rb_cArrayBuffer) {
        GetArrayBuffer(obj);
        if (!NIL_P(byte_offset)) {
            Check_Type(byte_offset, T_FIXNUM);
            array->byte_offset = FIX2ULONG(byte_offset);
            if (!rb_type_array_assert_alignment(array->byte_offset, array->size))
                rb_raise(rb_eRangeError, "Byte offset is not aligned.");
        }
        buffer_length = buf->length;
        if (!NIL_P(length)) {
            Check_Type(length, T_FIXNUM);
            array->length = FIX2ULONG(length);
            array->byte_length = array->length * array->size;
        } else {
            array->byte_length = buffer_length - array->byte_offset;
        }
        if ((array->byte_offset + array->byte_length) > buffer_length)
            rb_raise(rb_eRangeError, "Byte offset / length is not aligned.");
        if (array->length == 0) array->length = array->byte_length / array->size;
        if (array->byte_offset > buffer_length || array->byte_offset + array->length > buffer_length ||
             array->byte_offset + array->length * array->size > buffer_length) {
             rb_raise(rb_eRangeError, "Length is out of range.");
        }
        array->buf = obj;
    } else if (rb_obj_is_kind_of(obj, rb_cTypeArray) == Qtrue) {
        GetTypeArray(obj);
        array->length = ary->length;
        array->byte_length = (array->size * array->length);
        array->buf = rb_alloc_array_buffer(array->byte_length, NULL);
        array->byte_offset = 0;
        for (offset = 0; offset < array->length; ++offset) {
          VALUE offs = INT2FIX(offset);
          VALUE val = rb_funcall(obj, rb_type_array_intern_aget, 1, offs);
          rb_funcall(type_array, rb_type_array_intern_aset, 2, offs, val);
        }
    } else {
        rb_raise(rb_eTypeError, "TypeArray constructor %s not supported.", RSTRING_PTR(rb_obj_as_string(obj)));
    }
    rb_obj_call_init(type_array, 0, NULL);
    return type_array;
}

Instance Method Details

#[](1) ⇒ Fixnum, ...

Gets a value at a given offset, with coercion dependent on the array type of this instance.

Examples

ary = Int32Array.new("01234567")  =>  Int32Array
ary[1] = 23                       =>  nil
ary[1]                            =>  23

Returns:

  • (Fixnum, Bignum, Float)


727
728
729
730
731
732
733
# File 'ext/type_array/type_array.c', line 727

static VALUE rb_type_array_aget(VALUE obj, VALUE idx)
{
    GetTypeArray(obj);
    GetArrayBuffer(ary->buf);
    long index = rb_type_array_assert_offset(ary, idx);
    return ary->aref_fn(buf->buf, index);
}

#[]=(1) ⇒ nil

Sets a value at a given offset, with coercion dependent on the array type of this instance.

Examples

ary = Int32Array.new("01234567")  =>  Int32Array
ary[1] = 23                       =>  nil

Returns:

  • (nil)


698
699
700
701
702
703
704
705
706
707
708
709
710
711
712
713
# File 'ext/type_array/type_array.c', line 698

static VALUE rb_type_array_aset(VALUE obj, VALUE idx, VALUE item)
{
    GetTypeArray(obj);
    GetArrayBuffer(ary->buf);
    long index = rb_type_array_assert_offset(ary, idx);
    switch (TYPE(item)) {
    case T_FIXNUM:
    case T_BIGNUM:
    case T_FLOAT:
        break;
    default:
        rb_raise(rb_eTypeError, "Type arrays only support Fixnum, Bignum and Float instances");
    }
    ary->aset_fn(buf->buf, index, item);
    return Qnil;
}

#bufferString

Returns the underlying buffer managed by this ArrayBuffer instance.

Examples

ary = Int32Array.new("buffer")  =>  DataView
ary.buffer                      =>  ArrayBuffer

Returns:

  • (String)


643
644
645
646
647
# File 'ext/type_array/type_array.c', line 643

static VALUE rb_type_array_buffer(VALUE obj)
{
    GetTypeArray(obj);
    return ary->buf; 
}

#byte_lengthFixnum

Returns the size of the underlying buffer managed by this TypeArray instance.

Examples

ary = Int32Array.new("01234567")  =>  Int32Array
ary.byte_length                   =>  8

Returns:

  • (Fixnum)


483
484
485
486
487
# File 'ext/type_array/type_array.c', line 483

static VALUE rb_type_array_byte_length(VALUE obj)
{
    GetTypeArray(obj);
    return ULONG2NUM(ary->byte_length);
}

#byte_offsetFixnum

Returns the offset into the underlying buffer managed by this TypeArray instance.

Examples

ary = Int32Array.new("01234567")     =>  Int32Array
ary.byte_offset                      =>  0

ary = Int32Array.new("01234567", 2)  =>  Int32Array
ary.byte_offset                      =>  2

Returns:

  • (Fixnum)


681
682
683
684
685
# File 'ext/type_array/type_array.c', line 681

static VALUE rb_type_array_byte_offset(VALUE obj)
{
    GetTypeArray(obj);
    return ULONG2NUM(ary->byte_offset);
}

#div(0, 1) ⇒ Fixnum, ...

Gets two values at given offsets and divides them - only the result’s coerced to a Ruby object.

Examples

buf = ArrayBuffer.new(16)         =>  ArrayBuffer
ary = Int32Array.new(buf)         =>  Int32Array
ary[0] = 2                        =>  nil
ary[1] = 4                        =>  nil
ary[2] = 8                        =>  nil

ary.div(1, 0)                     =>  2
ary.div(2, 1)                     =>  2

Returns:

  • (Fixnum, Bignum, Float)


580
581
582
583
584
585
586
587
# File 'ext/type_array/type_array.c', line 580

static VALUE rb_type_array_div(VALUE obj, VALUE off1, VALUE off2)
{
    GetTypeArray(obj);
    GetArrayBuffer(ary->buf);
    long offset1 = rb_type_array_assert_offset(ary, off1);
    long offset2 = rb_type_array_assert_offset(ary, off2);
    return ary->div_fn(buf->buf, offset1, offset2);
}

#div(0, 1) ⇒ Fixnum, ...

Gets two values at given offsets and divides them - only the result’s coerced to a Ruby object.

Examples

buf = ArrayBuffer.new(16)         =>  ArrayBuffer
ary = Int32Array.new(buf)         =>  Int32Array
ary[0] = 2                        =>  nil
ary[1] = 4                        =>  nil
ary[2] = 8                        =>  nil

ary.div(1, 0)                     =>  2
ary.div(2, 1)                     =>  2

Returns:

  • (Fixnum, Bignum, Float)


605
606
607
608
609
610
611
612
# File 'ext/type_array/type_array.c', line 605

static VALUE rb_type_array_eql(VALUE obj, VALUE off1, VALUE off2)
{
    GetTypeArray(obj);
    GetArrayBuffer(ary->buf);
    long offset1 = rb_type_array_assert_offset(ary, off1);
    long offset2 = rb_type_array_assert_offset(ary, off2);
    return ary->eql_fn(buf->buf, offset1, offset2);
}

#lengthFixnum

Returns the max number of elements this typed array instance can accommodate.

Examples

ary = Int32Array.new("01234567")  =>  Int32Array
ary.byte_length                   =>  8
ary.length                        =>  2

Returns:

  • (Fixnum)


626
627
628
629
630
# File 'ext/type_array/type_array.c', line 626

static VALUE rb_type_array_length(VALUE obj)
{
    GetTypeArray(obj);
    return ULONG2NUM(ary->length);
}

#minus(0, 1) ⇒ Fixnum, ...

Gets two values at given offsets and subtracts them - only the result’s coerced to a Ruby object.

Examples

buf = ArrayBuffer.new(16)         =>  ArrayBuffer
ary = Int32Array.new(buf)         =>  Int32Array
ary[0] = 2                        =>  nil
ary[1] = 4                        =>  nil
ary[2] = 8                        =>  nil

ary.minus(1, 0)                   =>  2
ary.minus(2, 1)                   =>  4

Returns:

  • (Fixnum, Bignum, Float)


555
556
557
558
559
560
561
562
# File 'ext/type_array/type_array.c', line 555

static VALUE rb_type_array_minus(VALUE obj, VALUE off1, VALUE off2)
{
    GetTypeArray(obj);
    GetArrayBuffer(ary->buf);
    long offset1 = rb_type_array_assert_offset(ary, off1);
    long offset2 = rb_type_array_assert_offset(ary, off2);
    return ary->minus_fn(buf->buf, offset1, offset2);
}

#mul(0, 1) ⇒ Fixnum, ...

Gets two values at given offsets and multiples them - only the result’s coerced to a Ruby object.

Examples

buf = ArrayBuffer.new(16)         =>  ArrayBuffer
ary = Int32Array.new(buf)         =>  Int32Array
ary[0] = 2                        =>  nil
ary[1] = 4                        =>  nil
ary[2] = 8                        =>  nil

ary.mul(0,1)                      =>  8
ary.mul(1,2)                      =>  32

Returns:

  • (Fixnum, Bignum, Float)


505
506
507
508
509
510
511
512
# File 'ext/type_array/type_array.c', line 505

static VALUE rb_type_array_mul(VALUE obj, VALUE off1, VALUE off2)
{
    GetTypeArray(obj);
    GetArrayBuffer(ary->buf);
    long offset1 = rb_type_array_assert_offset(ary, off1);
    long offset2 = rb_type_array_assert_offset(ary, off2);
    return ary->mul_fn(buf->buf, offset1, offset2);
}

#plus(0, 1) ⇒ Fixnum, ...

Gets two values at given offsets and adds them - only the result’s coerced to a Ruby object.

Examples

buf = ArrayBuffer.new(16)         =>  ArrayBuffer
ary = Int32Array.new(buf)         =>  Int32Array
ary[0] = 2                        =>  nil
ary[1] = 4                        =>  nil
ary[2] = 8                        =>  nil

ary.plus(0,1)                     =>  6
ary.plus(1,2)                     =>  12

Returns:

  • (Fixnum, Bignum, Float)


530
531
532
533
534
535
536
537
# File 'ext/type_array/type_array.c', line 530

static VALUE rb_type_array_plus(VALUE obj, VALUE off1, VALUE off2)
{
    GetTypeArray(obj);
    GetArrayBuffer(ary->buf);
    long offset1 = rb_type_array_assert_offset(ary, off1);
    long offset2 = rb_type_array_assert_offset(ary, off2);
    return ary->plus_fn(buf->buf, offset1, offset2);
}

#to_sString

Returns a String (binary) representation of the underlying buffer managed by this TypeArray instance.

Examples

buf = ArrayBuffer.new("buffer")  =>  ArrayBuffer
ary = Int32Array.new(buf)        =>  Int32Array
ary.to_s                         =>  "buffer"

Returns:

  • (String)


661
662
663
664
665
# File 'ext/type_array/type_array.c', line 661

static VALUE rb_type_array_to_s(VALUE obj)
{
    GetTypeArray(obj);
    return rb_array_buffer_to_s(ary->buf); 
}