or run

npx @tessl/cli init
Log in

Version

Tile

Overview

Evals

Files

docs

buffer-conversion.mdbuffer-management.mdfloating-point-operations.mdindex.mdinteger-operations.mdstring-operations.mdvarint-operations.md
tile.json

buffer-conversion.mddocs/

Buffer Conversion and Encoding

Convert between different buffer formats and encode/decode using various schemes. ByteBuffer provides comprehensive conversion capabilities for interoperability with different JavaScript buffer types and multiple string encoding formats.

Capabilities

Buffer Format Conversion

Convert ByteBuffer to different buffer formats for compatibility with other libraries and APIs.

/**
 * Convert to Node.js Buffer
 * @param {boolean} forceCopy - Force copying even if backing buffer is already a Buffer (default: false)
 * @returns {Buffer} Node.js Buffer containing the data
 */
toBuffer(forceCopy);

/**
 * Convert to ArrayBuffer (browser compatible)
 * @returns {ArrayBuffer} ArrayBuffer containing the data
 */
toArrayBuffer();

Usage Examples:

const ByteBuffer = require("bytebuffer");
const bb = ByteBuffer.allocate(16);

// Write some data
bb.writeInt32(42);
bb.writeFloat32(3.14);

// Convert to Node.js Buffer
const nodeBuffer = bb.toBuffer();
console.log(nodeBuffer instanceof Buffer); // true
console.log(Array.from(nodeBuffer));       // [0, 0, 0, 42, 64, 72, 245, 195] (or similar)

// Convert to ArrayBuffer (works in browser and Node.js)
const arrayBuffer = bb.toArrayBuffer();
console.log(arrayBuffer instanceof ArrayBuffer); // true
console.log(arrayBuffer.byteLength);             // 16

// Force copy even if already a Buffer
const copyBuffer = bb.toBuffer(true);
console.log(copyBuffer !== nodeBuffer); // true (different object)

// Use with other APIs
const uint8View = new Uint8Array(arrayBuffer);
const dataView = new DataView(arrayBuffer);
console.log(dataView.getInt32(0)); // 42 (reading the written int32)

String Encoding Conversion

Convert buffer contents to various string encodings and create ByteBuffers from encoded strings.

/**
 * Convert buffer to string using specified encoding
 * @param {string} encoding - Encoding type ('base64', 'hex', 'binary', 'utf8', 'debug')
 *   Note: 'columns' encoding is non-functional due to implementation bug
 * @param {number} begin - Start offset (default: 0)
 * @param {number} end - End offset (default: limit)
 * @returns {string} Encoded string representation
 */
toString(encoding, begin, end);

/**
 * Convert buffer to Base64 string
 * @param {number} begin - Start offset (default: 0)
 * @param {number} end - End offset (default: limit)
 * @returns {string} Base64 encoded string
 */
toBase64(begin, end);

/**
 * Convert buffer to hexadecimal string
 * @param {number} begin - Start offset (default: 0)
 * @param {number} end - End offset (default: limit)
 * @returns {string} Hexadecimal string (lowercase)
 */
toHex(begin, end);

/**
 * Convert buffer to binary string (each byte as character)
 * @param {number} begin - Start offset (default: 0)
 * @param {number} end - End offset (default: limit)
 * @returns {string} Binary string representation
 */
toBinary(begin, end);

/**
 * Convert buffer to UTF-8 string
 * @param {number} begin - Start offset (default: 0)
 * @param {number} end - End offset (default: limit)
 * @returns {string} UTF-8 decoded string
 */
toUTF8(begin, end);

/**
 * Convert buffer to debug format (hex dump with ASCII)
 * @param {number} columns - Number of bytes per row (default: 16)
 * @returns {string} Debug formatted string
 */
toDebug(columns);

/**
 * Convert buffer to columnar debug format (deprecated/non-functional)
 * Note: This method is referenced in toString() but not implemented
 * Use toDebug() instead for debug formatting
 * @returns {string} Multi-line hex dump format
 */
