Core Function Vec

From Sputnik Wiki
Revision as of 20:20, 28 September 2013 by UberFoX (Talk | contribs)
Jump to: navigation, search
Vec( <expression>, <offset>, <bits> )
Vec( <expression>, <offset>, <bits> ) = <value>
Vec( <expression>, <offset>, <bits> )++
Vec( <expression>, <offset>, <bits> ) +=<value>
...
...
...

Contents

Description

Treats the string in EXPRESSION as a bit vector made up of elements of width bits and returns the value of the element specified by OFFSET as an unsigned integer and optionally sets BITS in the string to a given value.

BITS therefore specifies the number of bits that are reserved for each element in the bit vector. This must be a power of two from 1 to 32.

If BITS is 8, "elements" coincide with bytes of the input string.

If BITS is 16 or more, bytes of the input string are grouped into chunks of size BITS/8, and each group is converted to a number as with pack()/unpack() with big-endian formats n /N (and analogously for BITS==64). See pack for details.

If bits is 4 or less, the string is broken into bytes, then the bits of each byte are broken into 8/BITS groups.

Bits of a byte are numbered in a little-endian-ish way, as in 0x01 , 0x02 , 0x04 , 0x08 , 0x10 , 0x20 , 0x40 , 0x80.

For example, breaking the single input byte chr(0x36) into two groups gives a list (0x6, 0x3) ; breaking it into 4 groups gives (0x2, 0x1, 0x3, 0x0) .

vec may also be assigned to, by using the value parameter example:

vec($image, $max_x * $x + $y, 8) = 3; // Settting value 3

If the selected element is outside the string, the value 0 is returned. If an element off the end of the string is written to, Spunik will first extend the string with sufficiently many zero bytes. It is an error to try to write off the beginning of the string (i.e., negative OFFSET).

Strings created with vec can also be manipulated with the logical operators |, & , ^, and ~ .

These operators will assume a bit vector operation is desired when both operands are strings.

Parameters

expression

The string to use.

This should be a variable so it can be written to and stored.

The string will be increased in size as you demand so in the OFFSET.

The string will be considered a bit string so each character will be equal to a BYTE any excess Unicode characters will be totally ignored and take no action in get/set of the Vec() operations and when data is written to the string it will be ensured to be of BYTE size to avoid overflow into any excess Unicode bytes.

The string will be MODIFIED IN PLACE (as a char* internally) and is not reconstructed at each edit this provides maximal speed the only time this does not apply is if you are resizing the string then it has no choice but to copy it.

You can also preallocate the string a given length (See examples for how to).

offset

Offset is the marker for the end of the vector, and it counts back the number of bits specified to find the start.

Unlike in Perl you may use a Negative offset and it will cause the operation to take place that many characters from the end of the string.

bits

BITS specifies the number of bits that are reserved for each element in the bit vector.

This must be a power of two from 1 to 64.

value

Optional; A numeric value to set to the Vec().

If it is a floating point it will be rounded.

If it is a string or anything else it will be converted to an Integer (Int64).

If it is a Binary variable Vec() will try convert it to an integer of up to Int64 size (Any bytes in excess of 8 will be ignored).

The return value still takes effect even you set a value to the Vec().

Return Value

This function returns the value of the bit field specified by OFFSET.

You must use Vec() if you wish to edit the string at the offset and bits you can't use the return value from a Vec() and expect to edit it hoping to change the bit string this will fail.

You can't use the return value to modify the string.

Remarks

This function is inspired by Perl's Vec() function and any tutorial you find for Perl on that should work on this.

This function is smart enough to know if it should increase the strings size or not therefor it will return/edit the parts of the string you wish to without rebuilding the string each time this is significantly faster than recreating the string every time.

In Sputnik strings are immutable and also not immutable... For most operations a new string will be returned and the old one replaced however that is not the rule there are a number of functions that will modify the string in place and Vec() is one of them.

You can also modify strings in place yourself using the Fixed() statement.

When Vec() modifies the string it will make SURE to never go over byte size when it writes since Sputnik strings are Unicode they can go well over 255 however Vec() makes sure it only writes as a BYTE to avoid any issues like that.

A Vec() has to be on the left side of an operation for it to get SET such as otherwise you can only GET from it.

Technically the Vec() is not a function like most others it's actually more of a language feature similar to an If statement so if you enter wrong number of parameters you will be notified instantly even before execution of your script begins. Since it is a language feature rather than a generic function its structure is parsed literally.

Example

Convert a bit vector to to a binary array

my $foo = '';
vec($foo, 0, 64) = 0x537075746E696B00;
printf "\$foo is: %s\n", $foo;
# $foo is: Sputnik
$bin = BinaryFromStr($foo);
printr $bin;
# {BINARY:8}
# {
#         [0] => 83
#         [1] => 112
#         [2] => 117
#         [3] => 116
#         [4] => 110
#         [5] => 105
#         [6] => 107
#         [7] => 0
# }

Convert binary array to a bit vector

// Create a binary variable
$bin = Pack("A*", "Zputnik");
// Convert it to a string
// (bit vectors are strings)
$vec = (string)$bin;
 
// Edit the first character
vec($vec, 0, 8) = @'S';
 
// Add a period to the end
vec($vec, strlen($vec), 8) = @'.';
 
say $vec; # Sputnik.

Looking for a way to spawn a string of a specific size to be used as a Vec()?

# Vec() can work on an empty string just fine
# it will increase the strings size as it needs to
# there is no need to ever preallocate the string.
 
# However if you find you want to then this is how to.
 
