Skip to content

Add Unpack Method #118

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Open
wants to merge 3 commits into
base: master
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 3 additions & 0 deletions src/builder.ts
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@ import { Span } from './span';
import * as transform from './transform';

export { code, node, transform, Property, PropertyType, Span };
export { Endianess } from "./code";
export { Edge } from './edge';
export { LoopChecker } from './loop-checker';
export { ISpanAllocatorResult, SpanAllocator } from './span-allocator';
Expand Down Expand Up @@ -72,6 +73,8 @@ export class Builder {
otherwise?: node.Node): node.Invoke {
let res: node.Invoke;

// TODO: (Vizonex) Should we add a check for non-existant unpack properties here?

// `.invoke(name)`
if (map === undefined) {
res = new node.Invoke(fn, {});
Expand Down
16 changes: 16 additions & 0 deletions src/code/creator.ts
Original file line number Diff line number Diff line change
Expand Up @@ -181,4 +181,20 @@ export class Creator {
public test(field: string, value: number): code.Test {
return new code.Test(field, value);
}

/**
* Intrinsic operation.
*
* state[field] <<= 8 or >>= 8 (depending on endianess)
* state[field] |= value
* return (state[field] < (property size limit)) ? 0 : -1;
*
* @param field Property Name
* @param endianness Endianness Enum to determine if big
* or little endianness should be accounted for.
* defaults to `Endianess.Little`
*/
public unpack(field: string, endianness?: code.Endianess) : code.Unpack {
return new code.Unpack(field, endianness);
}
}
1 change: 1 addition & 0 deletions src/code/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -13,3 +13,4 @@ export { Store } from './store';
export { Test } from './test';
export { Update } from './update';
export { Value } from './value';
export { Unpack, Endianess } from './unpack';
32 changes: 32 additions & 0 deletions src/code/unpack.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,32 @@
import { Field } from "./field";

/** Options for `code.unpack()` */
export enum Endianess {
Little = 0,
Big = 1
};

/** Helps with making unpacking protocols.
* It unpacks variables via left & right shifting
* based on a given endianness argument
*/
export class Unpack extends Field {
public readonly bigEndian:boolean;
/**
* @param field Name of the property that should be unpacked to
* @param endianness determines how to unpack the value provided
* Default Value: `Endianess.Little`.
*/

constructor (field: string, endianness?:Endianess){
if (endianness === undefined){
endianness = Endianess.Little;
}
super(
'match',
endianness == Endianess.Little ? 'unpack_le' : 'unpack_be',
field
);
this.bigEndian = endianness == Endianess.Big;
}
}
16 changes: 15 additions & 1 deletion test/builder.test.ts
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
import { beforeEach, describe, it, type TestContext } from 'node:test';
import { Builder } from '../src/builder';
import { Builder, Endianess } from '../src/builder';

describe('LLParse/Builder', () => {
let b: Builder;
Expand Down Expand Up @@ -88,4 +88,18 @@ describe('LLParse/Builder', () => {
10,
]);
});

it('should create an unpack for Invoke'), (t: TestContext) => {
const start = b.node('start');
b.property('i16', 'unpack_value');
const unpack_error = b.error(0, 'failed to unpack value');
const invoke = b.invoke(
b.code.unpack('unpack_value', Endianess.Little),
start, unpack_error
);
const otherwise = invoke.getOtherwiseEdge();
t.assert.deepStrictEqual(
otherwise?.node, unpack_error
);
}
});