// toColumns(); // Non-functional - use toDebug() instead

Usage Examples:

const bb = ByteBuffer.allocate(32);

// Write mixed data
bb.writeUTF8String("Hello");
bb.writeInt32(0x12345678);
bb.writeFloat32(3.14);

// Convert to different string formats
const base64 = bb.toBase64();
const hex = bb.toHex();
const binary = bb.toBinary();
const utf8 = bb.toUTF8();

console.log("Base64:", base64);    // "SGVsbG8SNN$%something..."
console.log("Hex:", hex);          // "48656c6c6f12345678..."
console.log("Binary:", binary);    // "Hello4Vx..." (binary representation)
console.log("UTF-8:", utf8);       // "Hello4Vx@..." (may have invalid UTF-8)

// Convert specific ranges
bb.flip();
const firstFive = bb.toHex(0, 5);      // Just "Hello" in hex
const lastFour = bb.toHex(-4);         // Last 4 bytes

console.log("First 5 bytes:", firstFive); // "48656c6c6f"
console.log("Last 4 bytes:", lastFour);

// Debug output
const debugOutput = bb.toDebug();
console.log("Debug format:");
console.log(debugOutput);
// Output like:
// 00000000  48 65 6c 6c 6f 12 34 56  78 40 48 f5 c3 00 00 00  |Hello.4Vx@H.....|

// Note: toColumns() method doesn't exist in implementation
// Use toDebug() with different column widths instead
const narrowDebug = bb.toDebug(8);  // 8 bytes per row
console.log("Narrow format:");
console.log(narrowDebug);

Factory Methods from Encodings

Create ByteBuffer instances from various string encodings.

/**
 * Create ByteBuffer from Base64 encoded string
 * @param {string} str - Base64 encoded string
 * @param {boolean} littleEndian - Use little endian byte order (default: false)
 * @returns {ByteBuffer} New ByteBuffer with decoded data
 */
ByteBuffer.fromBase64(str, littleEndian);

/**
 * Create ByteBuffer from hexadecimal string
 * @param {string} str - Hexadecimal string (with or without spaces/separators)
 * @param {boolean} littleEndian - Use little endian byte order (default: false)
 * @param {boolean} noAssert - Skip assertions (default: false)
 * @returns {ByteBuffer} New ByteBuffer with decoded data
 */
ByteBuffer.fromHex(str, littleEndian, noAssert);

/**
 * Create ByteBuffer from binary string
 * @param {string} str - Binary string (each character represents one byte)
 * @param {boolean} littleEndian - Use little endian byte order (default: false)
 * @returns {ByteBuffer} New ByteBuffer with decoded data
 */
ByteBuffer.fromBinary(str, littleEndian);

/**
 * Create ByteBuffer from UTF-8 string
 * @param {string} str - UTF-8 string to encode
 * @param {boolean} littleEndian - Use little endian byte order (default: false)
 * @param {boolean} noAssert - Skip assertions (default: false)
 * @returns {ByteBuffer} New ByteBuffer with UTF-8 encoded data
 */
ByteBuffer.fromUTF8(str, littleEndian, noAssert);

/**
 * Create ByteBuffer from debug format string
 * @param {string} str - Debug format string (hex dump)
 * @param {boolean} littleEndian - Use little endian byte order (default: false)
 * @param {boolean} noAssert - Skip assertions (default: false)
 * @returns {ByteBuffer} New ByteBuffer with decoded data
 */
ByteBuffer.fromDebug(str, littleEndian, noAssert);

Usage Examples:

// Create from Base64
const base64Data = "SGVsbG8gV29ybGQ="; // "Hello World" in Base64
const bbFromBase64 = ByteBuffer.fromBase64(base64Data);
bbFromBase64.flip();
const decodedText = bbFromBase64.readUTF8String(11);
console.log(decodedText); // "Hello World"

