Core Function Vec

From Sputnik Wiki
(Difference between revisions)
Jump to: navigation, search
(Example)
 
(14 intermediate revisions by one user not shown)
Line 11: Line 11:
 
=== Description ===
 
=== 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.
+
Treats the binary variable 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 binary variable 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.
+
BITS therefore specifies the number of bits that are reserved for each element in the bit vector. This must from 1 to 64 however if it ranges from higher than 8 it must be in a power of two (below 8 does not have this limit).
  
If BITS is 8, "elements" coincide with bytes of the input string.
+
If BITS is 8, "elements" coincide with bytes of the input binary variable.
  
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 16 or more, bytes of the input binary variable 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.
+
If bits is 4 or less, the binary variable 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.
 
Bits of a byte are numbered in a little-endian-ish way, as in 0x01 , 0x02 , 0x04 , 0x08 , 0x10 , 0x20 , 0x40 , 0x80.
Line 31: Line 31:
 
</pre>
 
</pre>
  
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).
+
If the selected element is outside the binary variable, the value 0 is returned. If an element off the end of the binary variable is written to, Spunik will first extend the binary variable with sufficiently many zero bytes. It is an error to try to write off the beginning of the binary variable (i.e., negative OFFSET).
  
Strings created with vec can also be manipulated with the logical operators |, & , ^, and ~ .
+
Binary variables 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.
+
These operators will assume a bit vector operation is desired when both operands are binary variables.
  
 
=== Parameters ===
 
=== Parameters ===
  
==== expression ====
+
==== binary-array ====
  
