Skip to content

Commit 2caa1ab

Browse files
committedSep 13, 2024
Strictless Output Persistence
#31 #51 https://lifesigns1.bandcamp.com/album/lifesigns Funny how in the first issue, I wasn't liking the new GitHub UI at the time, now I don't mind it, and it does look really nice :D This first one is specifically for the persistence of the read offset when `strict` mode is disabled. It is only accessible with a getter on the NBTData object, and it will return `null` otherwise, when strict mode is enabled (still on by default). This is initially to set up allowing for easier test-parsing of files with adjacent content, like Bedrock's LevelDB entries. With NBTify currently not easily making the previous offset accessible, it makes it hard to deduce where the next reading step should start from. This simply adds that transparency on it's own. I may rework the method by how the NBTData object handles this, make it a little tidier. 4664e4c
1 parent 34ea2ba commit 2caa1ab

File tree

5 files changed

+26
-4
lines changed

5 files changed

+26
-4
lines changed
 

‎src/format.ts

+12
Original file line numberDiff line numberDiff line change
@@ -23,6 +23,7 @@ export class NBTData<T extends RootTagLike = RootTag> implements Format {
2323
endian: Endian;
2424
compression: Compression;
2525
bedrockLevel: BedrockLevel;
26+
#byteOffset: typeof this.byteOffset = null;
2627

2728
constructor(data: T | NBTData<T>, options: NBTDataOptions = {}) {
2829
if (data instanceof NBTData) {
@@ -50,6 +51,17 @@ export class NBTData<T extends RootTagLike = RootTag> implements Format {
5051
this.bedrockLevel = bedrockLevel;
5152
}
5253

54+
get byteOffset(): number | null {
55+
return this.#byteOffset;
56+
}
57+
58+
/**
59+
* @internal
60+
*/
61+
set byteOffset(value: typeof this.byteOffset) {
62+
this.#byteOffset = value;
63+
}
64+
5365
get [Symbol.toStringTag](): "NBTData" {
5466
return "NBTData";
5567
}

‎src/read.ts

+7-1
Original file line numberDiff line numberDiff line change
@@ -185,7 +185,13 @@ class NBTReader {
185185
throw new Error(`Encountered unexpected End tag at byte offset ${this.#byteOffset}, ${remaining} unread bytes remaining`);
186186
}
187187

188-
return new NBTData(root, { rootName: rootNameV, endian, compression, bedrockLevel });
188+
const result: NBTData<T> = new NBTData<T>(root, { rootName: rootNameV, endian, compression, bedrockLevel });
189+
190+
if (!strict) {
191+
result.byteOffset = this.#byteOffset;
192+
}
193+
194+
return result;
189195
}
190196

191197
#readTag<T extends Tag>(type: TAG): T;

‎test/index.test.ts

+7-3
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
import { describe, it } from "node:test";
2-
import { rejects, strictEqual, throws } from "node:assert";
2+
import assert, { rejects, strictEqual, throws } from "node:assert";
33
import { readFile, readdir } from "node:fs/promises";
44
import * as NBT from "../src/index.js";
55

@@ -29,8 +29,8 @@ describe("Read, Stringify, Parse and Write", () => {
2929
/** Determines if the test is for checking empty list handling. */
3030
const emptyList: boolean = name.startsWith("empty");
3131

32-
/** Disables strict mode for the Legacy Console Edition player data files. */
33-
const strict: boolean = !name.includes("_280dfc");
32+
/** Disables strict mode for Bedrock LevelDB and Legacy Console Edition player data files. */
33+
const strict: boolean = !/^BlockEntity|^chunk91|_280dfc/.test(name);
3434

3535
/** Reads the NBT file buffer by auto-detecting the file format. */
3636
const result: void | NBT.RootTag | NBT.NBTData = (snbt)
@@ -40,6 +40,10 @@ describe("Read, Stringify, Parse and Write", () => {
4040
: await NBT.read<NBT.RootTag>(buffer, { strict });
4141
if (result === undefined) return;
4242

43+
if (!strict && result instanceof NBT.NBTData) {
44+
assert(result.byteOffset !== null, `'${name}' should have bytes remaining because it shouldn't be parseable with strict mode`);
45+
}
46+
4347
/** Stringifies the NBTData result to an SNBT string. */
4448
const stringified: string | void = (listItemAssertion)
4549
? throws(() => NBT.stringify(result), `'${name}' stringifies to SNBT when it shouldn't`)

‎test/nbt/BlockEntity.dat

4.72 KB
Binary file not shown.

‎test/nbt/chunk91_.dat

1.59 KB
Binary file not shown.

0 commit comments

Comments
 (0)