// Create from hexadecimal
const hexData = "48656c6c6f20576f726c64"; // "Hello World" in hex
const bbFromHex = ByteBuffer.fromHex(hexData);
bbFromHex.flip();
const hexDecodedText = bbFromHex.readUTF8String(11);
console.log(hexDecodedText); // "Hello World"

// Hex string with separators (spaces, colons, etc.)
const formattedHex = "48:65:6c:6c:6f 20 57-6f-72-6c-64";
const bbFromFormattedHex = ByteBuffer.fromHex(formattedHex);

// Create from binary string
const binaryData = "Hello World"; // Each character = one byte
const bbFromBinary = ByteBuffer.fromBinary(binaryData);

// Create from UTF-8
const utf8Text = "Hello ไธ–็•Œ ๐ŸŒ";
const bbFromUTF8 = ByteBuffer.fromUTF8(utf8Text);
console.log(bbFromUTF8.limit); // Byte length of UTF-8 encoded string

// Create from debug format
const debugStr = `00000000  48 65 6c 6c 6f 20 57 6f  72 6c 64 00 00 00 00 00  |Hello World.....|`;
const bbFromDebug = ByteBuffer.fromDebug(debugStr);

Browser Compatibility Functions

Polyfill functions for Base64 encoding/decoding that work across environments.

/**
 * Binary string to Base64 (like window.btoa)
 * @param {string} str - Binary string to encode
 * @returns {string} Base64 encoded string
 */
ByteBuffer.btoa(str);

/**
 * Base64 to binary string (like window.atob)
 * @param {string} b64 - Base64 string to decode
 * @returns {string} Binary string
 */
ByteBuffer.atob(b64);

Usage Examples:

// These work in both Node.js and browsers
const binaryString = "Hello World";
const encoded = ByteBuffer.btoa(binaryString);
const decoded = ByteBuffer.atob(encoded);

console.log("Original:", binaryString);     // "Hello World"
console.log("Encoded:", encoded);           // "SGVsbG8gV29ybGQ="
console.log("Decoded:", decoded);           // "Hello World"

// Useful for cross-platform Base64 operations
const bb = ByteBuffer.allocate(16);
bb.writeUTF8String("Test");
const binaryData = bb.toBinary();
const base64Data = ByteBuffer.btoa(binaryData);
console.log("Cross-platform Base64:", base64Data);

Conversion Workflows

Common patterns for converting between different formats.

Usage Examples:

// Workflow 1: ByteBuffer -> Node.js Buffer -> Base64
const bb1 = ByteBuffer.allocate(8);
bb1.writeInt32(0x12345678);
bb1.writeInt32(0x9ABCDEF0);

const nodeBuffer = bb1.toBuffer();
const base64FromBuffer = nodeBuffer.toString('base64');
console.log("Via Node Buffer:", base64FromBuffer);

// Workflow 2: ByteBuffer -> Base64 directly
const base64Direct = bb1.toBase64();
console.log("Direct Base64:", base64Direct);
console.log("Same result:", base64FromBuffer === base64Direct);

// Workflow 3: Hex -> ByteBuffer -> ArrayBuffer -> TypedArray
const hexInput = "0123456789abcdef";
const bbFromHex = ByteBuffer.fromHex(hexInput);
const arrayBuffer = bbFromHex.toArrayBuffer();
const uint32View = new Uint32Array(arrayBuffer);

console.log("Uint32 values:", Array.from(uint32View));

// Workflow 4: Round-trip conversion test
const originalData = new Uint8Array([1, 2, 3, 4, 5]);
const bbRoundTrip = ByteBuffer.wrap(originalData);
const backToUint8 = new Uint8Array(bbRoundTrip.toArrayBuffer());

console.log("Round trip success:", 
    Array.from(originalData).toString() === Array.from(backToUint8).toString());

Advanced Encoding Operations

Working with partial ranges and encoding options.

Usage Examples:

const bb = ByteBuffer.allocate(32);

// Write structured data
bb.writeUTF8String("Header:");
const headerEnd = bb.offset;
bb.writeInt32(0x12345678);
bb.writeInt32(0x9ABCDEF0);
const dataEnd = bb.offset;
bb.writeUTF8String("Footer");