The string to use.
+
The binary variable to use.
  
 
This should be a variable so it can be written to and stored.
 
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 binary variable 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 binary variable will be MODIFIED IN PLACE (as a byte* 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 binary variable then it has no choice but to copy it.
  
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 binary variable a given length (See examples for how to).
 
+
You can also preallocate the string a given length (See examples for how to).
+
  
 
==== offset ====
 
==== offset ====
Line 57: Line 55:
 
Offset is the marker for the end of the vector, and it counts back the number of bits specified to find the start.
 
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.
+
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 binary variable.
  
 
==== bits ====
 
==== bits ====
Line 63: Line 61:
 
BITS specifies the number of bits that are reserved for each element in the bit vector.
 
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.
+
This must be a power of two IF the number is from 8 to 64 however numbers BELOW 8 are not required to be a power of two.
  
 
==== value ====
 
==== value ====
Line 81: Line 79:
 
This function returns the value of the bit field specified by OFFSET.
 
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 must use Vec() if you wish to edit the binary variable at the offset and bits you can't use the return value from a Vec() and expect to edit it hoping to change the binary variable this will fail.
  
You can't use the return value to modify the string.
+
You can't use the return value to modify the binary variable.
  
 
=== Remarks ===
 
=== Remarks ===
Line 89: Line 87:
 
This function is inspired by Perl's Vec() function and any tutorial you find for Perl one that should work on this.
 
This function is inspired by Perl's Vec() function and any tutorial you find for Perl one 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.
+
This function is smart enough to know if it should increase the binary variables size or not therefor it will return/edit the parts of the binary variable you wish to without rebuilding the binary variable each time this is significantly faster than recreating the binary variable 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.
+
In Sputnik binary variable are not immutable. For most operations a binary variable will be modified in place and the Vec() also modifies binary variables in place.
 
+
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.
 
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.
 
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.
 +
 +
To display a Vec()'s binary variable as a string you can cast it as a (string) like (string)$vec however that is ASCII only if you wish to use Unicode you must use the BinaryToStr() function
 +
 +
Vec() is often used when dealing with sockets since it very good at reading and creating all kinds of headers etc.
  
 
=== Example ===
 
=== Example ===
 +
 +
Bits example
 +
 +
<syntaxhighlight lang="sputnik">
 +
my $vec = null;
 +
vec($vec,  3, 4) = 1;  # bits 0 to 3
 +
vec($vec,  7, 4) = 10; # bits 4 to 7
 +
vec($vec, 11, 4) = 3;  # bits 8 to 11
 +
vec($vec, 15, 4) = 15; # bits 12 to 15
 +
# As there are 4 bits per number this can
 +
# be decoded by unpack() as a hex number
 +
my $hex = UnpackSingle("h*", $vec);
 +
print("vec() Has a created a string of nybbles, in hex: $hex\n");
 +
// PRINTS:
 +
// vec() Has a created a string of nybbles, in hex: 0001000A0003000F
 +
</syntaxhighlight>
  
 
Example of packing two floating point numbers into a bit vector then retrieving them later
 
Example of packing two floating point numbers into a bit vector then retrieving them later
  
 
<syntaxhighlight lang="sputnik">
 
<syntaxhighlight lang="sputnik">
my $foo = '';
+
my $foo = null;
 
vec($foo, 0, 32) = Pack("f", 133.7);
 
vec($foo, 0, 32) = Pack("f", 133.7);
 
vec($foo, 1, 32) = Pack("f", 777.42);
 
vec($foo, 1, 32) = Pack("f", 777.42);
Line 125: Line 139:
 
</syntaxhighlight>
 
</syntaxhighlight>
  
Convert a bit vector to to a binary array
+
Print a bit vector
  
 
<syntaxhighlight lang="sputnik">
 
<syntaxhighlight lang="sputnik">
my $foo = '';
+
my $foo = null;
 
vec($foo, 0, 64) = 0x537075746E696B00;
 
vec($foo, 0, 64) = 0x537075746E696B00;
printf "\$foo is: %s\n", $foo;
+
printf "\$foo is: %s\n", (string)$foo;
 
# $foo is: Sputnik
 
# $foo is: Sputnik
$bin = BinaryFromStr($foo);
+
printr $foo;
printr $bin;
+
 
# {BINARY:8}
 
# {BINARY:8}
 
# {
 
# {
Line 147: Line 160:
 
</syntaxhighlight>
 
</syntaxhighlight>
  
Convert binary array to a bit vector
+
Binary and Vec vectors are the same thing
  
 
<syntaxhighlight lang="sputnik">
 
<syntaxhighlight lang="sputnik">
 
// Create a binary variable
 
// Create a binary variable
$bin = Pack("A*", "Zputnik");
+
$vec = Pack("A*", "Zputnik");
// Convert it to a string
+
// (bit vectors are strings)
+
$vec = $bin;
+
  
 
// Edit the first character
 
// Edit the first character
Line 165: Line 175:
 
</syntaxhighlight>
 
</syntaxhighlight>
  
Looking for a way to spawn a string of a specific size to be used as a Vec()?
+
Looking for a way to spawn a binary variable of a specific size to be used as a Vec()?
  
 
<syntaxhighlight lang="sputnik">
 
<syntaxhighlight lang="sputnik">
# Vec() can work on an empty string just fine
+
# Vec() can work on an empty binary variable just fine
# it will increase the strings size as it needs to
+
# it will increase the binary variables size as it needs to
# there is no need to ever preallocate the string.
+
# there is no need to ever preallocate the binary variable.
  
 
# However if you find you want to then this is how to.
 
# However if you find you want to then this is how to.
  
# Characters in a string are same as bytes
+
# So a 100 byte long binary variable is same as
# So a 100 character long string is same as
+
$vec = BinaryCreate(100, @'T'); # Make a binary variable 100 bytes long filled with 'T' chars
# a 100 byte long
+
$vec = BinaryCreate(100, @'A'); # Make a binary variable 50 bytes long filled with 'A' chars
$vec = StrNew('T', 100); # Make a string 100 characters long filled with 'T' chars
+
$vec = StrNew(100, @' '); # Make a binary variable 50 bytes long filled with ' ' (space) chars
$vec = StrNew('A', 100); # Make a string 50 characters long filled with 'A' chars
+
$vec = BinaryCreate(100, 0); # Make a binary variable 50 bytes long filled with null chars (0x00 null byte)
$vec = StrNew(' ', 100); # Make a string 50 characters long filled with ' ' (space) chars
+
$vec = BinaryCreate(100, 077); # Use Octal to define the byte for the new binary variable to be filled with
$vec = StrNew(0, 100); # Make a string 50 characters long filled with null chars (0x00 null byte)
+
$vec = BinaryCreate(100, 0x31); # Use Hex to define the byte for the new binary variable to be filled with
$vec = StrNew(077, 100); # Use Octal to define the character for the new string to be filled with
+
$vec = BinaryCreate(100, 65); # Use Decimal to define the byte for the new binary variable 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
+
# Once you have created the binart variable of the size you need
 
# you can begin using Vec() on it example
 
# you can begin using Vec() on it example
  
# Pre-allocate the string
+
# Pre-allocate the binart variable
$vec = StrNew('-', 10);
+
$vec = BinaryCreate(10, @'-');
say $vec; # ----------
+
say (string)$vec; # ----------
 
vec($vec, 0, 8) = @'S'; # Use @'' which is the Sputnik CharLiteral
 
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, 1, 8) = @'P'; # It would be a bad idea to just use '' since that is a string!
Line 198: Line 206:
 
