volleyball-dev-frontend/node_modules/restructure/src/EncodeStream.js
2025-06-02 16:42:16 +00:00

130 lines
3.1 KiB
JavaScript

import {DecodeStream} from './DecodeStream.js';
const textEncoder = new TextEncoder();
const isBigEndian = new Uint8Array(new Uint16Array([0x1234]).buffer)[0] == 0x12;
export class EncodeStream {
constructor(buffer) {
this.buffer = buffer;
this.view = new DataView(this.buffer.buffer, this.buffer.byteOffset, this.buffer.byteLength);
this.pos = 0;
}
writeBuffer(buffer) {
this.buffer.set(buffer, this.pos);
this.pos += buffer.length;
}
writeString(string, encoding = 'ascii') {
let buf;
switch (encoding) {
case 'utf16le':
case 'utf16-le':
case 'ucs2': // node treats this the same as utf16.
buf = stringToUtf16(string, isBigEndian);
break;
case 'utf16be':
case 'utf16-be':
buf = stringToUtf16(string, !isBigEndian);
break;
case 'utf8':
buf = textEncoder.encode(string);
break;
case 'ascii':
buf = stringToAscii(string);
break;
default:
throw new Error(`Unsupported encoding: ${encoding}`);
}
this.writeBuffer(buf);
}
writeUInt24BE(val) {
this.buffer[this.pos++] = (val >>> 16) & 0xff;
this.buffer[this.pos++] = (val >>> 8) & 0xff;
this.buffer[this.pos++] = val & 0xff;
}
writeUInt24LE(val) {
this.buffer[this.pos++] = val & 0xff;
this.buffer[this.pos++] = (val >>> 8) & 0xff;
this.buffer[this.pos++] = (val >>> 16) & 0xff;
}
writeInt24BE(val) {
if (val >= 0) {
this.writeUInt24BE(val);
} else {
this.writeUInt24BE(val + 0xffffff + 1);
}
}
writeInt24LE(val) {
if (val >= 0) {
this.writeUInt24LE(val);
} else {
this.writeUInt24LE(val + 0xffffff + 1);
}
}
fill(val, length) {
if (length < this.buffer.length) {
this.buffer.fill(val, this.pos, this.pos + length);
this.pos += length;
} else {
const buf = new Uint8Array(length);
buf.fill(val);
this.writeBuffer(buf);
}
}
}
function stringToUtf16(string, swap) {
let buf = new Uint16Array(string.length);
for (let i = 0; i < string.length; i++) {
let code = string.charCodeAt(i);
if (swap) {
code = (code >> 8) | ((code & 0xff) << 8);
}
buf[i] = code;
}
return new Uint8Array(buf.buffer);
}
function stringToAscii(string) {
let buf = new Uint8Array(string.length);
for (let i = 0; i < string.length; i++) {
// Match node.js behavior - encoding allows 8-bit rather than 7-bit.
buf[i] = string.charCodeAt(i);
}
return buf;
}
for (let key of Object.getOwnPropertyNames(DataView.prototype)) {
if (key.slice(0, 3) === 'set') {
let type = key.slice(3).replace('Ui', 'UI');
if (type === 'Float32') {
type = 'Float';
} else if (type === 'Float64') {
type = 'Double';
}
let bytes = DecodeStream.TYPES[type];
EncodeStream.prototype['write' + type + (bytes === 1 ? '' : 'BE')] = function (value) {
this.view[key](this.pos, value, false);
this.pos += bytes;
};
if (bytes !== 1) {
EncodeStream.prototype['write' + type + 'LE'] = function (value) {
this.view[key](this.pos, value, true);
this.pos += bytes;
};
}
}
}