Class: FFI::AbstractMemory

Inherits:
Object
  • Object
show all
Defined in:
ext/ffi_c/AbstractMemory.c,
ext/ffi_c/AbstractMemory.c

Overview

AbstractMemory is the base class for many memory management classes such as Buffer.

This class has a lot of methods to work with integers :

  • put_intsize(offset, value)

  • get_intsize(offset)

  • put_uintsize(offset, value)

  • get_uintsize(offset)

  • writeuintsize(value)

  • read_intsize

  • write_uintsize(value)

  • read_uintsize

  • put_array_of_intsize(offset, ary)

  • get_array_of_intsize(offset, length)

  • put_array_of_uintsize(offset, ary)

  • get_array_of_uintsize(offset, length)

  • write_array_of_intsize(ary)

  • read_array_of_intsize(length)

  • write_array_of_uintsize(ary)

  • read_array_of_uintsize(length)

where size is 8, 16, 32 or 64. Same methods exist for long type.

Aliases exist : char for int8, short for int16, int for int32 and long_long for int64.

Others methods are listed below.

Direct Known Subclasses

Buffer, Pointer

Instance Method Summary collapse

Instance Method Details

#[](idx) ⇒ Object

Memory read accessor.



579
580
581
582
583
584
585
586
587
588
589
590
# File 'ext/ffi_c/AbstractMemory.c', line 579

static VALUE
memory_aref(VALUE self, VALUE idx)
{
    AbstractMemory* ptr;
    VALUE rbOffset = Qnil;

    Data_Get_Struct(self, AbstractMemory, ptr);

    rbOffset = ULONG2NUM(NUM2ULONG(idx) * ptr->typeSize);

    return rb_funcall2(self, id_plus, 1, &rbOffset);
}

#__copy_from__Object



598
599
600
601
602
603
604
605
606
607
608
# File 'ext/ffi_c/AbstractMemory.c', line 598

static VALUE
memory_copy_from(VALUE self, VALUE rbsrc, VALUE rblen)
{
    AbstractMemory* dst;

    Data_Get_Struct(self, AbstractMemory, dst);

    memcpy(dst->address, rbffi_AbstractMemory_Cast(rbsrc, rbffi_AbstractMemoryClass)->address, NUM2INT(rblen));

    return self;
}

#clearself

Set the memory to all-zero.



299
300
301
302
303
304
305
# File 'ext/ffi_c/AbstractMemory.c', line 299

static VALUE
memory_clear(VALUE self)
{
    AbstractMemory* ptr = MEMORY(self);
    memset(ptr->address, 0, ptr->size);
    return self;
}

#get_array_of_float32(offset, length) ⇒ Array<Float> Also known as: get_array_of_float

