diff --git a/src/decoder.ts b/src/decoder.ts index 66992ce..42b91ff 100644 --- a/src/decoder.ts +++ b/src/decoder.ts @@ -47,7 +47,7 @@ export class Decoder { } // TODO(jwetzell): add invalid frame id decoding. Scenario where a frame id is reused before one is complete - decode(packetBuf: Buffer): DataPacketChunk | InfoPacketChunk | undefined { + decode(packetBuf: Uint8Array): DataPacketChunk | InfoPacketChunk | undefined { const packet = Decoders.Packet(packetBuf); if (packet === undefined) { return packet; diff --git a/src/decoders/chunk.ts b/src/decoders/chunk.ts index 30c5371..2d88811 100644 --- a/src/decoders/chunk.ts +++ b/src/decoders/chunk.ts @@ -1,17 +1,18 @@ import { Chunk } from '../models/chunk'; -export default (buffer: Buffer, dataDecoder: Function): Chunk => { +export default (buffer: Uint8Array, dataDecoder: Function): Chunk => { let offset = 0; + const view = new DataView(buffer.buffer, buffer.byteOffset, buffer.byteLength); const chunk: Chunk = {}; - chunk.id = buffer.readUInt16LE(offset); + chunk.id = view.getUint16(offset, true); offset += 2; // NOTE(jwetzell): this data is split up as 1 bit for has_subchunks and 15 bits for the data_len - const combinedLengthAndFlag = buffer.readUInt16LE(offset); + const combinedLengthAndFlag = view.getUint16(offset, true); chunk.has_subchunks = combinedLengthAndFlag > 32768; chunk.data_len = chunk.has_subchunks ? combinedLengthAndFlag - 32768 : combinedLengthAndFlag; offset += 2; - chunk.chunk_data = buffer.subarray(offset, offset + chunk.data_len); + chunk.chunk_data = buffer.slice(offset, offset + chunk.data_len); dataDecoder(chunk); return chunk; diff --git a/src/decoders/data/data-packet-chunk.ts b/src/decoders/data/data-packet-chunk.ts index b29ba72..5524491 100644 --- a/src/decoders/data/data-packet-chunk.ts +++ b/src/decoders/data/data-packet-chunk.ts @@ -6,17 +6,22 @@ function decodeDataPacketChunk(dataPacketChunk: DataPacketChunk) { if (dataPacketChunk.has_subchunks && dataPacketChunk.chunk_data && dataPacketChunk.data_len) { let offset = 0; while (offset < dataPacketChunk.data_len) { - const chunkId = dataPacketChunk.chunk_data.readUInt16LE(offset); + const view = new DataView( + dataPacketChunk.chunk_data.buffer, + dataPacketChunk.chunk_data.byteOffset, + dataPacketChunk.chunk_data.byteLength + ); + const chunkId = view.getUint16(offset, true); switch (chunkId) { case 0x0000: - dataPacketChunk.packet_header = Decoders.PacketHeaderChunk(dataPacketChunk.chunk_data.subarray(offset)); + dataPacketChunk.packet_header = Decoders.PacketHeaderChunk(dataPacketChunk.chunk_data.slice(offset)); offset += Constants.CHUNK_HEADER_SIZE; if (dataPacketChunk.packet_header?.data_len) { offset += dataPacketChunk.packet_header.data_len; } break; case 0x0001: - dataPacketChunk.tracker_list = Decoders.DataTrackerListChunk(dataPacketChunk.chunk_data.subarray(offset)); + dataPacketChunk.tracker_list = Decoders.DataTrackerListChunk(dataPacketChunk.chunk_data.slice(offset)); offset += Constants.CHUNK_HEADER_SIZE; if (dataPacketChunk.tracker_list.data_len) { offset += dataPacketChunk.tracker_list.data_len; @@ -29,4 +34,5 @@ function decodeDataPacketChunk(dataPacketChunk: DataPacketChunk) { } } -export default (buffer: Buffer): DataPacketChunk => Decoders.Chunk(buffer, decodeDataPacketChunk) as DataPacketChunk; +export default (buffer: Uint8Array): DataPacketChunk => + Decoders.Chunk(buffer, decodeDataPacketChunk) as DataPacketChunk; diff --git a/src/decoders/data/data-tracker-chunk.ts b/src/decoders/data/data-tracker-chunk.ts index 47d34e0..121bc4f 100644 --- a/src/decoders/data/data-tracker-chunk.ts +++ b/src/decoders/data/data-tracker-chunk.ts @@ -6,7 +6,7 @@ function decodeTrackerChunk(trackerChunk: DataTrackerChunk) { if (trackerChunk.chunk_data && trackerChunk.data_len) { let offset = 0; while (offset < trackerChunk.data_len) { - const trackerFieldChunk = Decoders.DataTrackerFieldChunk(trackerChunk.chunk_data.subarray(offset)); + const trackerFieldChunk = Decoders.DataTrackerFieldChunk(trackerChunk.chunk_data.slice(offset)); offset += Constants.CHUNK_HEADER_SIZE; if (trackerFieldChunk.data_len) { offset += trackerFieldChunk.data_len; @@ -40,4 +40,4 @@ function decodeTrackerChunk(trackerChunk: DataTrackerChunk) { } } -export default (buffer: Buffer): DataTrackerChunk => Decoders.Chunk(buffer, decodeTrackerChunk) as DataTrackerChunk; +export default (buffer: Uint8Array): DataTrackerChunk => Decoders.Chunk(buffer, decodeTrackerChunk) as DataTrackerChunk; diff --git a/src/decoders/data/data-tracker-field-chunk.ts b/src/decoders/data/data-tracker-field-chunk.ts index fbc2327..cd089a4 100644 --- a/src/decoders/data/data-tracker-field-chunk.ts +++ b/src/decoders/data/data-tracker-field-chunk.ts @@ -5,9 +5,14 @@ import { DataTrackerFieldChunk } from '../../models/data/data-tracker-field-chun function readXYZ(trackerFieldChunk: DataTrackerFieldChunk, prefix: string = '') { if (trackerFieldChunk.chunk_data) { - trackerFieldChunk[`${prefix}x`] = trackerFieldChunk.chunk_data.readFloatLE(0); - trackerFieldChunk[`${prefix}y`] = trackerFieldChunk.chunk_data.readFloatLE(4); - trackerFieldChunk[`${prefix}z`] = trackerFieldChunk.chunk_data.readFloatLE(8); + const view = new DataView( + trackerFieldChunk.chunk_data.buffer, + trackerFieldChunk.chunk_data.byteOffset, + trackerFieldChunk.chunk_data.byteLength + ); + trackerFieldChunk[`${prefix}x`] = view.getFloat32(0, true); + trackerFieldChunk[`${prefix}y`] = view.getFloat32(4, true); + trackerFieldChunk[`${prefix}z`] = view.getFloat32(8, true); } } function decodeTrackerFieldChunk(trackerFieldChunk: DataTrackerFieldChunk) { @@ -24,7 +29,12 @@ function decodeTrackerFieldChunk(trackerFieldChunk: DataTrackerFieldChunk) { break; case 0x0003: if (trackerFieldChunk.chunk_data) { - trackerFieldChunk.validity = trackerFieldChunk.chunk_data.readFloatLE(); + const view = new DataView( + trackerFieldChunk.chunk_data.buffer, + trackerFieldChunk.chunk_data.byteOffset, + trackerFieldChunk.chunk_data.byteLength + ); + trackerFieldChunk.validity = view.getFloat32(0, true); } break; case 0x0004: @@ -35,7 +45,12 @@ function decodeTrackerFieldChunk(trackerFieldChunk: DataTrackerFieldChunk) { break; case 0x0006: if (trackerFieldChunk.chunk_data) { - trackerFieldChunk.tracker_timestamp = trackerFieldChunk.chunk_data.readBigUInt64LE(); + const view = new DataView( + trackerFieldChunk.chunk_data.buffer, + trackerFieldChunk.chunk_data.byteOffset, + trackerFieldChunk.chunk_data.byteLength + ); + trackerFieldChunk.tracker_timestamp = view.getBigUint64(0, true); } break; default: @@ -44,5 +59,5 @@ function decodeTrackerFieldChunk(trackerFieldChunk: DataTrackerFieldChunk) { } } -export default (buffer: Buffer): DataTrackerFieldChunk => +export default (buffer: Uint8Array): DataTrackerFieldChunk => Decoders.Chunk(buffer, decodeTrackerFieldChunk) as DataTrackerFieldChunk; diff --git a/src/decoders/data/data-tracker-list-chunk.ts b/src/decoders/data/data-tracker-list-chunk.ts index 406aac7..9332d1d 100644 --- a/src/decoders/data/data-tracker-list-chunk.ts +++ b/src/decoders/data/data-tracker-list-chunk.ts @@ -9,7 +9,7 @@ function decodeDataTrackerListChunk(dataTrackerListChunk: DataTrackerListChunk) let offset = 0; if (dataTrackerListChunk.chunk_data) { while (offset < dataTrackerListChunk.chunk_data.length) { - const trackerChunk = Decoders.DataTrackerChunk(dataTrackerListChunk.chunk_data.subarray(offset)); + const trackerChunk = Decoders.DataTrackerChunk(dataTrackerListChunk.chunk_data.slice(offset)); offset += Constants.CHUNK_HEADER_SIZE; if (trackerChunk.data_len) { offset += trackerChunk.data_len; @@ -20,5 +20,5 @@ function decodeDataTrackerListChunk(dataTrackerListChunk: DataTrackerListChunk) } } } -export default (buffer: Buffer): DataTrackerListChunk => +export default (buffer: Uint8Array): DataTrackerListChunk => Decoders.Chunk(buffer, decodeDataTrackerListChunk) as DataTrackerListChunk; diff --git a/src/decoders/info/info-packet-chunk.ts b/src/decoders/info/info-packet-chunk.ts index c792da2..ac52ff0 100644 --- a/src/decoders/info/info-packet-chunk.ts +++ b/src/decoders/info/info-packet-chunk.ts @@ -6,24 +6,29 @@ function decodeInfoPacketChunk(infoPacketChunk: InfoPacketChunk) { if (infoPacketChunk.has_subchunks && infoPacketChunk.chunk_data && infoPacketChunk.data_len) { let offset = 0; while (offset < infoPacketChunk.data_len) { - const chunkId = infoPacketChunk.chunk_data.readUInt16LE(offset); + const view = new DataView( + infoPacketChunk.chunk_data.buffer, + infoPacketChunk.chunk_data.byteOffset, + infoPacketChunk.chunk_data.byteLength + ); + const chunkId = view.getUint16(offset, true); switch (chunkId) { case 0x0000: - infoPacketChunk.packet_header = Decoders.PacketHeaderChunk(infoPacketChunk.chunk_data.subarray(offset)); + infoPacketChunk.packet_header = Decoders.PacketHeaderChunk(infoPacketChunk.chunk_data.slice(offset)); offset += Constants.CHUNK_HEADER_SIZE; if (infoPacketChunk.packet_header?.data_len) { offset += infoPacketChunk.packet_header.data_len; } break; case 0x0001: - infoPacketChunk.system_name = Decoders.InfoSystemNameChunk(infoPacketChunk.chunk_data.subarray(offset)); + infoPacketChunk.system_name = Decoders.InfoSystemNameChunk(infoPacketChunk.chunk_data.slice(offset)); offset += Constants.CHUNK_HEADER_SIZE; if (infoPacketChunk.system_name?.data_len) { offset += infoPacketChunk.system_name.data_len; } break; case 0x0002: - infoPacketChunk.tracker_list = Decoders.InfoTrackerListChunk(infoPacketChunk.chunk_data.subarray(offset)); + infoPacketChunk.tracker_list = Decoders.InfoTrackerListChunk(infoPacketChunk.chunk_data.slice(offset)); offset += Constants.CHUNK_HEADER_SIZE; if (infoPacketChunk.tracker_list?.data_len) { offset += infoPacketChunk.tracker_list.data_len; @@ -36,4 +41,5 @@ function decodeInfoPacketChunk(infoPacketChunk: InfoPacketChunk) { } } -export default (buffer: Buffer): InfoPacketChunk => Decoders.Chunk(buffer, decodeInfoPacketChunk) as InfoPacketChunk; +export default (buffer: Uint8Array): InfoPacketChunk => + Decoders.Chunk(buffer, decodeInfoPacketChunk) as InfoPacketChunk; diff --git a/src/decoders/info/info-system-name-chunk.ts b/src/decoders/info/info-system-name-chunk.ts index 0c5aab6..d1d83be 100644 --- a/src/decoders/info/info-system-name-chunk.ts +++ b/src/decoders/info/info-system-name-chunk.ts @@ -3,9 +3,11 @@ import { InfoSystemNameChunk } from '../../models/info/info-system-name-chunk'; function decodeSystemNameChunk(systemNameChunk: InfoSystemNameChunk) { if (systemNameChunk.chunk_data !== undefined && systemNameChunk.data_len !== undefined) { - systemNameChunk.system_name = systemNameChunk.chunk_data.subarray(0, systemNameChunk.data_len).toString(); + systemNameChunk.system_name = new TextDecoder().decode( + systemNameChunk.chunk_data.slice(0, systemNameChunk.data_len) + ); } } -export default (buffer: Buffer): InfoSystemNameChunk => +export default (buffer: Uint8Array): InfoSystemNameChunk => Decoders.Chunk(buffer, decodeSystemNameChunk) as InfoSystemNameChunk; diff --git a/src/decoders/info/info-tracker-chunk.ts b/src/decoders/info/info-tracker-chunk.ts index ffc2faa..ea4b456 100644 --- a/src/decoders/info/info-tracker-chunk.ts +++ b/src/decoders/info/info-tracker-chunk.ts @@ -6,10 +6,15 @@ function decodeInfoTrackerChunk(infoTrackerChunk: InfoTrackerChunk) { if (infoTrackerChunk.has_subchunks && infoTrackerChunk.chunk_data && infoTrackerChunk.data_len) { let offset = 0; while (offset < infoTrackerChunk.data_len) { - const chunkId = infoTrackerChunk.chunk_data.readUInt16LE(offset); + const view = new DataView( + infoTrackerChunk.chunk_data.buffer, + infoTrackerChunk.chunk_data.byteOffset, + infoTrackerChunk.chunk_data.byteLength + ); + const chunkId = view.getUint16(offset, true); switch (chunkId) { case 0x0000: - infoTrackerChunk.tracker_name = Decoders.InfoTrackerNameChunk(infoTrackerChunk.chunk_data.subarray(offset)); + infoTrackerChunk.tracker_name = Decoders.InfoTrackerNameChunk(infoTrackerChunk.chunk_data.slice(offset)); offset += Constants.CHUNK_HEADER_SIZE; if (infoTrackerChunk.tracker_name?.data_len) { offset += infoTrackerChunk?.tracker_name?.data_len; @@ -23,4 +28,4 @@ function decodeInfoTrackerChunk(infoTrackerChunk: InfoTrackerChunk) { } } -export default (buffer: Buffer): InfoTrackerChunk => Decoders.Chunk(buffer, decodeInfoTrackerChunk); +export default (buffer: Uint8Array): InfoTrackerChunk => Decoders.Chunk(buffer, decodeInfoTrackerChunk); diff --git a/src/decoders/info/info-tracker-list-chunk.ts b/src/decoders/info/info-tracker-list-chunk.ts index 941b868..402d978 100644 --- a/src/decoders/info/info-tracker-list-chunk.ts +++ b/src/decoders/info/info-tracker-list-chunk.ts @@ -8,7 +8,7 @@ function decodeInfoTrackerListChunk(infoTrackerListChunk: InfoTrackerListChunk) let offset = 0; if (infoTrackerListChunk.data_len) { while (offset < infoTrackerListChunk.data_len) { - const trackerChunk = Decoders.InfoTrackerChunk(infoTrackerListChunk.chunk_data.subarray(offset)); + const trackerChunk = Decoders.InfoTrackerChunk(infoTrackerListChunk.chunk_data.slice(offset)); offset += Constants.CHUNK_HEADER_SIZE; if (trackerChunk.data_len) { offset += trackerChunk.data_len; @@ -20,5 +20,5 @@ function decodeInfoTrackerListChunk(infoTrackerListChunk: InfoTrackerListChunk) } } } -export default (buffer: Buffer): InfoTrackerListChunk => +export default (buffer: Uint8Array): InfoTrackerListChunk => Decoders.Chunk(buffer, decodeInfoTrackerListChunk) as InfoTrackerListChunk; diff --git a/src/decoders/info/info-tracker-name-chunk.ts b/src/decoders/info/info-tracker-name-chunk.ts index 2b34dd2..315ad05 100644 --- a/src/decoders/info/info-tracker-name-chunk.ts +++ b/src/decoders/info/info-tracker-name-chunk.ts @@ -3,8 +3,10 @@ import { InfoTrackerNameChunk } from '../../models/info/info-tracker-name-chunk' function decodeTrackerNameChunk(trackerNameChunk: InfoTrackerNameChunk) { if (trackerNameChunk.chunk_data !== undefined && trackerNameChunk.data_len !== undefined) { - trackerNameChunk.tracker_name = trackerNameChunk.chunk_data.subarray(0, trackerNameChunk.data_len).toString(); + trackerNameChunk.tracker_name = new TextDecoder().decode( + trackerNameChunk.chunk_data.slice(0, trackerNameChunk.data_len) + ); } } -export default (buffer: Buffer): InfoTrackerNameChunk => +export default (buffer: Uint8Array): InfoTrackerNameChunk => Decoders.Chunk(buffer, decodeTrackerNameChunk) as InfoTrackerNameChunk; diff --git a/src/decoders/packet-header-chunk.ts b/src/decoders/packet-header-chunk.ts index da77c18..df66100 100644 --- a/src/decoders/packet-header-chunk.ts +++ b/src/decoders/packet-header-chunk.ts @@ -3,12 +3,19 @@ import { PacketHeaderChunk } from '../models/packet-header-chunk'; function decodePacketHeaderChunk(packetHeaderChunk: PacketHeaderChunk) { if (packetHeaderChunk.chunk_data) { - packetHeaderChunk.packet_timestamp = packetHeaderChunk.chunk_data.readBigUInt64LE(0); - packetHeaderChunk.version_high = packetHeaderChunk.chunk_data.readUInt8(8); - packetHeaderChunk.version_low = packetHeaderChunk.chunk_data.readUInt8(9); - packetHeaderChunk.frame_id = packetHeaderChunk.chunk_data.readUInt8(10); - packetHeaderChunk.frame_packet_count = packetHeaderChunk.chunk_data.readUInt8(11); + const view = new DataView( + packetHeaderChunk.chunk_data.buffer, + packetHeaderChunk.chunk_data.byteOffset, + packetHeaderChunk.chunk_data.byteLength + ); + packetHeaderChunk.packet_timestamp = view.getBigUint64(0, true); + packetHeaderChunk.version_high = view.getUint8(8); + packetHeaderChunk.version_low = view.getUint8(9); + packetHeaderChunk.frame_id = view.getUint8(10); + packetHeaderChunk.frame_packet_count = view.getUint8(11); } } -export default (buffer: Buffer): PacketHeaderChunk => Decoders.Chunk(buffer, decodePacketHeaderChunk); +export default (buffer: Uint8Array): PacketHeaderChunk => { + return Decoders.Chunk(buffer, decodePacketHeaderChunk); +}; diff --git a/src/decoders/packet.ts b/src/decoders/packet.ts index 2995bff..3c0be6d 100644 --- a/src/decoders/packet.ts +++ b/src/decoders/packet.ts @@ -2,8 +2,10 @@ import { Decoders } from '.'; import { DataPacketChunk } from '../models/data/data-packet-chunk'; import { InfoPacketChunk } from '../models/info/info-packet-chunk'; -export default (buffer: Buffer): InfoPacketChunk | DataPacketChunk | undefined => { - const chunkId = buffer.readUInt16LE(); +export default (buffer: Uint8Array): InfoPacketChunk | DataPacketChunk | undefined => { + const view = new DataView(buffer.buffer, buffer.byteOffset, buffer.byteLength); + const chunkId = view.getUint16(0, true); + switch (chunkId) { case 0x6756: return Decoders.InfoPacketChunk(buffer); diff --git a/src/encoder.ts b/src/encoder.ts index 04579e1..d8ecf71 100644 --- a/src/encoder.ts +++ b/src/encoder.ts @@ -47,14 +47,14 @@ export class Encoder { const trackerChunks = trackers.map((tracker: Tracker) => tracker.getInfoChunk()); - const infoPackets: Buffer[] = []; + const infoPackets: Uint8Array[] = []; - const trackerChunksLists: Buffer[][] = []; - let currentTrackerList: Buffer[] = []; + const trackerChunksLists: Uint8Array[][] = []; + let currentTrackerList: Uint8Array[] = []; let currentInfoPacketSize = Constants.PACKET_HEADER_SIZE + systemNameChunk.length + Constants.CHUNK_HEADER_SIZE; - trackerChunks.forEach((trackerChunk: Buffer) => { + trackerChunks.forEach((trackerChunk: Uint8Array) => { if (currentInfoPacketSize + trackerChunk.length > Constants.MAX_UDP_PACKET_SIZE) { trackerChunksLists.push(currentTrackerList); currentTrackerList = []; @@ -95,10 +95,10 @@ export class Encoder { } const allTrackerChunks = trackers.map((tracker) => tracker.getDataChunk()); - const dataPackets: Buffer[] = []; + const dataPackets: Uint8Array[] = []; - const trackerChunksLists: Buffer[][] = []; - let currentTrackerList: Buffer[] = []; + const trackerChunksLists: Uint8Array[][] = []; + let currentTrackerList: Uint8Array[] = []; let currentDataPacketSize = Constants.PACKET_HEADER_SIZE + Constants.CHUNK_HEADER_SIZE; diff --git a/src/encoders/chunk.ts b/src/encoders/chunk.ts index 186034e..bddec09 100644 --- a/src/encoders/chunk.ts +++ b/src/encoders/chunk.ts @@ -1,4 +1,4 @@ -export default (id: number, chunkData: Buffer, hasSubchunks: boolean): Buffer => { +export default (id: number, chunkData: Uint8Array, hasSubchunks: boolean): Uint8Array => { if (!Number.isInteger(id)) { throw new Error('chunk id must be an integer'); } @@ -11,10 +11,15 @@ export default (id: number, chunkData: Buffer, hasSubchunks: boolean): Buffer => throw new Error('chunkData can not be greater than 32767 bytes'); } - const header = Buffer.alloc(4); - header.writeUInt16LE(id); + const header = new DataView(new ArrayBuffer(4)); + header.setUint16(0, id, true); const hasSubChunksBit = (hasSubchunks ? 1 : 0) << 15; - header.writeUInt16LE(hasSubChunksBit + chunkData.length, 2); + header.setUint16(2, hasSubChunksBit + chunkData.length, true); - return Buffer.concat([header, chunkData]); + const headerBytes = new Uint8Array(header.buffer); + + const bytes = new Uint8Array(headerBytes.length + chunkData.length); + bytes.set(headerBytes); + bytes.set(chunkData, headerBytes.length); + return bytes; }; diff --git a/src/encoders/data/data-packet-chunk.ts b/src/encoders/data/data-packet-chunk.ts index 6e63cbc..27dcd99 100644 --- a/src/encoders/data/data-packet-chunk.ts +++ b/src/encoders/data/data-packet-chunk.ts @@ -1,3 +1,7 @@ import chunk from '../chunk'; -export default (packetHeaderChunk: Buffer, trackerListChunk: Buffer): Buffer => - chunk(0x6755, Buffer.concat([packetHeaderChunk, trackerListChunk]), true); +export default (packetHeaderChunk: Uint8Array, trackerListChunk: Uint8Array): Uint8Array => { + const chunkData = new Uint8Array(packetHeaderChunk.length + trackerListChunk.length); + chunkData.set(packetHeaderChunk); + chunkData.set(trackerListChunk, packetHeaderChunk.length); + return chunk(0x6755, chunkData, true); +}; diff --git a/src/encoders/data/data-tracker-accel-chunk.ts b/src/encoders/data/data-tracker-accel-chunk.ts index 049e929..b2a2451 100644 --- a/src/encoders/data/data-tracker-accel-chunk.ts +++ b/src/encoders/data/data-tracker-accel-chunk.ts @@ -1,9 +1,9 @@ import chunk from '../chunk'; -export default (x: number, y: number, z: number): Buffer => { - const buf = Buffer.alloc(12); - buf.writeFloatLE(x); - buf.writeFloatLE(y, 4); - buf.writeFloatLE(z, 8); - return chunk(0x0004, buf, false); +export default (x: number, y: number, z: number): Uint8Array => { + const buf = new DataView(new ArrayBuffer(12)); + buf.setFloat32(0, x, true); + buf.setFloat32(4, y, true); + buf.setFloat32(8, z, true); + return chunk(0x0004, new Uint8Array(buf.buffer), false); }; diff --git a/src/encoders/data/data-tracker-chunk.ts b/src/encoders/data/data-tracker-chunk.ts index 29af047..9944adb 100644 --- a/src/encoders/data/data-tracker-chunk.ts +++ b/src/encoders/data/data-tracker-chunk.ts @@ -1,4 +1,20 @@ import chunk from '../chunk'; -export default (trackerId: number, fieldChunks: Buffer[]): Buffer => - chunk(trackerId, Buffer.concat(fieldChunks), fieldChunks.length > 0); +export default (trackerId: number, fieldChunks: Uint8Array[]): Uint8Array => { + let fieldChunksTotalLength = 0; + + fieldChunks.forEach((fieldChunk) => { + fieldChunksTotalLength += fieldChunk.length; + }); + + const fieldChunksBytes = new Uint8Array(fieldChunksTotalLength); + + let offset = 0; + + fieldChunks.forEach((fieldChunk) => { + fieldChunksBytes.set(fieldChunk, offset); + offset += fieldChunk.length; + }); + + return chunk(trackerId, fieldChunksBytes, fieldChunks.length > 0); +}; diff --git a/src/encoders/data/data-tracker-list-chunk.ts b/src/encoders/data/data-tracker-list-chunk.ts index 7378ce1..ae9e55b 100644 --- a/src/encoders/data/data-tracker-list-chunk.ts +++ b/src/encoders/data/data-tracker-list-chunk.ts @@ -1,3 +1,20 @@ import chunk from '../chunk'; -export default (trackerChunks: Buffer[]) => chunk(0x0001, Buffer.concat(trackerChunks), true); +export default (trackerChunks: Uint8Array[]) => { + let trackerChunksTotalLength = 0; + + trackerChunks.forEach((trackerChunk) => { + trackerChunksTotalLength += trackerChunk.length; + }); + + const trackerChunksBytes = new Uint8Array(trackerChunksTotalLength); + + let offset = 0; + + trackerChunks.forEach((trackerChunk) => { + trackerChunksBytes.set(trackerChunk, offset); + offset += trackerChunk.length; + }); + + return chunk(0x0001, trackerChunksBytes, true); +}; diff --git a/src/encoders/data/data-tracker-ori-chunk.ts b/src/encoders/data/data-tracker-ori-chunk.ts index a77aae0..56aa3ba 100644 --- a/src/encoders/data/data-tracker-ori-chunk.ts +++ b/src/encoders/data/data-tracker-ori-chunk.ts @@ -1,9 +1,10 @@ import chunk from '../chunk'; -export default (x: number, y: number, z: number): Buffer => { - const buf = Buffer.alloc(12); - buf.writeFloatLE(x); - buf.writeFloatLE(y, 4); - buf.writeFloatLE(z, 8); - return chunk(0x0002, buf, false); +export default (x: number, y: number, z: number): Uint8Array => { + const buf = new DataView(new ArrayBuffer(12)); + + buf.setFloat32(0, x, true); + buf.setFloat32(4, y, true); + buf.setFloat32(8, z, true); + return chunk(0x0002, new Uint8Array(buf.buffer), false); }; diff --git a/src/encoders/data/data-tracker-pos-chunk.ts b/src/encoders/data/data-tracker-pos-chunk.ts index 38f3827..4813982 100644 --- a/src/encoders/data/data-tracker-pos-chunk.ts +++ b/src/encoders/data/data-tracker-pos-chunk.ts @@ -1,9 +1,11 @@ import chunk from '../chunk'; -export default (x: number, y: number, z: number): Buffer => { - const buf = Buffer.alloc(12); - buf.writeFloatLE(x); - buf.writeFloatLE(y, 4); - buf.writeFloatLE(z, 8); - return chunk(0x0000, buf, false); +export default (x: number, y: number, z: number): Uint8Array => { + const buf = new DataView(new ArrayBuffer(12)); + + buf.setFloat32(0, x, true); + buf.setFloat32(4, y, true); + buf.setFloat32(8, z, true); + + return chunk(0x0000, new Uint8Array(buf.buffer), false); }; diff --git a/src/encoders/data/data-tracker-speed-chunk.ts b/src/encoders/data/data-tracker-speed-chunk.ts index 681129f..7cd226d 100644 --- a/src/encoders/data/data-tracker-speed-chunk.ts +++ b/src/encoders/data/data-tracker-speed-chunk.ts @@ -1,9 +1,11 @@ import chunk from '../chunk'; -export default (x: number, y: number, z: number): Buffer => { - const buf = Buffer.alloc(12); - buf.writeFloatLE(x); - buf.writeFloatLE(y, 4); - buf.writeFloatLE(z, 8); - return chunk(0x0001, buf, false); +export default (x: number, y: number, z: number): Uint8Array => { + const buf = new DataView(new ArrayBuffer(12)); + + buf.setFloat32(0, x, true); + buf.setFloat32(4, y, true); + buf.setFloat32(8, z, true); + + return chunk(0x0001, new Uint8Array(buf.buffer), false); }; diff --git a/src/encoders/data/data-tracker-status-chunk.ts b/src/encoders/data/data-tracker-status-chunk.ts index 873d524..7c62862 100644 --- a/src/encoders/data/data-tracker-status-chunk.ts +++ b/src/encoders/data/data-tracker-status-chunk.ts @@ -1,7 +1,7 @@ import chunk from '../chunk'; -export default (validity: number): Buffer => { - const buf = Buffer.alloc(4); - buf.writeFloatLE(validity); - return chunk(0x0003, buf, false); +export default (validity: number): Uint8Array => { + const buf = new DataView(new ArrayBuffer(4)); + buf.setFloat32(0, validity, true); + return chunk(0x0003, new Uint8Array(buf.buffer), false); }; diff --git a/src/encoders/data/data-tracker-timestamp-chunk.ts b/src/encoders/data/data-tracker-timestamp-chunk.ts index 082a0fd..dcc674b 100644 --- a/src/encoders/data/data-tracker-timestamp-chunk.ts +++ b/src/encoders/data/data-tracker-timestamp-chunk.ts @@ -1,7 +1,7 @@ import chunk from '../chunk'; -export default (timestamp: bigint): Buffer => { - const buf = Buffer.alloc(8); - buf.writeBigUInt64LE(BigInt(timestamp)); - return chunk(0x0006, buf, false); +export default (timestamp: bigint): Uint8Array => { + const buf = new DataView(new ArrayBuffer(8)); + buf.setBigUint64(0, BigInt(timestamp), true); + return chunk(0x0006, new Uint8Array(buf.buffer), false); }; diff --git a/src/encoders/data/data-tracker-trgtpos-chunk.ts b/src/encoders/data/data-tracker-trgtpos-chunk.ts index b82ee27..5d67d87 100644 --- a/src/encoders/data/data-tracker-trgtpos-chunk.ts +++ b/src/encoders/data/data-tracker-trgtpos-chunk.ts @@ -1,9 +1,11 @@ import chunk from '../chunk'; -export default (x: number, y: number, z: number): Buffer => { - const buf = Buffer.alloc(12); - buf.writeFloatLE(x); - buf.writeFloatLE(y, 4); - buf.writeFloatLE(z, 8); - return chunk(0x0005, buf, false); +export default (x: number, y: number, z: number): Uint8Array => { + const buf = new DataView(new ArrayBuffer(12)); + + buf.setFloat32(0, x, true); + buf.setFloat32(4, y, true); + buf.setFloat32(8, z, true); + + return chunk(0x0005, new Uint8Array(buf.buffer), false); }; diff --git a/src/encoders/info/info-packet-chunk.ts b/src/encoders/info/info-packet-chunk.ts index 27f4fb0..07d76a9 100644 --- a/src/encoders/info/info-packet-chunk.ts +++ b/src/encoders/info/info-packet-chunk.ts @@ -1,4 +1,14 @@ import chunk from '../chunk'; -export default (packetHeaderChunk: Buffer, systemNameChunk: Buffer, trackerListChunk: Buffer): Buffer => - chunk(0x6756, Buffer.concat([packetHeaderChunk, systemNameChunk, trackerListChunk]), true); +export default ( + packetHeaderChunk: Uint8Array, + systemNameChunk: Uint8Array, + trackerListChunk: Uint8Array +): Uint8Array => { + const chunkData = new Uint8Array(packetHeaderChunk.length + systemNameChunk.length + trackerListChunk.length); + + chunkData.set(packetHeaderChunk); + chunkData.set(systemNameChunk, packetHeaderChunk.length); + chunkData.set(trackerListChunk, packetHeaderChunk.length + systemNameChunk.length); + return chunk(0x6756, chunkData, true); +}; diff --git a/src/encoders/info/info-system-name-chunk.ts b/src/encoders/info/info-system-name-chunk.ts index 246b5ab..f6d00ee 100644 --- a/src/encoders/info/info-system-name-chunk.ts +++ b/src/encoders/info/info-system-name-chunk.ts @@ -1,3 +1,3 @@ import chunk from '../chunk'; -export default (systemName: string): Buffer => chunk(0x0001, Buffer.from(systemName), false); +export default (systemName: string): Uint8Array => chunk(0x0001, new TextEncoder().encode(systemName), false); diff --git a/src/encoders/info/info-tracker-chunk.ts b/src/encoders/info/info-tracker-chunk.ts index f761b74..03cfaff 100644 --- a/src/encoders/info/info-tracker-chunk.ts +++ b/src/encoders/info/info-tracker-chunk.ts @@ -1,3 +1,4 @@ import chunk from '../chunk'; -export default (trackerId: number, trackerNameChunk: Buffer): Buffer => chunk(trackerId, trackerNameChunk, true); +export default (trackerId: number, trackerNameChunk: Uint8Array): Uint8Array => + chunk(trackerId, trackerNameChunk, true); diff --git a/src/encoders/info/info-tracker-list-chunk.ts b/src/encoders/info/info-tracker-list-chunk.ts index 4dd6b81..4e74564 100644 --- a/src/encoders/info/info-tracker-list-chunk.ts +++ b/src/encoders/info/info-tracker-list-chunk.ts @@ -1,3 +1,19 @@ import chunk from '../chunk'; -export default (trackerChunks: Buffer[]): Buffer => chunk(0x0002, Buffer.concat(trackerChunks), true); +export default (trackerChunks: Uint8Array[]): Uint8Array => { + let trackerChunksTotalLength = 0; + + trackerChunks.forEach((trackerChunk) => { + trackerChunksTotalLength += trackerChunk.length; + }); + + const trackerChunksBytes = new Uint8Array(trackerChunksTotalLength); + + let offset = 0; + + trackerChunks.forEach((trackerChunk) => { + trackerChunksBytes.set(trackerChunk, offset); + offset += trackerChunk.length; + }); + return chunk(0x0002, trackerChunksBytes, true); +}; diff --git a/src/encoders/info/info-tracker-name-chunk.ts b/src/encoders/info/info-tracker-name-chunk.ts index c116bb3..2157f27 100644 --- a/src/encoders/info/info-tracker-name-chunk.ts +++ b/src/encoders/info/info-tracker-name-chunk.ts @@ -1,3 +1,3 @@ import chunk from '../chunk'; -export default (trackerName: string) => chunk(0x0000, Buffer.from(trackerName), false); +export default (trackerName: string) => chunk(0x0000, new TextEncoder().encode(trackerName), false); diff --git a/src/encoders/packet-header-chunk.ts b/src/encoders/packet-header-chunk.ts index edc6a52..d844877 100644 --- a/src/encoders/packet-header-chunk.ts +++ b/src/encoders/packet-header-chunk.ts @@ -6,7 +6,7 @@ export default ( versionLow: number, frameId: number, framePacketCount: number -): Buffer => { +): Uint8Array => { if (!Number.isInteger(versionHigh)) { throw new Error('version high must be an integer'); } @@ -33,12 +33,12 @@ export default ( throw new Error('frame packet count must be >= 0 and <= 255'); } - const packetHeader = Buffer.alloc(12); - packetHeader.writeBigUInt64LE(BigInt(timestamp)); - packetHeader.writeUint8(versionHigh, 8); - packetHeader.writeUint8(versionLow, 9); - packetHeader.writeUint8(frameId, 10); - packetHeader.writeUint8(framePacketCount, 11); + const packetHeader = new DataView(new ArrayBuffer(12)); + packetHeader.setBigUint64(0, BigInt(timestamp), true); + packetHeader.setUint8(8, versionHigh); + packetHeader.setUint8(9, versionLow); + packetHeader.setUint8(10, frameId); + packetHeader.setUint8(11, framePacketCount); - return chunk(0x0000, packetHeader, false); + return chunk(0x0000, new Uint8Array(packetHeader.buffer), false); }; diff --git a/src/models/chunk.ts b/src/models/chunk.ts index 6372613..7a40c61 100644 --- a/src/models/chunk.ts +++ b/src/models/chunk.ts @@ -2,5 +2,5 @@ export interface Chunk { id?: number; has_subchunks?: boolean; data_len?: number; - chunk_data?: Buffer; + chunk_data?: Uint8Array; } diff --git a/src/models/data/data-tracker-field-chunk.ts b/src/models/data/data-tracker-field-chunk.ts index 42c5999..f0e5cf3 100644 --- a/src/models/data/data-tracker-field-chunk.ts +++ b/src/models/data/data-tracker-field-chunk.ts @@ -1,5 +1,5 @@ import { Chunk } from '../chunk'; export interface DataTrackerFieldChunk extends Chunk { - [key: string]: number | bigint | number[] | Buffer | undefined | boolean; + [key: string]: number | bigint | number[] | Uint8Array | undefined | boolean; } diff --git a/src/models/tracker.ts b/src/models/tracker.ts index ccb44d7..df28d76 100644 --- a/src/models/tracker.ts +++ b/src/models/tracker.ts @@ -61,7 +61,7 @@ export class Tracker { } getDataChunk() { - const fieldChunks: Buffer[] = []; + const fieldChunks: Uint8Array[] = []; if (this.pos) { fieldChunks.push(dataTrackerPosChunk(...this.pos));