diff options
author | Marcos Casagrande <marcoscvp90@gmail.com> | 2020-07-09 22:50:19 +0200 |
---|---|---|
committer | GitHub <noreply@github.com> | 2020-07-09 16:50:19 -0400 |
commit | dc6b3ef714c743358703512cd766aed4abc8bd3b (patch) | |
tree | 4379f29b5eae0af0a09223ca806d22f34acff858 /std/encoding/hex.ts | |
parent | 634d6af7a1506bb209f972ac75af375d0e523d48 (diff) |
BREAKING(std/encoding/hex): simplify API (#6690)
Diffstat (limited to 'std/encoding/hex.ts')
-rw-r--r-- | std/encoding/hex.ts | 97 |
1 files changed, 30 insertions, 67 deletions
diff --git a/std/encoding/hex.ts b/std/encoding/hex.ts index c246f7182..729df6c49 100644 --- a/std/encoding/hex.ts +++ b/std/encoding/hex.ts @@ -18,17 +18,16 @@ export function errLength(): Error { return new Error("encoding/hex: odd length hex string"); } -// fromHexChar converts a hex character into its value and a success flag. -function fromHexChar(byte: number): [number, boolean] { - switch (true) { - case 48 <= byte && byte <= 57: // '0' <= byte && byte <= '9' - return [byte - 48, true]; - case 97 <= byte && byte <= 102: // 'a' <= byte && byte <= 'f' - return [byte - 97 + 10, true]; - case 65 <= byte && byte <= 70: // 'A' <= byte && byte <= 'F' - return [byte - 65 + 10, true]; - } - return [0, false]; +// fromHexChar converts a hex character into its value. +function fromHexChar(byte: number): number { + // '0' <= byte && byte <= '9' + if (48 <= byte && byte <= 57) return byte - 48; + // 'a' <= byte && byte <= 'f' + if (97 <= byte && byte <= 102) return byte - 97 + 10; + // 'A' <= byte && byte <= 'F' + if (65 <= byte && byte <= 70) return byte - 65 + 10; + + throw errInvalidByte(byte); } /** @@ -41,24 +40,17 @@ export function encodedLen(n: number): number { } /** - * Encode encodes `src` into `encodedLen(src.length)` bytes of `dst`. - * As a convenience, it returns the number of bytes written to `dst` - * but this value is always `encodedLen(src.length)`. - * Encode implements hexadecimal encoding. - * @param dst + * Encode encodes `src` into `encodedLen(src.length)` bytes. * @param src */ -export function encode(src: Uint8Array, dst: Uint8Array): number { - const srcLength = encodedLen(src.length); - if (dst.length !== srcLength) { - throw new Error("Out of index."); - } - for (let i = 0; i < src.length; i++) { +export function encode(src: Uint8Array): Uint8Array { + const dst = new Uint8Array(encodedLen(src.length)); + for (let i = 0; i < dst.length; i++) { const v = src[i]; dst[i * 2] = hextable[v >> 4]; dst[i * 2 + 1] = hextable[v & 0x0f]; } - return srcLength; + return dst; } /** @@ -66,78 +58,49 @@ export function encode(src: Uint8Array, dst: Uint8Array): number { * @param src */ export function encodeToString(src: Uint8Array): string { - const dest = new Uint8Array(encodedLen(src.length)); - encode(src, dest); - return new TextDecoder().decode(dest); + return new TextDecoder().decode(encode(src)); } /** * Decode decodes `src` into `decodedLen(src.length)` bytes - * returning the actual number of bytes written to `dst`. - * Decode expects that `src` contains only hexadecimal characters and that `src` - * has even length. - * If the input is malformed, Decode returns the number of bytes decoded before + * If the input is malformed an error will be thrown * the error. - * @param dst * @param src */ -export function decode( - src: Uint8Array, - dst: Uint8Array -): [number, Error | void] { - let i = 0; - for (; i < Math.floor(src.length / 2); i++) { - const [a, aOK] = fromHexChar(src[i * 2]); - if (!aOK) { - return [i, errInvalidByte(src[i * 2])]; - } - const [b, bOK] = fromHexChar(src[i * 2 + 1]); - if (!bOK) { - return [i, errInvalidByte(src[i * 2 + 1])]; - } - +export function decode(src: Uint8Array): Uint8Array { + const dst = new Uint8Array(decodedLen(src.length)); + for (let i = 0; i < dst.length; i++) { + const a = fromHexChar(src[i * 2]); + const b = fromHexChar(src[i * 2 + 1]); dst[i] = (a << 4) | b; } if (src.length % 2 == 1) { // Check for invalid char before reporting bad length, // since the invalid char (if present) is an earlier problem. - const [, ok] = fromHexChar(src[i * 2]); - if (!ok) { - return [i, errInvalidByte(src[i * 2])]; - } - return [i, errLength()]; + fromHexChar(src[dst.length * 2]); + throw errLength(); } - return [i, undefined]; + return dst; } /** - * DecodedLen returns the length of a decoding of `x` source bytes. + * DecodedLen returns the length of decoding `x` source bytes. * Specifically, it returns `x / 2`. * @param x */ export function decodedLen(x: number): number { - return Math.floor(x / 2); + return x >>> 1; } /** * DecodeString returns the bytes represented by the hexadecimal string `s`. * DecodeString expects that src contains only hexadecimal characters and that * src has even length. - * If the input is malformed, DecodeString will throws an error. - * @param s the `string` need to decode to `Uint8Array` + * If the input is malformed, DecodeString will throw an error. + * @param s the `string` to decode to `Uint8Array` */ export function decodeString(s: string): Uint8Array { - const src = new TextEncoder().encode(s); - // We can use the source slice itself as the destination - // because the decode loop increments by one and then the 'seen' byte is not - // used anymore. - const [n, err] = decode(src, src); - - if (err) { - throw err; - } - - return src.slice(0, n); + return decode(new TextEncoder().encode(s)); } |