UNPKG

binary-structures

Version:

Yet another declarative binary packer/parser, but built for modern browsers.

134 lines (133 loc) 6.85 kB
import 'improved-map'; import { Size } from './serialization'; export declare type Primitive = number | string | ArrayBuffer; export declare type Mapped<T> = Map<string, T>; export declare type Encoded_Map = Mapped<any>; export declare type Encoded_Array = Array<any>; export declare type Encoded = Primitive | Encoded_Map | Encoded_Array; export declare type Map_Context = Encoded_Map; export declare type Array_Context = Encoded_Array; export declare type Context = Encoded; export declare const Parent: unique symbol; export interface Contextualized<P> { [Parent]?: P; } export declare type Context_Type<E extends Encoded, C> = E & Contextualized<C>; export declare type Context_Map<Encoded, Context> = Context_Type<Mapped<Encoded>, Context>; export declare type Context_Array<Encoded, Context> = Context_Type<Array<Encoded>, Context>; export declare type Context_Iterable<Encoded, Context> = Context_Map<Encoded, Context> | Context_Array<Encoded, Context>; export declare type Encoder<Decoded, E extends Encoded, Context> = (decoded: Decoded, context?: Context) => E; export declare type Decoder<E extends Encoded, Decoded, Context> = (encoded: E, context?: Context) => Decoded; export interface Transcoders<E extends Encoded, Decoded, Context> { encode?: Encoder<Decoded, E, Context>; decode?: Decoder<E, Decoded, Context>; little_endian?: boolean; } export declare const inspect_transcoder: <T>(data: T, context?: any) => T; export declare const inspect: { encode: <T>(data: T, context?: any) => T; decode: <T>(data: T, context?: any) => T; }; /** A function to fetch the data to be packed. * It is provided by the code handling the input data and called by the packer function to fetch the data to pack. */ export interface Fetcher<Decoded> { (): Decoded; } /** A function to deliver the parsed result to the correct place. * It is provided by the code managing the results container and called by the parser function with the parsed data. */ export interface Deliver<Decoded> { (data: Decoded): void; } export interface Parse_Options<Context> { byte_offset?: number; little_endian?: boolean; context?: Context; } export interface Pack_Options<C> extends Parse_Options<C> { data_view?: DataView; } export interface Packed { buffer: ArrayBuffer; size: Size; } export interface Parsed<Decoded> { data: Decoded; size: Size; } export interface Packer<Decoded, Context> { (source: Decoded | Fetcher<Decoded>, options?: Pack_Options<Context>): Packed; } export interface Parser<Decoded, Context> { (data_view: DataView, options?: Parse_Options<Context>, deliver?: Deliver<Decoded>): Parsed<Decoded>; } export interface Struct<Decoded, Context> { pack: Packer<Decoded, Context>; parse: Parser<Decoded, Context>; } export declare const Bits: <D, C>(bits: number, transcoders?: Transcoders<string | number, D, C>) => Struct<D, C>; export declare const Uint: <D, C>(bits: number, transcoders?: Transcoders<string | number, D, C>) => Struct<D, C>; export declare const Int: <D, C>(bits: number, transcoders?: Transcoders<string | number, D, C>) => Struct<D, C>; export declare const Float: <D, C>(bits: number, transcoders?: Transcoders<string | number, D, C>) => Struct<D, C>; export declare const Utf8: <D, C>(bits: number, transcoders?: Transcoders<string, D, C>) => Struct<D, C>; export declare type Numeric<C> = number | { bits?: number; bytes?: number; } | ((context?: C) => number); /** Byte_Buffer doesn't do any serialization, but just copies bytes to/from an ArrayBuffer that's a subset of the * serialized buffer. Byte_Buffer only works on byte-aligned data. * * @param {Numeric} length * @param {Transcoders<ArrayBuffer, any>} transcoders */ export declare const Byte_Buffer: <D, C>(length: Numeric<C>, transcoders?: Transcoders<ArrayBuffer, D, C>) => { pack: (source: D | Fetcher<D>, options?: Pack_Options<C>) => Packed; parse: (data_view: DataView, options?: Parse_Options<C>, deliver?: Deliver<D> | undefined) => { data: D; size: number; }; }; export declare const Padding: <C>(bits: Numeric<C>, transcoders?: Transcoders<number, any, C>) => Struct<any, C>; export declare type Chooser<C> = (context?: C) => number | string; export interface Choices<D, C> { [choice: number]: Struct<D, C>; [choice: string]: Struct<D, C>; } export interface Branch<D, C> { chooser: Chooser<C>; choices: Choices<D, C>; default_choice?: Struct<D, C>; } export declare const Branch: <D, C>({ chooser, choices, default_choice }: Branch<D, C>) => Struct<D, C>; export declare const Embed: <D, C extends Context_Iterable<D, S>, S>(embedded: Struct<Context_Iterable<D, S>, S> | Struct<D, C>) => Struct<D | Context_Type<Map<string, D>, S> | Context_Type<D[], S>, C>; export declare type Map_Item<I> = Struct<I, Mapped<I>>; export declare type Map_Iterable<I> = Array<[string, Map_Item<I>]>; export declare type Map_Transcoders<I, D, C> = Transcoders<Mapped<I>, D, C>; export interface Binary_Map<I, D, C> extends Mapped<Map_Item<I>>, Struct<D, C> { pack: (source: D | Fetcher<D>, options?: Pack_Options<C>, encoded?: Context_Map<I, C>) => Packed; parse: (data_view: DataView, options?: Parse_Options<C>, deliver?: Deliver<D>, results?: Context_Map<I, C>) => Parsed<D>; } export declare function Binary_Map<I, D, C>(transcoders?: Map_Transcoders<I, D, C> | Map_Iterable<I>, iterable?: Map_Iterable<I> | Map_Transcoders<I, D, C>): Binary_Map<I, D, C>; export declare namespace Binary_Map { let object_encoder: (obj: any) => Map<any, any>; let object_decoder: (map: Map<any, any>) => any; let object_transcoders: { encode: (obj: any) => Map<any, any>; decode: (map: Map<any, any>) => any; }; } export declare type Array_Item<I> = Struct<I, Array<I>>; export declare type Array_Transcoders<I, D, C> = Transcoders<Array<I>, D, C>; export interface Binary_Array<I, D, C> extends Array<Array_Item<I>>, Struct<D, C> { pack: (source: D | Fetcher<D>, options?: Pack_Options<C>, fetcher?: Fetcher<I>) => Packed; __pack_loop: (fetcher: Fetcher<I>, options: Pack_Options<Array<I>>, store: (result: Packed) => void, parent?: C) => number; parse: (data_view: DataView, options?: Parse_Options<C>, deliver?: Deliver<D>, results?: Context_Array<I, C>) => Parsed<D>; __parse_loop: (data_view: DataView, options: Parse_Options<Context_Array<I, C>>, deliver: Deliver<I>, parent?: C) => number; } export declare const Binary_Array: <I, D, C>(...elements: (Transcoders<I[], D, C> | Struct<I, I[]>)[]) => Binary_Array<I, D, C>; export interface Repeat_Options<I, D, C> extends Array_Transcoders<I, D, C> { count?: Numeric<C>; bytes?: Numeric<C>; } export declare const Repeat: <I, D, C>(...elements: (Repeat_Options<I, D, C> | Struct<I, I[]>)[]) => Binary_Array<I, D, C>;