diff options
author | Yosi Pramajaya <yosi.pramajaya@gmail.com> | 2020-12-06 21:51:13 +0700 |
---|---|---|
committer | GitHub <noreply@github.com> | 2020-12-06 09:51:13 -0500 |
commit | 0b37a79060e48c1fe6936c6e642044e9b20b9bb5 (patch) | |
tree | c8f759f1ad4f6f16bdf2193bac66eb92da9b4bd5 /std/bytes | |
parent | c10280214e5e15fb31b83368082916b9f25470f9 (diff) |
BREAKING(std/bytes): Adjust APIs based on std-wg discussion (#8612)
Diffstat (limited to 'std/bytes')
-rw-r--r-- | std/bytes/README.md | 77 | ||||
-rw-r--r-- | std/bytes/mod.ts | 85 | ||||
-rw-r--r-- | std/bytes/test.ts | 117 |
3 files changed, 193 insertions, 86 deletions
diff --git a/std/bytes/README.md b/std/bytes/README.md index 537c33473..bfe400344 100644 --- a/std/bytes/README.md +++ b/std/bytes/README.md @@ -6,67 +6,77 @@ bytes module is made to provide helpers to manipulation of bytes slice. All the following functions are exposed in `mod.ts`. -## findIndex +## indexOf -Find first index of binary pattern from given binary array. +Find first index of binary pattern from given binary array, or -1 if it is not +present. ```typescript -import { findIndex } from "https://deno.land/std@$STD_VERSION/bytes/mod.ts"; +import { indexOf } from "https://deno.land/std@$STD_VERSION/bytes/mod.ts"; -findIndex( +indexOf( new Uint8Array([1, 2, 0, 1, 2, 0, 1, 2, 0, 1, 3]), new Uint8Array([0, 1, 2]), -); +); // => returns 2 -// => returns 2 +indexOf( + new Uint8Array([1, 2, 0, 1, 2, 0, 1, 2, 0, 1, 3]), + new Uint8Array([0, 1, 2]), + 3, +); // => returns 5 ``` -## findLastIndex +## lastIndexOf -Find last index of binary pattern from given binary array. +Find last index of binary pattern from given binary array, or -1 if it is not +present. ```typescript -import { findLastIndex } from "https://deno.land/std@$STD_VERSION/bytes/mod.ts"; +import { lastIndexOf } from "https://deno.land/std@$STD_VERSION/bytes/mod.ts"; -findLastIndex( - new Uint8Array([0, 1, 2, 0, 1, 2, 0, 1, 3]), +lastIndexOf( + new Uint8Array([0, 1, 2, 3, 3, 0, 1, 2]), new Uint8Array([0, 1, 2]), -); +); // => returns 5 -// => returns 3 +lastIndexOf( + new Uint8Array([0, 1, 2, 3, 3, 0, 1, 2]), + new Uint8Array([0, 1, 2]), + 3, +); // => returns 0 ``` -## equal +## equals Check whether given binary arrays are equal to each other. ```typescript -import { equal } from "https://deno.land/std@$STD_VERSION/bytes/mod.ts"; +import { equals } from "https://deno.land/std@$STD_VERSION/bytes/mod.ts"; -equal(new Uint8Array([0, 1, 2, 3]), new Uint8Array([0, 1, 2, 3])); // returns true -equal(new Uint8Array([0, 1, 2, 3]), new Uint8Array([0, 1, 2, 4])); // returns false +equals(new Uint8Array([0, 1, 2, 3]), new Uint8Array([0, 1, 2, 3])); // returns true +equals(new Uint8Array([0, 1, 2, 3]), new Uint8Array([0, 1, 2, 4])); // returns false ``` -## hasPrefix +## startsWith -Check whether binary array has binary prefix. +Check whether binary array starts with prefix. ```typescript -import { hasPrefix } from "https://deno.land/std@$STD_VERSION/bytes/mod.ts"; +import { startsWith } from "https://deno.land/std@$STD_VERSION/bytes/mod.ts"; -hasPrefix(new Uint8Array([0, 1, 2]), new Uint8Array([0, 1])); // returns true -hasPrefix(new Uint8Array([0, 1, 2]), new Uint8Array([1, 2])); // returns false +startsWith(new Uint8Array([0, 1, 2]), new Uint8Array([0, 1])); // returns true +startsWith(new Uint8Array([0, 1, 2]), new Uint8Array([1, 2])); // returns false ``` -## hasSuffix +## endsWith Check whether binary array ends with suffix. ```typescript -import { hasSuffix } from "https://deno.land/std@$STD_VERSION/bytes/mod.ts"; +import { endsWith } from "https://deno.land/std@$STD_VERSION/bytes/mod.ts"; -hasSuffix(new Uint8Array([0, 1, 2]), new Uint8Array([0, 1])); // returns false -hasSuffix(new Uint8Array([0, 1, 2]), new Uint8Array([1, 2])); // returns true +endsWith(new Uint8Array([0, 1, 2]), new Uint8Array([0, 1])); // returns false +endsWith(new Uint8Array([0, 1, 2]), new Uint8Array([1, 2])); // returns true ``` ## repeat @@ -81,12 +91,19 @@ repeat(new Uint8Array([1]), 3); // returns Uint8Array(3) [ 1, 1, 1 ] ## concat -Concatenate two binary arrays and return new one. +Concatenate multiple binary arrays and return new one. ```typescript import { concat } from "https://deno.land/std@$STD_VERSION/bytes/mod.ts"; concat(new Uint8Array([1, 2]), new Uint8Array([3, 4])); // returns Uint8Array(4) [ 1, 2, 3, 4 ] + +concat( + new Uint8Array([1, 2]), + new Uint8Array([3, 4]), + new Uint8Array([5, 6]), + new Uint8Array([7, 8]), +); // => returns Uint8Array(8) [ 1, 2, 3, 4, 5, 6, 7, 8 ] ``` ## contains @@ -107,14 +124,14 @@ contains( ); // => returns false ``` -## copyBytes +## copy Copy bytes from one binary array to another. ```typescript -import { copyBytes } from "https://deno.land/std@$STD_VERSION/bytes/mod.ts"; +import { copy } from "https://deno.land/std@$STD_VERSION/bytes/mod.ts"; const dst = new Uint8Array(4); const src = Uint8Array.of(1, 2, 3, 4); -const len = copyBytes(src, dest); // returns len = 4 +const len = copy(src, dest); // returns len = 4 ``` diff --git a/std/bytes/mod.ts b/std/bytes/mod.ts index 8ae697c29..585aef2e9 100644 --- a/std/bytes/mod.ts +++ b/std/bytes/mod.ts @@ -1,12 +1,23 @@ // Copyright 2018-2020 the Deno authors. All rights reserved. MIT license. -/** Find first index of binary pattern from a. If not found, then return -1 +/** Find first index of binary pattern from source. If not found, then return -1 * @param source source array * @param pat pattern to find in source array + * @param start the index to start looking in the source */ -export function findIndex(source: Uint8Array, pat: Uint8Array): number { +export function indexOf( + source: Uint8Array, + pat: Uint8Array, + start = 0, +): number { + if (start >= source.length) { + return -1; + } + if (start < 0) { + start = 0; + } const s = pat[0]; - for (let i = 0; i < source.length; i++) { + for (let i = start; i < source.length; i++) { if (source[i] !== s) continue; const pin = i; let matched = 1; @@ -25,13 +36,24 @@ export function findIndex(source: Uint8Array, pat: Uint8Array): number { return -1; } -/** Find last index of binary pattern from a. If not found, then return -1. +/** Find last index of binary pattern from source. If not found, then return -1. * @param source source array * @param pat pattern to find in source array + * @param start the index to start looking in the source */ -export function findLastIndex(source: Uint8Array, pat: Uint8Array): number { +export function lastIndexOf( + source: Uint8Array, + pat: Uint8Array, + start = source.length - 1, +): number { + if (start < 0) { + return -1; + } + if (start >= source.length) { + start = source.length - 1; + } const e = pat[pat.length - 1]; - for (let i = source.length - 1; i >= 0; i--) { + for (let i = start; i >= 0; i--) { if (source[i] !== e) continue; const pin = i; let matched = 1; @@ -51,22 +73,22 @@ export function findLastIndex(source: Uint8Array, pat: Uint8Array): number { } /** Check whether binary arrays are equal to each other. - * @param source first array to check equality - * @param match second array to check equality + * @param a first array to check equality + * @param b second array to check equality */ -export function equal(source: Uint8Array, match: Uint8Array): boolean { - if (source.length !== match.length) return false; - for (let i = 0; i < match.length; i++) { - if (source[i] !== match[i]) return false; +export function equals(a: Uint8Array, b: Uint8Array): boolean { + if (a.length !== b.length) return false; + for (let i = 0; i < b.length; i++) { + if (a[i] !== b[i]) return false; } return true; } /** Check whether binary array starts with prefix. - * @param source srouce array + * @param source source array * @param prefix prefix array to check in source */ -export function hasPrefix(source: Uint8Array, prefix: Uint8Array): boolean { +export function startsWith(source: Uint8Array, prefix: Uint8Array): boolean { for (let i = 0, max = prefix.length; i < max; i++) { if (source[i] !== prefix[i]) return false; } @@ -77,7 +99,7 @@ export function hasPrefix(source: Uint8Array, prefix: Uint8Array): boolean { * @param source source array * @param suffix suffix array to check in source */ -export function hasSuffix(source: Uint8Array, suffix: Uint8Array): boolean { +export function endsWith(source: Uint8Array, suffix: Uint8Array): boolean { for ( let srci = source.length - 1, sfxi = suffix.length - 1; sfxi >= 0; @@ -91,6 +113,7 @@ export function hasSuffix(source: Uint8Array, suffix: Uint8Array): boolean { /** Repeat bytes. returns a new byte slice consisting of `count` copies of `b`. * @param origin The origin bytes * @param count The count you want to repeat. + * @throws `RangeError` When count is negative */ export function repeat(origin: Uint8Array, count: number): Uint8Array { if (count === 0) { @@ -98,7 +121,7 @@ export function repeat(origin: Uint8Array, count: number): Uint8Array { } if (count < 0) { - throw new Error("bytes: negative repeat count"); + throw new RangeError("bytes: negative repeat count"); } else if ((origin.length * count) / count !== origin.length) { throw new Error("bytes: repeat count causes overflow"); } @@ -111,23 +134,31 @@ export function repeat(origin: Uint8Array, count: number): Uint8Array { const nb = new Uint8Array(origin.length * count); - let bp = copyBytes(origin, nb); + let bp = copy(origin, nb); for (; bp < nb.length; bp *= 2) { - copyBytes(nb.slice(0, bp), nb, bp); + copy(nb.slice(0, bp), nb, bp); } return nb; } -/** Concatenate two binary arrays and return new one. - * @param origin origin array to concatenate - * @param b array to concatenate with origin +/** Concatenate multiple binary arrays and return new one. + * @param buf binary arrays to concatenate */ -export function concat(origin: Uint8Array, b: Uint8Array): Uint8Array { - const output = new Uint8Array(origin.length + b.length); - output.set(origin, 0); - output.set(b, origin.length); +export function concat(...buf: Uint8Array[]): Uint8Array { + let length = 0; + for (const b of buf) { + length += b.length; + } + + const output = new Uint8Array(length); + let index = 0; + for (const b of buf) { + output.set(b, index); + index += b.length; + } + return output; } @@ -136,7 +167,7 @@ export function concat(origin: Uint8Array, b: Uint8Array): Uint8Array { * @param pat patter array */ export function contains(source: Uint8Array, pat: Uint8Array): boolean { - return findIndex(source, pat) != -1; + return indexOf(source, pat) != -1; } /** @@ -148,7 +179,7 @@ export function contains(source: Uint8Array, pat: Uint8Array): boolean { * @param off Offset into `dst` at which to begin writing values from `src`. * @return number of bytes copied */ -export function copyBytes(src: Uint8Array, dst: Uint8Array, off = 0): number { +export function copy(src: Uint8Array, dst: Uint8Array, off = 0): number { off = Math.max(0, Math.min(off, dst.byteLength)); const dstBytesAvailable = dst.byteLength - off; if (src.byteLength > dstBytesAvailable) { diff --git a/std/bytes/test.ts b/std/bytes/test.ts index 46f819193..3aea70965 100644 --- a/std/bytes/test.ts +++ b/std/bytes/test.ts @@ -3,60 +3,106 @@ import { concat, contains, - copyBytes, - equal, - findIndex, - findLastIndex, - hasPrefix, - hasSuffix, + copy, + endsWith, + equals, + indexOf, + lastIndexOf, repeat, + startsWith, } from "./mod.ts"; import { assert, assertEquals, assertThrows } from "../testing/asserts.ts"; import { decode, encode } from "../encoding/utf8.ts"; -Deno.test("[bytes] findIndex1", () => { - const i = findIndex( +Deno.test("[bytes] indexOf1", () => { + const i = indexOf( new Uint8Array([1, 2, 0, 1, 2, 0, 1, 2, 0, 1, 3]), new Uint8Array([0, 1, 2]), ); assertEquals(i, 2); }); -Deno.test("[bytes] findIndex2", () => { - const i = findIndex(new Uint8Array([0, 0, 1]), new Uint8Array([0, 1])); +Deno.test("[bytes] indexOf2", () => { + const i = indexOf(new Uint8Array([0, 0, 1]), new Uint8Array([0, 1])); assertEquals(i, 1); }); -Deno.test("[bytes] findIndex3", () => { - const i = findIndex(encode("Deno"), encode("D")); +Deno.test("[bytes] indexOf3", () => { + const i = indexOf(encode("Deno"), encode("D")); assertEquals(i, 0); }); -Deno.test("[bytes] findLastIndex1", () => { - const i = findLastIndex( +Deno.test("[bytes] indexOf4", () => { + const i = indexOf(new Uint8Array(), new Uint8Array([0, 1])); + assertEquals(i, -1); +}); + +Deno.test("[bytes] indexOf with start index", () => { + const i = indexOf( + new Uint8Array([0, 1, 2, 0, 1, 2]), + new Uint8Array([0, 1]), + 1, + ); + assertEquals(i, 3); +}); + +Deno.test("[bytes] indexOf with start index 2", () => { + const i = indexOf( + new Uint8Array([0, 1, 2, 0, 1, 2]), + new Uint8Array([0, 1]), + 7, + ); + assertEquals(i, -1); +}); + +Deno.test("[bytes] lastIndexOf1", () => { + const i = lastIndexOf( new Uint8Array([0, 1, 2, 0, 1, 2, 0, 1, 3]), new Uint8Array([0, 1, 2]), ); assertEquals(i, 3); }); -Deno.test("[bytes] findLastIndex2", () => { - const i = findLastIndex(new Uint8Array([0, 1, 1]), new Uint8Array([0, 1])); +Deno.test("[bytes] lastIndexOf2", () => { + const i = lastIndexOf(new Uint8Array([0, 1, 1]), new Uint8Array([0, 1])); + assertEquals(i, 0); +}); + +Deno.test("[bytes] lastIndexOf3", () => { + const i = lastIndexOf(new Uint8Array(), new Uint8Array([0, 1])); + assertEquals(i, -1); +}); + +Deno.test("[bytes] lastIndexOf with start index", () => { + const i = lastIndexOf( + new Uint8Array([0, 1, 2, 0, 1, 2]), + new Uint8Array([0, 1]), + 2, + ); assertEquals(i, 0); }); -Deno.test("[bytes] equal", () => { - const v = equal(new Uint8Array([0, 1, 2, 3]), new Uint8Array([0, 1, 2, 3])); +Deno.test("[bytes] lastIndexOf with start index 2", () => { + const i = lastIndexOf( + new Uint8Array([0, 1, 2, 0, 1, 2]), + new Uint8Array([0, 1]), + -1, + ); + assertEquals(i, -1); +}); + +Deno.test("[bytes] equals", () => { + const v = equals(new Uint8Array([0, 1, 2, 3]), new Uint8Array([0, 1, 2, 3])); assertEquals(v, true); }); -Deno.test("[bytes] hasPrefix", () => { - const v = hasPrefix(new Uint8Array([0, 1, 2]), new Uint8Array([0, 1])); +Deno.test("[bytes] startsWith", () => { + const v = startsWith(new Uint8Array([0, 1, 2]), new Uint8Array([0, 1])); assertEquals(v, true); }); -Deno.test("[bytes] hasSuffix", () => { - const v = hasSuffix(new Uint8Array([0, 1, 2]), new Uint8Array([1, 2])); +Deno.test("[bytes] endsWith", () => { + const v = endsWith(new Uint8Array([0, 1, 2]), new Uint8Array([1, 2])); assertEquals(v, true); }); @@ -111,7 +157,20 @@ Deno.test("[bytes] concat empty arrays", () => { assert(u2 !== joined); }); -Deno.test("[bytes] contain", () => { +Deno.test("[bytes] concat multiple arrays", () => { + const u1 = encode("Hello "); + const u2 = encode("W"); + const u3 = encode("o"); + const u4 = encode("r"); + const u5 = encode("l"); + const u6 = encode("d"); + const joined = concat(u1, u2, u3, u4, u5, u6); + assertEquals(decode(joined), "Hello World"); + assert(u1 !== joined); + assert(u2 !== joined); +}); + +Deno.test("[bytes] contains", () => { const source = encode("deno.land"); const pattern = encode("deno"); assert(contains(source, pattern)); @@ -119,36 +178,36 @@ Deno.test("[bytes] contain", () => { assert(contains(new Uint8Array([0, 1, 2, 3]), new Uint8Array([2, 3]))); }); -Deno.test("[io/tuil] copyBytes", function (): void { +Deno.test("[bytes] copy", function (): void { const dst = new Uint8Array(4); dst.fill(0); let src = Uint8Array.of(1, 2); - let len = copyBytes(src, dst, 0); + let len = copy(src, dst, 0); assert(len === 2); assertEquals(dst, Uint8Array.of(1, 2, 0, 0)); dst.fill(0); src = Uint8Array.of(1, 2); - len = copyBytes(src, dst, 1); + len = copy(src, dst, 1); assert(len === 2); assertEquals(dst, Uint8Array.of(0, 1, 2, 0)); dst.fill(0); src = Uint8Array.of(1, 2, 3, 4, 5); - len = copyBytes(src, dst); + len = copy(src, dst); assert(len === 4); assertEquals(dst, Uint8Array.of(1, 2, 3, 4)); dst.fill(0); src = Uint8Array.of(1, 2); - len = copyBytes(src, dst, 100); + len = copy(src, dst, 100); assert(len === 0); assertEquals(dst, Uint8Array.of(0, 0, 0, 0)); dst.fill(0); src = Uint8Array.of(3, 4); - len = copyBytes(src, dst, -2); + len = copy(src, dst, -2); assert(len === 2); assertEquals(dst, Uint8Array.of(3, 4, 0, 0)); }); |