vec($vec, 5, 8) = @'I';
 
vec($vec, 5, 8) = @'I';
 
vec($vec, 6, 8) = @'K';
 
vec($vec, 6, 8) = @'K';
say $vec; # SPUTNIK---
+
say (string)$vec; # SPUTNIK---
 
</syntaxhighlight>
 
</syntaxhighlight>
  
Line 204: Line 212:
  
 
<syntaxhighlight lang="sputnik">
 
<syntaxhighlight lang="sputnik">
my $foo = '';
+
my $foo = null;
 
vec($foo, 0, 32) = 0x5065726C; # 'Perl'
 
vec($foo, 0, 32) = 0x5065726C; # 'Perl'
 
echo "Vec: $foo\n"; # Perl
 
echo "Vec: $foo\n"; # Perl
vec($foo, 1, 8)++; // Increase the second char in the string
+
vec($foo, 1, 8)++; // Increase the second char in the binary variable
 
echo "Vec: $foo\n"; # Pfrl
 
echo "Vec: $foo\n"; # Pfrl
vec($foo, 0, 8)++; // Increase the first char in the string
+
vec($foo, 0, 8)++; // Increase the first char in the binary variable
 
echo "Vec: $foo\n"; # Qfrl
 
echo "Vec: $foo\n"; # Qfrl
vec($foo, 2, 8) += 4; // Increase the third char in the string by 4
+
vec($foo, 2, 8) += 4; // Increase the third char in the binary variable by 4
 
echo "Vec: $foo\n"; # Qfvl
 
echo "Vec: $foo\n"; # Qfvl
 
vec($foo, 0, 8) -= vec($foo, 1, 8); // Sub the second char from first
 
vec($foo, 0, 8) -= vec($foo, 1, 8); // Sub the second char from first
Line 223: Line 231:
 
</syntaxhighlight>
 
</syntaxhighlight>
  
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.
+
The following code will build up an ASCII (in binary format) 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.
  
 
<syntaxhighlight lang="sputnik">
 
<syntaxhighlight lang="sputnik">
my $foo = '';
+
my $foo = null;
 
vec($foo, 0, 32) = 0x5065726C; # 'Perl'
 
vec($foo, 0, 32) = 0x5065726C; # 'Perl'
 
# $foo eq "Perl" eq "\x50\x65\x72\x6C", 32 bits
 
# $foo eq "Perl" eq "\x50\x65\x72\x6C", 32 bits
Line 251: Line 259:
 
</syntaxhighlight>
 
</syntaxhighlight>
  
The following code will build up an ASCII string saying 'Sputnik' (using 32-Bits)
+
The following code will build up an ASCII (in binary format) saying 'Sputnik' (using 32-Bits)
  
 
<syntaxhighlight lang="sputnik">
 
<syntaxhighlight lang="sputnik">
my $foo = '';
+
my $foo = null;
 
vec($foo, 0, 32) = 0x53707574; # 'Sput'
 
vec($foo, 0, 32) = 0x53707574; # 'Sput'
 
vec($foo, 1, 32) = 0x6E696B00; # 'nik'
 
vec($foo, 1, 32) = 0x6E696B00; # 'nik'
Line 261: Line 269:
 
</syntaxhighlight>
 
</syntaxhighlight>
  
