"Sputnik" help  
Sputnik Help
$ptr[<index>]:<type> = <value>
$ptr[<index>]::<type> = <value>
$ptr[<index>,<size>]:<type> = <value>
$ptr[<index>,<size>]::<type> = <value>
$ptr[<index>,<size>,<flags]:<type> = <value>
$ptr[<index>,<size>,<flags>]::<type> = <value>

Description

Sputnik features a powerful operator to deal with reading/writing to a memory pointer.

Read and Write to memory pointers similar to PTRRead() and PTRWrite() but using [] operator to simulate like it's an array.

Another ability of this operator is it can be used on Binary as if it was using a memory pointer.

Parameters

$ptr The variable that will be treated as an contains an IntPtr/UIntPtr. Alternatively a Binary variable to read/write.
index The index of the value to get.

If you use only one : then the index will act like an array of that object size so if you are reading Int64 values index 0 will be 0 but index 1 will really be index 8 since it will push up the indexes by the index * object size.

However if you do two : like :: then the index is a literal index so index 0 is 0 and 1 is 1 it will take the object size into account.

size If this is above 1 then the return value will be an array of that many elements if reading or it will write that many elements from an array if writing. Note however that if size is -1 and you are writing an array it will write all elements.
flags None yet
type

The type of value to read possible types are (case-sensitive):

c = Char (unsigned, ascii) [1 byte in size]
C = Char (Unicode) [2 bytes in size]
b = byte (signed) [1 byte in size]
B = byte (unsigned) [1 byte in size]
s = short (signed) [2 bytes in size]
i = int (signed) [4 bytes in size]
l = long (signed) [8 bytes in size]
S = ushort (unsigned) [2 bytes in size]
I = uint (unsigned) [4 bytes in size]
L = ulong (unsigned) [8 bytes in size]
f = float [4 bytes in size]
d = Double [8 bytes in size]
t = Pointer (signed) [(depends if running 32bit or 64bit Sputnik)]
T = UPointer (unsigned) [(depends if running 32bit or 64bit Sputnik)]

Remarks

If you are only using like $a = $ptr[<index>]::<type>; then it will return the value at that location or NULL if it can't obtain one.

This can be used to effortlessly read from pointers that you allocate using Alloc() or obtain from calling some DLL etc.

The Bracket Pointer operator in Sputnik is a powerful feature that allows you to read from and write to memory pointers or binary data in a convenient and intuitive way. It provides a compact and expressive syntax for memory manipulation.

With this operator, you can easily read and write values at specific memory locations without the need for complex pointer arithmetic or low-level memory access functions. It supports various data types, including integers, floating-point numbers, characters, and pointers, allowing you to work with different types of data in a unified manner.

The operator also provides flexibility in terms of indexing and size specification. You can specify an index to access a specific element within an array-like structure, or you can use the :: notation to specify a literal index that takes into account the size of the data type. Additionally, you can specify the size of the data when writing, allowing you to write multiple elements at once or write a whole array.

By using the Bracket Pointer operator, you can effortlessly read from and write to memory pointers allocated using functions like Alloc() or obtained from external sources. It simplifies memory management and enables efficient manipulation of memory contents.

Furthermore, the operator can also be used on binary data, treating it as if it were a memory pointer. This provides a convenient way to read and write values in binary format without the need for explicit packing and unpacking operations.

Overall, the Bracket Pointer operator enhances the readability and usability of Sputnik code when working with memory pointers and binary data, making memory manipulation tasks more intuitive and efficient.

Related

Memory Functions

Example

Basic example read/write floats:

// Allocate memory
my $ptr = Alloc(10, 0x00);
// Write floats using ARRAY index
// this causes index 1 to be 4 bytes in)
$ptr[0]:f = 133.77;
$ptr[1]:f = 777.42;
// Print whats currently in the array
say $ptr[0]:f; // 133.77
say $ptr[1]:f; // 777.42
// Free up ram when we are done
free($ptr);

Using += and ++ operators (works for all operators like that):

// Allocate memory
my $ptr = Alloc(3, 0x00);
// Write floats using ARRAY index
// this causes index 1 to be 4 bytes in)
$ptr[0]:f = 133.77;
$ptr[0]:f += 100;
$ptr[0]:f++;
// Print whats currently in the array
say $ptr[0]:f; // 234.77
// Free up ram when we are done
free($ptr);

You get a wildly different result if you write to the address directly instead of stacking the object size in bytes:

// Allocate memory
my $ptr = Alloc(10, 0x00);
// Write floats using direct index
// this causes index 1 to be 1 byte in)
$ptr[0]::f = 133.77;
$ptr[1]::f = 777.42;
// Print whats currently in the array
say $ptr[0]:f; // 54.71984
say $ptr[1]:f; // 9.52883E-44
// Free up ram when we are done
free($ptr);

