const TypedArray = Object.getPrototypeOf(Uint8Array);
const { prototype: arrayPrototype } = Array;
const { prototype: bufferPrototype } = Buffer;
+const { prototype: sharedBufferPrototype } = SharedArrayBuffer;
const { prototype: rePrototype } = RegExp;
const { prototype: typedArrayPrototype } = TypedArray;
const { prototype: viewPrototype } = View;
const { exec: reExec } = rePrototype;
const getBufferByteLength =
Object.getOwnPropertyDescriptor(bufferPrototype, "byteLength").get;
+const getSharedBufferByteLength =
+ Object.getOwnPropertyDescriptor(sharedBufferPrototype, "byteLength")
+ .get;
const getTypedArrayBuffer =
Object.getOwnPropertyDescriptor(typedArrayPrototype, "buffer").get;
+const getTypedArrayByteLength =
+ Object.getOwnPropertyDescriptor(typedArrayPrototype, "byteLength")
+ .get;
+const getTypedArrayByteOffset =
+ Object.getOwnPropertyDescriptor(typedArrayPrototype, "byteOffset")
+ .get;
const getViewBuffer =
Object.getOwnPropertyDescriptor(viewPrototype, "buffer").get;
+const getViewByteLength =
+ Object.getOwnPropertyDescriptor(viewPrototype, "byteLength").get;
+const getViewByteOffset =
+ Object.getOwnPropertyDescriptor(viewPrototype, "byteOffset").get;
const {
getUint8: viewGetUint8,
setUint8: viewSetUint8,
export const filenameSafeBase64String = ($, ...$s) =>
encodeBase64(bufferFromArgs($, $s), true);
+/**
+ * Returns the byte length for the provided array buffer or array
+ * buffer view.
+ *
+ * ☡ This function throws if the provided value is not an array buffer,
+ * data view, or typed array.
+ */
+export const getByteLength = ($) => {
+ try {
+ // Attempt to get the byte length from the provided value as an
+ // `ArrayBuffer`.
+ return call(getBufferByteLength, $, []);
+ } catch {
+ // The provided value is not an `ArrayBuffer`.
+ /* do nothing */
+ }
+ try {
+ // Attempt to get the byte length from the provided value as a
+ // `SharedArrayBuffer`.
+ return call(getSharedBufferByteLength, $, []);
+ } catch {
+ // The provided value is not a `SharedArrayBuffer`.
+ /* do nothing */
+ }
+ try {
+ // Attempt to get the byte length from the provided value as a
+ // data view.
+ return call(getViewByteLength, $, []);
+ } catch {
+ // The provided value is not a data view.
+ /* do nothing */
+ }
+ try {
+ // Attempt to get the byte length from the provided value as a
+ // typed array.
+ return call(getTypedArrayByteLength, $, []);
+ } catch {
+ // The provided value is not a typed array.
+ /* do nothing */
+ }
+ throw new TypeError(`Piscēs: Not an array buffer or view: ${$}.`);
+};
+
+/**
+ * Returns the byte offset for the provided array buffer or array
+ * buffer view.
+ *
+ * ※ This function always returns `0` for array buffers.
+ *
+ * ☡ This function throws if the provided value is not an array buffer,
+ * data view, or typed array.
+ */
+export const getByteOffset = ($) => {
+ if (isArrayBuffer($)) {
+ // The provided value is an array buffer.
+ return 0;
+ } else {
+ try {
+ // Attempt to get the byte offset from the provided value as a
+ // data view.
+ return call(getViewByteOffset, $, []);
+ } catch {
+ // The provided value is not a data view.
+ /* do nothing */
+ }
+ try {
+ // Attempt to get the byte offset from the provided value as a
+ // typed array.
+ return call(getTypedArrayByteOffset, $, []);
+ } catch {
+ // The provided value is not a typed array.
+ /* do nothing */
+ }
+ throw new TypeError(`Piscēs: Not an array buffer or view: ${$}.`);
+ }
+};
+
/**
* Returns whether the provided value is a view on an underlying array
* buffer.
*/
export const { isView: isArrayBufferView } = Buffer;
-/** Returns whether the provided value is an array buffer. */
+/**
+ * Returns whether the provided value is an array buffer.
+ *
+ * ※ This function returns true for both `ArrayBuffer`s and
+ * `SharedArrayBuffer`s.
+ */
export const isArrayBuffer = ($) => {
try {
// Try to see if the provided argument has array buffer internal
// The provided argument does not have array buffer internal slots.
/* do nothing */
}
+ try {
+ // Try to see if the provided argument has array buffer internal
+ // slots and return true if so.
+ return call(getSharedBufferByteLength, $, []), true;
+ } catch {
+ // The provided argument does not have array buffer internal slots.
+ /* do nothing */
+ }
return false;
};
}
};
-/** Returns whether the provided value is a data view. */
-export const isDataView = ($) => {
- try {
- // Try to see if the provided argument has data view internal slots
- // and return true if so.
- return call(getViewBuffer, $, []), true;
- } catch {
- // The provided argument does not have data view internal slots.
- return false;
- }
-};
-
/**
* Returns whether the provided value is a filename‐safe base64 string.
*
}
};
+/** Returns whether the provided value is a shared array buffer. */
+export const isSharedArrayBuffer = ($) => {
+ try {
+ // Try to see if the provided argument has shared array buffer
+ // internal slots and return true if so.
+ return call(getSharedBufferByteLength, $, []), true;
+ } catch {
+ // The provided argument does not have data view internal slots.
+ return false;
+ }
+};
+
/** Returns whether the provided value is a typed array. */
export const isTypedArray = ($) => {
try {
isBase16,
isBase32,
isBase64,
- isDataView,
isFilenameSafeBase64,
+ isSharedArrayBuffer,
isTypedArray,
isWRMGBase32,
toArrayBuffer,
isArrayBuffer(new ArrayBuffer()),
true,
);
+ assertStrictEquals(
+ isArrayBuffer(new SharedArrayBuffer()),
+ true,
+ );
});
it("[[Call]] returns false for others", () => {
() => {},
new Proxy({}, {}),
"string",
- new SharedArrayBuffer(),
new DataView(new ArrayBuffer()),
new Uint8Array(),
].forEach((value) =>
});
});
-describe("isDataView", () => {
- it("[[Call]] returns true for data views", () => {
- assertStrictEquals(
- isDataView(new DataView(new ArrayBuffer())),
- true,
- );
+describe("isFilenameSafeBase64", () => {
+ it("[[Call]] returns true for filename‐safe base64 strings", () => {
+ for (const { base64 } of data.values()) {
+ assertStrictEquals(
+ isFilenameSafeBase64(
+ base64.replace("+", "-").replace("/", "_"),
+ ),
+ true,
+ );
+ }
});
it("[[Call]] returns false for others", () => {
[],
() => {},
new Proxy({}, {}),
- "string",
- new ArrayBuffer(),
- new SharedArrayBuffer(),
- new Uint8Array(),
- ].forEach((value) => assertStrictEquals(isDataView(value), false));
+ "abc/",
+ "a",
+ "abc==",
+ ].forEach((value) =>
+ assertStrictEquals(isFilenameSafeBase64(value), false)
+ );
});
});
-describe("isFilenameSafeBase64", () => {
- it("[[Call]] returns true for filename‐safe base64 strings", () => {
- for (const { base64 } of data.values()) {
- assertStrictEquals(
- isFilenameSafeBase64(
- base64.replace("+", "-").replace("/", "_"),
- ),
- true,
- );
- }
+describe("isSharedArrayBuffer", () => {
+ it("[[Call]] returns true for shared array buffers", () => {
+ assertStrictEquals(
+ isSharedArrayBuffer(new SharedArrayBuffer()),
+ true,
+ );
});
it("[[Call]] returns false for others", () => {
[],
() => {},
new Proxy({}, {}),
- "abc/",
- "a",
- "abc==",
+ "string",
+ new ArrayBuffer(),
+ new DataView(new ArrayBuffer()),
+ new Uint8Array(),
].forEach((value) =>
- assertStrictEquals(isFilenameSafeBase64(value), false)
+ assertStrictEquals(isSharedArrayBuffer(value), false)
);
});
});