Skip to content
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

refactor: add additional parsers and tests #1524

Open
wants to merge 4 commits into
base: arthur/parser-combinator
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from 1 commit
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
184 changes: 184 additions & 0 deletions src/parser/index.ts
Expand Up @@ -635,6 +635,190 @@
}
}


// Temporary buffers to convert numbers.
const float32Array = new Float32Array(1);
const uInt8Float32Array = new Uint8Array(float32Array.buffer);
const float64Array = new Float64Array(1);
const uInt8Float64Array = new Uint8Array(float64Array.buffer);

// Check endianness.
float32Array[0] = -1; // 0xBF800000
// Either it is [0, 0, 128, 191] or [191, 128, 0, 0]. It is not possible to
// check this with `os.endianness()` because that is determined at compile time.
const bigEndian = uInt8Float32Array[3] === 0;
Comment on lines +679 to +689
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Taken from base Node buffer.js


class Float extends Parser<number> {
index: number;
result: 0;
floatLe: boolean;
constructor(le: boolean, dataLength: number) {
super();

Check warning on line 656 in src/parser/index.ts

View check run for this annotation

Codecov / codecov/patch

src/parser/index.ts#L656

Added line #L656 was not covered by tests

this.index = 0;
this.result = 0;
this.floatLe = le;

Check warning on line 660 in src/parser/index.ts

View check run for this annotation

Codecov / codecov/patch

src/parser/index.ts#L658-L660

Added lines #L658 - L660 were not covered by tests
}

parse(buffer: Buffer, offset: number): Result<number> {

if (this.floatLe) {
return bigEndian ? this.readFloatBackwards(buffer, offset) : this.readFloatForwards(buffer, offset);
} else {
return bigEndian ? this.readFloatForwards(buffer, offset) : this.readFloatBackwards(buffer, offset);
}
}

readFloatBackwards(buffer: Buffer, offset: number): Result<number> {
const dataLength = 4;
while (this.index < dataLength) {

Check warning on line 674 in src/parser/index.ts

View check run for this annotation

Codecov / codecov/patch

src/parser/index.ts#L673-L674

Added lines #L673 - L674 were not covered by tests
if (offset === buffer.length) {
return { done: false, value: undefined, offset: offset };

Check warning on line 676 in src/parser/index.ts

View check run for this annotation

Codecov / codecov/patch

src/parser/index.ts#L676

Added line #L676 was not covered by tests
}

uInt8Float32Array[dataLength - 1 - this.index++] = buffer[offset++];

Check warning on line 679 in src/parser/index.ts

View check run for this annotation

Codecov / codecov/patch

src/parser/index.ts#L679

Added line #L679 was not covered by tests

}
return { done: true, value: float32Array[0], offset: offset };

Check warning on line 682 in src/parser/index.ts

View check run for this annotation

Codecov / codecov/patch

src/parser/index.ts#L682

Added line #L682 was not covered by tests
}

readFloatForwards(buffer: Buffer, offset: number): Result<number> {
const dataLength = 4;
while (this.index < dataLength) {

Check warning on line 687 in src/parser/index.ts

View check run for this annotation

Codecov / codecov/patch

src/parser/index.ts#L686-L687

Added lines #L686 - L687 were not covered by tests
if (offset === buffer.length) {
return { done: false, value: undefined, offset: offset };

Check warning on line 689 in src/parser/index.ts

View check run for this annotation

Codecov / codecov/patch

src/parser/index.ts#L689

Added line #L689 was not covered by tests
}

uInt8Float32Array[this.index++] = buffer[offset++];

Check warning on line 692 in src/parser/index.ts

View check run for this annotation

Codecov / codecov/patch

src/parser/index.ts#L692

Added line #L692 was not covered by tests

}
return { done: true, value: float32Array[0], offset: offset };

Check warning on line 695 in src/parser/index.ts

View check run for this annotation

Codecov / codecov/patch

src/parser/index.ts#L695

Added line #L695 was not covered by tests
}

}

export class FloatLE extends Float {

constructor() {
super(true, 4);

Check warning on line 703 in src/parser/index.ts

View check run for this annotation

Codecov / codecov/patch

src/parser/index.ts#L703

Added line #L703 was not covered by tests
}

parse(buffer: Buffer, offset: number): Result<number> {
const dataLength = 4;

Check warning on line 707 in src/parser/index.ts

View check run for this annotation

Codecov / codecov/patch

src/parser/index.ts#L707

Added line #L707 was not covered by tests

// Fast path, buffer has all data available
if (offset + dataLength <= buffer.length) {
return { done: true, value: buffer.readFloatLE(offset), offset: offset + dataLength };

Check warning on line 711 in src/parser/index.ts

View check run for this annotation

Codecov / codecov/patch

src/parser/index.ts#L711

Added line #L711 was not covered by tests
}

return super.parse(buffer, offset);

Check warning on line 714 in src/parser/index.ts

View check run for this annotation

Codecov / codecov/patch

src/parser/index.ts#L714

Added line #L714 was not covered by tests
}
}

export class FloatBE extends Float {

constructor() {
super(false, 4);

Check warning on line 721 in src/parser/index.ts

View check run for this annotation

Codecov / codecov/patch

src/parser/index.ts#L721

Added line #L721 was not covered by tests
}

parse(buffer: Buffer, offset: number): Result<number> {
const dataLength = 4;

Check warning on line 725 in src/parser/index.ts

View check run for this annotation

Codecov / codecov/patch

src/parser/index.ts#L725

Added line #L725 was not covered by tests

// Fast path, buffer has all data available
if (offset + dataLength <= buffer.length) {
return { done: true, value: buffer.readFloatBE(offset), offset: offset + dataLength };

Check warning on line 729 in src/parser/index.ts

View check run for this annotation

Codecov / codecov/patch

src/parser/index.ts#L729

Added line #L729 was not covered by tests
}

return super.parse(buffer, offset);

Check warning on line 732 in src/parser/index.ts

View check run for this annotation

Codecov / codecov/patch

src/parser/index.ts#L732

Added line #L732 was not covered by tests
}
}