// Convert specific sections
const headerHex = bb.toHex(0, headerEnd);
const dataHex = bb.toHex(headerEnd, dataEnd);
const footerHex = bb.toHex(dataEnd);

console.log("Header hex:", headerHex);    // "4865616465723a"
console.log("Data hex:", dataHex);       // "123456789abcdef0"
console.log("Footer hex:", footerHex);   // "466f6f746572"

// Full buffer debug output
console.log("Full debug:");
console.log(bb.toDebug(8));  // 8 bytes per row

// Create composite from parts
const composite = ByteBuffer.concat([
    ByteBuffer.fromHex(headerHex),
    ByteBuffer.fromHex(dataHex),
    ByteBuffer.fromHex(footerHex)
]);

console.log("Composite matches original:", 
    composite.toHex() === bb.toHex());

Debug and Inspection Tools

Tools for debugging and inspecting buffer contents.

/**
 * Print debug information to console
 * @param {function} out - Output function (default: console.log)
 */
printDebug(out);

Usage Examples:

const bb = ByteBuffer.allocate(24);

// Fill with test data
bb.writeUTF8String("Test");
bb.writeInt16(0x1234);
bb.writeFloat32(3.14159);
bb.writeInt64(Long.fromString("9876543210"));

// Print debug info
bb.printDebug(); // Outputs to console.log

// Custom output function
const debugLines = [];
bb.printDebug(line => debugLines.push(line));
console.log("Captured debug output:");
debugLines.forEach(line => console.log("  " + line));

// Compare debug formats
console.log("\ntoDebug():");
console.log(bb.toDebug());

console.log("\nCustom debug format:");
console.log(bb.toDebug(16)); // 16 bytes per row instead

// Debug with different column widths
console.log("\n8 bytes per row:");
console.log(bb.toDebug(8));

console.log("\n32 bytes per row:");
console.log(bb.toDebug(32));

Error Handling

Conversion operations may encounter various error conditions:

  • Error: Invalid encoding format or malformed encoded strings
  • RangeError: Insufficient buffer capacity for conversion
  • TypeError: Invalid input types for conversion functions
  • Error: Unsupported operations in specific environments

Example Error Handling:

try {
    // Invalid Base64 string
    const invalid = ByteBuffer.fromBase64("Invalid Base64!");
} catch (error) {
    console.error("Base64 decode error:", error.message);
}

try {
    // Invalid hex string
    const invalidHex = ByteBuffer.fromHex("gg"); // 'g' is not valid hex
} catch (error) {
    console.error("Hex decode error:", error.message);
}

try {
    // Reading beyond buffer for conversion
    const small = ByteBuffer.allocate(4);
    small.writeInt32(42);
    const hex = small.toHex(0, 100); // Trying to read beyond limit
} catch (error) {
    console.error("Range error:", error.message);
}

// Safe conversion with error handling
function safeToBase64(bb) {
    try {
        return bb.toBase64();
    } catch (error) {
        console.error("Conversion failed:", error.message);
        return null;
    }
}

Performance Considerations

  • String encoding/decoding operations have computational overhead
  • Base64 conversion is slower than hex due to complex encoding rules
  • Debug format generation is expensive and should only be used for debugging
  • ArrayBuffer/Buffer conversion may involve memory copying depending on the backing buffer type
  • Large buffer conversions may impact performance and memory usage

Performance Tips:

// Prefer direct ByteBuffer operations over conversions
const bb = ByteBuffer.allocate(1000);
// Good: Direct operations
bb.writeInt32(42);
bb.writeFloat32(3.14);

// Less efficient: Convert to other formats unnecessarily
const buffer = bb.toBuffer();
const arrayBuffer = bb.toArrayBuffer();

// Use appropriate encoding for the use case
// Hex: Good for debugging, less efficient for storage
// Base64: Good for text protocols, more compact than hex
// Binary: Most efficient but limited to compatible contexts