Buffer API

Efficient binary data manipulation with typed reads, writes, configurable endianness, and auto-grow buffers.

Overview

The Buffer API provides a powerful way to work with binary data. It supports multiple data types (8/16/32-bit integers, 32/64-bit floats, strings, byte arrays), configurable endianness, automatic position tracking, safe bounds checking, and optional auto-grow when writing beyond capacity.

Creating Buffers

Buffer(size, autoGrow?)

Creates a new buffer with the specified capacity.

Returns: A new Buffer object.

var buf = Buffer(256)
var fixedBuf = Buffer(1024, false)  // No auto-grow

Reading Data

All read methods advance the buffer's position automatically.

Integer Reads

buf.readUInt8()

Reads an unsigned 8-bit integer (0–255).

buf.readInt8()

Reads a signed 8-bit integer (−128 to 127).

buf.readUInt16()

Reads an unsigned 16-bit integer (0–65,535). Respects current endianness.

buf.readInt16()

Reads a signed 16-bit integer (−32,768 to 32,767). Respects current endianness.

buf.readUInt32()

Reads an unsigned 32-bit integer (0–4,294,967,295). Respects current endianness.

buf.readInt32()

Reads a signed 32-bit integer (−2,147,483,648 to 2,147,483,647). Respects current endianness.

Floating Point Reads

buf.readFloat()

Reads a 32-bit IEEE 754 single-precision float. Respects current endianness.

buf.readDouble()

Reads a 64-bit IEEE 754 double-precision float. Respects current endianness.

String & Byte Reads

buf.readString()

Reads a null-terminated string. Stops at the first 0x00 byte and advances past the terminator.

buf.readStringN(count)

Reads exactly count bytes as a string, regardless of null terminators.

buf.readBytes(count)

Reads count bytes and returns them as a list of numbers (0–255).

var bytes = buf.readBytes(5)
// bytes = [72, 101, 108, 108, 111]  (ASCII for "Hello")

Writing Data

All write methods advance the buffer's position automatically. If auto-grow is enabled, the buffer expands as needed.

Integer Writes

buf.writeUInt8(value)

Writes an unsigned 8-bit integer (0–255).

buf.writeInt8(value)

Writes a signed 8-bit integer (−128 to 127).

buf.writeUInt16(value)

Writes an unsigned 16-bit integer. Respects current endianness.

buf.writeInt16(value)

Writes a signed 16-bit integer. Respects current endianness.

buf.writeUInt32(value)

Writes an unsigned 32-bit integer. Respects current endianness.

buf.writeInt32(value)

Writes a signed 32-bit integer. Respects current endianness.

Floating Point Writes

buf.writeFloat(value)

Writes a 32-bit IEEE 754 single-precision float. Respects current endianness.

buf.writeDouble(value)

Writes a 64-bit IEEE 754 double-precision float. Respects current endianness.

String & Byte Writes

buf.writeString(text)

Writes a string followed by a null terminator (0x00).

buf.writeStringRaw(text)

Writes a string without a null terminator.

buf.writeBytes(byteList)

Writes a list of byte values (0–255) to the buffer.

write then read
var buf = Buffer(64)
buf.writeUInt8(255)
buf.writeInt16(-1234)
buf.writeFloat(3.14159)
buf.writeString("Hello")

buf.rewind()
var byte = buf.readUInt8()     // 255
var short = buf.readInt16()    // -1234
var f = buf.readFloat()        // ~3.14159
var text = buf.readString()    // "Hello"
buf.seek(position)

Sets the buffer position to the specified byte offset.

Advances the buffer position by count bytes.

buf.rewind()

Resets the buffer position to 0.

buf.tell()

Returns the current position.

Buffer Management

buf.clear()

Resets the buffer: sets length and position to 0, zeros out all bytes.

buf.fill(byteValue)

Fills the entire buffer with the specified byte value and sets length to capacity.

buf.slice(start, end)

Creates a new buffer containing a copy of the specified range.

Returns: A new Buffer containing the slice.

buf.getLength()

Returns the high water mark (highest position written to).

buf.getCapacity()

Returns the total allocated size of the buffer.

buf.remaining()

Returns the number of bytes remaining between current position and length.

Endianness

buf.setEndianness(endian)

Sets the byte order for multi-byte read/write operations.

buf.getEndianness()

Returns the current byte order setting ("little" or "big").

Default: Little-endian. 8-bit operations are not affected by endianness since they are single bytes.
network byte order
var packet = Buffer(256)
packet.setEndianness("big")  // Network byte order
packet.writeUInt16(0xFFFF)
packet.writeUInt8(1)
packet.writeUInt32(12345)
packet.writeString("Payload")

Conversion Methods

buf.toHex()

Converts the buffer contents (up to length) to a lowercase hexadecimal string.

buf.clear()
buf.writeUInt8(222)  // 0xDE
buf.writeUInt8(173)  // 0xAD
buf.writeUInt8(190)  // 0xBE
buf.writeUInt8(239)  // 0xEF
var hex = buf.toHex()  // "deadbeef"
buf.toString()

Converts the buffer contents (up to first null byte or length) to a string.

Properties

position (native reference)

The position property is a native reference that automatically synchronizes with the internal buffer state. Read and write directly.

var pos = buf.position        // Read position
buf.position = 10             // Set position

buf.writeUInt8(42)
print(buf.position)            // Now 1 higher

buf.position = 1000           // Beyond capacity
print(buf.position)            // Clamped to capacity

Examples

Binary File Format

func serializeRecord(id, name, score) {
    var buf = Buffer(256)
    buf.setEndianness("little")
    buf.writeUInt32(0x52454344)  // Magic "RECD"
    buf.writeUInt16(1)            // Format version
    buf.writeUInt32(id)
    buf.writeString(name)
    buf.writeFloat(score)
    return buf
}

func deserializeRecord(buf) {
    buf.rewind()
    buf.setEndianness("little")
    var magic = buf.readUInt32()
    if (magic != 0x52454344) {
        print("Invalid magic number!")
        return null
    }
    var version = buf.readUInt16()
    var id = buf.readUInt32()
    var name = buf.readString()
    var score = buf.readFloat()
    return {"id": id, "name": name, "score": score}
}

var recordBuf = serializeRecord(42, "Alice", 98.5)
var record = deserializeRecord(recordBuf)

Working with Position

var buf = Buffer(256)
buf.writeUInt32(0x12345678)
var headerEnd = buf.position

buf.writeString("Some data")
var payloadEnd = buf.position

// Go back and update header with payload size
var payloadSize = payloadEnd - headerEnd
buf.position = 0
buf.writeUInt32(payloadSize)

buf.position = payloadEnd
buf.writeUInt8(0xFF)  // Footer
print("Total size: %v bytes", buf.getLength())