index.js 2.0 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677
  1. 'use strict';
  2. var forEach = require('for-each');
  3. var callBind = require('call-bind');
  4. var typedArrays = [
  5. 'Float32Array',
  6. 'Float64Array',
  7. 'Int8Array',
  8. 'Int16Array',
  9. 'Int32Array',
  10. 'Uint8Array',
  11. 'Uint8ClampedArray',
  12. 'Uint16Array',
  13. 'Uint32Array',
  14. 'BigInt64Array',
  15. 'BigUint64Array'
  16. ];
  17. var getters = {};
  18. var hasProto = [].__proto__ === Array.prototype; // eslint-disable-line no-proto
  19. var gOPD = Object.getOwnPropertyDescriptor;
  20. var oDP = Object.defineProperty;
  21. if (gOPD) {
  22. var getLength = function (x) {
  23. return x.length;
  24. };
  25. forEach(typedArrays, function (typedArray) {
  26. // In Safari 7, Typed Array constructors are typeof object
  27. if (typeof global[typedArray] === 'function' || typeof global[typedArray] === 'object') {
  28. var Proto = global[typedArray].prototype;
  29. var descriptor = gOPD(Proto, 'length');
  30. if (!descriptor && hasProto) {
  31. var superProto = Proto.__proto__; // eslint-disable-line no-proto
  32. descriptor = gOPD(superProto, 'length');
  33. }
  34. // Opera 12.16 has a magic length data property on instances AND on Proto
  35. if (descriptor && descriptor.get) {
  36. getters[typedArray] = callBind(descriptor.get);
  37. } else if (oDP) {
  38. // this is likely an engine where instances have a magic length data property
  39. var arr = new global[typedArray](2);
  40. descriptor = gOPD(arr, 'length');
  41. if (descriptor && descriptor.configurable) {
  42. oDP(arr, 'length', { value: 3 });
  43. }
  44. if (arr.length === 2) {
  45. getters[typedArray] = getLength;
  46. }
  47. }
  48. }
  49. });
  50. }
  51. var tryTypedArrays = function tryAllTypedArrays(value) {
  52. var foundLength;
  53. forEach(getters, function (getter) {
  54. if (typeof foundLength !== 'number') {
  55. try {
  56. var length = getter(value);
  57. if (typeof length === 'number') {
  58. foundLength = length;
  59. }
  60. } catch (e) {}
  61. }
  62. });
  63. return foundLength;
  64. };
  65. var isTypedArray = require('is-typed-array');
  66. module.exports = function typedArrayLength(value) {
  67. if (!isTypedArray(value)) {
  68. return false;
  69. }
  70. return tryTypedArrays(value);
  71. };