Get 32-bit floats in memory from offset offset (alias: #get_array_of_float).

#get_array_of_float64(offset, length) ⇒ Array<Float> Also known as: get_array_of_double

Get 64-bit floats (doubles) in memory from offset offset (alias: #get_array_of_double).

#get_array_of_pointer(offset, length) ⇒ Array<Pointer>

Get an array of Pointer of length length from offset.

#get_array_of_string(offset, count = nil) ⇒ Array<String>

Return an array of strings contained in memory.

Raises:

  • (IndexError)

    if offset is too great

  • (NullPointerError)

    if memory not initialized



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
# File 'ext/ffi_c/AbstractMemory.c', line 359

static VALUE
memory_get_array_of_string(int argc, VALUE* argv, VALUE self)
{
    VALUE offset = Qnil, countnum = Qnil, retVal = Qnil;
    AbstractMemory* ptr;
    long off;
    int count;

    rb_scan_args(argc, argv, "11", &offset, &countnum);
    off = NUM2LONG(offset);
    count = (countnum == Qnil ? 0 : NUM2INT(countnum));
    retVal = rb_ary_new2(count);

    Data_Get_Struct(self, AbstractMemory, ptr);
    checkRead(ptr);

    if (countnum != Qnil) {
        int i;

        checkBounds(ptr, off, count * sizeof (char*));
        
        for (i = 0; i < count; ++i) {
            const char* strptr = *((const char**) (ptr->address + off) + i);
            rb_ary_push(retVal, (strptr == NULL ? Qnil : rb_tainted_str_new2(strptr)));
        }

    } else {
        checkBounds(ptr, off, sizeof (char*));
        for ( ; off < ptr->size - (long) sizeof (void *); off += (long) sizeof (void *)) {
            const char* strptr = *(const char**) (ptr->address + off);
            if (strptr == NULL) {
                break;
            }
            rb_ary_push(retVal, rb_tainted_str_new2(strptr));
        }
    }

    return retVal;
}

#get_bytes(offset, length) ⇒ String

Return string contained in memory.

Raises:

  • (IndexError)

    if length is too great

  • (NullPointerError)

    if memory not initialized



459
460
461
462
463
464
465
466
467
468
469
470
471
472
# File 'ext/ffi_c/AbstractMemory.c', line 459

static VALUE
memory_get_bytes(VALUE self, VALUE offset, VALUE length)
{
    AbstractMemory* ptr = MEMORY(self);
    long off, len;
    
    off = NUM2LONG(offset);
    len = NUM2LONG(length);

    checkRead(ptr);
    checkBounds(ptr, off, len);
    
    return rb_tainted_str_new((char *) ptr->address + off, len);
}

#get_float32(offset) ⇒ Float Also known as: get_float

Get a 32-bit float from memory at offset offset (alias: #get_float).

#get_float64(offset) ⇒ Float Also known as: get_double

Get a 64-bit float (double) from memory at offset offset (alias: #get_double).

#get_pointer(offset) ⇒ Pointer

Get a Pointer to the memory from offset.

#get_string(offset, length = nil) ⇒ String

Return string contained in memory.

Raises:

  • (IndexError)

    if length is too great

  • (NullPointerError)

    if memory not initialized



331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
# File 'ext/ffi_c/AbstractMemory.c', line 331

static VALUE
memory_get_string(int argc, VALUE* argv, VALUE self)
{
    VALUE length = Qnil, offset = Qnil;
    AbstractMemory* ptr = MEMORY(self);
    long off, len;
    char* end;
    int nargs = rb_scan_args(argc, argv, "11", &offset, &length);

    off = NUM2LONG(offset);
    len = nargs > 1 && length != Qnil ? NUM2LONG(length) : (ptr->size - off);
    checkRead(ptr);
    checkBounds(ptr, off, len);

    end = memchr(ptr->address + off, 0, len);
    return rb_tainted_str_new((char *) ptr->address + off,
            (end != NULL ? end - ptr->address - off : len));
}

#put_array_of_float32(offset, ary) ⇒ self Also known as: put_array_of_float

Put values from ary as 32-bit floats in memory from offset offset (alias: #put_array_of_float).

#put_array_of_float64(offset, ary) ⇒ self Also known as: put_array_of_double

Put values from ary as 64-bit floats (doubles) in memory from offset offset (alias: #put_array_of_double).

#put_array_of_pointer(offset, ary) ⇒ self

Put an array of Pointer into memory from offset.

#put_bytes(offset, str, index = 0, length = nil) ⇒ self

Put a string in memory.

Raises:

  • (IndexError)

    if length is too great

  • (NullPointerError)

    if memory not initialized

  • (RangeError)

    if index is negative, or if index+length is greater than size of string

  • (SecurityError)

    when writing unsafe string to memory



487
488
489
490
491
492
493
494
495
496
497
498
499
500
501
502
503
504
505
506
507
508
509
510
511
512
513
514
515
516
517
518
519
# File 'ext/ffi_c/AbstractMemory.c', line 487

static VALUE
memory_put_bytes(int argc, VALUE* argv, VALUE self)
{
    AbstractMemory* ptr = MEMORY(self);
    VALUE offset = Qnil, str = Qnil, rbIndex = Qnil, rbLength = Qnil;
    long off, len, idx;
    int nargs = rb_scan_args(argc, argv, "22", &offset, &str, &rbIndex, &rbLength);

    Check_Type(str, T_STRING);

    off = NUM2LONG(offset);
    idx = nargs > 2 ? NUM2LONG(rbIndex) : 0;
    if (idx < 0) {
        rb_raise(rb_eRangeError, "index canot be less than zero");
        return Qnil;
    }
    len = nargs > 3 ? NUM2LONG(rbLength) : (RSTRING_LEN(str) - idx);
    if ((idx + len) > RSTRING_LEN(str)) {
        rb_raise(rb_eRangeError, "index+length is greater than size of string");
        return Qnil;
    }

    checkWrite(ptr);
    checkBounds(ptr, off, len);

    if (rb_safe_level() >= 1 && OBJ_TAINTED(str)) {
        rb_raise(rb_eSecurityError, "Writing unsafe string to memory");
        return Qnil;
    }
    memcpy(ptr->address + off, RSTRING_PTR(str) + idx, len);

    return self;
}

#put_float32offsetself Also known as: put_float

Put value as a 32-bit float in memory at offset offset (alias: #put_float).

#put_float64(offset, value) ⇒ self Also known as: put_double

Put value as a 64-bit float (double) in memory at offset offset (alias: #put_double).

#put_pointer(offset, value) ⇒ self

Put value in memory from offset..

#put_string(offset, str) ⇒ self

Put a string in memory.

Raises:

  • (SecurityError)

    when writing unsafe string to memory

  • (IndexError)

    if offset is too great

  • (NullPointerError)

    if memory not initialized



431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
# File 'ext/ffi_c/AbstractMemory.c', line 431

static VALUE
memory_put_string(VALUE self, VALUE offset, VALUE str)
{
    AbstractMemory* ptr = MEMORY(self);
    long off, len;

    Check_Type(str, T_STRING);
    off = NUM2LONG(offset);
    len = RSTRING_LEN(str);

    checkWrite(ptr);
    checkBounds(ptr, off, len + 1);

    memcpy(ptr->address + off, RSTRING_PTR(str), len);
    *((char *) ptr->address + off + len) = '\0';

    return self;
}

#read_array_of_double(length) ⇒ Array<Float>

Read 64-bit floats (doubles) from memory.

Same as:

memory.get_array_of_double(0, ary)

#read_array_of_float(length) ⇒ Array<Float>

Read 32-bit floats from memory.

Same as:

memory.get_array_of_float(0, ary)

#read_array_of_pointer(length) ⇒ Array<Pointer>

Read an array of Pointer of length length.

Same as:

memory.get_array_of_pointer(0, length)

#read_bytes(length) ⇒ String

equivalent to :

memory.get_bytes(0, length)


528
529
530
531
532
# File 'ext/ffi_c/AbstractMemory.c', line 528

static VALUE 
memory_read_bytes(VALUE self, VALUE length)
{
    return memory_get_bytes(self, INT2FIX(0), length);
}

#read_doubleFloat

Read a 64-bit float (double) from memory.

Same as:

memory.get_double(0)

#read_floatFloat

Read a 32-bit float from memory.

Same as:

memory.get_float(0)

#read_pointerPointer

Get a Pointer to the memory from base address.

Equivalent to:

memory.get_pointer(0)

#sizeNumeric Also known as: size

Return memory size in bytes (alias: #total)



312
313
314
315
316
317
318
319
320
# File 'ext/ffi_c/AbstractMemory.c', line 312

static VALUE
memory_size(VALUE self) 
{
    AbstractMemory* ptr;

    Data_Get_Struct(self, AbstractMemory, ptr);

    return LONG2NUM(ptr->size);
}

#type_sizeNumeric

Get the memory's type size.



562
563
564
565
566
567
568
569
570
# File 'ext/ffi_c/AbstractMemory.c', line 562

static VALUE
memory_type_size(VALUE self)
{
    AbstractMemory* ptr;

    Data_Get_Struct(self, AbstractMemory, ptr);

    return INT2NUM(ptr->typeSize);
}

#write_array_of_double(ary) ⇒ self

Write values from ary as 64-bit floats (doubles) in memory.

Same as:

memory.put_array_of_double(0, ary)

#write_array_of_float(ary) ⇒ self

Write values from ary as 32-bit floats in memory.

Same as:

memory.put_array_of_float(0, ary)

#write_array_of_pointer(ary) ⇒ self

Write an array of Pointer into memory from offset.

Same as :

memory.put_array_of_pointer(0, ary)

#write_bytes(str, index = 0, length = nil) ⇒ self

equivalent to :

memory.put_bytes(0, str, index, length)


543
544
545
546
547
548
549
550
551
552
553
554
555
# File 'ext/ffi_c/AbstractMemory.c', line 543

static VALUE 
memory_write_bytes(int argc, VALUE* argv, VALUE self)
{
    VALUE* wargv = ALLOCA_N(VALUE, argc + 1);
    int i;

    wargv[0] = INT2FIX(0);
    for (i = 0; i < argc; i++) {
        wargv[i + 1] = argv[i];
    }

    return memory_put_bytes(argc + 1, wargv, self);
}

#write_double(value) ⇒ self

Write value as a 64-bit float (double) in memory.

Same as:

memory.put_double(0, value)

#write_float(value) ⇒ self

Write value as a 32-bit float in memory.

Same as:

memory.put_float(0, value)

#write_pointer(value) ⇒ self

Write value in memory.

Equivalent to:

memory.put_pointer(0, value)