引入luban配表 需要命令行 npm install buffer
This commit is contained in:
@@ -0,0 +1,411 @@
|
||||
import b from "buffer/index.js";
|
||||
const { Buffer } = b;
|
||||
|
||||
export enum EDeserializeError {
|
||||
OK,
|
||||
NOT_ENOUGH,
|
||||
EXCEED_SIZE,
|
||||
}
|
||||
|
||||
|
||||
const MIN_CAPACITY: number = 16
|
||||
|
||||
const f_2power32 = Math.pow(2, 32)
|
||||
const f_2power56 = Math.pow(2, 56)
|
||||
|
||||
export default class ByteBuf {
|
||||
private static emptyBuff: Buffer = Buffer.allocUnsafe(0)
|
||||
|
||||
constructor(bytes?: Uint8Array) {
|
||||
this._bytes = bytes != null ? Buffer.from(bytes) : ByteBuf.emptyBuff
|
||||
this._readerIndex = 0
|
||||
this._writerIndex = bytes != null ? bytes.length : 0
|
||||
}
|
||||
|
||||
|
||||
Replace(bytes: Uint8Array) {
|
||||
this._bytes = Buffer.from(bytes)
|
||||
this._readerIndex = 0
|
||||
this._writerIndex = bytes.length
|
||||
}
|
||||
|
||||
Replace2(bytes: Uint8Array, beginPos: number, endPos: number) {
|
||||
this._bytes = Buffer.from(bytes, beginPos, endPos - beginPos)
|
||||
this._readerIndex = beginPos
|
||||
this._writerIndex = endPos
|
||||
}
|
||||
|
||||
private _bytes: Buffer
|
||||
|
||||
// get Bytes(): Buffer { return this._bytes }
|
||||
|
||||
private _readerIndex: number
|
||||
// get this._readerIndex(): number { return this._readerIndex }
|
||||
// set this._readerIndex(value: number) { this._readerIndex = value }
|
||||
|
||||
private _writerIndex: number
|
||||
// get this._writerIndex(): number { return this._writerIndex }
|
||||
// set this._writerIndex(value: number) { this._writerIndex = value }
|
||||
|
||||
get capacity(): number { return this._bytes.length }
|
||||
get size(): number { return this._writerIndex - this._readerIndex }
|
||||
get empty(): boolean { return this._writerIndex <= this._readerIndex }
|
||||
get notEmpty(): boolean { return this._writerIndex > this._readerIndex }
|
||||
|
||||
getBytesNotSafe(): Buffer { return this._bytes }
|
||||
|
||||
addReadIndex(add: number) {
|
||||
this._readerIndex += add
|
||||
}
|
||||
|
||||
private static emptyBytes: Uint8Array = new Uint8Array()
|
||||
|
||||
copyData(): Uint8Array {
|
||||
const n = this.remaining
|
||||
if (n > 0) {
|
||||
return new Uint8Array(this._bytes.buffer.slice(this._readerIndex, this._writerIndex))
|
||||
} else {
|
||||
return ByteBuf.emptyBytes
|
||||
}
|
||||
}
|
||||
|
||||
get remaining(): number { return this._writerIndex - this._readerIndex }
|
||||
|
||||
discardReadBytes() {
|
||||
this._bytes.copyWithin(0, this._readerIndex, this._writerIndex)
|
||||
this._writerIndex -= this._readerIndex
|
||||
this._readerIndex = 0
|
||||
}
|
||||
|
||||
|
||||
clear() {
|
||||
this._readerIndex = this._writerIndex = 0
|
||||
}
|
||||
|
||||
|
||||
private static propSize(initSize: number, needSize: number): number {
|
||||
for (let i = Math.max(initSize, MIN_CAPACITY); i <<= 1;) {
|
||||
if (i >= needSize) {
|
||||
return i
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private ensureRead(size: number) {
|
||||
if (this._readerIndex + size > this._writerIndex) {
|
||||
throw new Error()
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
private canRead(size: number): boolean {
|
||||
return (this._readerIndex + size <= this._writerIndex)
|
||||
}
|
||||
|
||||
readBool(): boolean {
|
||||
this.ensureRead(1)
|
||||
return this._bytes[this._readerIndex++] != 0
|
||||
}
|
||||
|
||||
readByte(): number {
|
||||
this.ensureRead(1)
|
||||
return this._bytes[this._readerIndex++]
|
||||
}
|
||||
|
||||
readShort(): number {
|
||||
this.ensureRead(1)
|
||||
const buf = this._bytes
|
||||
const h = buf.readUInt8(this._readerIndex)
|
||||
if (h < 0x80) {
|
||||
this._readerIndex++
|
||||
return h
|
||||
}
|
||||
else if (h < 0xc0) {
|
||||
this.ensureRead(2)
|
||||
const x = buf.readUInt16BE(this._readerIndex) & 0x3fff
|
||||
this._readerIndex += 2
|
||||
return x
|
||||
}
|
||||
else if ((h == 0xff)) {
|
||||
this.ensureRead(3)
|
||||
const x = buf.readInt16BE(this._readerIndex + 1)
|
||||
this._readerIndex += 3
|
||||
return x
|
||||
}
|
||||
else {
|
||||
throw new Error()
|
||||
}
|
||||
}
|
||||
|
||||
readInt(): number {
|
||||
const buf = this._bytes
|
||||
|
||||
this.ensureRead(1)
|
||||
const h = buf.readUInt8(this._readerIndex)
|
||||
if (h < 0x80) {
|
||||
this._readerIndex++
|
||||
return h
|
||||
}
|
||||
else if (h < 0xc0) {
|
||||
this.ensureRead(2)
|
||||
const x = buf.readUInt16BE(this._readerIndex) & 0x3fff
|
||||
this._readerIndex += 2
|
||||
return x
|
||||
}
|
||||
else if (h < 0xe0) {
|
||||
// console.log(`== read ${buf.readInt32BE(this._readerIndex)}`)
|
||||
this.ensureRead(3)
|
||||
const x = ((h & 0x1f) << 16) | (buf.readUInt16BE(this._readerIndex + 1))
|
||||
this._readerIndex += 3
|
||||
return x
|
||||
}
|
||||
else if (h < 0xf0) {
|
||||
this.ensureRead(4)
|
||||
// console.log(`== read ${buf.readInt32BE(this._readerIndex)}`)
|
||||
const x = buf.readInt32BE(this._readerIndex) & 0x0fffffff
|
||||
this._readerIndex += 4
|
||||
return x
|
||||
}
|
||||
else {
|
||||
this.ensureRead(5)
|
||||
const x = buf.readInt32BE(this._readerIndex + 1)
|
||||
this._readerIndex += 5
|
||||
return x
|
||||
}
|
||||
}
|
||||
|
||||
readFint(): number {
|
||||
this.ensureRead(4)
|
||||
const x = this._bytes.readInt32LE()
|
||||
this._readerIndex += 4
|
||||
return x
|
||||
}
|
||||
|
||||
readLongAsNumber(): number {
|
||||
const buf = this._bytes
|
||||
///
|
||||
/// 警告! 如有修改,记得调整 TryDeserializeInplaceOctets
|
||||
this.ensureRead(1)
|
||||
const h = buf.readUInt8(this._readerIndex)
|
||||
if (h < 0x80) {
|
||||
this._readerIndex++
|
||||
return h
|
||||
}
|
||||
else if (h < 0xc0) {
|
||||
this.ensureRead(2)
|
||||
const x = buf.readUInt16BE(this._readerIndex) & 0x3fff
|
||||
// console.log(`== read long :${x} index:${this._readerIndex}`)
|
||||
this._readerIndex += 2
|
||||
return x
|
||||
}
|
||||
else if (h < 0xe0) {
|
||||
// console.log(`== read ${buf.readInt32BE(this._readerIndex)}`)
|
||||
this.ensureRead(3)
|
||||
const x = ((h & 0x1f) << 16) | (buf.readUInt16BE(this._readerIndex + 1))
|
||||
this._readerIndex += 3
|
||||
return x
|
||||
}
|
||||
else if (h < 0xf0) {
|
||||
this.ensureRead(4)
|
||||
// console.log(`== read ${buf.readInt32BE(this._readerIndex)}`)
|
||||
const x = buf.readInt32BE(this._readerIndex) & 0x0fffffff
|
||||
this._readerIndex += 4
|
||||
return x
|
||||
}
|
||||
else if (h < 0xf8) {
|
||||
this.ensureRead(5)
|
||||
const xl = buf.readUInt32BE(this._readerIndex + 1)
|
||||
const xh = h & 0x07
|
||||
this._readerIndex += 5
|
||||
return xh * 0x100000000 + xl
|
||||
}
|
||||
else if (h < 0xfc) { // 1111 10xx - - - - -
|
||||
this.ensureRead(6)
|
||||
const xl = buf.readUInt32BE(this._readerIndex + 2)
|
||||
const xh = buf.readUInt16BE(this._readerIndex) & 0x3ff
|
||||
this._readerIndex += 6
|
||||
return xh * 0x100000000 + xl
|
||||
}
|
||||
else if (h < 0xfe) {
|
||||
this.ensureRead(7)
|
||||
const xl = buf.readUInt32BE(this._readerIndex + 3)
|
||||
const xh = (buf.readUInt32BE(this._readerIndex) >> 8) & 0x1ffff
|
||||
this._readerIndex += 7
|
||||
return xh * 0x100000000 + xl
|
||||
}
|
||||
else if (h < 0xff) { // 1111 1110, - - - - - - -
|
||||
this.ensureRead(8)
|
||||
// TODO 是否要对 < Number.MAX_SAFE_INTEGER 优化处理?
|
||||
const xl = buf.readUInt32BE(this._readerIndex + 4)
|
||||
const xh = buf.readUInt32BE(this._readerIndex) & 0xffffff
|
||||
this._readerIndex += 8
|
||||
return xh * f_2power32 + xl
|
||||
}
|
||||
else {
|
||||
this.ensureRead(9)
|
||||
const x = buf.readBigInt64BE(this._readerIndex + 1)
|
||||
// const xl = buf.readUInt32BE(this._readerIndex + 5)
|
||||
// const xh = buf.readInt32BE(this._readerIndex + 1)
|
||||
this._readerIndex += 9
|
||||
return Number(x)
|
||||
}
|
||||
}
|
||||
|
||||
readLong(): bigint {
|
||||
const buf = this._bytes
|
||||
///
|
||||
this.ensureRead(1)
|
||||
const h = buf.readUInt8(this._readerIndex)
|
||||
if (h < 0x80) {
|
||||
this._readerIndex++
|
||||
return BigInt(h)
|
||||
}
|
||||
else if (h < 0xc0) {
|
||||
this.ensureRead(2)
|
||||
const x = buf.readUInt16BE(this._readerIndex) & 0x3fff
|
||||
this._readerIndex += 2
|
||||
return BigInt(x)
|
||||
}
|
||||
else if (h < 0xe0) {
|
||||
this.ensureRead(3)
|
||||
const x = ((h & 0x1f) << 16) | (buf.readUInt16BE(this._readerIndex + 1))
|
||||
this._readerIndex += 3
|
||||
return BigInt(x)
|
||||
}
|
||||
else if (h < 0xf0) {
|
||||
this.ensureRead(4)
|
||||
const x = buf.readInt32BE(this._readerIndex) & 0x0fffffff
|
||||
this._readerIndex += 4
|
||||
return BigInt(x)
|
||||
}
|
||||
else if (h < 0xf8) {
|
||||
this.ensureRead(5)
|
||||
const xl = buf.readUInt32BE(this._readerIndex + 1)
|
||||
const xh = h & 0x07
|
||||
this._readerIndex += 5
|
||||
return BigInt(xh * 0x100000000 + xl)
|
||||
}
|
||||
else if (h < 0xfc) { // 1111 10xx - - - - -
|
||||
this.ensureRead(6)
|
||||
const xl = buf.readUInt32BE(this._readerIndex + 2)
|
||||
const xh = buf.readUInt16BE(this._readerIndex) & 0x3ff
|
||||
this._readerIndex += 6
|
||||
return BigInt(xh * 0x100000000 + xl)
|
||||
}
|
||||
else if (h < 0xfe) {
|
||||
this.ensureRead(7)
|
||||
const xl = buf.readUInt32BE(this._readerIndex + 3)
|
||||
const xh = (buf.readUInt32BE(this._readerIndex) >> 8) & 0x1ffff
|
||||
this._readerIndex += 7
|
||||
return BigInt(xh * 0x100000000 + xl)
|
||||
}
|
||||
else if (h < 0xff) { // 1111 1110, - - - - - - -
|
||||
this.ensureRead(8)
|
||||
// TODO 是否要对 < Number.MAX_SAFE_INTEGER 优化处理?
|
||||
const xl = buf.readUInt32BE(this._readerIndex + 4)
|
||||
const xh = buf.readUInt32BE(this._readerIndex) & 0xffffff
|
||||
// console.log(`== read8 ${xl} ${xh}`)
|
||||
this._readerIndex += 8
|
||||
return (BigInt(xh) << BigInt(32)) | BigInt(xl)
|
||||
}
|
||||
else {
|
||||
this.ensureRead(9)
|
||||
const x = buf.readBigInt64BE(this._readerIndex + 1)
|
||||
// const xl = buf.readUInt32BE(this._readerIndex + 5)
|
||||
// const xh = buf.readInt32BE(this._readerIndex + 1)
|
||||
this._readerIndex += 9
|
||||
return x
|
||||
}
|
||||
}
|
||||
|
||||
readFloat(): number {
|
||||
this.ensureRead(4)
|
||||
const x = this._bytes.readFloatLE(this._readerIndex)
|
||||
this._readerIndex += 4
|
||||
return x
|
||||
}
|
||||
|
||||
readDouble(): number {
|
||||
this.ensureRead(8)
|
||||
const x = this._bytes.readDoubleLE(this._readerIndex)
|
||||
this._readerIndex += 8
|
||||
return x
|
||||
}
|
||||
|
||||
readSize(): number {
|
||||
return this.readInt()
|
||||
}
|
||||
|
||||
// marshal int
|
||||
// n -> (n << 1) ^ (n >> 31)
|
||||
// read
|
||||
// (x >>> 1) ^ ((x << 31) >> 31)
|
||||
// (x >>> 1) ^ -(n&1)
|
||||
// WriteSint(x: number)
|
||||
// {
|
||||
// WriteUint(((uint)x << 1) ^ ((uint)x >> 31))
|
||||
// }
|
||||
|
||||
// readSint: number()
|
||||
// {
|
||||
// x: number = readUint()
|
||||
// return (int)((x >> 1) ^ ((x & 1) << 31))
|
||||
// }
|
||||
|
||||
|
||||
// marshal long
|
||||
// n -> (n << 1) ^ (n >> 63)
|
||||
// read
|
||||
// (x >>> 1) ^((x << 63) >> 63)
|
||||
// (x >>> 1) ^ -(n&1L)
|
||||
// WriteSlong(long x)
|
||||
// {
|
||||
// WriteUlong(((ulong)x << 1) ^ ((ulong)x >> 63))
|
||||
// }
|
||||
|
||||
// long readSlong()
|
||||
// {
|
||||
// long x = readLong()
|
||||
// return ((long)((ulong)x >> 1) ^ ((x & 1) << 63))
|
||||
// }
|
||||
|
||||
// // Uint8Array, [start, end)
|
||||
// static Func < Uint8Array, int, int, string > StringCacheFinder { get set }
|
||||
|
||||
readString(): string {
|
||||
const n = this.readSize()
|
||||
if (n > 0) {
|
||||
this.ensureRead(n)
|
||||
const s = this._bytes.toString("utf-8", this._readerIndex, this._readerIndex + n)
|
||||
this._readerIndex += n
|
||||
return s
|
||||
}
|
||||
else {
|
||||
return ""
|
||||
}
|
||||
}
|
||||
|
||||
readBytes(): Uint8Array {
|
||||
const n = this.readSize()
|
||||
if (n > 0) {
|
||||
this.ensureRead(n)
|
||||
const x = Buffer.from(this._bytes.slice(this._readerIndex, this._readerIndex + n))
|
||||
this._readerIndex += n
|
||||
return x
|
||||
}
|
||||
else {
|
||||
return ByteBuf.emptyBuff
|
||||
}
|
||||
}
|
||||
|
||||
readArrayBuffer(): ArrayBuffer {
|
||||
return this.readBytes().buffer
|
||||
}
|
||||
|
||||
SkipBytes() {
|
||||
const n = this.readSize()
|
||||
this.ensureRead(n)
|
||||
this._readerIndex += n
|
||||
}
|
||||
|
||||
}
|
||||
Reference in New Issue
Block a user