diff --git a/src/builder.ts b/src/builder.ts index a335a85..cb158eb 100644 --- a/src/builder.ts +++ b/src/builder.ts @@ -38,6 +38,22 @@ export class Builder { return new node.Match(name); } + public intBE(name: string, bytes: number): node.Int { + return new node.Int(name, bytes, true, false); + } + + public intLE(name: string, bytes: number): node.Int { + return new node.Int(name, bytes, true, true); + } + + public uIntBE(name: string, bytes: number): node.Int { + return new node.Int(name, bytes, false, false); + } + + public uIntLE(name: string, bytes: number): node.Int { + return new node.Int(name, bytes, false, true); + } + /** * Create terminal error node. Returns error code to user, and sets reason * in the parser's state object. diff --git a/src/node/index.ts b/src/node/index.ts index e3d5fe5..20f95b3 100644 --- a/src/node/index.ts +++ b/src/node/index.ts @@ -6,3 +6,4 @@ export { Match } from './match'; export { Pause } from './pause'; export { SpanStart } from './span-start'; export { SpanEnd } from './span-end'; +export { Int } from './int'; diff --git a/src/node/int.ts b/src/node/int.ts new file mode 100644 index 0000000..5700f6a --- /dev/null +++ b/src/node/int.ts @@ -0,0 +1,28 @@ +import * as assert from 'assert'; + +import { Node } from './base'; + +function buildName(field: string, bytes: number, signed: boolean, littleEndian: boolean) { + const type = signed ? 'int' : 'uint'; + const bits = bytes * 8; + const endianness = littleEndian ? 'le' : 'be'; + + if (bytes > 1) { + return `${field}_${type}_${bits}_${endianness}`; + } else { + return `${field}_${type}_${bits}`; + } +} + +export class Int extends Node { + /** + * @param field State's property name + */ + constructor(public readonly field: string, public readonly bytes: number, public readonly signed: boolean, public readonly littleEndian: boolean) { + super(buildName(field, bytes, signed, littleEndian)); + + if (/^_/.test(field)) { + throw new Error(`Can't use internal field in \`Int\`: "${field}"`); + } + } +}