]> Lady’s Gitweb - Pisces/commitdiff
Support SharedArrayBuffer; drop isDataView
authorLady <redacted>
Mon, 26 Jun 2023 01:57:06 +0000 (18:57 -0700)
committerLady <redacted>
Mon, 26 Jun 2023 01:57:06 +0000 (18:57 -0700)
- `SharedArrayBuffer` counts as an array buffer; use
  `isArrayBuffer($) && !isSharedArrayBuffer($)` to detect only
  non‐shared buffers.

- `isDataView` is no longer supported as a separate function; use
  `isArrayBufferView($) && !isTypedArray($)` to detect data views.

binary.js
binary.test.js

index f6d8cab9306f1c27945709b4959233e6b9c66364..aac9975d17ba374caa8c14d420a0596f86047e85 100644 (file)
--- a/binary.js
+++ b/binary.js
@@ -24,6 +24,7 @@ const View = DataView;
 const TypedArray = Object.getPrototypeOf(Uint8Array);
 const { prototype: arrayPrototype } = Array;
 const { prototype: bufferPrototype } = Buffer;
 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 { prototype: rePrototype } = RegExp;
 const { prototype: typedArrayPrototype } = TypedArray;
 const { prototype: viewPrototype } = View;
@@ -58,10 +59,23 @@ const binaryCodeUnitIterablePrototype = {
 const { exec: reExec } = rePrototype;
 const getBufferByteLength =
   Object.getOwnPropertyDescriptor(bufferPrototype, "byteLength").get;
 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 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 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,
 const {
   getUint8: viewGetUint8,
   setUint8: viewSetUint8,
@@ -646,6 +660,83 @@ export const filenameSafeBase64Binary = ($, ...$s) =>
 export const filenameSafeBase64String = ($, ...$s) =>
   encodeBase64(bufferFromArgs($, $s), true);
 
 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.
 /**
  * Returns whether the provided value is a view on an underlying array
  * buffer.
@@ -654,7 +745,12 @@ export const filenameSafeBase64String = ($, ...$s) =>
  */
 export const { isView: isArrayBufferView } = 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
 export const isArrayBuffer = ($) => {
   try {
     // Try to see if the provided argument has array buffer internal
@@ -664,6 +760,14 @@ export const isArrayBuffer = ($) => {
     // The provided argument does not have array buffer internal slots.
     /* do nothing */
   }
     // 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;
 };
 
   return false;
 };
 
@@ -727,18 +831,6 @@ export const isBase64 = ($) => {
   }
 };
 
   }
 };
 
-/** 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 filename‐safe base64 string.
  *
@@ -760,6 +852,18 @@ export const isFilenameSafeBase64 = ($) => {
   }
 };
 
   }
 };
 
+/** 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 {
 /** Returns whether the provided value is a typed array. */
 export const isTypedArray = ($) => {
   try {
index 9d8c16993b8630711d05ebfa006e0e461e4cac40..00860edbed74e01d98a9997fb773e0d667e84bfb 100644 (file)
@@ -29,8 +29,8 @@ import {
   isBase16,
   isBase32,
   isBase64,
   isBase16,
   isBase32,
   isBase64,
-  isDataView,
   isFilenameSafeBase64,
   isFilenameSafeBase64,
+  isSharedArrayBuffer,
   isTypedArray,
   isWRMGBase32,
   toArrayBuffer,
   isTypedArray,
   isWRMGBase32,
   toArrayBuffer,
@@ -589,6 +589,10 @@ describe("isArrayBuffer", () => {
       isArrayBuffer(new ArrayBuffer()),
       true,
     );
       isArrayBuffer(new ArrayBuffer()),
       true,
     );
+    assertStrictEquals(
+      isArrayBuffer(new SharedArrayBuffer()),
+      true,
+    );
   });
 
   it("[[Call]] returns false for others", () => {
   });
 
   it("[[Call]] returns false for others", () => {
@@ -604,7 +608,6 @@ describe("isArrayBuffer", () => {
       () => {},
       new Proxy({}, {}),
       "string",
       () => {},
       new Proxy({}, {}),
       "string",
-      new SharedArrayBuffer(),
       new DataView(new ArrayBuffer()),
       new Uint8Array(),
     ].forEach((value) =>
       new DataView(new ArrayBuffer()),
       new Uint8Array(),
     ].forEach((value) =>
@@ -731,12 +734,16 @@ describe("isBase64", () => {
   });
 });
 
   });
 });
 
-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", () => {
   });
 
   it("[[Call]] returns false for others", () => {
@@ -751,24 +758,21 @@ describe("isDataView", () => {
       [],
       () => {},
       new Proxy({}, {}),
       [],
       () => {},
       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", () => {
   });
 
   it("[[Call]] returns false for others", () => {
@@ -783,11 +787,12 @@ describe("isFilenameSafeBase64", () => {
       [],
       () => {},
       new Proxy({}, {}),
       [],
       () => {},
       new Proxy({}, {}),
-      "abc/",
-      "a",
-      "abc==",
+      "string",
+      new ArrayBuffer(),
+      new DataView(new ArrayBuffer()),
+      new Uint8Array(),
     ].forEach((value) =>
     ].forEach((value) =>
-      assertStrictEquals(isFilenameSafeBase64(value), false)
+      assertStrictEquals(isSharedArrayBuffer(value), false)
     );
   });
 });
     );
   });
 });
This page took 0.028437 seconds and 4 git commands to generate.