mirror of
https://github.com/denoland/std.git
synced 2024-11-22 04:59:05 +00:00
feat(encoding/binary): add varnumBytes(), varbigBytes() (denoland/deno#5173)
This commit is contained in:
parent
dce2ff677a
commit
431c07de25
@ -1,9 +1,9 @@
|
||||
// Copyright 2018-2020 the Deno authors. All rights reserved. MIT license.
|
||||
|
||||
type RawBaseTypes = "int8" | "int16" | "int32" | "uint8" | "uint16" | "uint32";
|
||||
type RawNumberTypes = RawBaseTypes | "float32" | "float64";
|
||||
type RawBigTypes = RawBaseTypes | "int64" | "uint64";
|
||||
type RawTypes = RawNumberTypes | RawBigTypes;
|
||||
type RawBaseType = "int8" | "int16" | "int32" | "uint8" | "uint16" | "uint32";
|
||||
type RawNumberType = RawBaseType | "float32" | "float64";
|
||||
type RawBigType = RawBaseType | "int64" | "uint64";
|
||||
export type DataType = RawNumberType | RawBigType;
|
||||
|
||||
/** How encoded binary data is ordered. */
|
||||
export type Endianness = "little" | "big";
|
||||
@ -11,7 +11,7 @@ export type Endianness = "little" | "big";
|
||||
/** Options for working with the `number` type. */
|
||||
export interface VarnumOptions {
|
||||
/** The binary format used. */
|
||||
dataType?: RawNumberTypes;
|
||||
dataType?: RawNumberType;
|
||||
/** The binary encoding order used. */
|
||||
endian?: Endianness;
|
||||
}
|
||||
@ -19,12 +19,12 @@ export interface VarnumOptions {
|
||||
/** Options for working with the `bigint` type. */
|
||||
export interface VarbigOptions {
|
||||
/** The binary format used. */
|
||||
dataType?: RawBigTypes;
|
||||
dataType?: RawBigType;
|
||||
/** The binary encoding order used. */
|
||||
endian?: Endianness;
|
||||
}
|
||||
|
||||
const rawTypeSizes = {
|
||||
const rawTypeSizes: Record<DataType, number> = {
|
||||
int8: 1,
|
||||
uint8: 1,
|
||||
int16: 2,
|
||||
@ -35,16 +35,16 @@ const rawTypeSizes = {
|
||||
uint64: 8,
|
||||
float32: 4,
|
||||
float64: 8,
|
||||
};
|
||||
} as const;
|
||||
|
||||
/** Returns the number of bytes required to store the given data-type. */
|
||||
export function sizeof(dataType: RawTypes): number {
|
||||
/** Number of bytes required to store `dataType`. */
|
||||
export function sizeof(dataType: DataType): number {
|
||||
return rawTypeSizes[dataType];
|
||||
}
|
||||
|
||||
/** Reads `n` bytes from `r`.
|
||||
*
|
||||
* Returns it in a `Uint8Array`, or throws `Deno.errors.UnexpectedEof` if `n` bytes cannot be read. */
|
||||
* Resolves it in a `Uint8Array`, or throws `Deno.errors.UnexpectedEof` if `n` bytes cannot be read. */
|
||||
export async function getNBytes(
|
||||
r: Deno.Reader,
|
||||
n: number
|
||||
@ -55,8 +55,9 @@ export async function getNBytes(
|
||||
return scratch;
|
||||
}
|
||||
|
||||
/** Decode a number from `b`, and return it as a `number`. Data-type defaults to `int32`.
|
||||
* Returns `null` if `b` is too short for the data-type given in `o`. */
|
||||
/** Decodes a number from `b`. If `o.bytes` is shorter than `sizeof(o.dataType)`, returns `null`.
|
||||
*
|
||||
* `o.dataType` defaults to `"int32"`. */
|
||||
export function varnum(b: Uint8Array, o: VarnumOptions = {}): number | null {
|
||||
o.dataType = o.dataType ?? "int32";
|
||||
const littleEndian = (o.endian ?? "big") === "little" ? true : false;
|
||||
@ -82,8 +83,9 @@ export function varnum(b: Uint8Array, o: VarnumOptions = {}): number | null {
|
||||
}
|
||||
}
|
||||
|
||||
/** Decode an integer from `b`, and return it as a `bigint`. Data-type defaults to `int64`.
|
||||
* Returns `null` if `b` is too short for the data-type given in `o`. */
|
||||
/** Decodes a bigint from `b`. If `o.bytes` is shorter than `sizeof(o.dataType)`, returns `null`.
|
||||
*
|
||||
* `o.dataType` defaults to `"int64"`. */
|
||||
export function varbig(b: Uint8Array, o: VarbigOptions = {}): bigint | null {
|
||||
o.dataType = o.dataType ?? "int64";
|
||||
const littleEndian = (o.endian ?? "big") === "little" ? true : false;
|
||||
@ -109,8 +111,9 @@ export function varbig(b: Uint8Array, o: VarbigOptions = {}): bigint | null {
|
||||
}
|
||||
}
|
||||
|
||||
/** Encode a number `x` into `b`, and return the number of bytes used. Data-type defaults to `int32`.
|
||||
* Returns 0 if `b` is too short for the data-type given in `o`. */
|
||||
/** Encodes number `x` into `b`. Returns the number of bytes used, or `0` if `b` is shorter than `sizeof(o.dataType)`.
|
||||
*
|
||||
* `o.dataType` defaults to `"int32"`. */
|
||||
export function putVarnum(
|
||||
b: Uint8Array,
|
||||
x: number,
|
||||
@ -149,8 +152,9 @@ export function putVarnum(
|
||||
return sizeof(o.dataType);
|
||||
}
|
||||
|
||||
/** Encode an integer `x` into `b`, and return the number of bytes used. Data-type defaults to `int64`.
|
||||
* Returns 0 if `b` is too short for the data-type given in `o`. */
|
||||
/** Encodes bigint `x` into `b`. Returns the number of bytes used, or `0` if `b` is shorter than `sizeof(o.dataType)`.
|
||||
*
|
||||
* `o.dataType` defaults to `"int64"`. */
|
||||
export function putVarbig(
|
||||
b: Uint8Array,
|
||||
x: bigint,
|
||||
@ -189,9 +193,9 @@ export function putVarbig(
|
||||
return sizeof(o.dataType);
|
||||
}
|
||||
|
||||
/** Reads a number from `r`, comsuming `sizeof(o.dataType)` bytes. Data-type defaults to `int32`.
|
||||
/** Decodes a number from `r`, comsuming `sizeof(o.dataType)` bytes. If less than `sizeof(o.dataType)` bytes were read, throws `Deno.errors.unexpectedEof`.
|
||||
*
|
||||
* Returns it as `number`, or throws `Deno.errors.UnexpectedEof` if not enough bytes can be read. */
|
||||
* `o.dataType` defaults to `"int32"`. */
|
||||
export async function readVarnum(
|
||||
r: Deno.Reader,
|
||||
o: VarnumOptions = {}
|
||||
@ -201,9 +205,9 @@ export async function readVarnum(
|
||||
return varnum(scratch, o) as number;
|
||||
}
|
||||
|
||||
/** Reads an integer from `r`, comsuming `sizeof(o.dataType)` bytes. Data-type defaults to `int64`.
|
||||
/** Decodes a bigint from `r`, comsuming `sizeof(o.dataType)` bytes. If less than `sizeof(o.dataType)` bytes were read, throws `Deno.errors.unexpectedEof`.
|
||||
*
|
||||
* Returns it as `bigint`, or throws `Deno.errors.UnexpectedEof` if not enough bytes can be read. */
|
||||
* `o.dataType` defaults to `"int64"`. */
|
||||
export async function readVarbig(
|
||||
r: Deno.Reader,
|
||||
o: VarbigOptions = {}
|
||||
@ -213,9 +217,9 @@ export async function readVarbig(
|
||||
return varbig(scratch, o) as bigint;
|
||||
}
|
||||
|
||||
/** Writes a number `x` to `w`. Data-type defaults to `int32`.
|
||||
/** Encodes and writes `x` to `w`. Resolves to the number of bytes written.
|
||||
*
|
||||
* Returns the number of bytes written. */
|
||||
* `o.dataType` defaults to `"int32"`. */
|
||||
export function writeVarnum(
|
||||
w: Deno.Writer,
|
||||
x: number,
|
||||
@ -227,9 +231,9 @@ export function writeVarnum(
|
||||
return w.write(scratch);
|
||||
}
|
||||
|
||||
/** Writes an integer `x` to `w`. Data-type defaults to `int64`.
|
||||
/** Encodes and writes `x` to `w`. Resolves to the number of bytes written.
|
||||
*
|
||||
* Returns the number of bytes written. */
|
||||
* `o.dataType` defaults to `"int64"`. */
|
||||
export function writeVarbig(
|
||||
w: Deno.Writer,
|
||||
x: bigint,
|
||||
@ -240,3 +244,23 @@ export function writeVarbig(
|
||||
putVarbig(scratch, x, o);
|
||||
return w.write(scratch);
|
||||
}
|
||||
|
||||
/** Encodes `x` into a new `Uint8Array`.
|
||||
*
|
||||
* `o.dataType` defaults to `"int32"` */
|
||||
export function varnumBytes(x: number, o: VarnumOptions = {}): Uint8Array {
|
||||
o.dataType = o.dataType ?? "int32";
|
||||
const b = new Uint8Array(sizeof(o.dataType));
|
||||
putVarnum(b, x, o);
|
||||
return b;
|
||||
}
|
||||
|
||||
/** Encodes `x` into a new `Uint8Array`.
|
||||
*
|
||||
* `o.dataType` defaults to `"int64"` */
|
||||
export function varbigBytes(x: bigint, o: VarbigOptions = {}): Uint8Array {
|
||||
o.dataType = o.dataType ?? "int64";
|
||||
const b = new Uint8Array(sizeof(o.dataType));
|
||||
putVarbig(b, x, o);
|
||||
return b;
|
||||
}
|
||||
|
@ -12,6 +12,8 @@ import {
|
||||
varnum,
|
||||
writeVarbig,
|
||||
writeVarnum,
|
||||
varbigBytes,
|
||||
varnumBytes,
|
||||
} from "./binary.ts";
|
||||
|
||||
Deno.test("testGetNBytes", async function (): Promise<void> {
|
||||
@ -160,3 +162,29 @@ Deno.test("testWriteVarnumLittleEndian", async function (): Promise<void> {
|
||||
await buff.read(data);
|
||||
assertEquals(data, new Uint8Array([0x01, 0x02, 0x03, 0x04]));
|
||||
});
|
||||
|
||||
Deno.test("testVarbigBytes", function (): void {
|
||||
const rslt = varbigBytes(0x0102030405060708n);
|
||||
assertEquals(
|
||||
rslt,
|
||||
new Uint8Array([0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08])
|
||||
);
|
||||
});
|
||||
|
||||
Deno.test("testVarbigBytesLittleEndian", function (): void {
|
||||
const rslt = varbigBytes(0x0807060504030201n, { endian: "little" });
|
||||
assertEquals(
|
||||
rslt,
|
||||
new Uint8Array([0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08])
|
||||
);
|
||||
});
|
||||
|
||||
Deno.test("testVarnumBytes", function (): void {
|
||||
const rslt = varnumBytes(0x01020304);
|
||||
assertEquals(rslt, new Uint8Array([0x01, 0x02, 0x03, 0x04]));
|
||||
});
|
||||
|
||||
Deno.test("testVarnumBytesLittleEndian", function (): void {
|
||||
const rslt = varnumBytes(0x04030201, { endian: "little" });
|
||||
assertEquals(rslt, new Uint8Array([0x01, 0x02, 0x03, 0x04]));
|
||||
});
|
||||
|
Loading…
Reference in New Issue
Block a user