diff --git a/src/utils/UMP.ts b/src/utils/UMP.ts new file mode 100644 index 000000000..ea18b7066 --- /dev/null +++ b/src/utils/UMP.ts @@ -0,0 +1,60 @@ +export interface UMPPart { + type: number; + size: number; + data: Uint8Array; +} + +export default class UMP { + buffer: Uint8Array; + offset: number; + + constructor(buffer: Uint8Array) { + this.buffer = buffer; + this.offset = 0; + } + + readVarInt(): number { + const prefix = this.buffer[this.offset]; + const size = this.varintSize(prefix); + let result = 0; + let shift = 0; + + if (size !== 5) { + shift = 8 - size; + const mask = (1 << shift) - 1; + result |= prefix & mask; + } + + for (let i = 1; i < size; i++) { + const byte = this.buffer[this.offset + i]; + result |= byte << shift; + shift += 8; + } + + this.offset += size; + return result; + } + + varintSize(byte: number): number { + let lo = 0; + for (let i = 7; i >= 4; i--) { + if (byte & (1 << i)) lo++; + else break; + } + return Math.min(lo + 1, 5); + } + + parse(): UMPPart[] { + const parts = []; + + while (this.offset < this.buffer.length) { + const part_type = this.readVarInt(); + const part_size = this.readVarInt(); + const part_data = this.buffer.slice(this.offset, this.offset + part_size); + this.offset += part_size; + parts.push({ type: part_type, size: part_size, data: part_data }); + } + + return parts; + } +} \ No newline at end of file diff --git a/src/utils/index.ts b/src/utils/index.ts index ffe84174f..b324a14dd 100644 --- a/src/utils/index.ts +++ b/src/utils/index.ts @@ -13,4 +13,7 @@ export { Platform } from './Utils.js'; export * as Utils from './Utils.js'; export { default as Log } from './Log.js'; -export * as LZW from './LZW.js'; \ No newline at end of file +export * as LZW from './LZW.js'; + +export { default as UMP } from './UMP.js'; +export * from './UMP.js'; \ No newline at end of file