goscript 0.0.37 → 0.0.39

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (198) hide show
  1. package/compiler/analysis.go +129 -8
  2. package/compiler/compiler.go +4 -1
  3. package/compiler/composite-lit.go +2 -4
  4. package/compiler/expr-call.go +12 -0
  5. package/compiler/lit.go +100 -6
  6. package/compiler/protobuf.go +2 -2
  7. package/compiler/spec-value.go +3 -3
  8. package/compiler/spec.go +6 -3
  9. package/compiler/stmt-assign.go +1 -1
  10. package/dist/gs/builtin/builtin.d.ts +45 -0
  11. package/dist/gs/builtin/builtin.js +197 -0
  12. package/dist/gs/builtin/builtin.js.map +1 -1
  13. package/dist/gs/builtin/slice.js +2 -1
  14. package/dist/gs/builtin/slice.js.map +1 -1
  15. package/dist/gs/bytes/buffer.gs.d.ts +56 -0
  16. package/dist/gs/bytes/buffer.gs.js +611 -0
  17. package/dist/gs/bytes/buffer.gs.js.map +1 -0
  18. package/dist/gs/bytes/bytes.gs.d.ts +78 -0
  19. package/dist/gs/bytes/bytes.gs.js +1011 -0
  20. package/dist/gs/bytes/bytes.gs.js.map +1 -0
  21. package/dist/gs/bytes/index.d.ts +4 -0
  22. package/dist/gs/bytes/index.js +5 -0
  23. package/dist/gs/bytes/index.js.map +1 -0
  24. package/dist/gs/bytes/iter.gs.d.ts +9 -0
  25. package/dist/gs/bytes/iter.gs.js +143 -0
  26. package/dist/gs/bytes/iter.gs.js.map +1 -0
  27. package/dist/gs/bytes/reader.gs.d.ts +34 -0
  28. package/dist/gs/bytes/reader.gs.js +198 -0
  29. package/dist/gs/bytes/reader.gs.js.map +1 -0
  30. package/dist/gs/github.com/pkg/errors/errors.d.ts +1 -1
  31. package/dist/gs/github.com/pkg/errors/errors.js +182 -23
  32. package/dist/gs/github.com/pkg/errors/errors.js.map +1 -1
  33. package/dist/gs/github.com/pkg/errors/go113.d.ts +1 -1
  34. package/dist/gs/github.com/pkg/errors/go113.js +1 -1
  35. package/dist/gs/github.com/pkg/errors/go113.js.map +1 -1
  36. package/dist/gs/github.com/pkg/errors/index.d.ts +3 -3
  37. package/dist/gs/github.com/pkg/errors/index.js +3 -3
  38. package/dist/gs/github.com/pkg/errors/index.js.map +1 -1
  39. package/dist/gs/github.com/pkg/errors/stack.d.ts +1 -1
  40. package/dist/gs/github.com/pkg/errors/stack.js +8 -5
  41. package/dist/gs/github.com/pkg/errors/stack.js.map +1 -1
  42. package/dist/gs/internal/abi/index.d.ts +20 -0
  43. package/dist/gs/internal/abi/index.js +20 -0
  44. package/dist/gs/internal/abi/index.js.map +1 -0
  45. package/dist/gs/internal/bytealg/index.d.ts +14 -0
  46. package/dist/gs/internal/bytealg/index.js +139 -0
  47. package/dist/gs/internal/bytealg/index.js.map +1 -0
  48. package/dist/gs/internal/byteorder/index.d.ts +1 -1
  49. package/dist/gs/internal/byteorder/index.js +4 -4
  50. package/dist/gs/internal/byteorder/index.js.map +1 -1
  51. package/dist/gs/math/index.d.ts +44 -44
  52. package/dist/gs/math/index.js +44 -44
  53. package/dist/gs/math/index.js.map +1 -1
  54. package/dist/gs/os/index.d.ts +19 -19
  55. package/dist/gs/os/index.js +19 -19
  56. package/dist/gs/os/index.js.map +1 -1
  57. package/dist/gs/reflect/deepequal.d.ts +2 -0
  58. package/dist/gs/reflect/deepequal.js +91 -0
  59. package/dist/gs/reflect/deepequal.js.map +1 -0
  60. package/dist/gs/reflect/index.d.ts +8 -0
  61. package/dist/gs/reflect/index.js +10 -0
  62. package/dist/gs/reflect/index.js.map +1 -0
  63. package/dist/gs/reflect/iter.d.ts +4 -0
  64. package/dist/gs/reflect/iter.js +24 -0
  65. package/dist/gs/reflect/iter.js.map +1 -0
  66. package/dist/gs/reflect/map.d.ts +20 -0
  67. package/dist/gs/reflect/map.js +74 -0
  68. package/dist/gs/reflect/map.js.map +1 -0
  69. package/dist/gs/reflect/swapper.d.ts +2 -0
  70. package/dist/gs/reflect/swapper.js +46 -0
  71. package/dist/gs/reflect/swapper.js.map +1 -0
  72. package/dist/gs/reflect/type.d.ts +134 -0
  73. package/dist/gs/reflect/type.js +825 -0
  74. package/dist/gs/reflect/type.js.map +1 -0
  75. package/dist/gs/reflect/types.d.ts +90 -0
  76. package/dist/gs/reflect/types.js +119 -0
  77. package/dist/gs/reflect/types.js.map +1 -0
  78. package/dist/gs/reflect/value.d.ts +13 -0
  79. package/dist/gs/reflect/value.js +202 -0
  80. package/dist/gs/reflect/value.js.map +1 -0
  81. package/dist/gs/reflect/visiblefields.d.ts +4 -0
  82. package/dist/gs/reflect/visiblefields.js +149 -0
  83. package/dist/gs/reflect/visiblefields.js.map +1 -0
  84. package/dist/gs/strconv/index.d.ts +6 -6
  85. package/dist/gs/strconv/index.js +6 -6
  86. package/dist/gs/strconv/index.js.map +1 -1
  87. package/dist/gs/strings/index.d.ts +1 -1
  88. package/dist/gs/strings/index.js +1 -1
  89. package/dist/gs/strings/index.js.map +1 -1
  90. package/dist/gs/strings/replace.js.map +1 -1
  91. package/dist/gs/sync/atomic/index.d.ts +4 -4
  92. package/dist/gs/sync/atomic/index.js +4 -4
  93. package/dist/gs/sync/atomic/index.js.map +1 -1
  94. package/dist/gs/syscall/index.d.ts +6 -6
  95. package/dist/gs/syscall/index.js +34 -28
  96. package/dist/gs/syscall/index.js.map +1 -1
  97. package/dist/gs/unicode/utf8/utf8.d.ts +1 -1
  98. package/dist/gs/unicode/utf8/utf8.js +4 -2
  99. package/dist/gs/unicode/utf8/utf8.js.map +1 -1
  100. package/dist/gs/unsafe/unsafe.js.map +1 -1
  101. package/gs/builtin/builtin.ts +219 -0
  102. package/gs/builtin/slice.ts +2 -1
  103. package/gs/bytes/buffer.gs.ts +614 -0
  104. package/gs/bytes/bytes.gs.ts +1180 -0
  105. package/gs/bytes/godoc.txt +69 -0
  106. package/gs/bytes/index.ts +69 -0
  107. package/gs/bytes/iter.gs.ts +149 -0
  108. package/gs/bytes/reader.gs.ts +230 -0
  109. package/gs/github.com/pkg/errors/errors.ts +408 -238
  110. package/gs/github.com/pkg/errors/go113.ts +5 -6
  111. package/gs/github.com/pkg/errors/index.ts +12 -3
  112. package/gs/github.com/pkg/errors/stack.ts +107 -105
  113. package/gs/internal/abi/index.ts +37 -0
  114. package/gs/internal/bytealg/index.ts +149 -0
  115. package/gs/internal/byteorder/index.ts +5 -5
  116. package/gs/math/abs.gs.test.ts +1 -1
  117. package/gs/math/acosh.gs.test.ts +4 -2
  118. package/gs/math/asin.gs.test.ts +1 -1
  119. package/gs/math/asinh.gs.test.ts +7 -3
  120. package/gs/math/atan.gs.test.ts +1 -1
  121. package/gs/math/atan2.gs.test.ts +17 -9
  122. package/gs/math/atanh.gs.test.ts +1 -1
  123. package/gs/math/bits.gs.test.ts +1 -1
  124. package/gs/math/cbrt.gs.test.ts +1 -1
  125. package/gs/math/const.gs.test.ts +34 -8
  126. package/gs/math/copysign.gs.test.ts +7 -3
  127. package/gs/math/dim.gs.test.ts +19 -7
  128. package/gs/math/erf.gs.test.ts +1 -1
  129. package/gs/math/erfinv.gs.test.ts +4 -2
  130. package/gs/math/exp.gs.test.ts +1 -1
  131. package/gs/math/expm1.gs.test.ts +6 -4
  132. package/gs/math/floor.gs.test.ts +17 -4
  133. package/gs/math/fma.gs.test.ts +53 -53
  134. package/gs/math/frexp.gs.test.ts +112 -117
  135. package/gs/math/gamma.gs.test.ts +1 -1
  136. package/gs/math/hypot.gs.test.ts +53 -53
  137. package/gs/math/index.ts +80 -44
  138. package/gs/math/j0.gs.test.ts +6 -2
  139. package/gs/math/j1.gs.test.ts +6 -2
  140. package/gs/math/jn.gs.test.ts +9 -5
  141. package/gs/math/ldexp.gs.test.ts +103 -86
  142. package/gs/math/lgamma.gs.test.ts +10 -10
  143. package/gs/math/log.gs.test.ts +1 -1
  144. package/gs/math/log10.gs.test.ts +1 -1
  145. package/gs/math/log1p.gs.test.ts +2 -2
  146. package/gs/math/logb.gs.test.ts +1 -1
  147. package/gs/math/mod.gs.test.ts +2 -2
  148. package/gs/math/modf.gs.test.ts +7 -7
  149. package/gs/math/nextafter.gs.test.ts +9 -7
  150. package/gs/math/pow.gs.test.ts +6 -4
  151. package/gs/math/pow10.gs.test.ts +1 -1
  152. package/gs/math/remainder.gs.test.ts +1 -1
  153. package/gs/math/signbit.gs.test.ts +1 -1
  154. package/gs/math/sin.gs.test.ts +1 -1
  155. package/gs/math/sincos.gs.test.ts +33 -14
  156. package/gs/math/sinh.gs.test.ts +1 -1
  157. package/gs/math/sqrt.gs.test.ts +1 -1
  158. package/gs/math/tan.gs.test.ts +3 -3
  159. package/gs/math/tanh.gs.test.ts +1 -1
  160. package/gs/os/index.ts +128 -19
  161. package/gs/reflect/ANALYSIS.md +278 -0
  162. package/gs/reflect/deepequal.test.ts +41 -0
  163. package/gs/reflect/deepequal.ts +169 -0
  164. package/gs/reflect/function-types.test.ts +146 -0
  165. package/gs/reflect/godoc.txt +67 -0
  166. package/gs/reflect/index.ts +83 -0
  167. package/gs/reflect/iter.ts +44 -0
  168. package/gs/reflect/map.test.ts +30 -0
  169. package/gs/reflect/map.ts +85 -0
  170. package/gs/reflect/swapper.ts +52 -0
  171. package/gs/reflect/type.ts +1016 -0
  172. package/gs/reflect/types.ts +214 -0
  173. package/gs/reflect/value.ts +270 -0
  174. package/gs/reflect/visiblefields.ts +177 -0
  175. package/gs/strconv/index.ts +39 -6
  176. package/gs/strings/index.ts +7 -1
  177. package/gs/strings/replace.ts +1 -9
  178. package/gs/sync/atomic/index.ts +53 -4
  179. package/gs/syscall/index.ts +45 -37
  180. package/gs/unicode/utf8/utf8.ts +8 -5
  181. package/gs/unsafe/unsafe.ts +1 -1
  182. package/package.json +2 -1
  183. package/dist/gs/internal/testlog/index.d.ts +0 -1
  184. package/dist/gs/internal/testlog/index.js +0 -5
  185. package/dist/gs/internal/testlog/index.js.map +0 -1
  186. package/dist/gs/maps/iter.gs.d.ts +0 -7
  187. package/dist/gs/maps/iter.gs.js +0 -65
  188. package/dist/gs/maps/iter.gs.js.map +0 -1
  189. package/dist/gs/maps/maps.gs.d.ts +0 -7
  190. package/dist/gs/maps/maps.gs.js +0 -79
  191. package/dist/gs/maps/maps.gs.js.map +0 -1
  192. package/dist/gs/stringslite/index.d.ts +0 -1
  193. package/dist/gs/stringslite/index.js +0 -2
  194. package/dist/gs/stringslite/index.js.map +0 -1
  195. package/dist/gs/stringslite/strings.d.ts +0 -11
  196. package/dist/gs/stringslite/strings.js +0 -67
  197. package/dist/gs/stringslite/strings.js.map +0 -1
  198. package/gs/internal/testlog/index.ts +0 -7