The following code will build up an ASCII string saying 'Sputnik' (using 64-Bits)
+
The following code will build up an ASCII (in binary format) saying 'Sputnik' (using 64-Bits)
  
 
<syntaxhighlight lang="sputnik">
 
<syntaxhighlight lang="sputnik">
my $foo = '';
+
my $foo = null;
 
vec($foo, 0, 64) = 0x537075746E696B00;
 
vec($foo, 0, 64) = 0x537075746E696B00;
 
printf "\$foo is: %s\n", (string)$foo;
 
printf "\$foo is: %s\n", (string)$foo;
Line 273: Line 281:
  
 
<syntaxhighlight lang="sputnik">
 
<syntaxhighlight lang="sputnik">
my $foo = '';
+
my $foo = null;
 
vec($foo, 0, 32) = 0x5065726C; # 'Perl'
 
vec($foo, 0, 32) = 0x5065726C; # 'Perl'
 
   
 
   
Line 324: Line 332:
 
$MAX = 1000;
 
$MAX = 1000;
  
my $sieve = '';
+
my $sieve = null;
 
vec($sieve, $MAX, 1) = 0;
 
vec($sieve, $MAX, 1) = 0;
 
$sieve = ~$sieve;
 
$sieve = ~$sieve;
Line 368: Line 376:
 
...
 
...
 
...
 
...
 +
</syntaxhighlight>
 +
 +
Are you wondering how to place Floating points into a Vec()? Here is how
 +
 +
<syntaxhighlight lang="sputnik">
 +
// Convert a Float to an Integer (32-bits)
 +
Function FpuToInt($value)
 +
{
 +
return UnpackSingle('i', PackSingle('f', $value));
 +
}
 +
// Convert a Integer to an Float (32-bits)
 +
Function IntToFpu($value)
 +
{
 +
return UnpackSingle('f', PackSingle('i', $value));
 +
}
 +
 +
// Now we get started
 +
 +
// Create a variable to hold the Vec
 +
// NULL is fine since it at least created
 +
// the variable
 +
my $vec = null;
 +
// Add some floating points to the vec
 +
Vec($vec, 0, 32) = FpuToInt(133.42);
 +
Vec($vec, 1, 32) = FpuToInt(777.42);
 +
Vec($vec, 2, 32) = FpuToInt(@PI);
 +
Vec($vec, 3, 32) = FpuToInt(@FloatMax);
 +
 +
// Read the floating points from the vec
 +
say IntToFpu(Vec($vec, 0, 32));
 +
say IntToFpu(Vec($vec, 1, 32));
 +
say IntToFpu(Vec($vec, 2, 32));
 +
say IntToFpu(Vec($vec, 3, 32));
 +
 +
// PRINTS:
 +
// 133.42
 +
// 777.42
 +
// 3.141593
 +
// 3.402823E+38
 +
</syntaxhighlight>
 +
 +
Same as above but this time for double precision floating points
 +
<syntaxhighlight lang="sputnik">
 +
// First we define some helper functions
 +
 +
// Convert a Float to an Integer (64-bits)
 +
Function FpuDToInt($value)
 +
{
 +
return UnpackSingle('q', PackSingle('d', $value));
 +
}
 +
// Convert a Integer to an Float (64-bits)
 +
Function IntToFpuD($value)
 +
{
 +
return UnpackSingle('d', PackSingle('q', $value));
 +
}
 +
 +
// Now we get started
 +
 +
// Create a variable to hold the Vec
 +
// NULL is fine since it at least created
 +
// the variable
 +
my $vec = null;
 +
// Add some floating points to the vec
 +
Vec($vec, 0, 64) = FpuDToInt(133.42);
 +
Vec($vec, 1, 64) = FpuDToInt(777.42);
 +
Vec($vec, 2, 64) = FpuDToInt(@PI);
 +
Vec($vec, 3, 64) = FpuDToInt(@DoubleMax);
 +
 +
// Read the floating points from the vec
 +
say IntToFpuD(Vec($vec, 0, 64));
 +
say IntToFpuD(Vec($vec, 1, 64));
 +
say IntToFpuD(Vec($vec, 2, 64));
 +
say IntToFpuD(Vec($vec, 3, 64));
 +
 +
// PRINTS:
 +
// 133.42
 +
// 777.42
 +