class Double extends Parser<number> {
index: number;
result: 0;
doubleLe: boolean;
constructor(le: boolean, dataLength: number) {
super();

Check warning on line 742 in src/parser/index.ts

View check run for this annotation

Codecov / codecov/patch

src/parser/index.ts#L742

Added line #L742 was not covered by tests

this.index = 0;
this.result = 0;
this.doubleLe = le;

Check warning on line 746 in src/parser/index.ts

View check run for this annotation

Codecov / codecov/patch

src/parser/index.ts#L744-L746

Added lines #L744 - L746 were not covered by tests
}

parse(buffer: Buffer, offset: number): Result<number> {

if (this.doubleLe) {
return bigEndian ? this.readDoubleBackwards(buffer, offset) : this.readDoubleForwards(buffer, offset);
} else {
return bigEndian ? this.readDoubleForwards(buffer, offset) : this.readDoubleBackwards(buffer, offset);
}
}

readDoubleBackwards(buffer: Buffer, offset: number): Result<number> {
const dataLength = 8;
while (this.index < dataLength) {

Check warning on line 760 in src/parser/index.ts

View check run for this annotation

Codecov / codecov/patch

src/parser/index.ts#L759-L760

Added lines #L759 - L760 were not covered by tests
if (offset === buffer.length) {
return { done: false, value: undefined, offset: offset };

Check warning on line 762 in src/parser/index.ts

View check run for this annotation

Codecov / codecov/patch

src/parser/index.ts#L762

Added line #L762 was not covered by tests
}

uInt8Float64Array[dataLength - 1 - this.index++] = buffer[offset++];

Check warning on line 765 in src/parser/index.ts

View check run for this annotation

Codecov / codecov/patch

src/parser/index.ts#L765

Added line #L765 was not covered by tests

}
return { done: true, value: float64Array[0], offset: offset };

Check warning on line 768 in src/parser/index.ts

View check run for this annotation

Codecov / codecov/patch

src/parser/index.ts#L768

Added line #L768 was not covered by tests
}

readDoubleForwards(buffer: Buffer, offset: number): Result<number> {
const dataLength = 8;
while (this.index < dataLength) {

Check warning on line 773 in src/parser/index.ts

View check run for this annotation

Codecov / codecov/patch

src/parser/index.ts#L772-L773

Added lines #L772 - L773 were not covered by tests
if (offset === buffer.length) {
return { done: false, value: undefined, offset: offset };

Check warning on line 775 in src/parser/index.ts

View check run for this annotation

Codecov / codecov/patch

src/parser/index.ts#L775

Added line #L775 was not covered by tests
}

uInt8Float64Array[this.index++] = buffer[offset++];

Check warning on line 778 in src/parser/index.ts

View check run for this annotation

Codecov / codecov/patch

src/parser/index.ts#L778

Added line #L778 was not covered by tests

}
return { done: true, value: float64Array[0], offset: offset };

Check warning on line 781 in src/parser/index.ts

View check run for this annotation

Codecov / codecov/patch

src/parser/index.ts#L781

Added line #L781 was not covered by tests
}

}

export class DoubleLE extends Double {

constructor() {
super(true, 8);

Check warning on line 789 in src/parser/index.ts

View check run for this annotation

Codecov / codecov/patch

src/parser/index.ts#L789

Added line #L789 was not covered by tests
}

parse(buffer: Buffer, offset: number): Result<number> {
const dataLength = 8;

Check warning on line 793 in src/parser/index.ts

View check run for this annotation

Codecov / codecov/patch

src/parser/index.ts#L793

Added line #L793 was not covered by tests

// Fast path, buffer has all data available
if (offset + dataLength <= buffer.length) {
return { done: true, value: buffer.readDoubleLE(offset), offset: offset + dataLength };

Check warning on line 797 in src/parser/index.ts

View check run for this annotation

Codecov / codecov/patch

src/parser/index.ts#L797

Added line #L797 was not covered by tests
}

return super.parse(buffer, offset);

Check warning on line 800 in src/parser/index.ts

View check run for this annotation

Codecov / codecov/patch

src/parser/index.ts#L800

Added line #L800 was not covered by tests
}
}

export class DoubleBE extends Double {

constructor() {
super(false, 8);

Check warning on line 807 in src/parser/index.ts

View check run for this annotation

Codecov / codecov/patch

src/parser/index.ts#L807

Added line #L807 was not covered by tests
}

parse(buffer: Buffer, offset: number): Result<number> {
const dataLength = 8;

Check warning on line 811 in src/parser/index.ts

View check run for this annotation

Codecov / codecov/patch

src/parser/index.ts#L811

Added line #L811 was not covered by tests

// Fast path, buffer has all data available
if (offset + dataLength <= buffer.length) {
return { done: true, value: buffer.readDoubleBE(offset), offset: offset + dataLength };

Check warning on line 815 in src/parser/index.ts

View check run for this annotation

Codecov / codecov/patch

src/parser/index.ts#L815

Added line #L815 was not covered by tests
}

return super.parse(buffer, offset);

Check warning on line 818 in src/parser/index.ts

View check run for this annotation

Codecov / codecov/patch

src/parser/index.ts#L818

Added line #L818 was not covered by tests
}
}

class NVarbyte extends Parser<Buffer> {
length: UInt8 | UInt16LE | UInt32LE;

Expand Down