gofront 1.8.0 → 1.9.0

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 (177) hide show
  1. package/README.md +3 -3
  2. package/package.json +5 -4
  3. package/src/backend/js/expressions.js +849 -371
  4. package/src/backend/js/index.js +241 -147
  5. package/src/backend/js/natives.js +383 -0
  6. package/src/backend/js/runtime.js +512 -2547
  7. package/src/backend/js/statements.js +506 -103
  8. package/src/backend/js/stdlib/index.js +45 -93
  9. package/src/backend/js/templ.js +32 -45
  10. package/src/backend/js/type-info.js +177 -13
  11. package/src/backend/shared/fixed-float.js +20 -0
  12. package/src/backend/shared/fmt-types.js +63 -171
  13. package/src/backend/shared/host-unicode.js +36 -0
  14. package/src/backend/wasm/boundary.js +490 -965
  15. package/src/backend/wasm/emit-builtins.js +643 -256
  16. package/src/backend/wasm/emit-exprs.js +124 -57
  17. package/src/backend/wasm/emit-maps.js +17 -367
  18. package/src/backend/wasm/emit-stmts.js +325 -75
  19. package/src/backend/wasm/emit.js +104 -13
  20. package/src/backend/wasm/globals.js +47 -8
  21. package/src/backend/wasm/glue.js +2 -4
  22. package/src/backend/wasm/index.js +36 -530
  23. package/src/backend/wasm/method-expr.js +12 -1
  24. package/src/backend/wasm/module-emitter.js +92 -717
  25. package/src/backend/wasm/monomorph.js +103 -6
  26. package/src/backend/wasm/natives.js +596 -0
  27. package/src/backend/wasm/prescan.js +5 -153
  28. package/src/backend/wasm/prune-funcs.js +89 -0
  29. package/src/backend/wasm/stdlib/index.js +2 -32
  30. package/src/backend/wasm/types.js +68 -20
  31. package/src/backend/wasm/variadic.js +3 -3
  32. package/src/cli/cli-core.js +5 -1
  33. package/src/cli/test-runner.js +115 -342
  34. package/src/compiler.js +108 -130
  35. package/src/lexer/lexer.js +105 -11
  36. package/src/lexer/templ-lexer.js +61 -18
  37. package/src/lexer/tokens.js +1 -0
  38. package/src/link/stdlib.js +354 -132
  39. package/src/link/type-names.js +148 -0
  40. package/src/link/wasm.js +30 -6
  41. package/src/lower/bounds.js +153 -0
  42. package/src/lower/captures.js +92 -33
  43. package/src/lower/embedding.js +32 -3
  44. package/src/lower/errors-as.js +196 -0
  45. package/src/lower/fmt-formatters.js +905 -0
  46. package/src/lower/functions.js +2 -0
  47. package/src/lower/gen-types.js +274 -0
  48. package/src/lower/index.js +7 -1
  49. package/src/lower/json-codecs.js +228 -247
  50. package/src/lower/ownership.js +25 -7
  51. package/src/lower/reachability.js +69 -51
  52. package/src/lower/walk.js +12 -0
  53. package/src/parser/declarations.js +28 -5
  54. package/src/parser/expressions.js +86 -16
  55. package/src/parser/statements.js +1 -0
  56. package/src/parser/templ.js +44 -5
  57. package/src/parser/types.js +1 -0
  58. package/src/resolver.js +1 -2
  59. package/src/typechecker/assignability.js +124 -11
  60. package/src/typechecker/const-fold.js +70 -27
  61. package/src/typechecker/constants.js +32 -6
  62. package/src/typechecker/expressions.js +326 -98
  63. package/src/typechecker/index.js +208 -33
  64. package/src/typechecker/init-order.js +136 -40
  65. package/src/typechecker/operand-text.js +40 -0
  66. package/src/typechecker/resolve.js +192 -36
  67. package/src/typechecker/statements.js +122 -11
  68. package/src/typechecker/stdlib/excluded.js +9 -5
  69. package/src/typechecker/stdlib/index.js +25 -9
  70. package/src/typechecker/termination.js +10 -1
  71. package/src/typechecker/types.js +203 -573
  72. package/stdlib/bytes/buffer.go +479 -0
  73. package/stdlib/bytes/bytes.go +1010 -0
  74. package/stdlib/bytes/reader.go +161 -0
  75. package/stdlib/context/context.go +115 -0
  76. package/stdlib/crypto/rand/rand.go +34 -0
  77. package/stdlib/crypto/sha256/sha256.go +249 -0
  78. package/stdlib/encoding/base64/base64.go +331 -0
  79. package/stdlib/encoding/binary/binary.go +332 -0
  80. package/stdlib/encoding/hex/hex.go +140 -0
  81. package/stdlib/encoding/json/json.go +62 -0
  82. package/stdlib/errors/errors.go +174 -0
  83. package/stdlib/fmt/errors.go +110 -0
  84. package/stdlib/fmt/format.go +732 -0
  85. package/stdlib/fmt/print.go +1232 -0
  86. package/stdlib/gom/gom.go +293 -0
  87. package/stdlib/html/html.go +251 -0
  88. package/stdlib/internal/fmtrt/fmtrt.go +163 -0
  89. package/stdlib/internal/jsonrt/dec.go +171 -38
  90. package/stdlib/internal/jsonrt/enc.go +186 -36
  91. package/stdlib/internal/jsonrt/scanner.go +17 -8
  92. package/stdlib/io/io.go +157 -1
  93. package/stdlib/maps/maps.go +131 -0
  94. package/stdlib/math/bits/bits.go +507 -0
  95. package/stdlib/math/extra.go +16 -14
  96. package/stdlib/math/math.go +439 -0
  97. package/stdlib/math/rand/rand.go +297 -0
  98. package/stdlib/os/os.go +93 -0
  99. package/stdlib/path/filepath/filepath.go +47 -0
  100. package/stdlib/path/path.go +394 -0
  101. package/stdlib/regexp/regexp.go +231 -0
  102. package/stdlib/slices/slices.go +526 -0
  103. package/stdlib/slices/sort.go +209 -0
  104. package/stdlib/slices/zsort_cmp.go +480 -0
  105. package/stdlib/slices/zsort_ordered.go +482 -0
  106. package/stdlib/sort/sort.go +391 -452
  107. package/stdlib/sort/zsort_func.go +480 -0
  108. package/stdlib/sort/zsort_iface.go +480 -0
  109. package/stdlib/strconv/float.go +1699 -0
  110. package/stdlib/strconv/isprint.go +752 -0
  111. package/stdlib/strconv/quote.go +235 -50
  112. package/stdlib/strconv/strconv.go +616 -0
  113. package/stdlib/strings/builder.go +95 -0
  114. package/stdlib/strings/reader.go +163 -0
  115. package/stdlib/strings/replacer.go +102 -0
  116. package/stdlib/strings/strings.go +807 -0
  117. package/stdlib/sync/sync.go +268 -0
  118. package/stdlib/testing/async_js.go +61 -0
  119. package/stdlib/testing/benchmark.go +297 -0
  120. package/stdlib/testing/testing.go +523 -0
  121. package/stdlib/time/duration.go +233 -0
  122. package/stdlib/time/format.go +745 -0
  123. package/stdlib/time/parse.go +790 -0
  124. package/stdlib/time/sleep_js.go +63 -0
  125. package/stdlib/time/time.go +834 -0
  126. package/stdlib/unicode/unicode.go +141 -3
  127. package/stdlib/unicode/utf8/utf8.go +464 -0
  128. package/src/backend/js/fmt-runtime.js +0 -573
  129. package/src/backend/js/stdlib/base64.js +0 -12
  130. package/src/backend/js/stdlib/binary.js +0 -102
  131. package/src/backend/js/stdlib/bits.js +0 -119
  132. package/src/backend/js/stdlib/builder.js +0 -98
  133. package/src/backend/js/stdlib/bytes.js +0 -368
  134. package/src/backend/js/stdlib/errors.js +0 -45
  135. package/src/backend/js/stdlib/fmt.js +0 -517
  136. package/src/backend/js/stdlib/gom.js +0 -155
  137. package/src/backend/js/stdlib/hex.js +0 -17
  138. package/src/backend/js/stdlib/html.js +0 -20
  139. package/src/backend/js/stdlib/io.js +0 -137
  140. package/src/backend/js/stdlib/json.js +0 -1167
  141. package/src/backend/js/stdlib/maps.js +0 -37
  142. package/src/backend/js/stdlib/math.js +0 -85
  143. package/src/backend/js/stdlib/os.js +0 -13
  144. package/src/backend/js/stdlib/path.js +0 -48
  145. package/src/backend/js/stdlib/rand.js +0 -32
  146. package/src/backend/js/stdlib/regexp.js +0 -54
  147. package/src/backend/js/stdlib/sha256.js +0 -12
  148. package/src/backend/js/stdlib/shared.js +0 -17
  149. package/src/backend/js/stdlib/simd.js +0 -34
  150. package/src/backend/js/stdlib/slices.js +0 -107
  151. package/src/backend/js/stdlib/sort.js +0 -30
  152. package/src/backend/js/stdlib/strconv.js +0 -79
  153. package/src/backend/js/stdlib/strings.js +0 -301
  154. package/src/backend/js/stdlib/sync.js +0 -13
  155. package/src/backend/js/stdlib/testing.js +0 -41
  156. package/src/backend/js/stdlib/time.js +0 -152
  157. package/src/backend/js/stdlib/unicode.js +0 -25
  158. package/src/backend/js/stdlib/utf8.js +0 -26
  159. package/src/backend/wasm/stdlib/bytes.js +0 -6716
  160. package/src/backend/wasm/stdlib/core.js +0 -10278
  161. package/src/backend/wasm/stdlib/io.js +0 -3578
  162. package/src/backend/wasm/stdlib/packages.js +0 -2402
  163. package/src/backend/wasm/stdlib/pure.js +0 -720
  164. package/src/backend/wasm/stdlib/time.js +0 -2229
  165. package/src/typechecker/stdlib/core.js +0 -1079
  166. package/src/typechecker/stdlib/extended.js +0 -1210
  167. package/stdlib/bytes/iter.go +0 -192
  168. package/stdlib/bytes/search.go +0 -240
  169. package/stdlib/bytes/split.go +0 -218
  170. package/stdlib/errors/overlay.go +0 -12
  171. package/stdlib/maps/iter.go +0 -65
  172. package/stdlib/slices/extra.go +0 -73
  173. package/stdlib/slices/iter.go +0 -113
  174. package/stdlib/strings/extra.go +0 -35
  175. package/stdlib/strings/iter.go +0 -122
  176. package/stdlib/sync/extra.go +0 -105
  177. package/stdlib/unicode/utf8/bytes.go +0 -239