@@ -0,0 +1,1011 @@
1
+ import * as $ from "@goscript/builtin/builtin.js";
2
+ import * as unicode from "@goscript/unicode/index.js";
3
+ import * as utf8 from "@goscript/unicode/utf8/index.js";
4
+ // Equal reports whether a and b
5
+ // are the same length and contain the same bytes.
6
+ // A nil argument is equivalent to an empty slice.
7
+ export function Equal(a, b) {
8
+ return $.bytesEqual(a, b);
9
+ }
10
+ // Compare returns an integer comparing two byte slices lexicographically.
11
+ // The result will be 0 if a == b, -1 if a < b, and +1 if a > b.
12
+ // A nil argument is equivalent to an empty slice.
13
+ export function Compare(a, b) {
14
+ return $.bytesCompare(a, b);
15
+ }
16
+ // explode splits s into a slice of UTF-8 sequences, one per Unicode code point (still slices of bytes),
17
+ // up to a maximum of n byte slices. Invalid UTF-8 sequences are chopped into individual bytes.
18
+ export function explode(s, n) {
19
+ if (n === 0) {
20
+ return null;
21
+ }
22
+ if (s === null || $.len(s) === 0) {
23
+ return null;
24
+ }
25
+ const result = [];
26
+ let i = 0;
27
+ while (i < $.len(s) && (n < 0 || result.length < n)) {
28
+ const [, size] = utf8.DecodeRune($.goSlice(s, i, undefined));
29
+ if (size <= 0) {
30
+ // Invalid UTF-8, take single byte
31
+ result.push($.goSlice(s, i, i + 1));
32
+ i++;
33
+ }
34
+ else {
35
+ result.push($.goSlice(s, i, i + size));
36
+ i += size;
37
+ }
38
+ }
39
+ // If we have remaining bytes and haven't reached n limit, add the rest
40
+ if (i < $.len(s) && (n < 0 || result.length < n)) {
41
+ result.push($.goSlice(s, i, undefined));
42
+ }
43
+ return $.arrayToSlice(result);
44
+ }
45
+ // Count counts the number of non-overlapping instances of sep in s.
46
+ // If sep is an empty slice, Count returns 1 + the number of UTF-8-encoded code points in s.
47
+ export function Count(s, sep) {
48
+ // Special case for empty separator
49
+ if (sep === null || $.len(sep) === 0) {
50
+ if (s === null)
51
+ return 1;
52
+ // For now, use simple byte count + 1 (TODO: proper UTF-8 rune counting)
53
+ return $.len(s) + 1;
54
+ }
55
+ // Single byte separator - optimized path
56
+ if ($.len(sep) === 1) {
57
+ return $.bytesCount(s, sep);
58
+ }
59
+ return $.bytesCount(s, sep);
60
+ }
61
+ // Contains reports whether subslice is within b.
62
+ export function Contains(b, subslice) {
63
+ return Index(b, subslice) !== -1;
64
+ }
65
+ // ContainsAny reports whether any of the UTF-8-encoded code points in chars are within b.
66
+ export function ContainsAny(b, chars) {
67
+ return IndexAny(b, chars) >= 0;
68
+ }
69
+ // ContainsRune reports whether the rune is contained in the UTF-8-encoded byte slice b.
70
+ export function ContainsRune(b, r) {
71
+ return IndexRune(b, r) >= 0;
72
+ }
73
+ // ContainsFunc reports whether any of the UTF-8-encoded code points r within b satisfy f(r).
74
+ export function ContainsFunc(b, f) {
75
+ return IndexFunc(b, f) >= 0;
76
+ }
77
+ // IndexByte returns the index of the first instance of c in b, or -1 if c is not present in b.
78
+ export function IndexByte(b, c) {
79
+ return $.bytesIndexByte(b, c);
80
+ }
81
+ export function indexBytePortable(s, c) {
82
+ if (s === null)
83
+ return -1;
84
+ const arr = $.bytesToArray(s);
85
+ return arr.indexOf(c);
86
+ }
87
+ // LastIndex returns the index of the last instance of sep in s, or -1 if sep is not present in s.
88
+ export function LastIndex(s, sep) {
89
+ if (sep === null || $.len(sep) === 0) {
90
+ return s === null ? 0 : $.len(s);
91
+ }
92
+ if ($.len(sep) === 1) {
93
+ return $.bytesLastIndexByte(s, sep[0]);
94
+ }
95
+ return $.bytesLastIndexOf(s, sep);
96
+ }
97
+ // LastIndexByte returns the index of the last instance of c in s, or -1 if c is not present in s.
98
+ export function LastIndexByte(s, c) {
99
+ return $.bytesLastIndexByte(s, c);
100
+ }
101
+ // IndexRune interprets s as a sequence of UTF-8-encoded code points.
102
+ // It returns the byte index of the first occurrence in s of the given rune.
103
+ // It returns -1 if rune is not present in s.
104
+ // If r is [utf8.RuneError], it returns the first instance of any
105
+ // invalid UTF-8 byte sequence.
106
+ export function IndexRune(s, r) {
107
+ if (s === null) {
108
+ return -1;
109
+ }
110
+ if (r < utf8.RuneSelf) {
111
+ // ASCII case - use IndexByte for efficiency
112
+ return IndexByte(s, r);
113
+ }
114
+ if (r === utf8.RuneError) {
115
+ // Look for invalid UTF-8 sequences
116
+ for (let i = 0; i < $.len(s);) {
117
+ const [r1, size] = utf8.DecodeRune($.goSlice(s, i, undefined));
118
+ if (r1 === utf8.RuneError && size === 1) {
119
+ return i;
120
+ }
121
+ if (size <= 0) {
122
+ return i;
123
+ }
124
+ i += size;
125
+ }
126
+ return -1;
127
+ }
128
+ // Encode the rune to bytes and search for it
129
+ const runeBytes = new Uint8Array(4);
130
+ const n = utf8.EncodeRune(runeBytes, r);
131
+ const needle = $.goSlice(runeBytes, 0, n);
132
+ return Index(s, needle);
133
+ }
134
+ // IndexAny interprets s as a sequence of UTF-8-encoded Unicode code points.
135
+ // It returns the byte index of the first occurrence in s of any of the Unicode
136
+ // code points in chars. It returns -1 if chars is empty or if there is no code
137
+ // point in common.
138
+ export function IndexAny(s, chars) {
139
+ if (s === null || chars.length === 0) {
140
+ return -1;
141
+ }
142
+ // Check if all chars are ASCII for optimization
143
+ let allASCII = true;
144
+ for (let i = 0; i < chars.length; i++) {
145
+ if (chars.charCodeAt(i) >= utf8.RuneSelf) {
146
+ allASCII = false;
147
+ break;
148
+ }
149
+ }
150
+ if (allASCII) {
151
+ // ASCII optimization
152
+ for (let i = 0; i < $.len(s); i++) {
153
+ const b = s[i];
154
+ if (b < utf8.RuneSelf && chars.indexOf(String.fromCharCode(b)) >= 0) {
155
+ return i;
156
+ }
157
+ }
158
+ return -1;
159
+ }
160
+ // Full UTF-8 handling
161
+ for (let i = 0; i < $.len(s);) {
162
+ const [r, size] = utf8.DecodeRune($.goSlice(s, i, undefined));
163
+ if (size <= 0) {
164
+ i++;
165
+ continue;
166
+ }
167
+ // Check if this rune is in chars
168
+ if (containsRune(chars, r)) {
169
+ return i;
170
+ }
171
+ i += size;
172
+ }
173
+ return -1;
174
+ }
175
+ // LastIndexAny interprets s as a sequence of UTF-8-encoded Unicode code
176
+ // points. It returns the byte index of the last occurrence in s of any of
177
+ // the Unicode code points in chars. It returns -1 if chars is empty or if
178
+ // there is no code point in common.
179
+ export function LastIndexAny(s, chars) {
180
+ if (s === null || chars.length === 0) {
181
+ return -1;
182
+ }
183
+ // Check if all chars are ASCII for optimization
184
+ let allASCII = true;
185
+ for (let i = 0; i < chars.length; i++) {
186
+ if (chars.charCodeAt(i) >= utf8.RuneSelf) {
187
+ allASCII = false;
188
+ break;
189
+ }
190
+ }
191
+ if (allASCII) {
192
+ // ASCII optimization - search backwards
193
+ for (let i = $.len(s) - 1; i >= 0; i--) {
194
+ const b = s[i];
195
+ if (b < utf8.RuneSelf && chars.indexOf(String.fromCharCode(b)) >= 0) {
196
+ return i;
197
+ }
198
+ }
199
+ return -1;
200
+ }
201
+ // Full UTF-8 handling - need to scan forward to find rune boundaries
202
+ let lastIndex = -1;
203
+ for (let i = 0; i < $.len(s);) {
204
+ const [r, size] = utf8.DecodeRune($.goSlice(s, i, undefined));
205
+ if (size <= 0) {
206
+ i++;
207
+ continue;
208
+ }
209
+ // Check if this rune is in chars
210
+ if (containsRune(chars, r)) {
211
+ lastIndex = i;
212
+ }
213
+ i += size;
214
+ }
215
+ return lastIndex;
216
+ }
217
+ // Generic split: splits after each instance of sep,
218
+ // including sepSave bytes of sep in the subslices.
219
+ export function genSplit(s, sep, sepSave, n) {
220
+ if (n === 0) {
221
+ return null;
222
+ }
223
+ if (sep === null || $.len(sep) === 0) {
224
+ return explode(s, n);
225
+ }
226
+ if (n < 0) {
227
+ n = Count(s, sep) + 1;
228
+ }
229
+ if (n > Count(s, sep) + 1) {
230
+ n = Count(s, sep) + 1;
231
+ }
232
+ const result = [];
233
+ let start = 0;
234
+ for (let i = 0; i < n - 1; i++) {
235
+ const m = Index($.goSlice(s, start, undefined), sep);
236
+ if (m < 0) {
237
+ break;
238
+ }
239
+ const end = start + m + sepSave;
240
+ result.push($.goSlice(s, start, end));
241
+ start += m + $.len(sep);
242
+ }
243
+ // Add the remaining part
244
+ result.push($.goSlice(s, start, undefined));
245
+ return $.arrayToSlice(result);
246
+ }
247
+ // SplitN slices s into subslices separated by sep and returns a slice of
248
+ // the subslices between those separators.
249
+ // If sep is empty, SplitN splits after each UTF-8 sequence.
250
+ // The count determines the number of subslices to return:
251
+ // - n > 0: at most n subslices; the last subslice will be the unsplit remainder;
252
+ // - n == 0: the result is nil (zero subslices);
253
+ // - n < 0: all subslices.
254
+ //
255
+ // To split around the first instance of a separator, see [Cut].
256
+ export function SplitN(s, sep, n) {
257
+ return genSplit(s, sep, 0, n);
258
+ }
259
+ // SplitAfterN slices s into subslices after each instance of sep and
260
+ // returns a slice of those subslices.
261
+ // If sep is empty, SplitAfterN splits after each UTF-8 sequence.
262
+ // The count determines the number of subslices to return:
263
+ // - n > 0: at most n subslices; the last subslice will be the unsplit remainder;
264
+ // - n == 0: the result is nil (zero subslices);
265
+ // - n < 0: all subslices.
266
+ export function SplitAfterN(s, sep, n) {
267
+ return genSplit(s, sep, $.len(sep), n);
268
+ }
269
+ // Split slices s into all subslices separated by sep and returns a slice of
270
+ // the subslices between those separators.
271
+ // If sep is empty, Split splits after each UTF-8 sequence.
272
+ // It is equivalent to SplitN with a count of -1.
273
+ //
274
+ // To split around the first instance of a separator, see [Cut].
275
+ export function Split(s, sep) {
276
+ return genSplit(s, sep, 0, -1);
277
+ }
278
+ // SplitAfter slices s into all subslices after each instance of sep and
279
+ // returns a slice of those subslices.
280
+ // If sep is empty, SplitAfter splits after each UTF-8 sequence.
281
+ // It is equivalent to SplitAfterN with a count of -1.
282
+ export function SplitAfter(s, sep) {
283
+ return genSplit(s, sep, $.len(sep), -1);
284
+ }
285
+ export let asciiSpace = $.arrayToSlice([0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0]);
286
+ // Fields interprets s as a sequence of UTF-8-encoded code points.
287
+ // It splits the slice s around each instance of one or more consecutive white space
288
+ // characters, as defined by [unicode.IsSpace], returning a slice of subslices of s or an
289
+ // empty slice if s contains only white space.
290
+ export function Fields(s) {
291
+ // Use FieldsFunc with unicode.IsSpace
292
+ return FieldsFunc(s, unicode.IsSpace);
293
+ }
294
+ // FieldsFunc interprets s as a sequence of UTF-8-encoded code points.
295
+ // It splits the slice s at each run of code points c satisfying f(c) and
296
+ // returns a slice of subslices of s. If all code points in s satisfy f(c), or
297
+ // len(s) == 0, an empty slice is returned.
298
+ //
299
+ // FieldsFunc makes no guarantees about the order in which it calls f(c)
300
+ // and assumes that f always returns the same value for a given c.
301
+ export function FieldsFunc(s, f) {
302
+ if (s === null || f === null) {
303
+ return null;
304
+ }
305
+ const result = [];
306
+ let start = -1;
307
+ for (let i = 0; i < $.len(s);) {
308
+ let size = 1;
309
+ let r = s[i];
310
+ if (r >= utf8.RuneSelf) {
311
+ const [rune, runeSize] = utf8.DecodeRune($.goSlice(s, i, undefined));
312
+ r = rune;
313
+ size = runeSize;
314
+ }
315
+ if (f(r)) {
316
+ // Found separator
317
+ if (start >= 0) {
318
+ result.push($.goSlice(s, start, i));
319
+ start = -1;
320
+ }
321
+ }
322
+ else if (start < 0) {
323
+ // Start of new field
324
+ start = i;
325
+ }
326
+ i += size;
327
+ }
328
+ // Add final field if any
329
+ if (start >= 0) {
330
+ result.push($.goSlice(s, start, undefined));
331
+ }
332
+ return result.length === 0 ? null : $.arrayToSlice(result);
333
+ }
334
+ // Join concatenates the elements of s to create a new byte slice. The separator
335
+ // sep is placed between elements in the resulting slice.
336
+ export function Join(s, sep) {
337
+ if (s === null || $.len(s) === 0) {
338
+ return new Uint8Array(0);
339
+ }
340
+ // Just return a copy for single element
341
+ if ($.len(s) === 1) {
342
+ if (s[0] === null)
343
+ return new Uint8Array(0);
344
+ return new Uint8Array($.bytesToArray(s[0]));
345
+ }
346
+ // Calculate total length needed
347
+ let totalLen = 0;
348
+ const sepLen = sep === null ? 0 : $.len(sep);
349
+ for (let i = 0; i < $.len(s); i++) {
350
+ const elem = s[i];
351
+ if (elem !== null) {
352
+ totalLen += $.len(elem);
353
+ }
354
+ }
355
+ if (sepLen > 0) {
356
+ totalLen += sepLen * ($.len(s) - 1);
357
+ }
358
+ // Build result
359
+ const result = new Uint8Array(totalLen);
360
+ let pos = 0;
361
+ for (let i = 0; i < $.len(s); i++) {
362
+ if (i > 0 && sepLen > 0) {
363
+ const sepArr = $.bytesToArray(sep);
364
+ for (let j = 0; j < sepArr.length; j++) {
365
+ result[pos++] = sepArr[j];
366
+ }
367
+ }
368
+ const elem = s[i];
369
+ if (elem !== null) {
370
+ const elemArr = $.bytesToArray(elem);
371
+ for (let j = 0; j < elemArr.length; j++) {
372
+ result[pos++] = elemArr[j];
373
+ }
374
+ }
375
+ }
376
+ return result;
377
+ }
378
+ // HasPrefix reports whether the byte slice s begins with prefix.
379
+ export function HasPrefix(s, prefix) {
380
+ if (s === null)
381
+ s = new Uint8Array(0);
382
+ if (prefix === null)
383
+ prefix = new Uint8Array(0);
384
+ if ($.len(s) < $.len(prefix))
385
+ return false;
386
+ const sArr = $.bytesToArray(s);
387
+ const prefixArr = $.bytesToArray(prefix);
388
+ for (let i = 0; i < prefixArr.length; i++) {
389
+ if (sArr[i] !== prefixArr[i])
390
+ return false;
391
+ }
392
+ return true;
393
+ }
394
+ // HasSuffix reports whether the byte slice s ends with suffix.
395
+ export function HasSuffix(s, suffix) {
396
+ if (s === null)
397
+ s = new Uint8Array(0);
398
+ if (suffix === null)
399
+ suffix = new Uint8Array(0);
400
+ if ($.len(s) < $.len(suffix))
401
+ return false;
402
+ const sArr = $.bytesToArray(s);
403
+ const suffixArr = $.bytesToArray(suffix);
404
+ const offset = sArr.length - suffixArr.length;
405
+ for (let i = 0; i < suffixArr.length; i++) {
406
+ if (sArr[offset + i] !== suffixArr[i])
407
+ return false;
408
+ }
409
+ return true;
410
+ }
411
+ // Map returns a copy of the byte slice s with all its characters modified
412
+ // according to the mapping function. If mapping returns a negative value, the character is
413
+ // dropped from the byte slice with no replacement. The characters in s and the
414
+ // output are interpreted as UTF-8-encoded code points.
415
+ export function Map(mapping, s) {
416
+ // TODO: Implement Map function with proper UTF-8 handling
417
+ throw new Error("Map: not implemented");
418
+ }
419
+ // Repeat returns a new byte slice consisting of count copies of b.
420
+ //
421
+ // It panics if count is negative or if the result of (len(b) * count)
422
+ // overflows.
423
+ export function Repeat(b, count) {
424
+ if (count === 0) {
425
+ return new Uint8Array(0);
426
+ }
427
+ if (count < 0) {
428
+ $.panic("bytes: negative Repeat count");
429
+ }
430
+ if (b === null || $.len(b) === 0) {
431
+ return new Uint8Array(0);
432
+ }
433
+ const bArr = $.bytesToArray(b);
434
+ const totalLen = bArr.length * count;
435
+ // Check for overflow
436
+ if (totalLen / count !== bArr.length) {
437
+ $.panic("bytes: Repeat output length overflow");
438
+ }
439
+ const result = new Uint8Array(totalLen);
440
+ let pos = 0;
441
+ for (let i = 0; i < count; i++) {
442
+ for (let j = 0; j < bArr.length; j++) {
443
+ result[pos++] = bArr[j];
444
+ }
445
+ }
446
+ return result;
447
+ }
448
+ // ToUpper returns a copy of the byte slice s with all Unicode letters mapped to
449
+ // their upper case.
450
+ export function ToUpper(s) {
451
+ if (s === null || $.len(s) === 0) {
452
+ return new Uint8Array(0);
453
+ }
454
+ const result = [];
455
+ for (let i = 0; i < $.len(s);) {
456
+ const [r, size] = utf8.DecodeRune($.goSlice(s, i, undefined));
457
+ if (size <= 0) {
458
+ // Invalid UTF-8, copy the byte as-is
459
+ result.push(s[i]);
460
+ i++;
461
+ }
462
+ else {
463
+ // Convert rune to uppercase
464
+ const upperR = unicode.ToUpper(r);
465
+ // Encode the uppercase rune back to bytes
466
+ const runeBytes = new Uint8Array(utf8.UTFMax);
467
+ const n = utf8.EncodeRune(runeBytes, upperR);
468
+ // Add the encoded bytes to result
469
+ for (let j = 0; j < n; j++) {
470
+ result.push(runeBytes[j]);
471
+ }
472
+ i += size;
473
+ }
474
+ }
475
+ return new Uint8Array(result);
476
+ }
477
+ // ToLower returns a copy of the byte slice s with all Unicode letters mapped to
478
+ // their lower case.
479
+ export function ToLower(s) {
480
+ if (s === null || $.len(s) === 0) {
481
+ return new Uint8Array(0);
482
+ }
483
+ const result = [];
484
+ for (let i = 0; i < $.len(s);) {
485
+ const [r, size] = utf8.DecodeRune($.goSlice(s, i, undefined));
486
+ if (size <= 0) {
487
+ // Invalid UTF-8, copy the byte as-is
488
+ result.push(s[i]);
489
+ i++;
490
+ }
491
+ else {
492
+ // Convert rune to lowercase
493
+ const lowerR = unicode.ToLower(r);
494
+ // Encode the lowercase rune back to bytes
495
+ const runeBytes = new Uint8Array(utf8.UTFMax);
496
+ const n = utf8.EncodeRune(runeBytes, lowerR);
497
+ // Add the encoded bytes to result
498
+ for (let j = 0; j < n; j++) {
499
+ result.push(runeBytes[j]);
500
+ }
501
+ i += size;
502
+ }
503
+ }
504
+ return new Uint8Array(result);
505
+ }
506
+ // ToTitle treats s as UTF-8-encoded bytes and returns a copy with all the Unicode letters mapped to their title case.
507
+ export function ToTitle(s) {
508
+ return Map(unicode.ToTitle, s);
509
+ }
510
+ // ToUpperSpecial treats s as UTF-8-encoded bytes and returns a copy with all the Unicode letters mapped to their
511
+ // upper case, giving priority to the special casing rules.
512
+ export function ToUpperSpecial(c, s) {
513
+ // TODO: Fix SpecialCase method calls
514
+ throw new Error("ToUpperSpecial: not implemented");
515
+ }
516
+ // ToLowerSpecial treats s as UTF-8-encoded bytes and returns a copy with all the Unicode letters mapped to their
517
+ // lower case, giving priority to the special casing rules.
518
+ export function ToLowerSpecial(c, s) {
519
+ // TODO: Fix SpecialCase method calls
520
+ throw new Error("ToLowerSpecial: not implemented");
521
+ }
522
+ // ToTitleSpecial treats s as UTF-8-encoded bytes and returns a copy with all the Unicode letters mapped to their
523
+ // title case, giving priority to the special casing rules.
524
+ export function ToTitleSpecial(c, s) {
525
+ // TODO: Fix SpecialCase method calls
526
+ throw new Error("ToTitleSpecial: not implemented");
527
+ }
528
+ // ToValidUTF8 treats s as UTF-8-encoded bytes and returns a copy with each run of bytes
529
+ // representing invalid UTF-8 replaced with the bytes in replacement, which may be empty.
530
+ export function ToValidUTF8(s, replacement) {
531
+ // TODO: Implement ToValidUTF8 with proper UTF-8 validation
532
+ throw new Error("ToValidUTF8: not implemented");
533
+ }
534
+ // isSeparator reports whether the rune could mark a word boundary.
535
+ // TODO: update when package unicode captures more of the properties.
536
+ export function isSeparator(r) {
537
+ // ASCII alphanumerics and underscore are not separators
538
+ if (r <= 0x7F) {
539
+ if ((48 <= r && r <= 57) || // 0-9
540
+ (97 <= r && r <= 122) || // a-z
541
+ (65 <= r && r <= 90) || // A-Z
542
+ r === 95) { // _
543
+ return false;
544
+ }
545
+ return true;
546
+ }
547
+ // Letters and digits are not separators
548
+ if (unicode.IsLetter(r) || unicode.IsDigit(r)) {
549
+ return false;
550
+ }
551
+ // Otherwise, all we can do for now is treat spaces as separators.
552
+ return unicode.IsSpace(r);
553
+ }
554
+ // Title treats s as UTF-8-encoded bytes and returns a copy with all Unicode letters that begin
555
+ // words mapped to their title case.
556
+ //
557
+ // Deprecated: The rule Title uses for word boundaries does not handle Unicode
558
+ // punctuation properly. Use golang.org/x/text/cases instead.
559
+ export function Title(s) {
560
+ // TODO: Implement Title function properly
561
+ throw new Error("Title: not implemented");
562
+ }
563
+ // TrimLeftFunc treats s as UTF-8-encoded bytes and returns a subslice of s by slicing off
564
+ // all leading UTF-8-encoded code points c that satisfy f(c).
565
+ export function TrimLeftFunc(s, f) {
566
+ const i = indexFunc(s, f, false);
567
+ if (i === -1) {
568
+ return null;
569
+ }
570
+ return $.goSlice(s, i, undefined);
571
+ }
572
+ // TrimRightFunc returns a subslice of s by slicing off all trailing
573
+ // UTF-8-encoded code points c that satisfy f(c).
574
+ export function TrimRightFunc(s, f) {
575
+ const i = lastIndexFunc(s, f, false);
576
+ if (i >= 0 && $.len(s) > i) {
577
+ const [, wid] = utf8.DecodeRune($.goSlice(s, i, undefined));
578
+ return $.goSlice(s, undefined, i + wid);
579
+ }
580
+ return null;
581
+ }
582
+ // TrimFunc returns a subslice of s by slicing off all leading and trailing
583
+ // UTF-8-encoded code points c that satisfy f(c).
584
+ export function TrimFunc(s, f) {
585
+ return TrimRightFunc(TrimLeftFunc(s, f), f);
586
+ }
587
+ // TrimPrefix returns s without the provided leading prefix string.
588
+ // If s doesn't start with prefix, s is returned unchanged.
589
+ export function TrimPrefix(s, prefix) {
590
+ if (HasPrefix(s, prefix)) {
591
+ return $.goSlice(s, $.len(prefix), undefined);
592
+ }
593
+ return s;
594
+ }
595
+ // TrimSuffix returns s without the provided trailing suffix string.
596
+ // If s doesn't end with suffix, s is returned unchanged.
597
+ export function TrimSuffix(s, suffix) {
598
+ if (HasSuffix(s, suffix)) {
599
+ return $.goSlice(s, undefined, $.len(s) - $.len(suffix));
600
+ }
601
+ return s;
602
+ }
603
+ // IndexFunc interprets s as a sequence of UTF-8-encoded code points.
604
+ // It returns the byte index in s of the first Unicode
605
+ // code point satisfying f(c), or -1 if none do.
606
+ export function IndexFunc(s, f) {
607
+ return indexFunc(s, f, true);
608
+ }
609
+ // LastIndexFunc interprets s as a sequence of UTF-8-encoded code points.
610
+ // It returns the byte index in s of the last Unicode
611
+ // code point satisfying f(c), or -1 if none do.
612
+ export function LastIndexFunc(s, f) {
613
+ return lastIndexFunc(s, f, true);
614
+ }
615
+ // indexFunc is the same as IndexFunc except that if
616
+ // truth==false, the sense of the predicate function is
617
+ // inverted.
618
+ export function indexFunc(s, f, truth) {
619
+ if (s === null || f === null) {
620
+ return -1;
621
+ }
622
+ for (let i = 0; i < $.len(s);) {
623
+ const [r, size] = utf8.DecodeRune($.goSlice(s, i, undefined));
624
+ if (size <= 0) {
625
+ // Invalid UTF-8
626
+ if (f(utf8.RuneError) === truth) {
627
+ return i;
628
+ }
629
+ i++;
630
+ }
631
+ else {
632
+ if (f(r) === truth) {
633
+ return i;
634
+ }
635
+ i += size;
636
+ }
637
+ }
638
+ return -1;
639
+ }
640
+ // lastIndexFunc is the same as LastIndexFunc except that if
641
+ // truth==false, the sense of the predicate function is
642
+ // inverted.
643
+ export function lastIndexFunc(s, f, truth) {
644
+ if (s === null || f === null) {
645
+ return -1;
646
+ }
647
+ let lastIndex = -1;
648
+ for (let i = 0; i < $.len(s);) {
649
+ const [r, size] = utf8.DecodeRune($.goSlice(s, i, undefined));
650
+ if (size <= 0) {
651
+ // Invalid UTF-8
652
+ if (f(utf8.RuneError) === truth) {
653
+ lastIndex = i;
654
+ }
655
+ i++;
656
+ }
657
+ else {
658
+ if (f(r) === truth) {
659
+ lastIndex = i;
660
+ }
661
+ i += size;
662
+ }
663
+ }
664
+ return lastIndex;
665
+ }
666
+ class asciiSet {
667
+ _value;
668
+ constructor(_value) {
669
+ this._value = _value;
670
+ }
671
+ valueOf() {
672
+ return this._value;
673
+ }
674
+ toString() {
675
+ return String(this._value);
676
+ }
677
+ static from(value) {
678
+ return new asciiSet(value);
679
+ }
680
+ // contains reports whether c is inside the set.
681
+ contains(c) {
682
+ const _as = this._value;
683
+ return ((_as[c >> 5] & (1 << (c & 31)))) !== 0;
684
+ }
685
+ }
686
+ // makeASCIISet creates a set of ASCII characters and reports whether all
687
+ // characters in chars are ASCII.
688
+ export function makeASCIISet(chars) {
689
+ const _as = new asciiSet([0, 0, 0, 0, 0, 0, 0, 0]);
690
+ for (let i = 0; i < chars.length; i++) {
691
+ const c = chars.charCodeAt(i);
692
+ if (c >= utf8.RuneSelf) {
693
+ return [_as, false];
694
+ }
695
+ _as._value[c >> 5] |= (1 << (c & 31));
696
+ }
697
+ return [_as, true];
698
+ }
699
+ // containsRune is a simplified version of strings.ContainsRune
700
+ // to avoid importing the strings package.
701
+ // We avoid bytes.ContainsRune to avoid allocating a temporary copy of s.
702
+ export function containsRune(s, r) {
703
+ for (let i = 0; i < s.length;) {
704
+ const c = s.codePointAt(i);
705
+ if (c === r)
706
+ return true;
707
+ i += c > 0xFFFF ? 2 : 1;
708
+ }
709
+ return false;
710
+ }
711
+ // Trim returns a subslice of s by slicing off all leading and
712
+ // trailing UTF-8-encoded code points contained in cutset.
713
+ export function Trim(s, cutset) {
714
+ if (s === null || cutset.length === 0) {
715
+ return s;
716
+ }
717
+ if (cutset.length === 1 && cutset.charCodeAt(0) < utf8.RuneSelf) {
718
+ // Single ASCII character optimization
719
+ return trimRightByte(trimLeftByte(s, cutset.charCodeAt(0)), cutset.charCodeAt(0));
720
+ }
721
+ const [as, allASCII] = makeASCIISet(cutset);
722
+ if (allASCII) {
723
+ return trimRightASCII(trimLeftASCII(s, as), as);
724
+ }
725
+ return trimRightUnicode(trimLeftUnicode(s, cutset), cutset);
726
+ }
727
+ // TrimLeft returns a subslice of s by slicing off all leading
728
+ // UTF-8-encoded code points contained in cutset.
729
+ export function TrimLeft(s, cutset) {
730
+ if (s === null || cutset.length === 0) {
731
+ return s;
732
+ }
733
+ if (cutset.length === 1 && cutset.charCodeAt(0) < utf8.RuneSelf) {
734
+ // Single ASCII character optimization
735
+ return trimLeftByte(s, cutset.charCodeAt(0));
736
+ }
737
+ const [as, allASCII] = makeASCIISet(cutset);
738
+ if (allASCII) {
739
+ return trimLeftASCII(s, as);
740
+ }
741
+ return trimLeftUnicode(s, cutset);
742
+ }
743
+ export function trimLeftByte(s, c) {
744
+ if (s === null)
745
+ return null;
746
+ for (let i = 0; i < $.len(s); i++) {
747
+ if (s[i] !== c) {
748
+ return $.goSlice(s, i, undefined);
749
+ }
750
+ }
751
+ return null;
752
+ }
753
+ export function trimLeftASCII(s, _as) {
754
+ if (s === null)
755
+ return null;
756
+ for (let i = 0; i < $.len(s); i++) {
757
+ const b = s[i];
758
+ if (b >= utf8.RuneSelf || !_as.contains(b)) {
759
+ return $.goSlice(s, i, undefined);
760
+ }
761
+ }
762
+ return null;
763
+ }
764
+ export function trimLeftUnicode(s, cutset) {
765
+ if (s === null)
766
+ return null;
767
+ for (let i = 0; i < $.len(s);) {
768
+ const [r, size] = utf8.DecodeRune($.goSlice(s, i, undefined));
769
+ if (size <= 0) {
770
+ // Invalid UTF-8, keep it
771
+ return $.goSlice(s, i, undefined);
772
+ }
773
+ if (!containsRune(cutset, r)) {
774
+ return $.goSlice(s, i, undefined);
775
+ }
776
+ i += size;
777
+ }
778
+ return null;
779
+ }
780
+ // TrimRight returns a subslice of s by slicing off all trailing
781
+ // UTF-8-encoded code points that are contained in cutset.
782
+ export function TrimRight(s, cutset) {
783
+ if (s === null || cutset.length === 0) {
784
+ return s;
785
+ }
786
+ if (cutset.length === 1 && cutset.charCodeAt(0) < utf8.RuneSelf) {
787
+ // Single ASCII character optimization
788
+ return trimRightByte(s, cutset.charCodeAt(0));
789
+ }
790
+ const [as, allASCII] = makeASCIISet(cutset);
791
+ if (allASCII) {
792
+ return trimRightASCII(s, as);
793
+ }
794
+ return trimRightUnicode(s, cutset);
795
+ }
796
+ export function trimRightByte(s, c) {
797
+ if (s === null)
798
+ return null;
799
+ for (let i = $.len(s) - 1; i >= 0; i--) {
800
+ if (s[i] !== c) {
801
+ return $.goSlice(s, undefined, i + 1);
802
+ }
803
+ }
804
+ return null;
805
+ }
806
+ export function trimRightASCII(s, _as) {
807
+ if (s === null)
808
+ return null;
809
+ for (let i = $.len(s) - 1; i >= 0; i--) {
810
+ const b = s[i];
811
+ if (b >= utf8.RuneSelf || !_as.contains(b)) {
812
+ return $.goSlice(s, undefined, i + 1);
813
+ }
814
+ }
815
+ return null;
816
+ }
817
+ export function trimRightUnicode(s, cutset) {
818
+ if (s === null)
819
+ return null;
820
+ // Need to scan from left to find rune boundaries, but track the last non-cutset position
821
+ let lastKeep = -1;
822
+ for (let i = 0; i < $.len(s);) {
823
+ const [r, size] = utf8.DecodeRune($.goSlice(s, i, undefined));
824
+ if (size <= 0) {
825
+ // Invalid UTF-8, keep everything up to here
826
+ return $.goSlice(s, undefined, i + 1);
827
+ }
828
+ if (!containsRune(cutset, r)) {
829
+ lastKeep = i + size;
830
+ }
831
+ i += size;
832
+ }
833
+ if (lastKeep < 0) {
834
+ return null;
835
+ }
836
+ return $.goSlice(s, undefined, lastKeep);
837
+ }
838
+ // TrimSpace returns a subslice of s by slicing off all leading and
839
+ // trailing white space, as defined by Unicode.
840
+ export function TrimSpace(s) {
841
+ return TrimFunc(s, unicode.IsSpace);
842
+ }
843
+ // Runes interprets s as a sequence of UTF-8-encoded code points.
844
+ // It returns a slice of runes (Unicode code points) equivalent to s.
845
+ export function Runes(s) {
846
+ if (s === null || $.len(s) === 0) {
847
+ return null;
848
+ }
849
+ const result = [];
850
+ for (let i = 0; i < $.len(s);) {
851
+ const [r, size] = utf8.DecodeRune($.goSlice(s, i, undefined));
852
+ if (size <= 0) {
853
+ // Invalid UTF-8, add replacement character
854
+ result.push(utf8.RuneError);
855
+ i++;
856
+ }
857
+ else {
858
+ result.push(r);
859
+ i += size;
860
+ }
861
+ }
862
+ return $.arrayToSlice(result);
863
+ }
864
+ // Replace returns a copy of the slice s with the first n
865
+ // non-overlapping instances of old replaced by new.
866
+ // If old is empty, it matches at the beginning of the slice
867
+ // and after each UTF-8 sequence, yielding up to k+1 replacements
868
+ // for a k-rune slice.
869
+ // If n < 0, there is no limit on the number of replacements.
870
+ export function Replace(s, old, _new, n) {
871
+ if (s === null) {
872
+ return new Uint8Array(0);
873
+ }
874
+ if (n === 0) {
875
+ // Make a copy without any replacements
876
+ return new Uint8Array($.bytesToArray(s));
877
+ }
878
+ // Handle empty old pattern - replace at beginning and after each UTF-8 sequence
879
+ if (old === null || $.len(old) === 0) {
880
+ const result = [];
881
+ const newBytes = _new === null ? [] : $.bytesToArray(_new);
882
+ // Add replacement at beginning
883
+ if (n !== 0) {
884
+ result.push(...newBytes);
885
+ if (n > 0)
886
+ n--;
887
+ }
888
+ // Add replacement after each UTF-8 sequence
889
+ for (let i = 0; i < $.len(s) && n !== 0;) {
890
+ const [, size] = utf8.DecodeRune($.goSlice(s, i, undefined));
891
+ if (size <= 0) {
892
+ result.push(s[i]);
893
+ i++;
894
+ }
895
+ else {
896
+ // Add the rune bytes
897
+ for (let j = 0; j < size; j++) {
898
+ result.push(s[i + j]);
899
+ }
900
+ i += size;
901
+ }
902
+ // Add replacement after this rune
903
+ if (n !== 0) {
904
+ result.push(...newBytes);
905
+ if (n > 0)
906
+ n--;
907
+ }
908
+ }
909
+ return new Uint8Array(result);
910
+ }
911
+ // Normal case - replace occurrences of old with new
912
+ const result = [];
913
+ const sBytes = $.bytesToArray(s);
914
+ const oldBytes = $.bytesToArray(old);
915
+ const newBytes = _new === null ? [] : $.bytesToArray(_new);
916
+ let i = 0;
917
+ let replacements = 0;
918
+ while (i <= sBytes.length - oldBytes.length && (n < 0 || replacements < n)) {
919
+ // Check if old pattern matches at current position
920
+ let matches = true;
921
+ for (let j = 0; j < oldBytes.length; j++) {
922
+ if (sBytes[i + j] !== oldBytes[j]) {
923
+ matches = false;
924
+ break;
925
+ }
926
+ }
927
+ if (matches) {
928
+ // Replace with new bytes
929
+ result.push(...newBytes);
930
+ i += oldBytes.length;
931
+ replacements++;
932
+ }
933
+ else {
934
+ // Copy one byte and advance
935
+ result.push(sBytes[i]);
936
+ i++;
937
+ }
938
+ }
939
+ // Copy remaining bytes
940
+ while (i < sBytes.length) {
941
+ result.push(sBytes[i]);
942
+ i++;
943
+ }
944
+ return new Uint8Array(result);
945
+ }
946
+ // ReplaceAll returns a copy of the slice s with all
947
+ // non-overlapping instances of old replaced by new.
948
+ // If old is empty, it matches at the beginning of the slice
949
+ // and after each UTF-8 sequence, yielding up to k+1 replacements
950
+ // for a k-rune slice.
951
+ export function ReplaceAll(s, old, _new) {
952
+ return Replace(s, old, _new, -1);
953
+ }
954
+ // EqualFold reports whether s and t, interpreted as UTF-8 strings,
955
+ // are equal under simple Unicode case-folding, which is a more general
956
+ // form of case-insensitivity.
957
+ export function EqualFold(s, t) {
958
+ // TODO: Implement EqualFold function properly (complex Unicode folding logic)
959
+ throw new Error("EqualFold: not implemented");
960
+ }
961
+ // Index returns the index of the first instance of sep in s, or -1 if sep is not present in s.
962
+ export function Index(s, sep) {
963
+ return $.bytesIndexOf(s, sep);
964
+ }
965
+ // Cut slices s around the first instance of sep,
966
+ // returning the text before and after sep.
967
+ // The found result reports whether sep appears in s.
968
+ // If sep does not appear in s, cut returns s, nil, false.
969
+ //
970
+ // Cut returns slices of the original slice s, not copies.
971
+ export function Cut(s, sep) {
972
+ const i = Index(s, sep);
973
+ if (i >= 0) {
974
+ return [$.goSlice(s, undefined, i), $.goSlice(s, i + $.len(sep), undefined), true];
975
+ }
976
+ return [s, null, false];
977
+ }
978
+ // Clone returns a copy of b[:len(b)].
979
+ // The result may have additional unused capacity.
980
+ // Clone(nil) returns nil.
981
+ export function Clone(b) {
982
+ if (b === null) {
983
+ return null;
984
+ }
985
+ return new Uint8Array($.bytesToArray(b));
986
+ }
987
+ // CutPrefix returns s without the provided leading prefix byte slice
988
+ // and reports whether it found the prefix.
989
+ // If s doesn't start with prefix, CutPrefix returns s, false.
990
+ // If prefix is the empty byte slice, CutPrefix returns s, true.
991
+ //
992
+ // CutPrefix returns slices of the original slice s, not copies.
993
+ export function CutPrefix(s, prefix) {
994
+ if (!HasPrefix(s, prefix)) {
995
+ return [s, false];
996
+ }
997
+ return [$.goSlice(s, $.len(prefix), undefined), true];
998
+ }
999
+ // CutSuffix returns s without the provided ending suffix byte slice
1000
+ // and reports whether it found the suffix.
1001
+ // If s doesn't end with suffix, CutSuffix returns s, false.
1002
+ // If suffix is the empty byte slice, CutSuffix returns s, true.
1003
+ //
1004
+ // CutSuffix returns slices of the original slice s, not copies.
1005
+ export function CutSuffix(s, suffix) {
1006
+ if (!HasSuffix(s, suffix)) {
1007
+ return [s, false];
1008
+ }
1009
+ return [$.goSlice(s, undefined, $.len(s) - $.len(suffix)), true];
1010
+ }
1011
+ //# sourceMappingURL=bytes.gs.js.map