Skip to content

Commit

Permalink
BREAKING(bytes): deprecate BytesList class (#3589)
Browse files Browse the repository at this point in the history
  • Loading branch information
aapoalas authored Aug 31, 2023
1 parent 7fc5cda commit 6d75c4e
Show file tree
Hide file tree
Showing 5 changed files with 214 additions and 91 deletions.
41 changes: 41 additions & 0 deletions bytes/bytes_list.ts
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,8 @@

/**
* An abstraction of multiple Uint8Arrays
*
* @deprecated (will be removed in 0.205.0) Use a plain array of Uint8Arrays instead.
*/
export class BytesList {
#len = 0;
Expand All @@ -16,12 +18,20 @@ export class BytesList {

/**
* Total size of bytes
*
* @deprecated
*/
size() {
return this.#len;
}
/**
* Push bytes with given offset infos
*
* @deprecated Use a plain array of Uint8Arrays instead.
* Adding into the array can be done with {@linkcode Array#push}.
* If {@linkcode start} or {@linkcode end} parameters are
* used then use {@linkcode Uint8Array#subarray}
* to slice the needed part without copying.
*/
add(value: Uint8Array, start = 0, end = value.byteLength) {
if (value.byteLength === 0 || end - start === 0) {
Expand All @@ -39,6 +49,16 @@ export class BytesList {

/**
* Drop head `n` bytes.
*
* @deprecated Use a plain array of Uint8Arrays instead.
* Shifting from the array can be done using conditional
* {@linkcode Array#shift}s against the number of bytes left
* to be dropped.
*
* If the next item in the array is longer than the number
* of bytes left to be dropped, then instead of shifting it out
* it should be replaced in-place with a subarray of itself that
* drops the remaining bytes from the front.
*/
shift(n: number) {
if (n === 0) {
Expand Down Expand Up @@ -67,6 +87,12 @@ export class BytesList {
/**
* Find chunk index in which `pos` locates by binary-search
* returns -1 if out of range
*
* @deprecated Use a plain array of Uint8Arrays instead.
* Finding the index of a chunk in the array can be
* done using {@linkcode Array#findIndex} with a counter
* for the number of bytes already encountered from past
* chunks' {@linkcode Uint8Array#byteLength}.
*/
getChunkIndex(pos: number): number {
let max = this.#chunks.length;
Expand All @@ -90,6 +116,10 @@ export class BytesList {

/**
* Get indexed byte from chunks
*
* @deprecated Use a plain array of Uint8Arrays instead.
* See {@linkcode getChunkIndex} for finding a chunk
* by number of bytes.
*/
get(i: number): number {
if (i < 0 || this.#len <= i) {
Expand All @@ -102,6 +132,8 @@ export class BytesList {

/**
* Iterator of bytes from given position
*
* @deprecated Use a plain array of Uint8Arrays instead.
*/
*iterator(start = 0): IterableIterator<number> {
const startIdx = this.getChunkIndex(start);
Expand All @@ -119,6 +151,13 @@ export class BytesList {

/**
* Returns subset of bytes copied
*
* @deprecated Use a plain array of Uint8Arrays instead.
* For copying the whole list see {@linkcode concat}.
* For copying subarrays find the start and end chunk indexes
* and the internal indexes within those Uint8Arrays, prepare
* a Uint8Array of size `end - start` and set the chunks (or
* chunk subarrays) into that at proper offsets.
*/
slice(start: number, end: number = this.#len): Uint8Array {
if (end === start) {
Expand Down Expand Up @@ -146,6 +185,8 @@ export class BytesList {
}
/**
* Concatenate chunks into single Uint8Array copied.
*
* @deprecated Use a plain array of Uint8Arrays and the `concat.ts` module instead.
*/
concat(): Uint8Array {
const result = new Uint8Array(this.#len);
Expand Down
58 changes: 29 additions & 29 deletions msgpack/encode.ts
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
// Copyright 2018-2023 the Deno authors. All rights reserved. MIT license.

import { BytesList } from "../bytes/bytes_list.ts";
import { concat } from "../bytes/concat.ts";

export type ValueType =
| number
Expand Down Expand Up @@ -48,9 +48,9 @@ const encoder = new TextEncoder();
* ```
*/
export function encode(object: ValueType) {
const byteList = new BytesList();
encodeSlice(object, byteList);
return byteList.concat();
const byteParts: Uint8Array[] = [];
encodeSlice(object, byteParts);
return concat(...byteParts);
}

function encodeFloat64(num: number) {
Expand Down Expand Up @@ -119,24 +119,24 @@ function encodeNumber(num: number) {
return encodeFloat64(num);
}

function encodeSlice(object: ValueType, byteList: BytesList) {
function encodeSlice(object: ValueType, byteParts: Uint8Array[]) {
if (object === null) {
byteList.add(new Uint8Array([0xc0]));
byteParts.push(new Uint8Array([0xc0]));
return;
}

if (object === false) {
byteList.add(new Uint8Array([0xc2]));
byteParts.push(new Uint8Array([0xc2]));
return;
}

if (object === true) {
byteList.add(new Uint8Array([0xc3]));
byteParts.push(new Uint8Array([0xc3]));
return;
}

if (typeof object === "number") {
byteList.add(encodeNumber(object));
byteParts.push(encodeNumber(object));
return;
}

Expand All @@ -149,7 +149,7 @@ function encodeSlice(object: ValueType, byteList: BytesList) {
const dataView = new DataView(new ArrayBuffer(9));
dataView.setBigInt64(1, object);
dataView.setUint8(0, 0xd3);
byteList.add(new Uint8Array(dataView.buffer));
byteParts.push(new Uint8Array(dataView.buffer));
return;
}

Expand All @@ -160,7 +160,7 @@ function encodeSlice(object: ValueType, byteList: BytesList) {
const dataView = new DataView(new ArrayBuffer(9));
dataView.setBigUint64(1, object);
dataView.setUint8(0, 0xcf);
byteList.add(new Uint8Array(dataView.buffer));
byteParts.push(new Uint8Array(dataView.buffer));
return;
}

Expand All @@ -169,71 +169,71 @@ function encodeSlice(object: ValueType, byteList: BytesList) {
const len = encoded.length;

if (len < FIVE_BITS) { // fixstr
byteList.add(new Uint8Array([0xa0 | len]));
byteParts.push(new Uint8Array([0xa0 | len]));
} else if (len < EIGHT_BITS) { // str 8
byteList.add(new Uint8Array([0xd9, len]));
byteParts.push(new Uint8Array([0xd9, len]));
} else if (len < SIXTEEN_BITS) { // str 16
const dataView = new DataView(new ArrayBuffer(3));
dataView.setUint16(1, len);
dataView.setUint8(0, 0xda);
byteList.add(new Uint8Array(dataView.buffer));
byteParts.push(new Uint8Array(dataView.buffer));
} else if (len < THIRTY_TWO_BITS) { // str 32
const dataView = new DataView(new ArrayBuffer(5));
dataView.setUint32(1, len);
dataView.setUint8(0, 0xdb);
byteList.add(new Uint8Array(dataView.buffer));
byteParts.push(new Uint8Array(dataView.buffer));
} else {
throw new Error(
"Cannot safely encode string with size larger than 32 bits",
);
}
byteList.add(encoded);
byteParts.push(encoded);
return;
}

if (object instanceof Uint8Array) {
if (object.length < EIGHT_BITS) { // bin 8
byteList.add(new Uint8Array([0xc4, object.length]));
byteParts.push(new Uint8Array([0xc4, object.length]));
} else if (object.length < SIXTEEN_BITS) { // bin 16
const dataView = new DataView(new ArrayBuffer(3));
dataView.setUint16(1, object.length);
dataView.setUint8(0, 0xc5);
byteList.add(new Uint8Array(dataView.buffer));
byteParts.push(new Uint8Array(dataView.buffer));
} else if (object.length < THIRTY_TWO_BITS) { // bin 32
const dataView = new DataView(new ArrayBuffer(5));
dataView.setUint32(1, object.length);
dataView.setUint8(0, 0xc6);
byteList.add(new Uint8Array(dataView.buffer));
byteParts.push(new Uint8Array(dataView.buffer));
} else {
throw new Error(
"Cannot safely encode Uint8Array with size larger than 32 bits",
);
}
byteList.add(object);
byteParts.push(object);
return;
}

if (Array.isArray(object)) {
if (object.length < FOUR_BITS) { // fixarray
byteList.add(new Uint8Array([0x90 | object.length]));
byteParts.push(new Uint8Array([0x90 | object.length]));
} else if (object.length < SIXTEEN_BITS) { // array 16
const dataView = new DataView(new ArrayBuffer(3));
dataView.setUint16(1, object.length);
dataView.setUint8(0, 0xdc);
byteList.add(new Uint8Array(dataView.buffer));
byteParts.push(new Uint8Array(dataView.buffer));
} else if (object.length < THIRTY_TWO_BITS) { // array 32
const dataView = new DataView(new ArrayBuffer(5));
dataView.setUint32(1, object.length);
dataView.setUint8(0, 0xdd);
byteList.add(new Uint8Array(dataView.buffer));
byteParts.push(new Uint8Array(dataView.buffer));
} else {
throw new Error(
"Cannot safely encode array with size larger than 32 bits",
);
}

for (const obj of object) {
encodeSlice(obj, byteList);
encodeSlice(obj, byteParts);
}
return;
}
Expand All @@ -243,24 +243,24 @@ function encodeSlice(object: ValueType, byteList: BytesList) {
const numKeys = Object.keys(object).length;

if (numKeys < FOUR_BITS) { // fixarray
byteList.add(new Uint8Array([0x80 | numKeys]));
byteParts.push(new Uint8Array([0x80 | numKeys]));
} else if (numKeys < SIXTEEN_BITS) { // map 16
const dataView = new DataView(new ArrayBuffer(3));
dataView.setUint16(1, numKeys);
dataView.setUint8(0, 0xde);
byteList.add(new Uint8Array(dataView.buffer));
byteParts.push(new Uint8Array(dataView.buffer));
} else if (numKeys < THIRTY_TWO_BITS) { // map 32
const dataView = new DataView(new ArrayBuffer(5));
dataView.setUint32(1, numKeys);
dataView.setUint8(0, 0xdf);
byteList.add(new Uint8Array(dataView.buffer));
byteParts.push(new Uint8Array(dataView.buffer));
} else {
throw new Error("Cannot safely encode map with size larger than 32 bits");
}

for (const [key, value] of Object.entries(object)) {
encodeSlice(key, byteList);
encodeSlice(value, byteList);
encodeSlice(key, byteParts);
encodeSlice(value, byteParts);
}
return;
}
Expand Down
5 changes: 3 additions & 2 deletions streams/_common.ts
Original file line number Diff line number Diff line change
Expand Up @@ -6,11 +6,12 @@ export const DEFAULT_BUFFER_SIZE = 32 * 1024;

/** Generate longest proper prefix which is also suffix array. */
export function createLPS(pat: Uint8Array): Uint8Array {
const lps = new Uint8Array(pat.length);
const length = pat.length;
const lps = new Uint8Array(length);
lps[0] = 0;
let prefixEnd = 0;
let i = 1;
while (i < lps.length) {
while (i < length) {
if (pat[i] === pat[prefixEnd]) {
prefixEnd++;
lps[i] = prefixEnd;
Expand Down
Loading

0 comments on commit 6d75c4e

Please sign in to comment.