Core Function Vec

From Sputnik Wiki
(Difference between revisions)
Jump to: navigation, search
(Remarks)
(Example)
Line 83: Line 83:
 
vec($foo, 0, 8) ^= @'A'; // Do a Xor operation
 
vec($foo, 0, 8) ^= @'A'; // Do a Xor operation
 
echo "Vec: $foo\n"; # ªfvl
 
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
 
</syntaxhighlight>
 
</syntaxhighlight>
  

Revision as of 18:47, 28 September 2013

Vec( <expression>, <offset>, <bits> )

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.

offset

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

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 32.

Return Value

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

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.

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

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'

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

To transform a bit vector into a string or 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
$bitsArray = split(unpack("b*", $foo, true), '');
foreach($bitsArray 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