Example of writing multiple variable types:

// Allocate memory
my $ptr = Alloc(10, 0x00);
// Write using direct index
// this causes index 1 to be 1 byte in)
$ptr[0]::f = 133.77;
$ptr[4]::i = 101;
$ptr[8]::f = 942.77;
// Print whats currently in the array
say $ptr[0]::f; // 133.77
say $ptr[4]::i; // 101
say $ptr[8]::f; // 942.77
// Free up ram when we are done
free($ptr);

Large Example:

Class ByteWriter
{
    my $_data;
    my $_capacity;
    my $Length = 0;
    Function __Construct( $size = 0 )
    {
        if($size <= 0)
            $size = 10;
        SetCapacity($size);
        $Length = 0;
    }
    Function GetCapacity()    
    {
        return $_capacity;
    }
    Function SetCapacity( $value )
    {
        if($value <= 0)
        {
            if($_data ~~ IntPtr)
                free($_data);
            $_data = null;
            $_capacity = 0;
        }
        else
        {
            if($_data ~~ IntPtr)
            {
                my $OldPtr = $_data;
                $_data = Alloc($value, 0x00);
                for(my $i = 0; $i < $_capacity; $i++)
                    $_data[$i]::B = $OldPtr[$i]::B;
                $_capacity = $value;
                free($OldPtr);
            }
            else
            {
                $_data = Alloc($value, 0x00);
                $_capacity = $value;
            }
        }
    }
    Function WriteByte( $value )
    {
        if ($Length == GetCapacity())
            SetCapacity(2 * GetCapacity());
        $_data[$Length]::B = $value;
        $Length++;
    }
    Function WriteBytes( $value )
    {
        foreach(my $byte in (Binary)$value)
            WriteByte($byte);
    }
    Function WritePack( $format, $value )
    {
        my $bin = Pack($format, $value);
        foreach(my $byte in $bin)
            WriteByte($byte);
    }
    Function DebugPrint( )
    {
        say "Capacity: " . GetCapacity();
        say "Length: " . $Length;
        for(my $i = 0; $i < $Length; $i++)
        {
            my $byte = $_data[$i]::B;
            printf("Index '%02d' Byte '%02d' Hex '%X' Char '%c'\n", $i, $byte, $byte, $byte);
        }
    }
};
my $s = new ByteWriter();
$s->WriteByte(20);
$s->WriteByte(30);
$s->WriteByte(40);
$s->WriteByte(50);
$s->WriteByte(60);
$s->WriteBytes(bin(1,2,3,4,5,6,7));
$s->WritePack("z0", "Hello");
 
$s->DebugPrint();
 
// Prints
// Capacity: 20
// Length: 17
// Index '00' Byte '20' Hex '14' Char '¶'
// Index '01' Byte '30' Hex '1E' Char '?'
// Index '02' Byte '40' Hex '28' Char '('
// Index '03' Byte '50' Hex '32' Char '2'
// Index '04' Byte '60' Hex '3C' Char '<'
// Index '05' Byte '01' Hex '1' Char '?'
// Index '06' Byte '02' Hex '2' Char '?'
// Index '07' Byte '03' Hex '3' Char '?'
// Index '08' Byte '04' Hex '4' Char '?'
// Index '09' Byte '05' Hex '5' Char '?'
// Index '10' Byte '06' Hex '6' Char '?'
// Index '11' Byte '07' Hex '7' Char ''
// Index '12' Byte '72' Hex '48' Char 'H'
// Index '13' Byte '101' Hex '65' Char 'e'
// Index '14' Byte '108' Hex '6C' Char 'l'
// Index '15' Byte '108' Hex '6C' Char 'l'
// Index '16' Byte '111' Hex '6F' Char 'o'

Here is an example of reading Binary as if it was a memory pointer using this operator.

my $bin = BinNew(8);

BinaryWriteValue($bin, 0, @SizeCodeDWord, -31337);
BinaryWriteValue($bin, 4, @SizeCodeDWord, (^UInt32)31.77);

say "Read Int " . (Int32)BinaryReadValue($bin, 0, @SizeCodeDWord);
say "Read Float " . (^Float)BinaryReadValue($bin, 4, @SizeCodeDWord);

say "Read Int (Alt) " . $bin[0]:i;
say "Read Float (Alt) " . $bin[1]:f;

// PRINTS
// Read Int -31337
// Read Float 31.77
// Read Int (Alt) -31337
// Read Float (Alt) 31.77

 


Contact
Cheryl (uberfox@hotmail.com)
Homepage
http://ubersoft.org