# Characters in a string are same as bytes
# So a 100 character long string is same as
# a 100 byte long
$vec = StrNew('T', 100); # Make a string 100 characters long filled with 'T' chars
$vec = StrNew('A', 100); # Make a string 50 characters long filled with 'A' chars
$vec = StrNew(' ', 100); # Make a string 50 characters long filled with ' ' (space) chars
$vec = StrNew(0, 100); # Make a string 50 characters long filled with null chars (0x00 null byte)
$vec = StrNew(077, 100); # Use Octal to define the character for the new string to be filled with
$vec = StrNew(0x31, 100); # Use Hex to define the character for the new string to be filled with
$vec = StrNew(65, 100); # Use Decimal to define the character for the new string to be filled with
 
# Once you have created the string of the size you need
# you can begin using Vec() on it example
 
# Pre-allocate the string
$vec = StrNew('-', 10);
say $vec; # ----------
vec($vec, 0, 8) = @'S'; # Use @'' which is the Sputnik CharLiteral
vec($vec, 1, 8) = @'P'; # It would be a bad idea to just use '' since that is a string!
vec($vec, 2, 8) = @'U';
vec($vec, 3, 8) = @'T';
vec($vec, 4, 8) = @'N';
vec($vec, 5, 8) = @'I';
vec($vec, 6, 8) = @'K';
say $vec; # SPUTNIK---

One often undocumented feature of the Vec() is its ability to use Operators such as ++ example:

my $foo = '';
vec($foo, 0, 32) = 0x5065726C; # 'Perl'
echo "Vec: $foo\n"; # Perl
vec($foo, 1, 8)++; // Increase the second char in the string
echo "Vec: $foo\n"; # Pdrl
vec($foo, 0, 8)++; // Increase the first char in the string
echo "Vec: $foo\n"; # Qdrl
vec($foo, 2, 8) += 4; // Increase the third char in the string by 4
echo "Vec: $foo\n"; # Qfvl
vec($foo, 0, 8) -= vec($foo, 1, 8); // Sub the second char from first
echo "Vec: $foo\n"; # ëfvl
vec($foo, 0, 8) ^= @'A'; // Do a Xor operation
echo "Vec: $foo\n"; # ªfvl
 
# Note that .= and ..= work differently on Vectors so
vec($foo, 0, 8) .= 10; // Is equal to += 10
vec($foo, 0, 8) ..= 10; // Is equal to -= 10

The following code will build up an ASCII string saying 'PerlPerlPerl' . The comments show the string after each step. Note that this code works in the same way on big-endian or little-endian machines.

my $foo = '';
vec($foo, 0, 32) = 0x5065726C; # 'Perl'
# $foo eq "Perl" eq "\x50\x65\x72\x6C", 32 bits
printf "Char '%1^c' Byte '%1^d'\n", vec($foo, 0, 8); # prints 80 == 0x50 == ord('P')
vec($foo, 2, 16) = 0x5065; # 'PerlPe'
vec($foo, 3, 16) = 0x726C; # 'PerlPerl'
vec($foo, 8, 8) = 0x50; # 'PerlPerlP'
vec($foo, 9, 8) = 0x65; # 'PerlPerlPe'
vec($foo, 20, 4) = 2; # 'PerlPerlPe' . "\x02"
vec($foo, 21, 4) = 7; # 'PerlPerlPer'
# 'r' is "\x72"
vec($foo, 45, 2) = 3; # 'PerlPerlPer' . "\x0c"
vec($foo, 93, 1) = 1; # 'PerlPerlPer' . "\x2c"
vec($foo, 94, 1) = 1; # 'PerlPerlPerl'
# 'l' is "\x6c"
printf "\$foo is '%s'\n", $foo;
// Prints
// $foo is 'PerlPerlPerl'
 
// Lets replace the middle Perl with Lrep
vec($foo, 1, 32) = 0x4C726570; # 'Lrep'
printf "\$foo is '%s'\n", $foo;
// $foo is 'PerlLrepPerl'

The following code will build up an ASCII string saying 'Sputnik' (using 32-Bits)

my $foo = '';
vec($foo, 0, 32) = 0x53707574; # 'Sput'
vec($foo, 1, 32) = 0x6E696B00; # 'nik'
printf "\$foo is: %s\n", $foo;
// $foo is: Sputnik

The following code will build up an ASCII string saying 'Sputnik' (using 64-Bits)

my $foo = '';
vec($foo, 0, 64) = 0x537075746E696B00;
printf "\$foo is: %s\n", $foo;
// $foo is: Sputnik

To transform a bit vector into a list of 0's and 1's, use these:

my $foo = '';
vec($foo, 0, 32) = 0x5065726C; # 'Perl'
 
$bits = unpack("b*", $foo, true);
print "$bits\n"; // Prints: 00001010101001100100111000110110
 
// To get each individual bit
foreach(unpack("b*", $foo, true) as $b)
{
	echo "Bit '$b'\n";
}
// Prints
// Bit '0'
// Bit '0'
// Bit '0'
// Bit '0'
// Bit '1'
// Bit '0'
// Bit '1'
// Bit '0'
// Bit '1'
// Bit '0'
// Bit '1'
// Bit '0'
// Bit '0'
// Bit '1'
// Bit '1'
// Bit '0'
// Bit '0'
// Bit '1'
// Bit '0'
// Bit '0'
// Bit '1'
// Bit '1'
// Bit '1'
// Bit '0'
// Bit '0'
// Bit '0'
// Bit '1'
// Bit '1'
// Bit '0'
// Bit '1'
// Bit '1'
// Bit '0'
Personal tools
Namespaces
Variants
Actions
Navigation
Toolbox