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.1'

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:



278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
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
# File 'ext/type_array/type_array.c', line 278

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;
    } else if (klass == rb_cUInt8Array) {
        array->aref_fn = rb_type_array_aref_uint8;
        array->aset_fn = rb_type_array_aset_uint8;
    } else if (klass == rb_cInt16Array) {
        array->aref_fn = rb_type_array_aref_int16;
        array->aset_fn = rb_type_array_aset_int16;
    } else if (klass == rb_cUInt16Array) {
        array->aref_fn = rb_type_array_aref_uint16;
        array->aset_fn = rb_type_array_aset_uint16;
    } else if (klass == rb_cInt32Array) {
        array->aref_fn = rb_type_array_aref_int32;
        array->aset_fn = rb_type_array_aset_int32;
    } else if (klass == rb_cUInt32Array) {
        array->aref_fn = rb_type_array_aref_uint32;
        array->aset_fn = rb_type_array_aset_uint32;
    } else if (klass == rb_cFloat32Array) {
        array->aref_fn = rb_type_array_aref_float32;
        array->aset_fn = rb_type_array_aset_float32;
    } else if (klass == rb_cFloat64Array) {
        array->aref_fn = rb_type_array_aref_float64;
        array->aset_fn = rb_type_array_aset_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)


498
499
500
501
502
503
504
# File 'ext/type_array/type_array.c', line 498

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)


469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
# File 'ext/type_array/type_array.c', line 469

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)


414
415
416
417
418
# File 'ext/type_array/type_array.c', line 414

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)


379
380
381
382
383
# File 'ext/type_array/type_array.c', line 379

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)


452
453
454
455
456
# File 'ext/type_array/type_array.c', line 452

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

#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)


397
398
399
400
401
# File 'ext/type_array/type_array.c', line 397

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

#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)


432
433
434
435
436
# File 'ext/type_array/type_array.c', line 432

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