* Returns an ArrayBuffer for encoding generated from the provided
* arguments.
*/
-const bufferFromArgs = ($, $s) =>
- $ instanceof Buffer
- ? $
- : $ instanceof View
- ? call(getViewBuffer, $, [])
- : $ instanceof TypedArray
- ? call(getTypedArrayBuffer, $, [])
- : ((string) =>
+const bufferFromArgs = ($, $s) => {
+ try {
+ // Try just getting the array buffer associated with the first
+ // argument and returning it if possible.
+ return toArrayBuffer($);
+ } catch {
+ // There is no array buffer associated with the first argument.
+ //
+ // Construct a string and convert it to an array buffer instead.
+ return ((string) =>
call(
getViewBuffer,
reduce(
)
: `${$}`,
);
+ }
+};
/**
* Returns the result of decoding the provided base16 string into an
export const filenameSafeBase64String = ($, ...$s) =>
encodeBase64(bufferFromArgs($, $s), true);
+/**
+ * Returns whether the provided value is a view on an underlying array
+ * buffer.
+ *
+ * ※ This function returns true for typed arrays and data views.
+ */
+export const { isView: isArrayBufferView } = Buffer;
+
/**
* Returns whether the provided value is a base16 string.
*
}
};
+/**
+ * Returns the array buffer associated with the provided object.
+ *
+ * ☡ This function throws if the provided object is not a data view or
+ * typed array.
+ */
+export const toArrayBuffer = ($) => {
+ try {
+ // The provided argument has array buffer internal slots.
+ return call(getBufferByteLength, $, []), $;
+ } catch {}
+ try {
+ // The provided argument has typed array internal slots.
+ return call(getTypedArrayBuffer, $, []);
+ } catch {}
+ try {
+ // The provided argument has data view internal slots.
+ return call(getViewBuffer, $, []);
+ } catch {}
+ throw new TypeError(`Piscēs: Not an array buffer or view: ${$}.`);
+};
+
/**
* Returns an ArrayBuffer generated from the provided W·R·M·G
* (Crockford) base32 string.
base64String,
filenameSafeBase64Binary,
filenameSafeBase64String,
+ isArrayBufferView,
isBase16,
isBase32,
isBase64,
isFilenameSafeBase64,
isWRMGBase32,
+ toArrayBuffer,
wrmgBase32Binary,
wrmgBase32String,
} from "./binary.js";
});
});
+describe("isArrayBufferView", () => {
+ it("[[Call]] returns true for data views", () => {
+ assertStrictEquals(
+ isArrayBufferView(new DataView(new ArrayBuffer())),
+ true,
+ );
+ });
+
+ it("[[Call]] returns true for typed arrays", () => {
+ assertStrictEquals(
+ isArrayBufferView(new Uint8ClampedArray()),
+ true,
+ );
+ assertStrictEquals(isArrayBufferView(new BigInt64Array()), true);
+ });
+
+ it("[[Call]] returns false for others", () => {
+ [
+ undefined,
+ null,
+ true,
+ Symbol(),
+ 27,
+ 98n,
+ {},
+ [],
+ () => {},
+ new Proxy({}, {}),
+ "string",
+ new ArrayBuffer(),
+ new SharedArrayBuffer(),
+ ].forEach((value) =>
+ assertStrictEquals(isArrayBufferView(value), false)
+ );
+ });
+});
+
describe("isBase16", () => {
it("[[Call]] returns true for base64 strings", () => {
for (const { base16 } of data.values()) {
- assert(isBase16(base16));
- assert(isBase16(base16.toLowerCase()));
+ assertStrictEquals(isBase16(base16), true);
+ assertStrictEquals(isBase16(base16.toLowerCase()), true);
}
});
"a",
"abc",
"abcg",
- ].forEach((value) => assert(!isBase16(value)));
+ ].forEach((value) => assertStrictEquals(isBase16(value), false));
});
});
describe("isBase32", () => {
it("[[Call]] returns true for base32 strings", () => {
for (const { base32 } of data.values()) {
- assert(isBase32(base32));
- assert(isBase32(base32.toLowerCase()));
+ assertStrictEquals(isBase32(base32), true);
+ assertStrictEquals(isBase32(base32.toLowerCase()), true);
}
});
"ABC1",
"A=======",
"ABCDEFGHI",
- ].forEach((value) => assert(!isBase32(value)));
+ ].forEach((value) => assertStrictEquals(isBase32(value), false));
});
});
describe("isBase64", () => {
it("[[Call]] returns true for base64 strings", () => {
for (const { base64 } of data.values()) {
- assert(isBase64(base64));
+ assertStrictEquals(isBase64(base64), true);
}
});
"abc_",
"a",
"abc==",
- ].forEach((value) => assert(!isBase64(value)));
+ ].forEach((value) => assertStrictEquals(isBase64(value), false));
});
});
describe("isFilenameSafeBase64", () => {
it("[[Call]] returns true for filename‐safe base64 strings", () => {
for (const { base64 } of data.values()) {
- assert(
+ assertStrictEquals(
isFilenameSafeBase64(
base64.replace("+", "-").replace("/", "_"),
),
+ true,
);
}
});
"abc/",
"a",
"abc==",
- ].forEach((value) => assert(!isFilenameSafeBase64(value)));
+ ].forEach((value) =>
+ assertStrictEquals(isFilenameSafeBase64(value), false)
+ );
});
});
describe("isWRMGBase32", () => {
it("[[Call]] returns true for W·R·M·G base32 strings", () => {
for (const { wrmg } of data.values()) {
- assert(isWRMGBase32(wrmg));
- assert(isWRMGBase32(wrmg.toLowerCase()));
- assert(isWRMGBase32(`--${wrmg}--`));
- assert(isWRMGBase32(wrmg.replaceAll(/1/gu, "I")));
- assert(isWRMGBase32(wrmg.replaceAll(/1/gu, "L")));
- assert(isWRMGBase32(wrmg.replaceAll(/0/gu, "O")));
- assert(isWRMGBase32(wrmg.replaceAll(/1/gu, "i")));
- assert(isWRMGBase32(wrmg.replaceAll(/1/gu, "l")));
- assert(isWRMGBase32(wrmg.replaceAll(/0/gu, "o")));
- assert(isWRMGBase32(wrmg.replaceAll(/./gu, ($) => {
- const rand = Math.random();
- return rand < 0.25
- ? $
- : rand < 0.5
- ? `-${$}`
- : rand < 0.75
- ? `${$}-`
- : `-${$}-`;
- })));
+ assertStrictEquals(isWRMGBase32(wrmg), true);
+ assertStrictEquals(isWRMGBase32(wrmg.toLowerCase()), true);
+ assertStrictEquals(isWRMGBase32(`--${wrmg}--`), true);
+ assertStrictEquals(
+ isWRMGBase32(wrmg.replaceAll(/1/gu, "I")),
+ true,
+ );
+ assertStrictEquals(
+ isWRMGBase32(wrmg.replaceAll(/1/gu, "L")),
+ true,
+ );
+ assertStrictEquals(
+ isWRMGBase32(wrmg.replaceAll(/0/gu, "O")),
+ true,
+ );
+ assertStrictEquals(
+ isWRMGBase32(wrmg.replaceAll(/1/gu, "i")),
+ true,
+ );
+ assertStrictEquals(
+ isWRMGBase32(wrmg.replaceAll(/1/gu, "l")),
+ true,
+ );
+ assertStrictEquals(
+ isWRMGBase32(wrmg.replaceAll(/0/gu, "o")),
+ true,
+ );
+ assertStrictEquals(
+ isWRMGBase32(wrmg.replaceAll(/./gu, ($) => {
+ const rand = Math.random();
+ return rand < 0.25
+ ? $
+ : rand < 0.5
+ ? `-${$}`
+ : rand < 0.75
+ ? `${$}-`
+ : `-${$}-`;
+ })),
+ true,
+ );
}
});
"ABCU",
"A",
"ABCDEFGH1",
- ].forEach((value) => assert(!isWRMGBase32(value)));
+ ].forEach((value) =>
+ assertStrictEquals(isWRMGBase32(value), false)
+ );
+ });
+});
+
+describe("toArrayBuffer", () => {
+ it("[[Call]] returns the argument for array buffers", () => {
+ const buffer = new ArrayBuffer();
+ assertStrictEquals(toArrayBuffer(buffer), buffer);
+ });
+
+ it("[[Call]] returns the buffer for data views", () => {
+ const src = Uint8Array.from([2, 3, 1]);
+ const buffer = toArrayBuffer(new DataView(src.buffer));
+ assert(buffer instanceof ArrayBuffer);
+ assertEquals(new Uint8Array(buffer), src);
+ });
+
+ it("[[Call]] returns the buffer for typed arrays", () => {
+ const src = Uint8Array.from([2, 3, 1]);
+ const buffer = toArrayBuffer(src);
+ assert(buffer instanceof ArrayBuffer);
+ assertEquals(new Uint8Array(buffer), src);
+ });
+
+ it("[[Call]] throws for others", () => {
+ [
+ undefined,
+ null,
+ true,
+ Symbol(),
+ 27,
+ 98n,
+ {},
+ [],
+ () => {},
+ new Proxy({}, {}),
+ "string",
+ ].forEach((value) =>
+ assertThrows(() => {
+ toArrayBuffer(value);
+ })
+ );
});
});