sequence.js 5.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161
  1. "use strict";
  2. Object.defineProperty(exports, "__esModule", { value: true });
  3. exports.indexOf = indexOf;
  4. exports.lastIndexOf = lastIndexOf;
  5. exports.includes = includes;
  6. exports.startsWith = startsWith;
  7. exports.endsWith = endsWith;
  8. exports.slice = slice;
  9. exports.tail = tail;
  10. exports.copy = copy;
  11. exports.compare = compare;
  12. const buffer_source_js_1 = require("./buffer-source.js");
  13. function clampIndex(value, fallback, length) {
  14. const normalized = Number.isFinite(value) ? Math.trunc(value) : fallback;
  15. if (normalized <= 0) {
  16. return 0;
  17. }
  18. if (normalized >= length) {
  19. return length;
  20. }
  21. return normalized;
  22. }
  23. function normalizeForwardRange(length, options) {
  24. const start = clampIndex(options?.start, 0, length);
  25. const end = clampIndex(options?.end, length, length);
  26. return end >= start ? [start, end] : [start, start];
  27. }
  28. function normalizeReverseRange(length, options) {
  29. const start = clampIndex(options?.start, length, length);
  30. const end = clampIndex(options?.end, 0, length);
  31. return start >= end ? [end, start] : [start, start];
  32. }
  33. function normalizeSliceIndex(value, fallback, length) {
  34. const normalized = Number.isFinite(value) ? Math.trunc(value) : fallback;
  35. if (normalized < 0) {
  36. return Math.max(length + normalized, 0);
  37. }
  38. if (normalized > length) {
  39. return length;
  40. }
  41. return normalized;
  42. }
  43. function encodeAscii(text) {
  44. const bytes = new Uint8Array(text.length);
  45. for (let i = 0; i < text.length; i++) {
  46. bytes[i] = text.charCodeAt(i) & 0xff;
  47. }
  48. return bytes;
  49. }
  50. function encodeUtf8(text) {
  51. return new TextEncoder().encode(text);
  52. }
  53. function toPatternBytes(pattern, options) {
  54. if (typeof pattern === "string") {
  55. return options?.encoding === "utf8" ? encodeUtf8(pattern) : encodeAscii(pattern);
  56. }
  57. return (0, buffer_source_js_1.toUint8Array)(pattern);
  58. }
  59. function bytesEqualAt(data, pattern, offset) {
  60. for (let index = 0; index < pattern.byteLength; index++) {
  61. if (data[offset + index] !== pattern[index]) {
  62. return false;
  63. }
  64. }
  65. return true;
  66. }
  67. function indexOf(data, pattern, options) {
  68. const bytes = (0, buffer_source_js_1.toUint8Array)(data);
  69. const needle = toPatternBytes(pattern, options);
  70. const [start, end] = normalizeForwardRange(bytes.byteLength, options);
  71. if (needle.byteLength === 0) {
  72. return start;
  73. }
  74. const lastOffset = end - needle.byteLength;
  75. if (lastOffset < start) {
  76. return -1;
  77. }
  78. for (let offset = start; offset <= lastOffset; offset++) {
  79. if (bytesEqualAt(bytes, needle, offset)) {
  80. return offset;
  81. }
  82. }
  83. return -1;
  84. }
  85. function lastIndexOf(data, pattern, options) {
  86. const bytes = (0, buffer_source_js_1.toUint8Array)(data);
  87. const needle = toPatternBytes(pattern, options);
  88. const [end, start] = normalizeReverseRange(bytes.byteLength, options);
  89. if (needle.byteLength === 0) {
  90. return start;
  91. }
  92. const firstOffset = start - needle.byteLength;
  93. if (firstOffset < end) {
  94. return -1;
  95. }
  96. for (let offset = firstOffset; offset >= end; offset--) {
  97. if (bytesEqualAt(bytes, needle, offset)) {
  98. return offset;
  99. }
  100. }
  101. return -1;
  102. }
  103. function includes(data, pattern, options) {
  104. return indexOf(data, pattern, options) !== -1;
  105. }
  106. function startsWith(data, pattern, options) {
  107. const bytes = (0, buffer_source_js_1.toUint8Array)(data);
  108. const needle = toPatternBytes(pattern, options);
  109. if (needle.byteLength > bytes.byteLength) {
  110. return false;
  111. }
  112. return bytesEqualAt(bytes, needle, 0);
  113. }
  114. function endsWith(data, pattern, options) {
  115. const bytes = (0, buffer_source_js_1.toUint8Array)(data);
  116. const needle = toPatternBytes(pattern, options);
  117. if (needle.byteLength > bytes.byteLength) {
  118. return false;
  119. }
  120. return bytesEqualAt(bytes, needle, bytes.byteLength - needle.byteLength);
  121. }
  122. function slice(data, start, end) {
  123. const bytes = (0, buffer_source_js_1.toUint8Array)(data);
  124. const normalizedStart = normalizeSliceIndex(start, 0, bytes.byteLength);
  125. const normalizedEnd = normalizeSliceIndex(end, bytes.byteLength, bytes.byteLength);
  126. if (normalizedEnd <= normalizedStart) {
  127. return bytes.subarray(normalizedStart, normalizedStart);
  128. }
  129. return bytes.subarray(normalizedStart, normalizedEnd);
  130. }
  131. function tail(data, length) {
  132. const bytes = (0, buffer_source_js_1.toUint8Array)(data);
  133. const normalizedLength = Number.isFinite(length) ? Math.max(0, Math.trunc(length)) : 0;
  134. if (normalizedLength >= bytes.byteLength) {
  135. return bytes;
  136. }
  137. return bytes.subarray(bytes.byteLength - normalizedLength);
  138. }
  139. function copy(data) {
  140. return (0, buffer_source_js_1.toUint8ArrayCopy)(data);
  141. }
  142. function compare(a, b) {
  143. const left = (0, buffer_source_js_1.toUint8Array)(a);
  144. const right = (0, buffer_source_js_1.toUint8Array)(b);
  145. const limit = Math.min(left.byteLength, right.byteLength);
  146. for (let index = 0; index < limit; index++) {
  147. if (left[index] < right[index]) {
  148. return -1;
  149. }
  150. if (left[index] > right[index]) {
  151. return 1;
  152. }
  153. }
  154. if (left.byteLength < right.byteLength) {
  155. return -1;
  156. }
  157. if (left.byteLength > right.byteLength) {
  158. return 1;
  159. }
  160. return 0;
  161. }