@@ -0,0 +1,479 @@
1
+ //go:build gofront
2
+
3
+ //gofront:target both
4
+
5
+ package bytes
6
+
7
+ import (
8
+ "errors"
9
+ "io"
10
+ "unicode/utf8"
11
+ )
12
+
13
+ // smallBufferSize is an initial allocation minimal capacity.
14
+ const smallBufferSize = 64
15
+
16
+ // A Buffer is a variable-sized buffer of bytes with [Buffer.Read] and [Buffer.Write] methods.
17
+ // The zero value for Buffer is an empty buffer ready to use.
18
+ type Buffer struct {
19
+ buf []byte // contents are the bytes buf[off : len(buf)]
20
+ off int // read at &buf[off], write at &buf[len(buf)]
21
+ lastRead readOp // last read operation, so that Unread* can work correctly.
22
+ }
23
+
24
+ // The readOp constants describe the last action performed on
25
+ // the buffer, so that UnreadRune and UnreadByte can check for
26
+ // invalid usage. opReadRuneX constants are chosen such that
27
+ // converted to int they correspond to the rune size that was read.
28
+ type readOp int8
29
+
30
+ // Don't use iota for these, as the values need to correspond with the
31
+ // names and comments, which is easier to see when being explicit.
32
+ const (
33
+ opRead readOp = -1 // Any other read operation.
34
+ opInvalid readOp = 0 // Non-read operation.
35
+ opReadRune1 readOp = 1 // Read rune of size 1.
36
+ opReadRune2 readOp = 2 // Read rune of size 2.
37
+ opReadRune3 readOp = 3 // Read rune of size 3.
38
+ opReadRune4 readOp = 4 // Read rune of size 4.
39
+ )
40
+
41
+ // MinRead is the minimum slice size passed to a Read call by
42
+ // Buffer.ReadFrom. As long as the Buffer has at least MinRead bytes beyond
43
+ // what is required to hold the contents of r, ReadFrom will not grow the
44
+ // underlying buffer.
45
+ const MinRead = 512
46
+
47
+ // ErrTooLarge is passed to panic if memory cannot be allocated to store data in a buffer.
48
+ var ErrTooLarge = errors.New("bytes.Buffer: too large")
49
+
50
+ const maxInt = int(^uint(0) >> 1)
51
+
52
+ // Bytes returns a slice of length b.Len() holding the unread portion of the buffer.
53
+ // The slice is valid for use only until the next buffer modification (that is,
54
+ // only until the next call to a method like [Buffer.Read], [Buffer.Write], [Buffer.Reset], or [Buffer.Truncate]).
55
+ // The slice aliases the buffer content at least until the next buffer modification,
56
+ // so immediate changes to the slice will affect the result of future reads.
57
+ func (b *Buffer) Bytes() []byte { return b.buf[b.off:] }
58
+
59
+ // AvailableBuffer returns an empty buffer with b.Available() capacity.
60
+ // This buffer is intended to be appended to and
61
+ // passed to an immediately succeeding [Buffer.Write] call.
62
+ // The buffer is only valid until the next write operation on b.
63
+ func (b *Buffer) AvailableBuffer() []byte { return b.buf[len(b.buf):] }
64
+
65
+ // String returns the contents of the unread portion of the buffer
66
+ // as a string. If the [Buffer] is a nil pointer, it returns "<nil>".
67
+ func (b *Buffer) String() string {
68
+ if b == nil {
69
+ // Special case, useful in debugging.
70
+ return "<nil>"
71
+ }
72
+ return string(b.buf[b.off:])
73
+ }
74
+
75
+ // empty reports whether the unread portion of the buffer is empty.
76
+ func (b *Buffer) empty() bool { return len(b.buf) <= b.off }
77
+
78
+ // Len returns the number of bytes of the unread portion of the buffer;
79
+ // b.Len() == len(b.Bytes()).
80
+ func (b *Buffer) Len() int { return len(b.buf) - b.off }
81
+
82
+ // Cap returns the capacity of the buffer's underlying byte slice, that is, the
83
+ // total space allocated for the buffer's data.
84
+ func (b *Buffer) Cap() int { return cap(b.buf) }
85
+
86
+ // Available returns how many bytes are unused in the buffer.
87
+ func (b *Buffer) Available() int { return cap(b.buf) - len(b.buf) }
88
+
89
+ // Truncate discards all but the first n unread bytes from the buffer
90
+ // but continues to use the same allocated storage.
91
+ // It panics if n is negative or greater than the length of the buffer.
92
+ func (b *Buffer) Truncate(n int) {
93
+ if n == 0 {
94
+ b.Reset()
95
+ return
96
+ }
97
+ b.lastRead = opInvalid
98
+ if n < 0 || n > b.Len() {
99
+ panic("bytes.Buffer: truncation out of range")
100
+ }
101
+ b.buf = b.buf[:b.off+n]
102
+ }
103
+
104
+ // Reset resets the buffer to be empty,
105
+ // but it retains the underlying storage for use by future writes.
106
+ // Reset is the same as [Buffer.Truncate](0).
107
+ func (b *Buffer) Reset() {
108
+ b.buf = b.buf[:0]
109
+ b.off = 0
110
+ b.lastRead = opInvalid
111
+ }
112
+
113
+ // tryGrowByReslice is an inlineable version of grow for the fast-case where the
114
+ // internal buffer only needs to be resliced.
115
+ // It returns the index where bytes should be written and whether it succeeded.
116
+ func (b *Buffer) tryGrowByReslice(n int) (int, bool) {
117
+ if l := len(b.buf); n <= cap(b.buf)-l {
118
+ b.buf = b.buf[:l+n]
119
+ return l, true
120
+ }
121
+ return 0, false
122
+ }
123
+
124
+ // grow grows the buffer to guarantee space for n more bytes.
125
+ // It returns the index where bytes should be written.
126
+ // If the buffer can't grow it will panic with ErrTooLarge.
127
+ func (b *Buffer) grow(n int) int {
128
+ m := b.Len()
129
+ // If buffer is empty, reset to recover space.
130
+ if m == 0 && b.off != 0 {
131
+ b.Reset()
132
+ }
133
+ // Try to grow by means of a reslice.
134
+ if i, ok := b.tryGrowByReslice(n); ok {
135
+ return i
136
+ }
137
+ if b.buf == nil && n <= smallBufferSize {
138
+ b.buf = make([]byte, n, smallBufferSize)
139
+ return 0
140
+ }
141
+ c := cap(b.buf)
142
+ if n <= c/2-m {
143
+ // We can slide things down instead of allocating a new
144
+ // slice. We only need m+n <= c to slide, but
145
+ // we instead let capacity get twice as large so we
146
+ // don't spend all our time copying.
147
+ copy(b.buf, b.buf[b.off:])
148
+ } else if c > maxInt-c-n {
149
+ panic(ErrTooLarge)
150
+ } else {
151
+ // Add b.off to account for b.buf[:b.off] being sliced off the front.
152
+ b.buf = growSlice(b.buf[b.off:], b.off+n)
153
+ }
154
+ // Restore b.off and len(b.buf).
155
+ b.off = 0
156
+ b.buf = b.buf[:m+n]
157
+ return m
158
+ }
159
+
160
+ // Grow grows the buffer's capacity, if necessary, to guarantee space for
161
+ // another n bytes. After Grow(n), at least n bytes can be written to the
162
+ // buffer without another allocation.
163
+ // If n is negative, Grow will panic.
164
+ // If the buffer can't grow it will panic with [ErrTooLarge].
165
+ func (b *Buffer) Grow(n int) {
166
+ if n < 0 {
167
+ panic("bytes.Buffer.Grow: negative count")
168
+ }
169
+ m := b.grow(n)
170
+ b.buf = b.buf[:m]
171
+ }
172
+
173
+ // Write appends the contents of p to the buffer, growing the buffer as
174
+ // needed. The return value n is the length of p; err is always nil. If the
175
+ // buffer becomes too large, Write will panic with [ErrTooLarge].
176
+ func (b *Buffer) Write(p []byte) (n int, err error) {
177
+ b.lastRead = opInvalid
178
+ m, ok := b.tryGrowByReslice(len(p))
179
+ if !ok {
180
+ m = b.grow(len(p))
181
+ }
182
+ return copy(b.buf[m:], p), nil
183
+ }
184
+
185
+ // WriteString appends the contents of s to the buffer, growing the buffer as
186
+ // needed. The return value n is the length of s; err is always nil. If the
187
+ // buffer becomes too large, WriteString will panic with [ErrTooLarge].
188
+ func (b *Buffer) WriteString(s string) (n int, err error) {
189
+ b.lastRead = opInvalid
190
+ m, ok := b.tryGrowByReslice(len(s))
191
+ if !ok {
192
+ m = b.grow(len(s))
193
+ }
194
+ return copy(b.buf[m:], s), nil
195
+ }
196
+
197
+ // growSlice grows b by n, preserving the original content of b.
198
+ // If the allocation fails, it panics with ErrTooLarge.
199
+ func growSlice(b []byte, n int) []byte {
200
+ // TODO(http://golang.org/issue/51462): We should rely on the append-make
201
+ // pattern so that the compiler can call runtime.growslice. For example:
202
+ // return append(b, make([]byte, n)...)
203
+ // This avoids unnecessary zero-ing of the first len(b) bytes of the
204
+ // allocated slice, but this pattern causes b to escape onto the heap.
205
+ //
206
+ // Instead use the append-make pattern with a nil slice to ensure that
207
+ // we allocate buffers rounded up to the closest size class.
208
+ c := len(b) + n // ensure enough space for n elements
209
+ if c < 2*cap(b) {
210
+ // The growth rate has historically always been 2x. In the future,
211
+ // we could rely purely on append to determine the growth rate.
212
+ c = 2 * cap(b)
213
+ }
214
+ b2 := append([]byte(nil), make([]byte, c)...)
215
+ i := copy(b2, b)
216
+ return b2[:i]
217
+ }
218
+
219
+ // WriteByte appends the byte c to the buffer, growing the buffer as needed.
220
+ // The returned error is always nil, but is included to match [bufio.Writer]'s
221
+ // WriteByte. If the buffer becomes too large, WriteByte will panic with
222
+ // [ErrTooLarge].
223
+ func (b *Buffer) WriteByte(c byte) error {
224
+ b.lastRead = opInvalid
225
+ m, ok := b.tryGrowByReslice(1)
226
+ if !ok {
227
+ m = b.grow(1)
228
+ }
229
+ b.buf[m] = c
230
+ return nil
231
+ }
232
+
233
+ // WriteRune appends the UTF-8 encoding of Unicode code point r to the
234
+ // buffer, returning its length and an error, which is always nil but is
235
+ // included to match [bufio.Writer]'s WriteRune. The buffer is grown as needed;
236
+ // if it becomes too large, WriteRune will panic with [ErrTooLarge].
237
+ func (b *Buffer) WriteRune(r rune) (n int, err error) {
238
+ // Compare as uint32 to correctly handle negative runes.
239
+ if uint32(r) < utf8.RuneSelf {
240
+ b.WriteByte(byte(r))
241
+ return 1, nil
242
+ }
243
+ b.lastRead = opInvalid
244
+ m, ok := b.tryGrowByReslice(utf8.UTFMax)
245
+ if !ok {
246
+ m = b.grow(utf8.UTFMax)
247
+ }
248
+ b.buf = utf8.AppendRune(b.buf[:m], r)
249
+ return len(b.buf) - m, nil
250
+ }
251
+
252
+ // ReadFrom reads data from r until EOF and appends it to the buffer, growing
253
+ // the buffer as needed. The return value n is the number of bytes read. Any
254
+ // error except io.EOF encountered during the read is also returned. If the
255
+ // buffer becomes too large, ReadFrom will panic with [ErrTooLarge].
256
+ func (b *Buffer) ReadFrom(r io.Reader) (n int64, err error) {
257
+ b.lastRead = opInvalid
258
+ for {
259
+ i := b.grow(MinRead)
260
+ b.buf = b.buf[:i]
261
+ m, e := r.Read(b.buf[i:cap(b.buf)])
262
+ if m < 0 {
263
+ panic(errors.New("bytes.Buffer: reader returned negative count from Read"))
264
+ }
265
+
266
+ b.buf = b.buf[:i+m]
267
+ n += int64(m)
268
+ if e == io.EOF {
269
+ return n, nil // e is EOF, so return nil explicitly
270
+ }
271
+ if e != nil {
272
+ return n, e
273
+ }
274
+ }
275
+ }
276
+
277
+ // WriteTo writes data to w until the buffer is drained or an error occurs.
278
+ // The return value n is the number of bytes written; it always fits into an
279
+ // int, but it is int64 to match the [io.WriterTo] interface. Any error
280
+ // encountered during the write is also returned.
281
+ func (b *Buffer) WriteTo(w io.Writer) (n int64, err error) {
282
+ b.lastRead = opInvalid
283
+ if nBytes := b.Len(); nBytes > 0 {
284
+ m, e := w.Write(b.buf[b.off:])
285
+ if m > nBytes {
286
+ panic("bytes.Buffer.WriteTo: invalid Write count")
287
+ }
288
+ b.off += m
289
+ n = int64(m)
290
+ if e != nil {
291
+ return n, e
292
+ }
293
+ // all bytes should have been written, by definition of
294
+ // Write method in io.Writer
295
+ if m != nBytes {
296
+ return n, io.ErrShortWrite
297
+ }
298
+ }
299
+ // Buffer is now empty; reset.
300
+ b.Reset()
301
+ return n, nil
302
+ }
303
+
304
+ // Read reads the next len(p) bytes from the buffer or until the buffer
305
+ // is drained. The return value n is the number of bytes read. If the
306
+ // buffer has no data to return, err is [io.EOF] (unless len(p) is zero);
307
+ // otherwise it is nil.
308
+ func (b *Buffer) Read(p []byte) (n int, err error) {
309
+ b.lastRead = opInvalid
310
+ if b.empty() {
311
+ // Buffer is empty, reset to recover space.
312
+ b.Reset()
313
+ if len(p) == 0 {
314
+ return 0, nil
315
+ }
316
+ return 0, io.EOF
317
+ }
318
+ n = copy(p, b.buf[b.off:])
319
+ b.off += n
320
+ if n > 0 {
321
+ b.lastRead = opRead
322
+ }
323
+ return n, nil
324
+ }
325
+
326
+ // Next returns a slice containing the next n bytes from the buffer,
327
+ // advancing the buffer as if the bytes had been returned by [Buffer.Read].
328
+ // If there are fewer than n bytes in the buffer, Next returns the entire buffer.
329
+ // The slice is only valid until the next call to a read or write method.
330
+ func (b *Buffer) Next(n int) []byte {
331
+ b.lastRead = opInvalid
332
+ m := b.Len()
333
+ if n > m {
334
+ n = m
335
+ }
336
+ data := b.buf[b.off : b.off+n]
337
+ b.off += n
338
+ if n > 0 {
339
+ b.lastRead = opRead
340
+ }
341
+ return data
342
+ }
343
+
344
+ // Peek returns the next n bytes without advancing the reader. If Peek returns
345
+ // fewer than n bytes, it also returns [io.EOF].
346
+ func (b *Buffer) Peek(n int) ([]byte, error) {
347
+ if b.Len() < n {
348
+ return b.buf[b.off:], io.EOF
349
+ }
350
+ return b.buf[b.off : b.off+n], nil
351
+ }
352
+
353
+ // ReadByte reads and returns the next byte from the buffer.
354
+ // If no byte is available, it returns error [io.EOF].
355
+ func (b *Buffer) ReadByte() (byte, error) {
356
+ if b.empty() {
357
+ // Buffer is empty, reset to recover space.
358
+ b.Reset()
359
+ return 0, io.EOF
360
+ }
361
+ c := b.buf[b.off]
362
+ b.off++
363
+ b.lastRead = opRead
364
+ return c, nil
365
+ }
366
+
367
+ // ReadRune reads and returns the next UTF-8-encoded
368
+ // Unicode code point from the buffer.
369
+ // If no bytes are available, the error returned is io.EOF.
370
+ // If the bytes are an erroneous UTF-8 encoding, it
371
+ // consumes one byte and returns U+FFFD, 1.
372
+ func (b *Buffer) ReadRune() (r rune, size int, err error) {
373
+ if b.empty() {
374
+ // Buffer is empty, reset to recover space.
375
+ b.Reset()
376
+ return 0, 0, io.EOF
377
+ }
378
+ c := b.buf[b.off]
379
+ if c < utf8.RuneSelf {
380
+ b.off++
381
+ b.lastRead = opReadRune1
382
+ return rune(c), 1, nil
383
+ }
384
+ r, n := utf8.DecodeRune(b.buf[b.off:])
385
+ b.off += n
386
+ b.lastRead = readOp(n)
387
+ return r, n, nil
388
+ }
389
+
390
+ // UnreadRune unreads the last rune returned by [Buffer.ReadRune].
391
+ // If the most recent read or write operation on the buffer was
392
+ // not a successful [Buffer.ReadRune], UnreadRune returns an error. (In this regard
393
+ // it is stricter than [Buffer.UnreadByte], which will unread the last byte
394
+ // from any read operation.)
395
+ func (b *Buffer) UnreadRune() error {
396
+ if b.lastRead <= opInvalid {
397
+ return errors.New("bytes.Buffer: UnreadRune: previous operation was not a successful ReadRune")
398
+ }
399
+ if b.off >= int(b.lastRead) {
400
+ b.off -= int(b.lastRead)
401
+ }
402
+ b.lastRead = opInvalid
403
+ return nil
404
+ }
405
+
406
+ // UnreadByte unreads the last byte returned by the most recent successful
407
+ // read operation that read at least one byte. If a write has happened since
408
+ // the last read, if the last read returned an error, or if the read read zero
409
+ // bytes, UnreadByte returns an error.
410
+ func (b *Buffer) UnreadByte() error {
411
+ if b.lastRead == opInvalid {
412
+ return errors.New("bytes.Buffer: UnreadByte: previous operation was not a successful read")
413
+ }
414
+ b.lastRead = opInvalid
415
+ if b.off > 0 {
416
+ b.off--
417
+ }
418
+ return nil
419
+ }
420
+
421
+ // ReadBytes reads until the first occurrence of delim in the input,
422
+ // returning a slice containing the data up to and including the delimiter.
423
+ // If ReadBytes encounters an error before finding a delimiter,
424
+ // it returns the data read before the error and the error itself (often [io.EOF]).
425
+ // ReadBytes returns err != nil if and only if the returned data does not end in
426
+ // delim.
427
+ func (b *Buffer) ReadBytes(delim byte) (line []byte, err error) {
428
+ slice, err := b.readSlice(delim)
429
+ // return a copy of slice. The buffer's backing array may
430
+ // be overwritten by later calls.
431
+ line = append(line, slice...)
432
+ return line, err
433
+ }
434
+
435
+ // readSlice is like ReadBytes but returns a reference to internal buffer data.
436
+ func (b *Buffer) readSlice(delim byte) (line []byte, err error) {
437
+ i := IndexByte(b.buf[b.off:], delim)
438
+ end := b.off + i + 1
439
+ if i < 0 {
440
+ end = len(b.buf)
441
+ err = io.EOF
442
+ }
443
+ line = b.buf[b.off:end]
444
+ b.off = end
445
+ b.lastRead = opRead
446
+ return line, err
447
+ }
448
+
449
+ // ReadString reads until the first occurrence of delim in the input,
450
+ // returning a string containing the data up to and including the delimiter.
451
+ // If ReadString encounters an error before finding a delimiter,
452
+ // it returns the data read before the error and the error itself (often [io.EOF]).
453
+ // ReadString returns err != nil if and only if the returned data does not end
454
+ // in delim.
455
+ func (b *Buffer) ReadString(delim byte) (line string, err error) {
456
+ slice, err := b.readSlice(delim)
457
+ return string(slice), err
458
+ }
459
+
460
+ // NewBuffer creates and initializes a new [Buffer] using buf as its
461
+ // initial contents. The new [Buffer] takes ownership of buf, and the
462
+ // caller should not use buf after this call. NewBuffer is intended to
463
+ // prepare a [Buffer] to read existing data. It can also be used to set
464
+ // the initial size of the internal buffer for writing. To do that,
465
+ // buf should have the desired capacity but a length of zero.
466
+ //
467
+ // In most cases, new([Buffer]) (or just declaring a [Buffer] variable) is
468
+ // sufficient to initialize a [Buffer].
469
+ func NewBuffer(buf []byte) *Buffer { return &Buffer{buf: buf} }
470
+
471
+ // NewBufferString creates and initializes a new [Buffer] using string s as its
472
+ // initial contents. It is intended to prepare a buffer to read an existing
473
+ // string.
474
+ //
475
+ // In most cases, new([Buffer]) (or just declaring a [Buffer] variable) is
476
+ // sufficient to initialize a [Buffer].
477
+ func NewBufferString(s string) *Buffer {
478
+ return &Buffer{buf: []byte(s)}
479
+ }