0.0.2 • Published 1 year ago

@mqix/structured v0.0.2

Weekly downloads
-
License
-
Repository
github
Last release
1 year ago

Structured

This is a library for serialization of javascript objects from and to c like packed structs as an Uint8Array.

Install

npm install @mqix/structured

Or copy the index.js file from the dist folder.

Example

import Structured, { uint32, float32, uint8, bool } from "."

const deviceDataStruct = new Structured(false, true, [
	["deviceId", uint32],
	["temperature", float32],
	["humidity", float32],
	["batteryLevel", uint8],
	["isOnline", bool],
	["location", [
		["latitude", float32],
		["longitude", float32]
	]]
]) 

const bytes = new Uint8Array([...])
const data = deviceDataStruct.fromBytes(bytes)

If you using typescript the object gets infered from the constructor like this below.

const data: {
    deviceId: number;
    temperature: number;
    humidity: number;
    batteryLevel: number;
    isOnline: boolean;
    location: {
        latitude: number;
        longitude: number;
    };
}

And to create an buffer from an object looks like this below.

const responseDataStruct = new Structured(false, true, [
	["deviceId", uint32],
	["valid", bool],
]) 

const responseBytes = responseDataStruct.toBytes({deviceId: 5, valid: true}) 

Structured

/**
 * **Structured**
 * 
 * `cleanEmptySpace` in `writeBytes` needs to be true if you want to make sure all the empty spaces in the value
 * are written as zeros. This is useful when you reuse the `Uint8Array`
 *  
 * The `result` you pass in `readBytes` can be fully reused if it the same shape. In this case it does not create objects unless something is missing. 
 */
class Structured {
    properties: Properties;
    size: number;
    littleEndian: boolean;
    cleanEmptySpace: boolean;
    constructor(littleEndian: boolean, cleanEmptySpace: boolean, struct: T);
    readBytes(bytes: Uint8Array, result: StructToObject<T>, view?: DataView, index?: number, littleEndian?: boolean): void;
    writeBytes(value: StructToObject<T>, bytes: Uint8Array, view?: DataView, index?: number, littleEndian?: boolean, cleanEmptySpace?: boolean): void;
    fromBytes(bytes: Uint8Array): StructToObject<T>;
    toBytes(object: StructToObject<T>): Uint8Array;
}

Types

This libary also has predefined types for the structs.

SymbolJavaScript Type
uint8number
int8number
uint16number
int16number
uint32number
int32number
float32number
float64number
int64bigint
uint64bigint
doublenumber
longbigint
boolboolean
string(size)string

Structured

You could use instance of Structure as a type.

const a = new Structure(true, true, [
  ["value", int16]
])

const b = new Structure(true, true, [
  ["name", string(16)]
  ["a", a] 
])

Or you could use the [["name", type]] syntax for nested types directly.

Arrays

array(size, uint8, true)

The last arguments of array is of type boolean and indicates that it should leave out values where all its bytes are zero in the result.

Union Types

union([
  ["a", uint8],
  ["b", string(10)]
])

Custom Types

If you need a custom type you can create your own. you just need to follow the interface below that all types are based on.

/**
 * **StructuredType**
 * 
 * This is the interface that all the types have.
 *
 * `size` is the fixed ammount of bytes the type consumes in the memory layout.
 *
 * if `cleanEmptySpace` in `writeBytes` is true the  unused bytes of the type to be set to zero in the `bytes`.
 *  
 * Implement `fromBytes` if you want to create an inmutable type.
 * Else if you want to create mutable type you need implement the `readBytes` function.
 * You cant have both.
 */
export interface StructuredType<T> {
	size: number
	fromBytes?(bytes: Uint8Array, view: DataView, index: number, littleEndian: boolean): T
	readBytes?(bytes: Uint8Array, result: T, view: DataView, index: number, littleEndian: boolean): void
	writeBytes(value: T, bytes: Uint8Array, view: DataView, index: number, littleEndian: boolean, cleanEmptySpace: boolean): void
}
0.0.2

1 year ago

0.0.1

1 year ago

0.0.0

1 year ago