typed-cstruct
    Preparing search index...

    typed-cstruct

    typed-cstruct

    Read and write a binary C struct, Use it as a JavaScript object (Off course, it's fully typed).

    npm install typed-cstruct
    
    import {
    Struct,
    u8, i16, f32,
    sizedArray, sizedCharArrayAsString, enumLike, convert, defineBuilder
    } from "typed-cstruct";

    // 0. Check the struct definition
    // struct {
    // uint8_t a;
    // int16_t b;
    // float c;
    // } buf = { 1, 0x0302, 1.0f };
    const buf = new Uint8Array([
    0x01, // a
    0x02, 0x03, // b
    0x00, 0x00, 0x80, 0x3f // c
    ]);

    // 1. Define a struct
    const struct = new Struct()
    .field("a", u8) // unsigned 8-bit(1-byte) integer
    .field("b", i16) // 16-bit(2-byte) integer
    .field("c", f32); // 32-bit(4-byte) float

    // 2a. Read a struct from a buffer
    const obj = struct.read({ buf });
    console.log(obj); // => { a: 1, b: 770, c: 1 } == { a: 1, b: 0x0302, c: 1.0 }

    // 2b. Write a struct to a buffer
    const newBuf = new Uint8Array(7);
    struct.write({ a: 2, b: 0x0403, c: 2.0 }, { buf: newBuf });
    console.log(newBuf); // => Uint8Array [ 2, 4, 3, 0, 0, 0, 64 ]

    // 2c. Overwrite a field
    struct.proxy({ buf: newBuf }).a = 3;
    console.log(newBuf); // => Uint8Array [ 3, 4, 3, 0, 0, 0, 64 ]

    // 2d. Get size of a struct
    console.log(struct.size); // => 7

    You can specify the offset to read a struct from a buffer.

    struct.read({ buf, offset: 1 }); // Skip the first byte
    

    You can specify the endian of a struct. (default: little)

    const struct = new Struct({ buf, endian: "big" });
    

    You can define an array field.

    // struct {
    // uint8_t a;
    // int16_t b[3];
    // } buf = { 1, { 0x0102, 0x0304, 0x0506 } };
    const struct = new Struct()
    .field("a", u8)
    .field("b", sizedArray(i16, 3)); // 3 x 16-bit(2-byte) integers

    You can define a nested struct.

    // struct {
    // uint8_t a;
    // struct {
    // int16_t b;
    // float c;
    // } d;
    // } buf = { 1, { 0x0203, 1.0f } };
    const struct = new Struct()
    .field("a", u8)
    .field("d", new Struct()
    .field("b", i16)
    .field("c", f32));

    You can define a string field.

    // struct {
    // uint8_t a;
    // char b[4];
    // } buf = { 1, "foo" };
    const struct = new Struct()
    .field("a", u8)
    .field("b", sizedCharArrayAsString(4)); // 4-byte string

    Default encoding is utf8. You can specify the encoding and decoding functions.

    const encode = (str) => new Uint8Array(str.split("").map((c) => c.charCodeAt(0)));
    const decode = (buf) => buf.map((c) => String.fromCharCode(c)).join("");
    const struct = new Struct()
    .field("a", u8)
    .field("b", sizedCharArrayAsString(4, { encode, decode })); // 4-byte string

    You can define an enum field.

    // struct {
    // uint8_t a;
    // enum {
    // FOO = 1,
    // BAR = 2,
    // BAZ = 3
    // } b;
    // } buf = { 1, 2 };
    const struct = new Struct()
    .field("a", u8)
    .field("b", enumLike(u8, { 1: 'FOO', 2: 'BAR', 3: 'BAZ' } as const));
    const buf = new Uint8Array([0x01, 0x02]);
    const obj = struct.read({ buf });
    console.log(obj); // => { a: 1, b: 'BAR' }

    You can define a custom field.

    // struct {
    // uint8_t a;
    // uint8_t pos[2];
    // }
    const position = defineBuilder({ // define custom builder
    size: 2,
    read(opts) {
    const offset = opts.offset || 0;
    return { x: u8.read({ ...opts, offset }), y: u8.read({ ...opts, offset: offset + 1 }) };
    },
    });
    const struct = new Struct()
    .field("a", u8)
    .field("pos", position);
    const buf = new Uint8Array([0x01, 0x02, 0x03]);
    const obj = struct.read({ buf });
    console.log(obj); // => { a: 1, pos: { x: 2, y: 3 } }

    You can use convert function to convert a value (readonly).

    const struct = new Struct()
    .field("a", u8)
    .field("pos", convert(sizedArray(u8, 2), ([x, y]) => ({ x, y })));
    const buf = new Uint8Array([0x01, 0x02, 0x03]);
    const obj = struct.read({ buf });
    console.log(obj); // => { a: 1, pos: { x: 2, y: 3 } }

    MIT