// 3.14159265358979
 +
// 1.79769313486232E+308
 +
</syntaxhighlight>
 +
 +
Example of using a bit value lower than 8 to set the bits instead of bytes
 +
 +
<syntaxhighlight lang="sputnik">
 +
// Enum to store the privs
 +
Enum Privs
 +
{
 +
$DeleteFile = 0,
 +
$UploadFile = 1,
 +
$DownloadFile = 2,
 +
$RenameFile = 3,
 +
$MoveFile = 4,
 +
$CreateFolder = 5,
 +
$DeleteFolder = 6,
 +
$RenameFolder = 7,
 +
$MoveFolder = 8,
 +
$ReadChat = 9,
 +
$SendChat = 10,
 +
$CreateChat = 11,
 +
$CloseChat = 12
 +
};
 +
// A simple function to print what privs are enabled
 +
Function PrintPrivs( $data )
 +
{
 +
foreach( Enumerate('Privs') as my $Key => my $Value )
 +
{
 +
my $Status = Vec($data, $Value, 1);
 +
if($Status) // Only show privs we can use
 +
say "Priv '$Key' Access is '$Status'";
 +
}
 +
}
 +
// Define a variable to hold the bit vector
 +
my $Access = null;
 +
// Set privs in the bit vector
 +
Vec($Access, Privs->$UploadFile, 1) = true;
 +
Vec($Access, Privs->$CreateFolder, 1) = true;
 +
Vec($Access, Privs->$ReadChat, 1) = true;
 +
Vec($Access, Privs->$CloseChat, 1) = true;
 +
// Print the privs from the bit vector
 +
say "Print Privs";
 +
PrintPrivs($Access);
 +
// Print the binary of the bit vector
 +
printr $access;
 +
// PRINTS
 +
// Priv 'uploadfile' Access is '1'
 +
// Priv 'createfolder' Access is '1'
 +
// Priv 'readchat' Access is '1'
 +
// Priv 'closechat' Access is '1'
 +
// Binary
 +
// (
 +
//    [0] => 34
 +
//    [1] => 18
 +
// )
 
</syntaxhighlight>
 
</syntaxhighlight>
  
 
[[Category:Core Function]]
 
[[Category:Core Function]]

Latest revision as of 16:15, 26 June 2015

Vec( <expression>, <offset>, <bits> )
Vec( <expression>, <offset>, <bits> ) = <value>
Vec( <expression>, <offset>, <bits> )++
Vec( <expression>, <offset>, <bits> ) +=<value>
...
...
...

Contents

Description

Treats the binary variable 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 binary variable to a given value.

BITS therefore specifies the number of bits that are reserved for each element in the bit vector. This must from 1 to 64 however if it ranges from higher than 8 it must be in a power of two (below 8 does not have this limit).

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

If BITS is 16 or more, bytes of the input binary variable 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 binary variable 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 binary variable, the value 0 is returned. If an element off the end of the binary variable is written to, Spunik will first extend the binary variable with sufficiently many zero bytes. It is an error to try to write off the beginning of the binary variable (i.e., negative OFFSET).

Binary variables 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 binary variables.

Parameters

binary-array

The binary variable to use.

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

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

The binary variable will be MODIFIED IN PLACE (as a byte* 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 binary variable then it has no choice but to copy it.

You can also preallocate the binary variable 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 binary variable.

bits

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

This must be a power of two IF the number is from 8 to 64 however numbers BELOW 8 are not required to be a power of two.

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 binary variable at the offset and bits you can't use the return value from a Vec() and expect to edit it hoping to change the binary variable this will fail.

You can't use the return value to modify the binary variable.

Remarks

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

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

In Sputnik binary variable are not immutable. For most operations a binary variable will be modified in place and the Vec() also modifies binary variables in place.

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.

To display a Vec()'s binary variable as a string you can cast it as a (string) like (string)$vec however that is ASCII only if you wish to use Unicode you must use the BinaryToStr() function

Vec() is often used when dealing with sockets since it very good at reading and creating all kinds of headers etc.

Example

Bits example

my $vec = null;
vec($vec,  3, 4) = 1;  # bits 0 to 3
vec($vec,  7, 4) = 10; # bits 4 to 7
vec($vec, 11, 4) = 3;  # bits 8 to 11
vec($vec, 15, 4) = 15; # bits 12 to 15
# As there are 4 bits per number this can
# be decoded by unpack() as a hex number
my $hex = UnpackSingle("h*", $vec);
print("vec() Has a created a string of nybbles, in hex: $hex\n");
// PRINTS:
// vec() Has a created a string of nybbles, in hex: 0001000A0003000F

Example of packing two floating point numbers into a bit vector then retrieving them later

my $foo = null;
vec($foo, 0, 32) = Pack("f", 133.7);
vec($foo, 1, 32) = Pack("f", 777.42);
# This works because Vec() will read the binary array similar to how
# Unpack() would read it with with C s i q format Vec() will choose
# what it thinks is the correct format to read based on how big the
# binary array is and it will pad 0 bytes to the end if its off like
# 3 bytes or 7 bytes etc.
 
say "\$foo is '$foo'";
#$foo is 'C♣³3DBZá'
 
say "First float is: " . Unpack("f", vec($foo, 0, 32), 3);
#First float is: 133.7
 
say "Second float is: " . Unpack("f", vec($foo, 1, 32), 3);
#Second float is: 777.42

Print a bit vector

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

Binary and Vec vectors are the same thing

// Create a binary variable
$vec = Pack("A*", "Zputnik");
 
// 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 binary variable of a specific size to be used as a Vec()?

# Vec() can work on an empty binary variable just fine
# it will increase the binary variables size as it needs to
# there is no need to ever preallocate the binary variable.
 
# However if you find you want to then this is how to.
 
# So a 100 byte long binary variable is same as
$vec = BinaryCreate(100, @'T'); # Make a binary variable 100 bytes long filled with 'T' chars
$vec = BinaryCreate(100, @'A'); # Make a binary variable 50 bytes long filled with 'A' chars
$vec = StrNew(100, @' '); # Make a binary variable 50 bytes long filled with ' ' (space) chars
$vec = BinaryCreate(100, 0); # Make a binary variable 50 bytes long filled with null chars (0x00 null byte)
$vec = BinaryCreate(100, 077); # Use Octal to define the byte for the new binary variable to be filled with
$vec = BinaryCreate(100, 0x31); # Use Hex to define the byte for the new binary variable to be filled with
$vec = BinaryCreate(100, 65); # Use Decimal to define the byte for the new binary variable to be filled with
 
# Once you have created the binart variable of the size you need
# you can begin using Vec() on it example
 
# Pre-allocate the binart variable
$vec = BinaryCreate(10, @'-');
say (string)$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 (string)$vec; # SPUTNIK---

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

my $foo = null;
vec($foo, 0, 32) = 0x5065726C; # 'Perl'
echo "Vec: $foo\n"; # Perl
vec($foo, 1, 8)++; // Increase the second char in the binary variable
echo "Vec: $foo\n"; # Pfrl
vec($foo, 0, 8)++; // Increase the first char in the binary variable
echo "Vec: $foo\n"; # Qfrl
vec($foo, 2, 8) += 4; // Increase the third char in the binary variable 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 (in binary format) 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 = null;
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", (string)$foo;
// Prints
// $foo is 'PerlPerlPerl'
 
// Lets replace the middle Perl with Lrep
vec($foo, 1, 32) = 0x4C726570; # 'Lrep'
printf "\$foo is '%s'\n", (string)$foo;
// $foo is 'PerlLrepPerl'

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

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

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

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

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

my $foo = null;
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'

Using a bit vector to find prime numbers

$MAX = 1000;
 
my $sieve = null;
vec($sieve, $MAX, 1) = 0;
$sieve = ~$sieve;
 
for (my $i = 2; $i <= sqrt($MAX); $i++)
{
	if(!vec($sieve, $i, 1))
		continue;
	for (my $x = $i * 2; $x <= $MAX; $x += $i)
		vec($sieve, $x, 1) = 0;
}
 
for (2 .. $MAX)
{
	print "$_\n" if(vec($sieve, $_, 1));
}
# Prints
# 2
# 3
# 5
# 7
# 11
# 13
# 17
# 19
# 23
# 29
# 31
# 37
# 41
# 43
# 47
# 53
# 59
# 61
# 67
# 71
# 73
# 79
# 83
# 89
# 97
...
...

Are you wondering how to place Floating points into a Vec()? Here is how

// Convert a Float to an Integer (32-bits)
Function FpuToInt($value)
{
	return UnpackSingle('i', PackSingle('f', $value));
}
// Convert a Integer to an Float (32-bits)
Function IntToFpu($value)
{
	return UnpackSingle('f', PackSingle('i', $value));
}
 
// Now we get started
 
// Create a variable to hold the Vec
// NULL is fine since it at least created
// the variable
my $vec = null;
// Add some floating points to the vec
Vec($vec, 0, 32) = FpuToInt(133.42);
Vec($vec, 1, 32) = FpuToInt(777.42);
Vec($vec, 2, 32) = FpuToInt(@PI);
Vec($vec, 3, 32) = FpuToInt(@FloatMax);
 
// Read the floating points from the vec
say IntToFpu(Vec($vec, 0, 32));
say IntToFpu(Vec($vec, 1, 32));
say IntToFpu(Vec($vec, 2, 32));
say IntToFpu(Vec($vec, 3, 32));
 
// PRINTS:
// 133.42
// 777.42
// 3.141593
// 3.402823E+38

Same as above but this time for double precision floating points

// First we define some helper functions
 
// Convert a Float to an Integer (64-bits)
Function FpuDToInt($value)
{
	return UnpackSingle('q', PackSingle('d', $value));
}
// Convert a Integer to an Float (64-bits)
Function IntToFpuD($value)
{
	return UnpackSingle('d', PackSingle('q', $value));
}
 
// Now we get started
 
// Create a variable to hold the Vec
// NULL is fine since it at least created
// the variable
my $vec = null;
// Add some floating points to the vec
Vec($vec, 0, 64) = FpuDToInt(133.42);
Vec($vec, 1, 64) = FpuDToInt(777.42);
Vec($vec, 2, 64) = FpuDToInt(@PI);
Vec($vec, 3, 64) = FpuDToInt(@DoubleMax);
 
// Read the floating points from the vec
say IntToFpuD(Vec($vec, 0, 64));
say IntToFpuD(Vec($vec, 1, 64));
say IntToFpuD(Vec($vec, 2, 64));
say IntToFpuD(Vec($vec, 3, 64));
 
// PRINTS:
// 133.42
// 777.42
// 3.14159265358979
// 1.79769313486232E+308

Example of using a bit value lower than 8 to set the bits instead of bytes

// Enum to store the privs
Enum Privs
{
	$DeleteFile			= 0,
	$UploadFile			= 1,
	$DownloadFile			= 2,
	$RenameFile			= 3,
	$MoveFile			= 4,
	$CreateFolder			= 5,
	$DeleteFolder			= 6,
	$RenameFolder			= 7,
	$MoveFolder			= 8,
	$ReadChat			= 9,
	$SendChat			= 10,
	$CreateChat			= 11,
	$CloseChat			= 12
};
// A simple function to print what privs are enabled
Function PrintPrivs( $data )
{
	foreach( Enumerate('Privs') as my $Key => my $Value )
	{
		my $Status = Vec($data, $Value, 1);
		if($Status) // Only show privs we can use
			say "Priv '$Key' Access is '$Status'";
	}
}
// Define a variable to hold the bit vector
my $Access = null;
// Set privs in the bit vector
Vec($Access, Privs->$UploadFile, 1) = true;
Vec($Access, Privs->$CreateFolder, 1) = true;
Vec($Access, Privs->$ReadChat, 1) = true;
Vec($Access, Privs->$CloseChat, 1) = true;
// Print the privs from the bit vector
say "Print Privs";
PrintPrivs($Access);
// Print the binary of the bit vector
printr $access;
// PRINTS
// Priv 'uploadfile' Access is '1'
// Priv 'createfolder' Access is '1'
// Priv 'readchat' Access is '1'
// Priv 'closechat' Access is '1'
// Binary
// (
//     [0] => 34
//     [1] => 18
// )
Personal tools
Namespaces
Variants
Actions
Navigation
Toolbox