From f5d165eea5bd5ded2c1a3cad17212d2fc9ea8bb2 Mon Sep 17 00:00:00 2001 From: Offroaders123 <65947371+Offroaders123@users.noreply.github.com> Date: Tue, 28 Jun 2022 14:34:30 -0700 Subject: [PATCH] Reader Method Madness Changes: - A few more changes to what I've been working on for the last few days. This commit makes the tag reading methods for the Reader more consistent, and de-abstracts the logic for reading the bytes from the data buffer. It was challenging for me to find where the function calls were when I first looked into the original NBT.js library, so while a bit repetitive, I took those function calls out of the extra `read()` method and moved their logic directly into their own tag methods, to better show what they were doing to get the byte data using the `DataView`. - I also renamed some of the Reader attributes, just to make them a little more readable too. I have nothing against camelcase haha, but it's sometimes easier to just have to remember one word for a variable in some spots. - Simplified the header checking functions! Took out a few extra steps that get you to the same place. Got some inspiration and help from a few different places for these last few commits: https://github.com/janispritzkau/nbt-ts https://gist.github.com/jonathanlurie/04fa6343e64f750d03072ac92584b5df (Will be using this soon, thought I'd add it now just in case I lose track of it) https://github.com/C4K3/nbted/issues/4 https://stackoverflow.com/questions/30229522/how-can-i-join-an-array-of-numbers-into-1-concatenated-number https://stackoverflow.com/questions/54019143/issue-with-combining-large-array-of-numbers-into-one-single-number --- src/read.js | 93 +++++++++++++++++++++++++++++------------------------ 1 file changed, 51 insertions(+), 42 deletions(-) diff --git a/src/read.js b/src/read.js index da65f10..558e7e8 100644 --- a/src/read.js +++ b/src/read.js @@ -42,19 +42,20 @@ async function runReader(data,endian){ const compound = reader.byte(); if (compound !== tags.compound) throw new Error("Top tag must be a compound"); - return { name: reader.string(), type: "compound", value: reader.compound() }; + const name = reader.string(); + const value = reader.compound(); + + return { name, type: "compound", value }; } function hasBedrockLevelHeader(data){ - const header = new Uint8Array(data.slice(0,4)); - const result = (header[1] === 0 && header[2] === 0 && header[3] === 0); - return result; + const header = Number(...data.slice(1,4)); + return header === 0x0; } function hasGzipHeader(data){ - const header = new Uint8Array(data.slice(0,2)); - const result = (header[0] === 0x1f && header[1] === 0x8b); - return result; + const header = new DataView(data.buffer).getInt16(); + return header === 0x1f8b; } class Reader { @@ -62,87 +63,95 @@ class Reader { if (!data) throw new Error(`Unexpected falsy value for the "data" parameter.`); this.offset = 0; - this.endian = endian; + this.endian = (endian === "little"); - this.arrayView = new Uint8Array(data); - this.dataView = new DataView(this.arrayView.buffer); - } - read(type,size) { - const value = this.dataView[`get${type}`](this.offset,(this.endian === "little")); - this.offset += size; - return value; + this.data = new Uint8Array(data); + this.view = new DataView(this.data.buffer); } byte() { - return this.read("Int8",1); - } - ubyte() { - return this.read("Uint8",1); + const value = this.view.getInt8(this.offset); + this.offset += 1; + return value; } short() { - return this.read("Int16",2); + const value = this.view.getInt16(this.offset,this.endian); + this.offset += 2; + return value; } int() { - return this.read("Int32",4); + const value = this.view.getInt32(this.offset,this.endian); + this.offset += 4; + return value; } float() { - return this.read("Float32",4); + const value = this.view.getFloat32(this.offset,this.endian); + this.offset += 4; + return value; } double() { - return this.read("Float64",8); + const value = this.view.getFloat64(this.offset,this.endian); + this.offset += 8; + return value; } long() { - return this.read("BigInt64",8); + const value = this.view.getBigInt64(this.offset,this.endian); + this.offset += 8; + return value; } byteArray() { const length = this.int(); - const bytes = []; + const value = []; for (let i = 0; i < length; i++){ - bytes.push(this.byte()); + const entry = this.byte(); + value.push(entry); } - return bytes; + return value; } intArray() { const length = this.int(); - const ints = []; + const value = []; for (let i = 0; i < length; i++){ - ints.push(this.int()); + const entry = this.int(); + value.push(entry); } - return ints; + return value; } longArray() { const length = this.int(); - const longs = []; + const value = []; for (let i = 0; i < length; i++){ - longs.push(this.long()); + const entry = this.long(); + value.push(entry); } - return longs; + return value; } string() { const length = this.short(); - const slice = this.arrayView.slice(this.offset,this.offset + length); + const value = this.data.slice(this.offset,this.offset + length); this.offset += length; - return new TextDecoder().decode(slice); + return new TextDecoder().decode(value); } list() { const tag = this.byte(); const type = types[tag]; const length = this.int(); - const values = []; + const value = []; for (let i = 0; i < length; i++){ - values.push(this[type]()); + const entry = this[type](); + value.push(entry); } - return { type, value: values }; + return { type, value }; } compound() { - const values = {}; + const value = {}; while (true){ const tag = this.byte(); const type = types[tag]; if (tag === tags.end) break; const name = this.string(); - const value = this[type](); - values[name] = { type, value }; + const entry = this[type](); + value[name] = { type, value: entry }; } - return values; + return value; } } \ No newline at end of file