129 lines
2.6 KiB
Go
129 lines
2.6 KiB
Go
package strutil
|
|
|
|
import (
|
|
"bytes"
|
|
"fmt"
|
|
"strings"
|
|
)
|
|
|
|
// Buffer wrap and extends the bytes.Buffer
|
|
type Buffer struct {
|
|
bytes.Buffer
|
|
}
|
|
|
|
// NewBuffer instance
|
|
func NewBuffer() *Buffer {
|
|
return &Buffer{}
|
|
}
|
|
|
|
// WriteAny type value to buffer
|
|
func (b *Buffer) WriteAny(vs ...any) {
|
|
for _, v := range vs {
|
|
_, _ = b.Buffer.WriteString(fmt.Sprint(v))
|
|
}
|
|
}
|
|
|
|
// QuietWriteByte to buffer
|
|
func (b *Buffer) QuietWriteByte(c byte) {
|
|
_ = b.WriteByte(c)
|
|
}
|
|
|
|
// QuietWritef write message to buffer
|
|
func (b *Buffer) QuietWritef(tpl string, vs ...any) {
|
|
_, _ = b.WriteString(fmt.Sprintf(tpl, vs...))
|
|
}
|
|
|
|
// Writeln write message to buffer with newline
|
|
func (b *Buffer) Writeln(ss ...string) {
|
|
b.QuietWriteln(ss...)
|
|
}
|
|
|
|
// QuietWriteln write message to buffer with newline
|
|
func (b *Buffer) QuietWriteln(ss ...string) {
|
|
_, _ = b.WriteString(strings.Join(ss, ""))
|
|
_ = b.WriteByte('\n')
|
|
}
|
|
|
|
// QuietWriteString to buffer
|
|
func (b *Buffer) QuietWriteString(ss ...string) {
|
|
_, _ = b.WriteString(strings.Join(ss, ""))
|
|
}
|
|
|
|
// MustWriteString to buffer
|
|
func (b *Buffer) MustWriteString(ss ...string) {
|
|
_, err := b.WriteString(strings.Join(ss, ""))
|
|
if err != nil {
|
|
panic(err)
|
|
}
|
|
}
|
|
|
|
// ResetAndGet buffer string.
|
|
func (b *Buffer) ResetAndGet() string {
|
|
s := b.String()
|
|
b.Reset()
|
|
return s
|
|
}
|
|
|
|
// ByteChanPool struct
|
|
//
|
|
// Usage:
|
|
//
|
|
// bp := strutil.NewByteChanPool(500, 1024, 1024)
|
|
// buf:=bp.Get()
|
|
// defer bp.Put(buf)
|
|
// // use buf do something ...
|
|
//
|
|
// refer https://www.flysnow.org/2020/08/21/golang-chan-byte-pool.html
|
|
// from https://github.com/minio/minio/blob/master/internal/bpool/bpool.go
|
|
type ByteChanPool struct {
|
|
c chan []byte
|
|
w int
|
|
wcap int
|
|
}
|
|
|
|
// NewByteChanPool instance
|
|
func NewByteChanPool(maxSize int, width int, capWidth int) *ByteChanPool {
|
|
return &ByteChanPool{
|
|
c: make(chan []byte, maxSize),
|
|
w: width,
|
|
wcap: capWidth,
|
|
}
|
|
}
|
|
|
|
// Get gets a []byte from the BytePool, or creates a new one if none are
|
|
// available in the pool.
|
|
func (bp *ByteChanPool) Get() (b []byte) {
|
|
select {
|
|
case b = <-bp.c:
|
|
// reuse existing buffer
|
|
default:
|
|
// create new buffer
|
|
if bp.wcap > 0 {
|
|
b = make([]byte, bp.w, bp.wcap)
|
|
} else {
|
|
b = make([]byte, bp.w)
|
|
}
|
|
}
|
|
return
|
|
}
|
|
|
|
// Put returns the given Buffer to the BytePool.
|
|
func (bp *ByteChanPool) Put(b []byte) {
|
|
select {
|
|
case bp.c <- b:
|
|
// buffer went back into pool
|
|
default:
|
|
// buffer didn't go back into pool, just discard
|
|
}
|
|
}
|
|
|
|
// Width returns the width of the byte arrays in this pool.
|
|
func (bp *ByteChanPool) Width() (n int) {
|
|
return bp.w
|
|
}
|
|
|
|
// WidthCap returns the cap width of the byte arrays in this pool.
|
|
func (bp *ByteChanPool) WidthCap() (n int) {
|
|
return bp.wcap
|
|
}
|