Source: BinaryArray.js

  1. /** Class for returning array members from {@link Binary} objects */
  2. class BinaryArrayBase {
  3. // @member
  4. type
  5. // @member
  6. dv
  7. // @member
  8. offset
  9. // @member
  10. length
  11. // @member
  12. bytes
  13. /**
  14. * Creates a new customized array
  15. * @param {DataView} dv - The DataView handling the buffer where the data lives
  16. * @param {object} type - The type of the array members from {@link Types}
  17. * @param {number} offset - The offset of the first member of the array into the buffer
  18. * @param {number} length - The length of the array
  19. */
  20. constructor (dv, type, offset, length) {
  21. this.type = type
  22. this.dv = dv
  23. this.offset = offset
  24. this.length = length
  25. this.bytes = length * type.bytes
  26. }
  27. /**
  28. * Proxy array methods using this iterator
  29. * @param {function} fn - The function to apply on the array elements
  30. * @return {array} - The new generated array (not bound to original values)
  31. * @method
  32. */
  33. map = (fn) => Array.from(this, fn)
  34. // reduce = (...args) => Array.prototype.reduce.call([...this], ...args);
  35. /**
  36. * Transform this array into a JSON string
  37. * @return {string} - The JSON string representing this array
  38. * @method
  39. */
  40. toJSON = () => JSON.parse(JSON.stringify(this.map()));
  41. /**
  42. * Make a generator iterator
  43. * @method
  44. * @generator
  45. * @function iterator
  46. * @yield {any} - Each of this array elements of type {@link Types}
  47. * @name iterator
  48. */
  49. * [Symbol.iterator] () {
  50. // Deconstruct to optimize and ease reading
  51. const {
  52. length,
  53. dv,
  54. offset,
  55. type: { get, bytes }
  56. } = this
  57. // Use a new index for each iterator. This makes multiple
  58. // iterations over the iterable safe for non-trivial cases,
  59. // such as use of break or nested looping over the same iterable.
  60. for (let index = 0; index < length; index++) {
  61. yield get(dv, offset + bytes * index)
  62. }
  63. }
  64. }
  65. /**
  66. * A Proxy handler for the {@link BinaryArray} class to allow accessing its elements
  67. * @enum
  68. */
  69. const BinaryArrayHandler = {
  70. /**
  71. * Getter for the elements of the handled {@link BinaryArray}
  72. * @param {BinaryArray} target - The handled {@link BinaryArray} instance
  73. * @param {string} prop - The property to return (only handled when prop is a string representing a number)
  74. * @return {any} - The element at {@link prop} position, or a reflected value from {@link target}
  75. */
  76. get (target, prop) {
  77. // Very inefficient way
  78. // Need to:
  79. // - Override Array internals, but are private
  80. // - Override `[]` operator, but it's not possible
  81. if (prop === '0' || (typeof prop === 'string' && Number(prop) > 0)) {
  82. // Destructure to optimize
  83. const {
  84. dv,
  85. offset,
  86. type: { get, bytes }
  87. } = target
  88. return get(dv, offset + bytes * Number(prop))
  89. }
  90. // Return original value
  91. return Reflect.get(target, prop)
  92. },
  93. /**
  94. * Setter for the elements of the handled {@link BinaryArray}
  95. * @param {BinaryArray} target - The handled {@link BinaryArray} instance
  96. * @param {string} prop - The property to set (only handled when prop is a string representing a number)
  97. * @param {any} value - The value to assign to the {@link prop}'th element
  98. * @return {boolean} - If {@link prop} is numericalish, true (as needed for JS setters), else the return value from the {@link target} reflected setter
  99. */
  100. set (target, prop, value) {
  101. if (prop === '0' || (typeof prop === 'string' && Number(prop) > 0)) {
  102. // Destructure to optimize
  103. const {
  104. dv,
  105. offset,
  106. type: { set, bytes }
  107. } = target
  108. set(dv, offset + bytes * Number(prop), value)
  109. return true
  110. }
  111. return Reflect.set(target, prop, value)
  112. }
  113. }
  114. // #TODO: BUG: Argument Spread Operator not working
  115. // well when packing with webpack
  116. /**
  117. * Proxy creator for {@link BinaryArrayBase}
  118. * @param {DataView} dv - The DataView handling the buffer where the data lives
  119. * @param {object} type - The type of the array members from {@link Types}
  120. * @param {number} offset - The offset before the first member of the array
  121. * @param {number} length - The length of the array
  122. * @return {Proxy} - The proxy to {@link BinaryArrayBase} with {@link BinaryArrayHandler} as proxy handler
  123. */
  124. const BinaryArray = (dv, type, offset, length) => {
  125. return new Proxy(
  126. new BinaryArrayBase(dv, type, offset, length),
  127. BinaryArrayHandler
  128. )
  129. }
  130. export default BinaryArray