data.js 5.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184
  1. "use strict";
  2. Object.defineProperty(exports, "__esModule", { value: true });
  3. exports.zeroPadBytes = exports.zeroPadValue = exports.stripZerosLeft = exports.dataSlice = exports.dataLength = exports.concat = exports.hexlify = exports.isBytesLike = exports.isHexString = exports.getBytesCopy = exports.getBytes = void 0;
  4. /**
  5. * Some data helpers.
  6. *
  7. *
  8. * @_subsection api/utils:Data Helpers [about-data]
  9. */
  10. const errors_js_1 = require("./errors.js");
  11. function _getBytes(value, name, copy) {
  12. if (value instanceof Uint8Array) {
  13. if (copy) {
  14. return new Uint8Array(value);
  15. }
  16. return value;
  17. }
  18. if (typeof (value) === "string" && value.match(/^0x(?:[0-9a-f][0-9a-f])*$/i)) {
  19. const result = new Uint8Array((value.length - 2) / 2);
  20. let offset = 2;
  21. for (let i = 0; i < result.length; i++) {
  22. result[i] = parseInt(value.substring(offset, offset + 2), 16);
  23. offset += 2;
  24. }
  25. return result;
  26. }
  27. (0, errors_js_1.assertArgument)(false, "invalid BytesLike value", name || "value", value);
  28. }
  29. /**
  30. * Get a typed Uint8Array for %%value%%. If already a Uint8Array
  31. * the original %%value%% is returned; if a copy is required use
  32. * [[getBytesCopy]].
  33. *
  34. * @see: getBytesCopy
  35. */
  36. function getBytes(value, name) {
  37. return _getBytes(value, name, false);
  38. }
  39. exports.getBytes = getBytes;
  40. /**
  41. * Get a typed Uint8Array for %%value%%, creating a copy if necessary
  42. * to prevent any modifications of the returned value from being
  43. * reflected elsewhere.
  44. *
  45. * @see: getBytes
  46. */
  47. function getBytesCopy(value, name) {
  48. return _getBytes(value, name, true);
  49. }
  50. exports.getBytesCopy = getBytesCopy;
  51. /**
  52. * Returns true if %%value%% is a valid [[HexString]].
  53. *
  54. * If %%length%% is ``true`` or a //number//, it also checks that
  55. * %%value%% is a valid [[DataHexString]] of %%length%% (if a //number//)
  56. * bytes of data (e.g. ``0x1234`` is 2 bytes).
  57. */
  58. function isHexString(value, length) {
  59. if (typeof (value) !== "string" || !value.match(/^0x[0-9A-Fa-f]*$/)) {
  60. return false;
  61. }
  62. if (typeof (length) === "number" && value.length !== 2 + 2 * length) {
  63. return false;
  64. }
  65. if (length === true && (value.length % 2) !== 0) {
  66. return false;
  67. }
  68. return true;
  69. }
  70. exports.isHexString = isHexString;
  71. /**
  72. * Returns true if %%value%% is a valid representation of arbitrary
  73. * data (i.e. a valid [[DataHexString]] or a Uint8Array).
  74. */
  75. function isBytesLike(value) {
  76. return (isHexString(value, true) || (value instanceof Uint8Array));
  77. }
  78. exports.isBytesLike = isBytesLike;
  79. const HexCharacters = "0123456789abcdef";
  80. /**
  81. * Returns a [[DataHexString]] representation of %%data%%.
  82. */
  83. function hexlify(data) {
  84. const bytes = getBytes(data);
  85. let result = "0x";
  86. for (let i = 0; i < bytes.length; i++) {
  87. const v = bytes[i];
  88. result += HexCharacters[(v & 0xf0) >> 4] + HexCharacters[v & 0x0f];
  89. }
  90. return result;
  91. }
  92. exports.hexlify = hexlify;
  93. /**
  94. * Returns a [[DataHexString]] by concatenating all values
  95. * within %%data%%.
  96. */
  97. function concat(datas) {
  98. return "0x" + datas.map((d) => hexlify(d).substring(2)).join("");
  99. }
  100. exports.concat = concat;
  101. /**
  102. * Returns the length of %%data%%, in bytes.
  103. */
  104. function dataLength(data) {
  105. if (isHexString(data, true)) {
  106. return (data.length - 2) / 2;
  107. }
  108. return getBytes(data).length;
  109. }
  110. exports.dataLength = dataLength;
  111. /**
  112. * Returns a [[DataHexString]] by slicing %%data%% from the %%start%%
  113. * offset to the %%end%% offset.
  114. *
  115. * By default %%start%% is 0 and %%end%% is the length of %%data%%.
  116. */
  117. function dataSlice(data, start, end) {
  118. const bytes = getBytes(data);
  119. if (end != null && end > bytes.length) {
  120. (0, errors_js_1.assert)(false, "cannot slice beyond data bounds", "BUFFER_OVERRUN", {
  121. buffer: bytes, length: bytes.length, offset: end
  122. });
  123. }
  124. return hexlify(bytes.slice((start == null) ? 0 : start, (end == null) ? bytes.length : end));
  125. }
  126. exports.dataSlice = dataSlice;
  127. /**
  128. * Return the [[DataHexString]] result by stripping all **leading**
  129. ** zero bytes from %%data%%.
  130. */
  131. function stripZerosLeft(data) {
  132. let bytes = hexlify(data).substring(2);
  133. while (bytes.startsWith("00")) {
  134. bytes = bytes.substring(2);
  135. }
  136. return "0x" + bytes;
  137. }
  138. exports.stripZerosLeft = stripZerosLeft;
  139. function zeroPad(data, length, left) {
  140. const bytes = getBytes(data);
  141. (0, errors_js_1.assert)(length >= bytes.length, "padding exceeds data length", "BUFFER_OVERRUN", {
  142. buffer: new Uint8Array(bytes),
  143. length: length,
  144. offset: length + 1
  145. });
  146. const result = new Uint8Array(length);
  147. result.fill(0);
  148. if (left) {
  149. result.set(bytes, length - bytes.length);
  150. }
  151. else {
  152. result.set(bytes, 0);
  153. }
  154. return hexlify(result);
  155. }
  156. /**
  157. * Return the [[DataHexString]] of %%data%% padded on the **left**
  158. * to %%length%% bytes.
  159. *
  160. * If %%data%% already exceeds %%length%%, a [[BufferOverrunError]] is
  161. * thrown.
  162. *
  163. * This pads data the same as **values** are in Solidity
  164. * (e.g. ``uint128``).
  165. */
  166. function zeroPadValue(data, length) {
  167. return zeroPad(data, length, true);
  168. }
  169. exports.zeroPadValue = zeroPadValue;
  170. /**
  171. * Return the [[DataHexString]] of %%data%% padded on the **right**
  172. * to %%length%% bytes.
  173. *
  174. * If %%data%% already exceeds %%length%%, a [[BufferOverrunError]] is
  175. * thrown.
  176. *
  177. * This pads data the same as **bytes** are in Solidity
  178. * (e.g. ``bytes16``).
  179. */
  180. function zeroPadBytes(data, length) {
  181. return zeroPad(data, length, false);
  182. }
  183. exports.zeroPadBytes = zeroPadBytes;
  184. //# sourceMappingURL=data.js.map