blob: 80e479d909ef3ec967a85f1d9afe941ecff79b8f [file]
/*
* Licensed to the Apache Software Foundation (ASF) under one
* or more contributor license agreements. See the NOTICE file
* distributed with this work for additional information
* regarding copyright ownership. The ASF licenses this file
* to you under the Apache License, Version 2.0 (the
* "License"); you may not use this file except in compliance
* with the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing,
* software distributed under the License is distributed on an
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
* KIND, either express or implied. See the License for the
* specific language governing permissions and limitations
* under the License.
*/
import { Config, LATIN1 } from "./type";
import { isNodeEnv } from "./util";
import { PlatformBuffer, alloc, fromUint8Array } from "./platformBuffer";
export const BinaryReader = (config: Config) => {
const sliceStringEnable = isNodeEnv && config.useSliceString;
let cursor = 0;
let dataView!: DataView;
let buffer!: PlatformBuffer;
let bigString: string;
const stringLatin1 = sliceStringEnable ? stringLatin1Fast : stringLatin1Slow;
function reset(ab: Uint8Array) {
buffer = fromUint8Array(ab);
dataView = new DataView(buffer.buffer, buffer.byteOffset);
if (sliceStringEnable) {
bigString = buffer.latin1Slice(0, buffer.byteLength);
}
cursor = 0;
}
function uint8() {
return dataView.getUint8(cursor++);
}
function int8() {
return dataView.getInt8(cursor++);
}
function uint16() {
const result = dataView.getUint16(cursor, true);
cursor += 2;
return result;
}
function int16() {
const result = dataView.getInt16(cursor, true);
cursor += 2;
return result;
}
function skip(len: number) {
cursor += len;
}
function int32() {
const result = dataView.getInt32(cursor, true);
cursor += 4;
return result;
}
function uint32() {
const result = dataView.getUint32(cursor, true);
cursor += 4;
return result;
}
function int64() {
const result = dataView.getBigInt64(cursor, true);
cursor += 8;
return result;
}
function uint64() {
const result = dataView.getBigUint64(cursor, true);
cursor += 8;
return result;
}
function float() {
const result = dataView.getFloat32(cursor, true);
cursor += 4;
return result;
}
function double() {
const result = dataView.getFloat64(cursor, true);
cursor += 8;
return result;
}
function stringUtf8(len: number) {
const result = buffer.utf8Slice(cursor, cursor + len);
cursor += len;
return result;
}
function stringOfVarInt32() {
const useLatin1 = config.useLatin1 ? uint8() === LATIN1 : false;
const len = varInt32();
return useLatin1 ? stringLatin1(len) : stringUtf8(len);
}
function stringLatin1Fast(len: number) {
const result = bigString.substring(cursor, cursor + len);
cursor += len;
return result;
}
function stringLatin1Slow(len: number) {
const result = buffer.latin1Slice(cursor, cursor + len);
cursor += len;
return result;
}
function binary(len: number) {
const result = alloc(len);
buffer.copy(result, 0, cursor, cursor + len);
cursor += len;
return result;
}
function bufferRef(len: number) {
const result = buffer.subarray(cursor, cursor + len);
cursor += len;
return result;
}
function varInt32() {
let byte_ = int8();
let result = byte_ & 0x7f;
if ((byte_ & 0x80) != 0) {
byte_ = int8();
result |= (byte_ & 0x7f) << 7;
if ((byte_ & 0x80) != 0) {
byte_ = int8();
result |= (byte_ & 0x7f) << 14;
if ((byte_ & 0x80) != 0) {
byte_ = int8();
result |= (byte_ & 0x7f) << 21;
if ((byte_ & 0x80) != 0) {
byte_ = int8();
result |= (byte_ & 0x7f) << 28;
}
}
}
}
return result;
}
return {
getCursor: () => cursor,
setCursor: (v: number) => (cursor = v),
varInt32,
int8,
buffer: binary,
bufferRef,
uint8,
reset,
stringUtf8,
stringLatin1,
stringOfVarInt32,
double,
float,
uint16,
int16,
uint64,
skip,
int64,
uint32,
int32,
};
};