1
0
mirror of https://github.com/imgproxy/imgproxy.git synced 2025-12-23 22:11:10 +02:00
Files
imgproxy/xmlparser/buffer.go
Victor Sokolov 69c7d2f117 IMG-76: new linter config & fixes (#1587)
* IMG-76: new linter config & fixes

* Upgrade golangci-lint to 2.7.2
2025-12-10 13:46:22 +01:00

94 lines
1.8 KiB
Go

package xmlparser
import (
"bytes"
"math"
"slices"
"sync"
)
var bufPool = sync.Pool{
New: func() any {
// Reserve some capacity to not re-allocate on short strings.
buf := make(buffer, 0, 1024)
return &buf
},
}
// buffer is a slice of bytes with some additional convenience methods.
type buffer []byte
// Free truncates the buffer and returns it to the pool.
func (b *buffer) Free() {
// Don't keep large buffers around.
if len(*b) > 16*1024 {
return
}
b.Reset()
bufPool.Put(b)
}
// Reset truncates the buffer.
func (b *buffer) Reset() {
*b = (*b)[:0]
}
func (b *buffer) Write(p []byte) (n int, err error) {
if len(p) == 0 {
return 0, nil
}
b.grow(len(p))
*b = append(*b, p...)
return len(p), nil
}
// WriteByte writes a single byte to the buffer.
func (b *buffer) WriteByte(p byte) error {
b.grow(1)
*b = append(*b, p)
return nil
}
// HasSuffix reports whether the buffer ends with the given suffix.
func (b *buffer) HasSuffix(suffix []byte) bool {
return bytes.HasSuffix(*b, suffix)
}
// Remove removes the last n bytes.
func (b *buffer) Remove(n int) {
l := len(*b)
n = min(n, l)
*b = (*b)[:l-n]
}
// Bytes returns the contents of the buffer as a byte slice.
func (b *buffer) Bytes() []byte {
return *b
}
// String returns the contents of the buffer as a string.
func (b *buffer) String() string {
return string(*b)
}
// Len returns the number of bytes written to the buffer.
func (b *buffer) Len() int {
return len(*b)
}
// grow ensures that the buffer has at least n free bytes of capacity.
// It grows the buffer to the next power of two if necessary.
func (b *buffer) grow(n int) {
if req := len(*b) + n; req > cap(*b) {
p := math.Ceil(math.Log2(float64(req)))
*b = slices.Grow(*b, 1<<int(p))
}
}
// newBuffer creates a new buffer from the pool.
func newBuffer() *buffer {
return bufPool.Get().(*buffer)
}