Press ← or → to navigate between chapters
Press S or / to search in the book
Press ? to show this help
Press Esc to hide this help
Rhai - Embedded Scripting for Rust BLOB’sBLOB’s (Binary Large OBjects), used to hold packed arrays of bytes, have built-in support in Rhai.
A BLOB has no literal representation, but is created via the blob
function, or simply returned as the result of a function call (e.g. generate_thumbnail_image
that generates a thumbnail version of a large image as a BLOB).
All items stored in a BLOB are bytes (i.e. u8
) and the BLOB can freely grow or shrink with bytes added or removed.
The Rust type of a Rhai BLOB is rhai::Blob
which is an alias to Vec<u8>
.
type_of()
a BLOB returns "blob"
.
BLOB’s are disabled via the no_index
feature.
Like arrays, BLOB’s are accessed with zero-based, non-negative integer indices:
From endblob
[
index position from 0 to (length−1)]
A negative position accesses an element in the BLOB counting from the end, with −1 being the last element.
blob
[
index position from −1 to −length]
The value of a particular byte in a BLOB is mapped to an INT
(which can be 64-bit or 32-bit depending on the only_i32
feature).
Only the lowest 8 bits are significant, all other bits are ignored.
Create a BLOBThe function blob
allows creating an empty BLOB, optionally filling it to a required size with a particular value (default zero).
let x = blob(); // empty BLOB
let x = blob(10); // BLOB with ten zeros
let x = blob(50, 42); // BLOB with 50x 42's
Tip: Initialize with byte stream
To quickly initialize a BLOB with a particular byte stream, the write_be
method can be used to write eight bytes at a time (four under only_i32
) in big-endian byte order.
If fewer than eight bytes are needed, remember to right-pad the number as big-endian byte order is used.
let buf = blob(12, 0); // BLOB with 12x zeros
// Write eight bytes at a time, in big-endian order
buf.write_be(0, 8, 0xab_cd_ef_12_34_56_78_90);
buf.write_be(8, 8, 0x0a_0b_0c_0d_00_00_00_00);
// ^^^^^^^^^^^ remember to pad unused bytes
print(buf); // prints "[abcdef1234567890 0a0b0c0d]"
buf[3] == 0x12;
buf[10] == 0x0c;
// Under 'only_i32', write four bytes at a time:
buf.write_be(0, 4, 0xab_cd_ef_12);
buf.write_be(4, 4, 0x34_56_78_90);
buf.write_be(8, 4, 0x0a_0b_0c_0d);
Writing ASCII Bytes
Non-ASCII characters (i.e. characters not within 1-127) are ignored.
For many embedded applications, it is necessary to encode an ASCII string as a byte stream.
Use the write_ascii
method to write ASCII strings into any specific range within a BLOB.
The following is an example of a building a 16-byte command to send to an embedded device.
// Assume the following 16-byte command for an embedded device:
// ┌─────────┬───────────────┬──────────────────────────────────┬───────┐
// │ 0 │ 1 │ 2-13 │ 14-15 │
// ├─────────┼───────────────┼──────────────────────────────────┼───────┤
// │ command │ string length │ ASCII string, max. 12 characters │ CRC │
// └─────────┴───────────────┴──────────────────────────────────┴───────┘
let buf = blob(16, 0); // initialize command buffer
let text = "foo & bar"; // text string to send to device
buf[0] = 0x42; // command code
buf[1] = s.len(); // length of string
buf.write_ascii(2..14, text); // write the string
let crc = buf.calc_crc(); // calculate CRC
buf.write_le(14, 2, crc); // write CRC
print(buf); // prints "[4209666f6f202620 626172000000abcd]"
// ^^ command code ^^^^ CRC
// ^^ string length
// ^^^^^^^^^^^^^^^^^^^ foo & bar
device.send(buf); // send command to device
The write_utf8
function writes a string in UTF-8 encoding.
UTF-8, however, is not very common for embedded applications.
Built-in FunctionsThe following functions (mostly defined in the BasicBlobPackage
but excluded when using a raw Engine
) operate on BLOB’s.
blob
constructor function
to_array
none converts the BLOB into an array of integers as_string
none converts the BLOB into a string (the byte stream is interpreted as UTF-8) get
position, counting from end if < 0 gets a copy of the byte at a certain position (0 if the position is not valid) set
push
, append
, +=
operator
append
, +=
operator
append
, +=
operator
concatenates a string or character (as UTF-8 encoded byte-stream) to the end of the BLOB +
operator
+
operator
+
operator
==
operator
!=
operator
insert
pop
none removes the last byte and returns it (0 if empty) shift
none removes the first byte and returns it (0 if empty) extract
extract
range of bytes to extract, from beginning if ≤ 0, to end if ≥ length extracts a portion of the BLOB into a new BLOB remove
position, counting from end if < 0 removes a byte at a particular position and returns it (0 if the position is not valid) reverse
none reverses the BLOB byte by byte len
method and property none returns the number of bytes in the BLOB is_empty
method and property none returns true
if the BLOB is empty pad
clear
none empties the BLOB truncate
target length cuts off the BLOB at exactly a specified length (discarding all subsequent bytes) chop
target length cuts off the head of the BLOB, leaving the tail at exactly a specified length contains
, in
operator byte value to find does the BLOB contain a particular byte value? split
drain
drain
range of bytes to remove, from beginning if ≤ 0, to end if ≥ length removes a portion of the BLOB, returning the removed bytes as a new BLOB retain
retain
range of bytes to retain, from beginning if ≤ 0, to end if ≥ length retains a portion of the BLOB, removes all other bytes and returning them as a new BLOB splice
splice
parse_le_int
only_i32
), none if ≤ 0parse_le_int
range of bytes to parse, from beginning if ≤ 0, to end if ≥ length (up to 8 bytes, 4 under only_i32
) parses an integer at the particular offset in little-endian byte order (if not enough bytes, zeros are padded; extra bytes are ignored) parse_be_int
only_i32
), none if ≤ 0parse_be_int
range of bytes to parse, from beginning if ≤ 0, to end if ≥ length (up to 8 bytes, 4 under only_i32
) parses an integer at the particular offset in big-endian byte order (if not enough bytes, zeros are padded; extra bytes are ignored) parse_le_float
no_float
)
f32_float
), none if ≤ 0parse_le_float
no_float
) range of bytes to parse, from beginning if ≤ 0, to end if ≥ length (up to 8 bytes, 4 under f32_float
) parses a floating-point number at the particular offset in little-endian byte order (if not enough bytes, zeros are padded; extra bytes are ignored) parse_be_float
no_float
)
f32_float
), none if ≤ 0parse_be_float
no_float
) range of bytes to parse, from beginning if ≤ 0, to end if ≥ length (up to 8 bytes, 4 under f32_float
) parses a floating-point number at the particular offset in big-endian byte order (if not enough bytes, zeros are padded; extra bytes are ignored) write_le
only_i32
or f32_float
), none if ≤ 0write_le
only_i32
or f32_float
)write_be
only_i32
or f32_float
), none if ≤ 0write_be
only_i32
or f32_float
)write_utf8
write_utf8
write_ascii
write_ascii
RetroSearch is an open source project built by @garambo | Open a GitHub Issue
Search and Browse the WWW like it's 1997 | Search results from DuckDuckGo
HTML:
3.2
| Encoding:
UTF-8
| Version:
0.7.4