Device + Agent
A blob is a block of arbitrary binary data represented by an object instantiated from Squirrel’s Blob class:
local dataBlob = blob();
Blobs are mutable and will grow as data is written to them. However, a blob of a specific size in bytes may be created by passing an integer value as a parameter:
local kiloByteBlob = blob(1024);
The blob can grow beyond this size — as you inevitably do by calling blob() with no size parameter and writing one or more bytes to it. If the blob’s new size exceeds its current memory allocation, Squirrel will create a new blob with the required size, but only if there is sufficient memory for Squirrel to store both the original and the larger blob while the bytes from the former are copied to the latter. When the reallocation is complete, the original blob’s memory is freed. If you know how large your blob needs to be, it is therefore more memory efficient to allocate that much memory at the outset by passing the required size as in the example above. This avoids unnecessary memory reallocation.
Squirrel treats blobs as files. Each blob maintains a byte-location pointer which is moved automatically as data is read from or written to the blob. The pointer may be also be moved manually using the seek() method. The tell() method returns the current position of the pointer.
Blobs, like all Squirrel data types on the imp, are little endian (least-significant byte comes first).
Individual bytes within a blob may be accessed by index, as if the blob were an array of 8-bit integers:
local value = blob[14];
Individual bytes can be written the same way:
blob[15] = byteValue.tochar();
Within agent and device code, blobs can be explicitly converted to strings using Squirrel’s tostring() method:
local dataString = aBlob.tostring();
Blobs are accessed by reference, and adding a blob to another entity, such as a table or an array, or passing it into a function parameter, does not add a copy of the blob but a reference to it.
For example, the following code
local blobOne = blob(10);
local tableOne = {};
local tableTwo = {};
tableOne.myBlob <- blobOne;
tableTwo.aBlob <- blobOne;
Causes the two tables tableOne and tableTwo to each contain a reference to a single, shared blob, blobOne. This is the case even though the two tables identify that same blob with their own, different keys.
You should note, however, that storing a blob within another blob, for example by using the writeblob() method, does not store a reference to the blob passed in as an argument but rather copies it as bytes into the target blob. Subsequently changing the copied blob will not cause the target blob to be changed too.
The simple line:
if (blobOne == blobTwo) { ... }
compares the references stored in the two variables blobOne and blobTwo — they will be the same only if the two variables reference the same blob.
There is no built-in Squirrel function for comparing the contents of two blobs. However, you can make use of the imp API method crypto.equals() for this task. It takes two blobs (or strings) and returns true
if their contents match. It works in device code and agent code. For example:
local a = blob(1024);
local b = blob(1024);
a[999] = 42;
local c = crypto.equals(a, b);
server.log("Blobs " + (c ? "match" : "don't match"));
For more guidance on using blobs, please see the Squirrel Programming Guide.
The blob object has the following member methods:
The blob object has the following member function: