github.com/yaling888/clash@v1.53.0/common/pool/bufferv2.go (about) 1 package pool 2 3 import ( 4 "bytes" 5 "encoding/binary" 6 "io" 7 "net" 8 "net/netip" 9 "sync" 10 "unicode/utf8" 11 ) 12 13 var buffer2Pool = sync.Pool{ 14 New: func() any { 15 return &Buffer{ 16 buf: new(bytes.Buffer), 17 } 18 }, 19 } 20 21 type Buffer struct { 22 buf *bytes.Buffer 23 } 24 25 func NewBuffer() *Buffer { 26 return buffer2Pool.Get().(*Buffer) 27 } 28 29 func (b *Buffer) Release() { 30 b.buf.Reset() 31 buffer2Pool.Put(b) 32 } 33 34 func (b *Buffer) Reset() { 35 b.buf.Reset() 36 } 37 38 func (b *Buffer) Grow(n int) { 39 b.buf.Grow(n) 40 } 41 42 func (b *Buffer) Len() int { 43 return b.buf.Len() 44 } 45 46 func (b *Buffer) Cap() int { 47 return b.buf.Cap() 48 } 49 50 func (b *Buffer) Read(p []byte) (n int, err error) { 51 return b.buf.Read(p) 52 } 53 54 func (b *Buffer) ReadByte() (byte, error) { 55 return b.buf.ReadByte() 56 } 57 58 func (b *Buffer) ReadFrom(r io.Reader) (n int64, err error) { 59 return b.buf.ReadFrom(r) 60 } 61 62 func (b *Buffer) ReadFullFrom(r io.Reader, size int64) (n int64, err error) { 63 n, err = b.buf.ReadFrom(io.LimitReader(r, size)) 64 if err == nil && n != size { 65 err = io.ErrUnexpectedEOF 66 return 67 } 68 return 69 } 70 71 func (b *Buffer) ReadUint8(r io.Reader) (uint8, error) { 72 _, err := b.ReadFullFrom(r, 1) 73 if err != nil { 74 return 0, err 75 } 76 return b.buf.ReadByte() 77 } 78 79 func (b *Buffer) ReadUint16(r io.Reader) (uint16, error) { 80 _, err := b.ReadFullFrom(r, 2) 81 if err != nil { 82 return 0, err 83 } 84 return binary.NativeEndian.Uint16(b.buf.Next(2)), nil 85 } 86 87 func (b *Buffer) ReadUint32(r io.Reader) (uint32, error) { 88 _, err := b.ReadFullFrom(r, 4) 89 if err != nil { 90 return 0, err 91 } 92 return binary.NativeEndian.Uint32(b.buf.Next(4)), nil 93 } 94 95 func (b *Buffer) ReadUint64(r io.Reader) (uint64, error) { 96 _, err := b.ReadFullFrom(r, 8) 97 if err != nil { 98 return 0, err 99 } 100 return binary.NativeEndian.Uint64(b.buf.Next(8)), nil 101 } 102 103 func (b *Buffer) ReadUint16be(r io.Reader) (uint16, error) { 104 _, err := b.ReadFullFrom(r, 2) 105 if err != nil { 106 return 0, err 107 } 108 return binary.BigEndian.Uint16(b.buf.Next(2)), nil 109 } 110 111 func (b *Buffer) ReadUint32be(r io.Reader) (uint32, error) { 112 _, err := b.ReadFullFrom(r, 4) 113 if err != nil { 114 return 0, err 115 } 116 return binary.BigEndian.Uint32(b.buf.Next(4)), nil 117 } 118 119 func (b *Buffer) ReadUint64be(r io.Reader) (uint64, error) { 120 _, err := b.ReadFullFrom(r, 8) 121 if err != nil { 122 return 0, err 123 } 124 return binary.BigEndian.Uint64(b.buf.Next(8)), nil 125 } 126 127 func (b *Buffer) Write(p []byte) (n int, err error) { 128 return b.buf.Write(p) 129 } 130 131 func (b *Buffer) WriteTo(w io.Writer) (n int64, err error) { 132 return b.buf.WriteTo(w) 133 } 134 135 func (b *Buffer) Next(n int) []byte { 136 return b.buf.Next(n) 137 } 138 139 func (b *Buffer) Bytes() []byte { 140 return b.buf.Bytes() 141 } 142 143 var bufferWriterPool = sync.Pool{New: func() any { return &BufferWriter{} }} 144 145 func GetBufferWriter() *BufferWriter { 146 return bufferWriterPool.Get().(*BufferWriter) 147 } 148 149 func PutBufferWriter(buf *BufferWriter) { 150 buf.Reset() 151 bufferWriterPool.Put(buf) 152 } 153 154 const ( 155 smallBufferSize = 64 156 maxInt = int(^uint(0) >> 1) 157 ) 158 159 type BufferReader []byte 160 161 type BufferWriter []byte 162 163 func (br *BufferReader) Len() int { 164 return len(*br) 165 } 166 167 func (br *BufferReader) Cap() int { 168 return cap(*br) 169 } 170 171 func (br *BufferReader) IsEmpty() bool { 172 return br.Len() == 0 173 } 174 175 func (br *BufferReader) SplitAt(n int) (BufferReader, BufferReader) { 176 n = min(n, br.Len()) 177 buf := *br 178 return buf[:n], buf[n:] 179 } 180 181 func (br *BufferReader) SplitBy(f func(byte) bool) (BufferReader, BufferReader) { 182 for i, c := range *br { 183 if f(c) { 184 return br.SplitAt(i) 185 } 186 } 187 return *br, nil 188 } 189 190 func (br *BufferReader) ReadUint8() uint8 { 191 r := (*br)[0] 192 *br = (*br)[1:] 193 return r 194 } 195 196 func (br *BufferReader) ReadUint16() uint16 { 197 r := binary.NativeEndian.Uint16((*br)[:2]) 198 *br = (*br)[2:] 199 return r 200 } 201 202 func (br *BufferReader) ReadUint32() uint32 { 203 r := binary.NativeEndian.Uint32((*br)[:4]) 204 *br = (*br)[4:] 205 return r 206 } 207 208 func (br *BufferReader) ReadUint64() uint64 { 209 r := binary.NativeEndian.Uint64((*br)[:8]) 210 *br = (*br)[8:] 211 return r 212 } 213 214 func (br *BufferReader) ReadUint16be() uint16 { 215 r := binary.BigEndian.Uint16((*br)[:2]) 216 *br = (*br)[2:] 217 return r 218 } 219 220 func (br *BufferReader) ReadUint32be() uint32 { 221 r := binary.BigEndian.Uint32((*br)[:4]) 222 *br = (*br)[4:] 223 return r 224 } 225 226 func (br *BufferReader) ReadUint64be() uint64 { 227 r := binary.BigEndian.Uint64((*br)[:8]) 228 *br = (*br)[8:] 229 return r 230 } 231 232 func (br *BufferReader) ReadUvarint() (uint64, error) { 233 return binary.ReadUvarint(br) 234 } 235 236 func (br *BufferReader) ReadVarint() (int64, error) { 237 return binary.ReadVarint(br) 238 } 239 240 func (br *BufferReader) Skip(n int) { 241 *br = (*br)[n:] 242 } 243 244 func (br *BufferReader) Read(p []byte) (n int, err error) { 245 if br.IsEmpty() { 246 if len(p) == 0 { 247 return 0, nil 248 } 249 return 0, io.EOF 250 } 251 252 n = copy(p, *br) 253 *br = (*br)[n:] 254 return 255 } 256 257 func (br *BufferReader) ReadByte() (byte, error) { 258 if br.Len() == 0 { 259 return 0, io.EOF 260 } 261 return br.ReadUint8(), nil 262 } 263 264 func (br *BufferReader) ReadIPv4() netip.Addr { 265 ip := netip.AddrFrom4([4]byte((*br)[:4])) 266 *br = (*br)[4:] 267 return ip 268 } 269 270 func (br *BufferReader) ReadIPv6() netip.Addr { 271 ip := netip.AddrFrom16([16]byte((*br)[:16])) 272 *br = (*br)[16:] 273 return ip 274 } 275 276 func (bw *BufferWriter) Len() int { 277 return len(*bw) 278 } 279 280 func (bw *BufferWriter) Cap() int { 281 return cap(*bw) 282 } 283 284 // tryGrowByReslice is an inlineable version of grow for the fast-case where the 285 // internal buffer only needs to be resliced. 286 // It returns the index where bytes should be written and whether it succeeded. 287 func (bw *BufferWriter) tryGrowByReslice(n int) (int, bool) { 288 if l := len(*bw); n <= cap(*bw)-l { 289 *bw = (*bw)[:l+n] 290 return l, true 291 } 292 return 0, false 293 } 294 295 // growSlice grows b by n, preserving the original content of b. 296 // If the allocation fails, it panics with ErrTooLarge. 297 func growSlice(b []byte, n int) []byte { 298 defer func() { 299 if recover() != nil { 300 panic(bytes.ErrTooLarge) 301 } 302 }() 303 // TODO(http://golang.org/issue/51462): We should rely on the append-make 304 // pattern so that the compiler can call runtime.growslice. For example: 305 // return append(b, make([]byte, n)...) 306 // This avoids unnecessary zero-ing of the first len(b) bytes of the 307 // allocated slice, but this pattern causes b to escape onto the heap. 308 // 309 // Instead use the append-make pattern with a nil slice to ensure that 310 // we allocate buffers rounded up to the closest size class. 311 // 312 // ensure enough space for n elements 313 // The growth rate has historically always been 2x. In the future, 314 // we could rely purely on append to determine the growth rate. 315 c := max(len(b)+n, 2*cap(b)) 316 b2 := append([]byte(nil), make([]byte, c)...) 317 copy(b2, b) 318 return b2[:len(b)] 319 } 320 321 // grow the buffer to guarantee space for n more bytes. 322 // It returns the index where bytes should be written. 323 // If the buffer can't grow it will panic with ErrTooLarge. 324 func (bw *BufferWriter) grow(n int) int { 325 m := bw.Len() 326 // Try to grow by means of a reslice. 327 if i, ok := bw.tryGrowByReslice(n); ok { 328 return i 329 } 330 if *bw == nil && n <= smallBufferSize { 331 *bw = make([]byte, n, smallBufferSize) 332 return 0 333 } 334 c := cap(*bw) 335 if c > maxInt-c-n { 336 panic(bytes.ErrTooLarge) 337 } else if n > c/2-m { 338 // Add b.off to account for *b[:b.off] being sliced off the front. 339 *bw = growSlice((*bw)[:], n) 340 } 341 // Restore b.off and len(b.buf). 342 *bw = (*bw)[:m+n] 343 return m 344 } 345 346 func (bw *BufferWriter) Grow(n int) int { 347 m, ok := bw.tryGrowByReslice(n) 348 if !ok { 349 m = bw.grow(n) 350 } 351 return m 352 } 353 354 func (bw *BufferWriter) next(n int) []byte { 355 m := bw.Grow(n) 356 return (*bw)[m : m+n] 357 } 358 359 func (bw *BufferWriter) PutUint8(v uint8) { 360 m := bw.Grow(1) 361 (*bw)[m] = v 362 } 363 364 func (bw *BufferWriter) PutUint16(v uint16) { 365 binary.NativeEndian.PutUint16(bw.next(2), v) 366 } 367 368 func (bw *BufferWriter) PutUint32(v uint32) { 369 binary.NativeEndian.PutUint32(bw.next(4), v) 370 } 371 372 func (bw *BufferWriter) PutUint64(v uint64) { 373 binary.NativeEndian.PutUint64(bw.next(8), v) 374 } 375 376 func (bw *BufferWriter) PutUint16be(v uint16) { 377 binary.BigEndian.PutUint16(bw.next(2), v) 378 } 379 380 func (bw *BufferWriter) PutUint32be(v uint32) { 381 binary.BigEndian.PutUint32(bw.next(4), v) 382 } 383 384 func (bw *BufferWriter) PutUint64be(v uint64) { 385 binary.BigEndian.PutUint64(bw.next(8), v) 386 } 387 388 func (bw *BufferWriter) PutUvarint(v uint64) { 389 n := binary.MaxVarintLen64 390 m := bw.Grow(n) 391 392 n = binary.PutUvarint((*bw)[m:], v) 393 *bw = (*bw)[:m+n] 394 } 395 396 func (bw *BufferWriter) PutVarint(v int64) { 397 n := binary.MaxVarintLen64 398 m := bw.Grow(n) 399 400 n = binary.PutVarint((*bw)[m:], v) 401 *bw = (*bw)[:m+n] 402 } 403 404 func (bw *BufferWriter) PutSlice(p []byte) { 405 copy(bw.next(len(p)), p) 406 } 407 408 func (bw *BufferWriter) PutIPv4(ip net.IP) { 409 copy(bw.next(4), ip.To4()) 410 } 411 412 func (bw *BufferWriter) PutIPv6(ip net.IP) { 413 copy(bw.next(16), ip.To16()) 414 } 415 416 func (bw *BufferWriter) PutNetIPv4(addr netip.Addr) { 417 bw.PutIPv4(addr.AsSlice()) 418 } 419 420 func (bw *BufferWriter) PutNetIPv6(addr netip.Addr) { 421 bw.PutIPv6(addr.AsSlice()) 422 } 423 424 func (bw *BufferWriter) PutString(s string) { 425 copy(bw.next(len(s)), s) 426 } 427 428 func (bw *BufferWriter) PutRune(r rune) { 429 // Compare as uint32 to correctly handle negative runes. 430 if uint32(r) < utf8.RuneSelf { 431 bw.PutUint8(byte(r)) 432 return 433 } 434 m := bw.Grow(utf8.UTFMax) 435 *bw = utf8.AppendRune((*bw)[:m], r) 436 } 437 438 func (bw *BufferWriter) ReadFull(r io.Reader, n int) error { 439 l := bw.Len() 440 _, err := io.ReadFull(r, bw.next(n)) 441 if err != nil { 442 *bw = (*bw)[:l] 443 } 444 return err 445 } 446 447 func (bw *BufferWriter) WriteTo(w io.Writer) (n int64, err error) { 448 if nBytes := bw.Len(); nBytes > 0 { 449 m, e := w.Write((*bw)[:]) 450 if m > nBytes { 451 panic("bytes.Buffer.WriteTo: invalid Write count") 452 } 453 n = int64(m) 454 if e != nil { 455 return n, e 456 } 457 // all bytes should have been written, by definition of 458 // Write method in io.Writer 459 if m != nBytes { 460 return n, io.ErrShortWrite 461 } 462 } 463 // Buffer is now empty; reset. 464 bw.Reset() 465 return n, nil 466 } 467 468 func (bw *BufferWriter) Slice(begin, end int) BufferWriter { 469 w := (*bw)[begin:end] 470 w.Reset() 471 return w 472 } 473 474 func (bw *BufferWriter) Truncate(n int) *BufferWriter { 475 *bw = (*bw)[:n] 476 return bw 477 } 478 479 func (bw *BufferWriter) Write(p []byte) (n int, err error) { 480 n = len(p) 481 bw.PutSlice(p) 482 return 483 } 484 485 func (bw *BufferWriter) Bytes() []byte { 486 return (*bw)[:] 487 } 488 489 func (bw *BufferWriter) String() string { 490 return string((*bw)[:]) 491 } 492 493 func (bw *BufferWriter) Reset() { 494 *bw = (*bw)[:0] 495 }