Compare commits
21 commits
Author | SHA1 | Date | |
---|---|---|---|
ceffc3eb87 | |||
c097cc5480 | |||
71a717ae80 | |||
d02bf4693b | |||
2e6ec04512 | |||
33e8466e9d | |||
77d74ae657 | |||
961df8cd72 | |||
4cacdbf113 | |||
b7a482d1f2 | |||
c1e43e2937 | |||
63a3e5c73b | |||
3bb2f542ef | |||
24f26db2c1 | |||
242b3f512b | |||
dd46ec825b | |||
a157685fcc | |||
8367213725 | |||
d12d971ef5 | |||
dd3eb43809 | |||
aabf5cdbb3 |
22 changed files with 654 additions and 2979 deletions
33
.github/workflows/browser.yml
vendored
Normal file
33
.github/workflows/browser.yml
vendored
Normal file
|
@ -0,0 +1,33 @@
|
|||
# This workflow will do a clean installation of node dependencies, cache/restore them, build the source code and run tests across different versions of node
|
||||
# For more information see: https://docs.github.com/en/actions/automating-builds-and-tests/building-and-testing-nodejs
|
||||
|
||||
name: Build for Browser
|
||||
|
||||
on:
|
||||
push:
|
||||
branches: [ "master" ]
|
||||
pull_request:
|
||||
branches: [ "master" ]
|
||||
|
||||
jobs:
|
||||
build:
|
||||
|
||||
runs-on: ubuntu-latest
|
||||
|
||||
strategy:
|
||||
matrix:
|
||||
node-version: [18.x]
|
||||
# See supported Node.js release schedule at https://nodejs.org/en/about/releases/
|
||||
|
||||
steps:
|
||||
- uses: actions/checkout@v3
|
||||
- name: Use Node.js ${{ matrix.node-version }}
|
||||
uses: actions/setup-node@v3
|
||||
with:
|
||||
node-version: ${{ matrix.node-version }}
|
||||
cache: 'npm'
|
||||
- run: npm ci
|
||||
# Don't run updateCheck for now
|
||||
#- run: npm run dev:updateCheck
|
||||
- run: npm run buildweb
|
||||
#- run: npm test
|
2
.github/workflows/node.js.yml
vendored
2
.github/workflows/node.js.yml
vendored
|
@ -1,7 +1,7 @@
|
|||
# This workflow will do a clean installation of node dependencies, cache/restore them, build the source code and run tests across different versions of node
|
||||
# For more information see: https://docs.github.com/en/actions/automating-builds-and-tests/building-and-testing-nodejs
|
||||
|
||||
name: Node.js CI
|
||||
name: Build for NodeJS
|
||||
|
||||
on:
|
||||
push:
|
||||
|
|
|
@ -1,4 +1,5 @@
|
|||
.github/*
|
||||
base/*
|
||||
enums/*
|
||||
index.ts
|
||||
combined.ts
|
||||
|
|
2
LICENSE
2
LICENSE
|
@ -1,6 +1,6 @@
|
|||
MIT License
|
||||
|
||||
Copyright (c) 2023 Holly Stubbs (tgpholly)
|
||||
Copyright (c) 2021-2024 Holly Stubbs (tgpholly)
|
||||
|
||||
Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
of this software and associated documentation files (the "Software"), to deal
|
||||
|
|
|
@ -22,12 +22,13 @@ I tried to keep it as simple as possible to use, for example if you want to writ
|
|||
writer.writeByte(<number>);
|
||||
```
|
||||
|
||||
You can find a list of all of the methods for [Writers](https://github.com/tgpholly/bufferStuff/blob/master/writers/IWriter.ts) and [Readers](https://github.com/tgpholly/bufferStuff/blob/master/readers/IReader.ts) in their interface files.
|
||||
You can find a list of all of the methods for [Writers](https://git.eusv.net/tgpholly/bufferStuff/src/branch/master/writers/IWriter.ts) and [Readers](https://git.eusv.net/tgpholly/bufferStuff/src/branch/master/readers/IReader.ts) in their interface files.
|
||||
|
||||
## Projects using bufferStuff
|
||||
If your project uses bufferStuff feel free to make a PR to add it to this list!
|
||||
### [tgpholly/mc-beta-server](https://github.com/tgpholly/mc-beta-server)
|
||||
### [tgpholly/mc-beta-server](https://git.eusv.net/tgpholly/mc-beta-server)
|
||||
### [tgpholly/ultrakillMP_server](https://github.com/tgpholly/ultrakillMP_server)
|
||||
### [tgpholly/t00-multiuser](https://git.eusv.net/tgpholly/t00-multiuser)
|
||||
|
||||
## Projects similar to bufferStuff
|
||||
### [tgpholly/csharp-extensions/BinaryTools](https://github.com/tgpholly/csharp-extensions/tree/master/BinaryTools) - Basically bufferStuff but for C#
|
||||
|
|
387
base/BufferShim.ts
Normal file
387
base/BufferShim.ts
Normal file
|
@ -0,0 +1,387 @@
|
|||
// Copyright (c) Holly Stubbs (tgpholly) - Licensed under MIT
|
||||
// Check LICENSE in repository root for more information.
|
||||
|
||||
// This is a mostly 1:1 feature complete implementation of node's Buffer class for browsers.
|
||||
// It's missing some of the static stuff but everything in the object *should* be there.
|
||||
|
||||
class BrowserBuffer {
|
||||
public buffer:Uint8Array;
|
||||
private dataView:DataView;
|
||||
|
||||
public constructor(dataOrSize: Array<number> | ArrayBufferLike | number) {
|
||||
if (typeof(dataOrSize) === "number") {
|
||||
this.buffer = new Uint8Array(dataOrSize);
|
||||
} else if (typeof(dataOrSize) === "object") {
|
||||
this.buffer = new Uint8Array(dataOrSize); // Convert whatever comes in to a Uint8Array.
|
||||
} else {
|
||||
this.buffer = new Uint8Array(0); // Fallback
|
||||
}
|
||||
|
||||
this.dataView = new DataView(this.buffer.buffer);
|
||||
}
|
||||
|
||||
public static allocUnsafe(size:number) { return this.alloc(size); }
|
||||
public static allocUnsafeSlow(size:number) { return this.alloc(size); }
|
||||
public static alloc(size:number) {
|
||||
return new BrowserBuffer(size);
|
||||
}
|
||||
|
||||
public static concat(buffers:Array<BrowserBuffer>, totalLength?:number) {
|
||||
let joinedArrays:Uint8Array;
|
||||
if (totalLength !== undefined) {
|
||||
joinedArrays = new Uint8Array(totalLength);
|
||||
} else {
|
||||
let arraysLength = 0;
|
||||
for (const buffer of buffers) {
|
||||
arraysLength += buffer.length;
|
||||
}
|
||||
joinedArrays = new Uint8Array(arraysLength);
|
||||
}
|
||||
|
||||
let offset = 0;
|
||||
for (const buffer of buffers) {
|
||||
joinedArrays.set(buffer.buffer, offset);
|
||||
offset += buffer.length;
|
||||
}
|
||||
|
||||
return new BrowserBuffer(joinedArrays);
|
||||
}
|
||||
|
||||
public static from(data: Array<number> | ArrayBufferLike | string) {
|
||||
if (typeof(data) === "string") {
|
||||
throw new Error("BrowserBuffer does not currently support creating buffers from strings.");
|
||||
}
|
||||
|
||||
return new BrowserBuffer(data);
|
||||
}
|
||||
|
||||
// NOTE: Here to match node buffer, has no use.
|
||||
public static readonly poolSize:number = 8192;
|
||||
|
||||
// TODO: Implement
|
||||
public static of() {}
|
||||
public static isBuffer() {}
|
||||
public static isEncoding() {}
|
||||
public static byteLength() {}
|
||||
public static copyBytesFrom() {}
|
||||
public static compare() {}
|
||||
|
||||
public get length() {
|
||||
return this.buffer.length;
|
||||
}
|
||||
|
||||
private checkRanged(value:number|bigint, valueName:string, lowRange:number|bigint, highRange:number|bigint) {
|
||||
if (value < lowRange || value > highRange) {
|
||||
throw new Error(`The value of "${valueName}" is out of range. It must be >= ${lowRange} and <= ${highRange}. Received ${value}`);
|
||||
}
|
||||
}
|
||||
|
||||
private checkValue(value:number|bigint, low:number|bigint, high:number|bigint) {
|
||||
this.checkRanged(value, "value", low, high);
|
||||
}
|
||||
|
||||
private checkOffset(offset?:number) {
|
||||
if (offset) {
|
||||
this.checkRanged(offset, "offset", 0, this.buffer.length - 1);
|
||||
}
|
||||
}
|
||||
|
||||
// Writing methods
|
||||
public writeInt8(value:number, offset:number) {
|
||||
this.checkValue(value, -128, 127);
|
||||
this.checkOffset(offset);
|
||||
|
||||
this.dataView.setInt8(offset, value);
|
||||
|
||||
return this;
|
||||
}
|
||||
|
||||
public writeUInt8(value:number, offset:number) {
|
||||
this.checkValue(value, 0, 255);
|
||||
this.checkOffset(offset);
|
||||
|
||||
this.dataView.setUint8(offset, value);
|
||||
|
||||
return this;
|
||||
}
|
||||
|
||||
// Little Endian
|
||||
|
||||
public writeInt16LE(value:number, offset:number) {
|
||||
this.checkValue(value, -32768, 32767);
|
||||
this.checkOffset(offset);
|
||||
|
||||
this.dataView.setInt16(offset, value, true);
|
||||
|
||||
return this;
|
||||
}
|
||||
|
||||
public writeUInt16LE(value:number, offset:number) {
|
||||
this.checkValue(value, 0, 65535);
|
||||
this.checkOffset(offset);
|
||||
|
||||
this.dataView.setUint16(offset, value, true);
|
||||
|
||||
return this;
|
||||
}
|
||||
|
||||
public writeInt32LE(value:number, offset:number) {
|
||||
this.checkValue(value, -2147483648, 2147483647);
|
||||
this.checkOffset(offset);
|
||||
|
||||
this.dataView.setInt32(offset, value, true);
|
||||
|
||||
return this;
|
||||
}
|
||||
|
||||
public writeUInt32LE(value:number, offset:number) {
|
||||
this.checkValue(value, 0, 4294967295);
|
||||
this.checkOffset(offset);
|
||||
|
||||
this.dataView.setUint32(offset, value, true);
|
||||
|
||||
return this;
|
||||
}
|
||||
|
||||
public writeBigInt64LE(value:bigint|number, offset:number) {
|
||||
if (typeof(value) === "number") {
|
||||
value = BigInt(value);
|
||||
}
|
||||
|
||||
this.checkValue(value, -(2n ** 63n), 2n ** 63n);
|
||||
this.checkOffset(offset);
|
||||
|
||||
this.dataView.setBigInt64(offset, value, true);
|
||||
|
||||
return this;
|
||||
}
|
||||
|
||||
public writeBigUint64LE(value:bigint|number, offset:number) {
|
||||
if (typeof(value) === "number") {
|
||||
value = BigInt(value);
|
||||
}
|
||||
|
||||
this.checkValue(value, 0n, 2n ** 64n);
|
||||
this.checkOffset(offset);
|
||||
|
||||
this.dataView.setBigUint64(offset, value, true);
|
||||
|
||||
return this;
|
||||
}
|
||||
|
||||
public writeFloatLE(value:number, offset:number) {
|
||||
this.checkOffset(offset);
|
||||
|
||||
this.dataView.setFloat32(offset, value, true);
|
||||
|
||||
return this;
|
||||
}
|
||||
|
||||
public writeDoubleLE(value:number, offset:number) {
|
||||
this.checkOffset(offset);
|
||||
|
||||
this.dataView.setFloat64(offset, value, true);
|
||||
|
||||
return this;
|
||||
}
|
||||
|
||||
// Big Endian
|
||||
public writeInt16BE(value:number, offset:number) {
|
||||
this.checkValue(value, -32768, 32767);
|
||||
this.checkOffset(offset);
|
||||
|
||||
this.dataView.setInt16(offset, value, false);
|
||||
|
||||
return this;
|
||||
}
|
||||
|
||||
public writeUInt16BE(value:number, offset:number) {
|
||||
this.checkValue(value, 0, 65535);
|
||||
this.checkOffset(offset);
|
||||
|
||||
this.dataView.setUint16(offset, value, false);
|
||||
|
||||
return this;
|
||||
}
|
||||
|
||||
public writeInt32BE(value:number, offset:number) {
|
||||
this.checkValue(value, -2147483648, 2147483647);
|
||||
this.checkOffset(offset);
|
||||
|
||||
this.dataView.setInt32(offset, value, false);
|
||||
|
||||
return this;
|
||||
}
|
||||
|
||||
public writeUInt32BE(value:number, offset:number) {
|
||||
this.checkValue(value, 0, 4294967295);
|
||||
this.checkOffset(offset);
|
||||
|
||||
this.dataView.setUint32(offset, value, false);
|
||||
|
||||
return this;
|
||||
}
|
||||
|
||||
public writeBigInt64BE(value:bigint|number, offset:number) {
|
||||
if (typeof(value) === "number") {
|
||||
value = BigInt(value);
|
||||
}
|
||||
|
||||
this.checkValue(value, -(2n ** 63n), 2n ** 63n);
|
||||
this.checkOffset(offset);
|
||||
|
||||
this.dataView.setBigInt64(offset, value, false);
|
||||
|
||||
return this;
|
||||
}
|
||||
|
||||
public writeBigUint64BE(value:bigint|number, offset:number) {
|
||||
if (typeof(value) === "number") {
|
||||
value = BigInt(value);
|
||||
}
|
||||
|
||||
this.checkValue(value, 0n, 2n ** 64n);
|
||||
this.checkOffset(offset);
|
||||
|
||||
this.dataView.setBigUint64(offset, value, false);
|
||||
|
||||
return this;
|
||||
}
|
||||
|
||||
public writeFloatBE(value:number, offset:number) {
|
||||
this.checkOffset(offset);
|
||||
|
||||
this.dataView.setFloat32(offset, value, false);
|
||||
|
||||
return this;
|
||||
}
|
||||
|
||||
public writeDoubleBE(value:number, offset:number) {
|
||||
this.checkOffset(offset);
|
||||
|
||||
this.dataView.setFloat64(offset, value, false);
|
||||
|
||||
return this;
|
||||
}
|
||||
|
||||
// Reading methods
|
||||
public readInt8(offset:number) {
|
||||
this.checkOffset(offset);
|
||||
|
||||
return this.dataView.getInt8(offset);
|
||||
}
|
||||
|
||||
public readUInt8(offset:number) {
|
||||
this.checkOffset(offset);
|
||||
|
||||
return this.dataView.getUint8(offset);
|
||||
}
|
||||
|
||||
// Little Endian
|
||||
|
||||
public readInt16LE(offset:number) {
|
||||
this.checkOffset(offset);
|
||||
|
||||
return this.dataView.getInt16(offset, true);
|
||||
}
|
||||
|
||||
public readUInt16LE(offset:number) {
|
||||
this.checkOffset(offset);
|
||||
|
||||
return this.dataView.getUint16(offset, true);
|
||||
}
|
||||
|
||||
public readInt32LE(offset:number) {
|
||||
this.checkOffset(offset);
|
||||
|
||||
return this.dataView.getInt32(offset, true);
|
||||
}
|
||||
|
||||
public readUInt32LE(offset:number) {
|
||||
this.checkOffset(offset);
|
||||
|
||||
return this.dataView.getUint32(offset, true);
|
||||
}
|
||||
|
||||
public readBigInt64LE(offset:number) {
|
||||
this.checkOffset(offset);
|
||||
|
||||
return this.dataView.getBigInt64(offset, true);
|
||||
}
|
||||
|
||||
public readBigUint64LE(offset:number) {
|
||||
this.checkOffset(offset);
|
||||
|
||||
return this.dataView.getBigUint64(offset, true);
|
||||
}
|
||||
|
||||
public readFloatLE(offset:number) {
|
||||
this.checkOffset(offset);
|
||||
|
||||
return this.dataView.getFloat32(offset, true);
|
||||
}
|
||||
|
||||
public readDoubleLE(offset:number) {
|
||||
this.checkOffset(offset);
|
||||
|
||||
return this.dataView.getFloat64(offset, true);
|
||||
}
|
||||
|
||||
// Big Endian
|
||||
public readInt16BE(offset:number) {
|
||||
this.checkOffset(offset);
|
||||
|
||||
return this.dataView.getInt16(offset, false);
|
||||
}
|
||||
|
||||
public readUInt16BE(offset:number) {
|
||||
this.checkOffset(offset);
|
||||
|
||||
return this.dataView.getUint16(offset, false);
|
||||
}
|
||||
|
||||
public readInt32BE(offset:number) {
|
||||
this.checkOffset(offset);
|
||||
|
||||
return this.dataView.getInt32(offset, false);
|
||||
}
|
||||
|
||||
public readUInt32BE(offset:number) {
|
||||
this.checkOffset(offset);
|
||||
|
||||
return this.dataView.getUint32(offset, false);
|
||||
}
|
||||
|
||||
public readBigInt64BE(offset:number) {
|
||||
this.checkOffset(offset);
|
||||
|
||||
return this.dataView.getBigInt64(offset, false);
|
||||
}
|
||||
|
||||
public readBigUint64BE(offset:number) {
|
||||
this.checkOffset(offset);
|
||||
|
||||
return this.dataView.getBigUint64(offset, false);
|
||||
}
|
||||
|
||||
public readFloatBE(offset:number) {
|
||||
this.checkOffset(offset);
|
||||
|
||||
return this.dataView.getFloat32(offset, false);
|
||||
}
|
||||
|
||||
public readDoubleBE(offset:number) {
|
||||
this.checkOffset(offset);
|
||||
|
||||
return this.dataView.getFloat64(offset, false);
|
||||
}
|
||||
}
|
||||
|
||||
export function getBufferClass() : BufferConstructor {
|
||||
if (typeof(Buffer) === "undefined") {
|
||||
// @ts-ignore
|
||||
return BrowserBuffer;
|
||||
} else {
|
||||
return Buffer;
|
||||
}
|
||||
}
|
|
@ -1,3 +1,6 @@
|
|||
// Copyright (c) Holly Stubbs (tgpholly) - Licensed under MIT
|
||||
// Check LICENSE in repository root for more information.
|
||||
|
||||
export class ReaderBase {
|
||||
public buffer:Buffer;
|
||||
public offset:number;
|
||||
|
@ -7,6 +10,14 @@ export class ReaderBase {
|
|||
this.offset = 0;
|
||||
}
|
||||
|
||||
public get readOffset() {
|
||||
return this.offset;
|
||||
}
|
||||
|
||||
public get length() {
|
||||
return this.buffer.length;
|
||||
}
|
||||
|
||||
public readBuffer(bytes:number) {
|
||||
const value = this.buffer.subarray(this.offset, this.offset + bytes);
|
||||
this.offset += bytes;
|
||||
|
@ -39,4 +50,25 @@ export class ReaderBase {
|
|||
public readBool() {
|
||||
return Boolean(this.readUByte());
|
||||
}
|
||||
|
||||
public readShortString() {
|
||||
const length = this.readUByte();
|
||||
let text = "";
|
||||
|
||||
for (let i = 0; i < length; i++) {
|
||||
text += String.fromCharCode(this.readUByte());
|
||||
}
|
||||
|
||||
return text;
|
||||
}
|
||||
|
||||
public readBytesAsString(bytesToRead:number) {
|
||||
let text = "";
|
||||
|
||||
for (let i = 0; i < bytesToRead; i++) {
|
||||
text += String.fromCharCode(this.readUByte());
|
||||
}
|
||||
|
||||
return text;
|
||||
}
|
||||
}
|
|
@ -1,14 +1,27 @@
|
|||
// Copyright (c) Holly Stubbs (tgpholly) - Licensed under MIT
|
||||
// Check LICENSE in repository root for more information.
|
||||
|
||||
import { getBufferClass } from "./BufferShim";
|
||||
|
||||
export class WriterBase {
|
||||
public buffer:Buffer;
|
||||
public offset:number;
|
||||
public readonly resizable:boolean;
|
||||
|
||||
public constructor(size:number = 0) {
|
||||
this.buffer = Buffer.alloc(size);
|
||||
this.buffer = getBufferClass().alloc(size);
|
||||
this.offset = 0;
|
||||
this.resizable = size === 0;
|
||||
}
|
||||
|
||||
public get writeOffset() {
|
||||
return this.offset;
|
||||
}
|
||||
|
||||
public get length() {
|
||||
return this.buffer.length;
|
||||
}
|
||||
|
||||
public toBuffer() {
|
||||
return this.buffer;
|
||||
}
|
||||
|
@ -18,20 +31,20 @@ export class WriterBase {
|
|||
}
|
||||
|
||||
public writeBuffer(buffer:Buffer) {
|
||||
this.buffer = Buffer.concat([this.buffer, buffer], this.buffer.length + buffer.length);
|
||||
this.buffer = getBufferClass().concat([this.buffer, buffer], this.buffer.length + buffer.length);
|
||||
|
||||
return this;
|
||||
}
|
||||
|
||||
public writeUint8Array(array:Uint8Array) {
|
||||
this.writeBuffer(Buffer.from(array));
|
||||
this.writeBuffer(getBufferClass().from(array));
|
||||
|
||||
return this;
|
||||
}
|
||||
|
||||
public writeByte(value:number) {
|
||||
if (this.resizable) {
|
||||
const buffer = Buffer.alloc(1);
|
||||
const buffer = getBufferClass().alloc(1);
|
||||
buffer.writeInt8(value);
|
||||
this.writeBuffer(buffer);
|
||||
} else {
|
||||
|
@ -44,7 +57,7 @@ export class WriterBase {
|
|||
|
||||
public writeUByte(value:number) {
|
||||
if (this.resizable) {
|
||||
const buffer = Buffer.alloc(1);
|
||||
const buffer = getBufferClass().alloc(1);
|
||||
buffer.writeUInt8(value);
|
||||
this.writeBuffer(buffer);
|
||||
} else {
|
||||
|
@ -63,4 +76,19 @@ export class WriterBase {
|
|||
|
||||
return this;
|
||||
}
|
||||
|
||||
public writeStringAsBytes(text:string) {
|
||||
let buffer;
|
||||
if (this.resizable) {
|
||||
buffer = getBufferClass().alloc(text.length);
|
||||
} else {
|
||||
buffer = this.buffer;
|
||||
}
|
||||
|
||||
for (let i = 0; i < text.length; i++) {
|
||||
buffer.writeUInt8(text.charCodeAt(i), i);
|
||||
}
|
||||
|
||||
return this;
|
||||
}
|
||||
}
|
3
index.ts
3
index.ts
|
@ -1,3 +1,6 @@
|
|||
// Copyright (c) Holly Stubbs (tgpholly) - Licensed under MIT
|
||||
// Check LICENSE in repository root for more information.
|
||||
|
||||
import { IReader } from "./readers/IReader";
|
||||
import { IWriter } from "./writers/IWriter";
|
||||
import { ReaderBE } from "./readers/ReaderBE";
|
||||
|
|
2869
package-lock.json
generated
2869
package-lock.json
generated
File diff suppressed because it is too large
Load diff
26
package.json
26
package.json
|
@ -1,33 +1,39 @@
|
|||
{
|
||||
"name": "bufferstuff",
|
||||
"version": "1.3.0",
|
||||
"version": "1.5.1",
|
||||
"description": "A set of utility classes for reading and writing binary data in NodeJS and the browser",
|
||||
"main": "./lib/index.js",
|
||||
"types": "./lib/index.d.ts",
|
||||
"scripts": {
|
||||
"updateCheck": "check-outdated",
|
||||
"_clean": "tsc --build --clean",
|
||||
|
||||
"build": "npm-run-all build:*",
|
||||
"build:smash": "ts-node ./tooling/fileSmasher.ts",
|
||||
"build:build": "tsc --build",
|
||||
"build:cleanup": "ts-node ./tooling/cleanup.ts",
|
||||
"_clean": "tsc --build --clean"
|
||||
|
||||
"buildweb": "npm-run-all buildweb:*",
|
||||
"buildweb:smash": "ts-node ./tooling/fileSmasher.ts forweb",
|
||||
"buildweb:build": "tsc --build",
|
||||
"buildweb:cleanup": "ts-node ./tooling/cleanup.ts"
|
||||
},
|
||||
"repository": {
|
||||
"type": "git",
|
||||
"url": "git+https://github.com/tgpholly/bufferStuff.git"
|
||||
"url": "https://git.eusv.net/tgpholly/bufferStuff.git"
|
||||
},
|
||||
"keywords": [],
|
||||
"author": "tgpholly",
|
||||
"license": "MIT",
|
||||
"bugs": {
|
||||
"url": "https://github.com/tgpholly/bufferStuff/issues"
|
||||
"url": "https://git.eusv.net/tgpholly/bufferStuff/issues"
|
||||
},
|
||||
"homepage": "https://github.com/tgpholly/bufferStuff#readme",
|
||||
"homepage": "https://git.eusv.net/tgpholly/bufferStuff#readme",
|
||||
"devDependencies": {
|
||||
"check-outdated": "^2.11.0",
|
||||
"ts-loader": "^9.4.4",
|
||||
"ts-node": "^10.9.1",
|
||||
"typescript": "^5.1.6",
|
||||
"npm-run-all": "^4.1.5"
|
||||
"check-outdated": "^2.12.0",
|
||||
"npm-run-all": "^4.1.5",
|
||||
"terser": "^5.27.0",
|
||||
"ts-node": "^10.9.2",
|
||||
"typescript": "^5.3.3"
|
||||
}
|
||||
}
|
||||
|
|
|
@ -1,9 +1,16 @@
|
|||
// Copyright (c) Holly Stubbs (tgpholly) - Licensed under MIT
|
||||
// Check LICENSE in repository root for more information.
|
||||
|
||||
export interface IReader {
|
||||
readOffset: number,
|
||||
length: number,
|
||||
readBuffer(bytes:number): Buffer,
|
||||
readUint8Array(bytes:number): Uint8Array,
|
||||
readByte(): number,
|
||||
readUByte(): number,
|
||||
readBool(): boolean,
|
||||
readShortString(): string,
|
||||
readBytesAsString(bytesToRead:number): string,
|
||||
readShort(): number,
|
||||
readUShort(): number,
|
||||
readInt(): number,
|
||||
|
@ -12,7 +19,7 @@ export interface IReader {
|
|||
readULong(): bigint,
|
||||
readFloat(): number,
|
||||
readDouble(): number,
|
||||
readShortString(): string,
|
||||
readString(): string,
|
||||
readShortsAsString(shortsToRead:number): string,
|
||||
readString16(): string,
|
||||
}
|
|
@ -1,3 +1,6 @@
|
|||
// Copyright (c) Holly Stubbs (tgpholly) - Licensed under MIT
|
||||
// Check LICENSE in repository root for more information.
|
||||
|
||||
import { IReader } from "./IReader";
|
||||
import { ReaderBase } from "../base/ReaderBase";
|
||||
|
||||
|
@ -50,20 +53,9 @@ export class ReaderBE extends ReaderBase implements IReader {
|
|||
return value;
|
||||
}
|
||||
|
||||
public readShortString() {
|
||||
const length = this.readUByte();
|
||||
let text:string = "";
|
||||
|
||||
for (let i = 0; i < length; i++) {
|
||||
text += String.fromCharCode(this.readUByte());
|
||||
}
|
||||
|
||||
return text;
|
||||
}
|
||||
|
||||
public readString() {
|
||||
const length = this.readUShort();
|
||||
let text:string = "";
|
||||
let text = "";
|
||||
|
||||
for (let i = 0; i < length; i++) {
|
||||
text += String.fromCharCode(this.readUByte());
|
||||
|
@ -74,7 +66,7 @@ export class ReaderBE extends ReaderBase implements IReader {
|
|||
|
||||
public readString16() {
|
||||
const length = this.readUShort();
|
||||
let text:string = "";
|
||||
let text = "";
|
||||
|
||||
for (let i = 0; i < length; i++) {
|
||||
text += String.fromCharCode(this.readUShort());
|
||||
|
@ -82,4 +74,14 @@ export class ReaderBE extends ReaderBase implements IReader {
|
|||
|
||||
return text;
|
||||
}
|
||||
|
||||
public readShortsAsString(shortsToRead:number) {
|
||||
let text = "";
|
||||
|
||||
for (let i = 0; i < shortsToRead; i++) {
|
||||
text += String.fromCharCode(this.readUShort());
|
||||
}
|
||||
|
||||
return text;
|
||||
}
|
||||
}
|
|
@ -1,3 +1,6 @@
|
|||
// Copyright (c) Holly Stubbs (tgpholly) - Licensed under MIT
|
||||
// Check LICENSE in repository root for more information.
|
||||
|
||||
import { IReader } from "./IReader";
|
||||
import { ReaderBase } from "../base/ReaderBase";
|
||||
|
||||
|
@ -50,17 +53,6 @@ export class ReaderLE extends ReaderBase implements IReader {
|
|||
return value;
|
||||
}
|
||||
|
||||
public readShortString() {
|
||||
const length = this.readUByte();
|
||||
let text:string = "";
|
||||
|
||||
for (let i = 0; i < length; i++) {
|
||||
text += String.fromCharCode(this.readUByte());
|
||||
}
|
||||
|
||||
return text;
|
||||
}
|
||||
|
||||
public readString() {
|
||||
const length = this.readUShort();
|
||||
let text:string = "";
|
||||
|
@ -82,4 +74,14 @@ export class ReaderLE extends ReaderBase implements IReader {
|
|||
|
||||
return text;
|
||||
}
|
||||
|
||||
public readShortsAsString(shortsToRead:number) {
|
||||
let text = "";
|
||||
|
||||
for (let i = 0; i < shortsToRead; i++) {
|
||||
text += String.fromCharCode(this.readUShort());
|
||||
}
|
||||
|
||||
return text;
|
||||
}
|
||||
}
|
|
@ -1,3 +1,6 @@
|
|||
// Copyright (c) Holly Stubbs (tgpholly) - Licensed under MIT
|
||||
// Check LICENSE in repository root for more information.
|
||||
|
||||
import { readdirSync, rmSync, renameSync } from "fs";
|
||||
|
||||
const libFiles = readdirSync("./lib");
|
||||
|
|
|
@ -1,3 +1,6 @@
|
|||
// Copyright (c) Holly Stubbs (tgpholly) - Licensed under MIT
|
||||
// Check LICENSE in repository root for more information.
|
||||
|
||||
// fileSmasher ~.~
|
||||
// for when you're just too lazy to
|
||||
// do it properly.
|
||||
|
@ -12,7 +15,7 @@ const toolinglessFolderPath = __dirname.replace("/tooling", "/");
|
|||
function readDir(nam:string) {
|
||||
const files = readdirSync(nam);
|
||||
for (const file of files) {
|
||||
if (nam == toolinglessFolderPath && (file.startsWith(".") || file == "tooling" || file == "lib" || file == "web" || file == "node_modules" || file == "combined.ts")) {
|
||||
if (nam == toolinglessFolderPath && (file.startsWith(".") || file == "tooling" || file == "lib" || file == "node_modules" || file == "combined.ts")) {
|
||||
continue;
|
||||
}
|
||||
|
||||
|
@ -60,7 +63,11 @@ for (const line of splitLines) {
|
|||
continue;
|
||||
}
|
||||
// Fix up classes, interfaces and such.
|
||||
resultLines.push(checkForMatchAndReplace(line));
|
||||
if (process.argv[2] === "forweb") {
|
||||
resultLines.push(line.replace("export class", "class").replace("export function", "function").replace("export enum", "enum").replace("export interface", "interface"));
|
||||
} else {
|
||||
resultLines.push(checkForMatchAndReplace(line));
|
||||
}
|
||||
}
|
||||
|
||||
writeFileSync("./combined.ts", resultLines.join("\n"));
|
||||
|
|
10
tooling/mangle.ts
Normal file
10
tooling/mangle.ts
Normal file
|
@ -0,0 +1,10 @@
|
|||
import { readFileSync, writeFileSync } from "fs";
|
||||
import { minify } from "terser";
|
||||
|
||||
(async () => {
|
||||
const mangled = await minify(readFileSync("./lib/index.js").toString(), {
|
||||
mangle: true,
|
||||
toplevel: true,
|
||||
});
|
||||
writeFileSync("./lib/index.min.js", `${mangled.code}`);
|
||||
})();
|
|
@ -2,7 +2,7 @@
|
|||
"compilerOptions": {
|
||||
"module": "CommonJS",
|
||||
"moduleResolution": "node",
|
||||
"target": "es6",
|
||||
"target": "ES2020",
|
||||
"esModuleInterop": true,
|
||||
"resolveJsonModule": true,
|
||||
"rootDir": "./",
|
||||
|
|
|
@ -1,69 +0,0 @@
|
|||
export class Buffer {
|
||||
public data:Uint8Array;
|
||||
|
||||
public constructor(size:number, data?:Array<number>|Uint8Array) {
|
||||
if (data !== undefined) {
|
||||
let usableData:Uint8Array;
|
||||
if (data instanceof Array) {
|
||||
usableData = new Uint8Array(data);
|
||||
} else {
|
||||
usableData = data;
|
||||
}
|
||||
|
||||
this.data = usableData;
|
||||
} else {
|
||||
this.data = new Uint8Array(size);
|
||||
}
|
||||
}
|
||||
|
||||
public get length() {
|
||||
return this.data.length;
|
||||
}
|
||||
|
||||
// TODO: toString
|
||||
|
||||
// TODO: Check correctness of this.
|
||||
public static concat(buffers:Array<Buffer>, totalLength?:number) {
|
||||
let joinedArrays:Uint8Array;
|
||||
if (totalLength !== undefined) {
|
||||
joinedArrays = new Uint8Array(totalLength);
|
||||
} else {
|
||||
let arraysLength = 0;
|
||||
for (const buffer of buffers) {
|
||||
arraysLength += buffer.length;
|
||||
}
|
||||
joinedArrays = new Uint8Array(arraysLength);
|
||||
}
|
||||
|
||||
let offset = 0;
|
||||
for (const buffer of buffers) {
|
||||
joinedArrays.set(buffer.data, offset);
|
||||
offset += buffer.length;
|
||||
}
|
||||
|
||||
return new Buffer(0, joinedArrays);
|
||||
}
|
||||
|
||||
// Little Endian
|
||||
|
||||
// Writer methods
|
||||
public writeInt8(value:number, offset?:number) {
|
||||
if (offset === undefined) {
|
||||
// TODO: Handle writing without an offset
|
||||
throw new Error("Writing without offset is currently unimplemented");
|
||||
}
|
||||
if (value >= 0) {
|
||||
this.data[offset] = value;
|
||||
} else {
|
||||
this.data[offset] = 256 + value;
|
||||
}
|
||||
}
|
||||
|
||||
public writeUInt8(value:number, offset?:number) {
|
||||
if (offset === undefined) {
|
||||
// TODO: Handle writing without an offset
|
||||
throw new Error("Writing without offset is currently unimplemented");
|
||||
}
|
||||
this.data[offset] = value;
|
||||
}
|
||||
}
|
|
@ -1,4 +1,9 @@
|
|||
// Copyright (c) Holly Stubbs (tgpholly) - Licensed under MIT
|
||||
// Check LICENSE in repository root for more information.
|
||||
|
||||
export interface IWriter {
|
||||
writeOffset: number,
|
||||
length: number,
|
||||
toBuffer(): Buffer,
|
||||
toString(): string,
|
||||
writeBuffer(buffer:Buffer): IWriter,
|
||||
|
@ -6,15 +11,17 @@ export interface IWriter {
|
|||
writeByte(value:number): IWriter,
|
||||
writeUByte(value:number): IWriter,
|
||||
writeBool(value:boolean|number): IWriter,
|
||||
writeStringAsBytes(text:string): IWriter,
|
||||
writeShort(value:number): IWriter,
|
||||
writeUShort(value:number): IWriter,
|
||||
writeInt(value:number): IWriter,
|
||||
writeUInt(value:number): IWriter,
|
||||
writeLong(value:number|bigint): IWriter,
|
||||
writeULong(value:number): IWriter,
|
||||
writeULong(value:number|bigint): IWriter,
|
||||
writeFloat(value:number): IWriter,
|
||||
writeDouble(value:number): IWriter,
|
||||
writeShortString(text:string): IWriter,
|
||||
writeString(text:string): IWriter,
|
||||
writeString16(text:string): IWriter,
|
||||
writeStringAsShorts(text:string): IWriter
|
||||
}
|
|
@ -1,10 +1,14 @@
|
|||
// Copyright (c) Holly Stubbs (tgpholly) - Licensed under MIT
|
||||
// Check LICENSE in repository root for more information.
|
||||
|
||||
import { IWriter } from "./IWriter";
|
||||
import { WriterBase } from "../base/WriterBase";
|
||||
import { getBufferClass } from "../base/BufferShim";
|
||||
|
||||
export class WriterBE extends WriterBase implements IWriter {
|
||||
public writeShort(value:number) {
|
||||
if (this.resizable) {
|
||||
const buffer = Buffer.alloc(2);
|
||||
const buffer = getBufferClass().alloc(2);
|
||||
buffer.writeInt16BE(value);
|
||||
this.writeBuffer(buffer);
|
||||
} else {
|
||||
|
@ -17,7 +21,7 @@ export class WriterBE extends WriterBase implements IWriter {
|
|||
|
||||
public writeUShort(value:number) {
|
||||
if (this.resizable) {
|
||||
const buffer = Buffer.alloc(2);
|
||||
const buffer = getBufferClass().alloc(2);
|
||||
buffer.writeUInt16BE(value);
|
||||
this.writeBuffer(buffer);
|
||||
} else {
|
||||
|
@ -30,7 +34,7 @@ export class WriterBE extends WriterBase implements IWriter {
|
|||
|
||||
public writeInt(value:number) {
|
||||
if (this.resizable) {
|
||||
const buffer = Buffer.alloc(4);
|
||||
const buffer = getBufferClass().alloc(4);
|
||||
buffer.writeInt32BE(value);
|
||||
this.writeBuffer(buffer);
|
||||
} else {
|
||||
|
@ -43,7 +47,7 @@ export class WriterBE extends WriterBase implements IWriter {
|
|||
|
||||
public writeUInt(value:number) {
|
||||
if (this.resizable) {
|
||||
const buffer = Buffer.alloc(4);
|
||||
const buffer = getBufferClass().alloc(4);
|
||||
buffer.writeUInt32BE(value);
|
||||
this.writeBuffer(buffer);
|
||||
} else {
|
||||
|
@ -60,7 +64,7 @@ export class WriterBE extends WriterBase implements IWriter {
|
|||
}
|
||||
|
||||
if (this.resizable) {
|
||||
const buffer = Buffer.alloc(8);
|
||||
const buffer = getBufferClass().alloc(8);
|
||||
buffer.writeBigInt64BE(value);
|
||||
this.writeBuffer(buffer);
|
||||
} else {
|
||||
|
@ -77,7 +81,7 @@ export class WriterBE extends WriterBase implements IWriter {
|
|||
}
|
||||
|
||||
if (this.resizable) {
|
||||
const buffer = Buffer.alloc(8);
|
||||
const buffer = getBufferClass().alloc(8);
|
||||
buffer.writeBigUint64BE(value);
|
||||
this.writeBuffer(buffer);
|
||||
} else {
|
||||
|
@ -90,7 +94,7 @@ export class WriterBE extends WriterBase implements IWriter {
|
|||
|
||||
public writeFloat(value:number) {
|
||||
if (this.resizable) {
|
||||
const buffer = Buffer.alloc(4);
|
||||
const buffer = getBufferClass().alloc(4);
|
||||
buffer.writeFloatBE(value);
|
||||
this.writeBuffer(buffer);
|
||||
} else {
|
||||
|
@ -103,7 +107,7 @@ export class WriterBE extends WriterBase implements IWriter {
|
|||
|
||||
public writeDouble(value:number) {
|
||||
if (this.resizable) {
|
||||
const buffer = Buffer.alloc(8);
|
||||
const buffer = getBufferClass().alloc(8);
|
||||
buffer.writeDoubleBE(value);
|
||||
this.writeBuffer(buffer);
|
||||
} else {
|
||||
|
@ -143,4 +147,19 @@ export class WriterBE extends WriterBase implements IWriter {
|
|||
|
||||
return this;
|
||||
}
|
||||
|
||||
public writeStringAsShorts(text:string) {
|
||||
let buffer:Buffer;
|
||||
if (this.resizable) {
|
||||
buffer = getBufferClass().alloc(text.length * 2);
|
||||
} else {
|
||||
buffer = this.buffer;
|
||||
}
|
||||
|
||||
for (let i = 0; i < text.length; i++) {
|
||||
buffer.writeUint16BE(text.charCodeAt(i), i);
|
||||
}
|
||||
|
||||
return this;
|
||||
}
|
||||
}
|
|
@ -1,10 +1,14 @@
|
|||
// Copyright (c) Holly Stubbs (tgpholly) - Licensed under MIT
|
||||
// Check LICENSE in repository root for more information.
|
||||
|
||||
import { IWriter } from "./IWriter";
|
||||
import { WriterBase } from "../base/WriterBase";
|
||||
import { getBufferClass } from "../base/BufferShim";
|
||||
|
||||
export class WriterLE extends WriterBase implements IWriter {
|
||||
public writeShort(value:number) {
|
||||
if (this.resizable) {
|
||||
const buffer = Buffer.alloc(2);
|
||||
const buffer = getBufferClass().alloc(2);
|
||||
buffer.writeInt16LE(value);
|
||||
this.writeBuffer(buffer);
|
||||
} else {
|
||||
|
@ -17,7 +21,7 @@ export class WriterLE extends WriterBase implements IWriter {
|
|||
|
||||
public writeUShort(value:number) {
|
||||
if (this.resizable) {
|
||||
const buffer = Buffer.alloc(2);
|
||||
const buffer = getBufferClass().alloc(2);
|
||||
buffer.writeUInt16LE(value);
|
||||
this.writeBuffer(buffer);
|
||||
} else {
|
||||
|
@ -30,7 +34,7 @@ export class WriterLE extends WriterBase implements IWriter {
|
|||
|
||||
public writeInt(value:number) {
|
||||
if (this.resizable) {
|
||||
const buffer = Buffer.alloc(4);
|
||||
const buffer = getBufferClass().alloc(4);
|
||||
buffer.writeInt32LE(value);
|
||||
this.writeBuffer(buffer);
|
||||
} else {
|
||||
|
@ -42,7 +46,7 @@ export class WriterLE extends WriterBase implements IWriter {
|
|||
}
|
||||
public writeUInt(value:number) {
|
||||
if (this.resizable) {
|
||||
const buffer = Buffer.alloc(4);
|
||||
const buffer = getBufferClass().alloc(4);
|
||||
buffer.writeUInt32LE(value);
|
||||
this.writeBuffer(buffer);
|
||||
} else {
|
||||
|
@ -59,7 +63,7 @@ export class WriterLE extends WriterBase implements IWriter {
|
|||
}
|
||||
|
||||
if (this.resizable) {
|
||||
const buffer = Buffer.alloc(8);
|
||||
const buffer = getBufferClass().alloc(8);
|
||||
buffer.writeBigInt64LE(value);
|
||||
this.writeBuffer(buffer);
|
||||
} else {
|
||||
|
@ -76,7 +80,7 @@ export class WriterLE extends WriterBase implements IWriter {
|
|||
}
|
||||
|
||||
if (this.resizable) {
|
||||
const buffer = Buffer.alloc(8);
|
||||
const buffer = getBufferClass().alloc(8);
|
||||
buffer.writeBigUint64LE(value);
|
||||
this.writeBuffer(buffer);
|
||||
} else {
|
||||
|
@ -89,7 +93,7 @@ export class WriterLE extends WriterBase implements IWriter {
|
|||
|
||||
public writeFloat(value:number) {
|
||||
if (this.resizable) {
|
||||
const buffer = Buffer.alloc(4);
|
||||
const buffer = getBufferClass().alloc(4);
|
||||
buffer.writeFloatLE(value);
|
||||
this.writeBuffer(buffer);
|
||||
} else {
|
||||
|
@ -102,7 +106,7 @@ export class WriterLE extends WriterBase implements IWriter {
|
|||
|
||||
public writeDouble(value:number) {
|
||||
if (this.resizable) {
|
||||
const buffer = Buffer.alloc(8);
|
||||
const buffer = getBufferClass().alloc(8);
|
||||
buffer.writeDoubleLE(value);
|
||||
this.writeBuffer(buffer);
|
||||
} else {
|
||||
|
@ -142,4 +146,19 @@ export class WriterLE extends WriterBase implements IWriter {
|
|||
|
||||
return this;
|
||||
}
|
||||
|
||||
public writeStringAsShorts(text:string) {
|
||||
let buffer:Buffer;
|
||||
if (this.resizable) {
|
||||
buffer = getBufferClass().alloc(text.length * 2);
|
||||
} else {
|
||||
buffer = this.buffer;
|
||||
}
|
||||
|
||||
for (let i = 0; i < text.length; i++) {
|
||||
buffer.writeUint16LE(text.charCodeAt(i), i);
|
||||
}
|
||||
|
||||
return this;
|
||||
}
|
||||
}
|
Loading…
Reference in a new issue