Files
monibuca/pkg/util/buffer.go
2025-09-13 08:56:14 +08:00

309 lines
6.1 KiB
Go
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

package util
import (
"encoding/binary"
"fmt"
"io"
"math"
"net"
)
type Integer interface {
~int | ~int16 | ~int32 | ~int64 | ~uint | ~uint16 | ~uint32 | ~uint64
}
func PutBE[T Integer](b []byte, num T) []byte {
for i, n := 0, len(b); i < n; i++ {
b[i] = byte(num >> ((n - i - 1) << 3))
}
return b
}
func ReadBE[T Integer](b []byte) (num T) {
num = 0
for i, n := 0, len(b); i < n; i++ {
num += T(b[i]) << ((n - i - 1) << 3)
}
return
}
func GetBE[T Integer](b []byte, num *T) T {
*num = 0
for i, n := 0, len(b); i < n; i++ {
*num += T(b[i]) << ((n - i - 1) << 3)
}
return *num
}
// Buffer 用于方便自动扩容的内存写入,已经读取
type Buffer []byte
// ReuseBuffer 重用buffer内容可能会被覆盖要尽早复制
type ReuseBuffer struct {
Buffer
}
func (ReuseBuffer) Reuse() bool {
return true
}
// LimitBuffer 限制buffer的长度不会改变原来的buffer防止内存泄漏
type LimitBuffer struct {
Buffer
}
func (b *LimitBuffer) ReadN(n int) (result LimitBuffer) {
result.Buffer = b.Buffer.ReadN(n)
return
}
func (b LimitBuffer) Clone() (result LimitBuffer) {
result.Buffer = b.Buffer.Clone()
return
}
func (b LimitBuffer) SubBuf(start int, length int) (result LimitBuffer) {
result.Buffer = b.Buffer.SubBuf(start, length)
return
}
func (b *LimitBuffer) Malloc(count int) (result LimitBuffer) {
l := b.Len()
newL := l + count
if c := b.Cap(); newL > c {
panic(fmt.Sprintf("LimitBuffer Malloc %d > %d", newL, c))
} else {
*b = b.SubBuf(0, newL)
}
return b.SubBuf(l, count)
}
func (b *LimitBuffer) Write(a []byte) (n int, err error) {
l := b.Len()
newL := l + len(a)
if c := b.Cap(); newL > c {
return 0, fmt.Errorf("LimitBuffer Write %d > %d", newL, c)
// panic(fmt.Sprintf("LimitBuffer Write %d > %d", newL, c))
} else {
b.Buffer = b.Buffer.SubBuf(0, newL)
copy(b.Buffer[l:], a)
}
return len(a), nil
}
// IBytes 用于区分传入的内存是否是复用内存,例如从网络中读取的数据,如果是复用内存,需要尽早复制
type IBytes interface {
Len() int
Bytes() []byte
Reuse() bool
}
type IBuffer interface {
Len() int
Bytes() []byte
Reuse() bool
SubBuf(start int, length int) Buffer
Malloc(count int) Buffer
Reset()
WriteUint32(v uint32)
WriteUint24(v uint32)
WriteUint16(v uint16)
WriteFloat64(v float64)
WriteByte(v byte)
WriteString(a string)
Write(a []byte) (n int, err error)
ReadN(n int) Buffer
ReadFloat64() float64
ReadUint64() uint64
ReadUint32() uint32
ReadUint24() uint32
ReadUint16() uint16
ReadByte() byte
Read(buf []byte) (n int, err error)
Clone() Buffer
CanRead() bool
CanReadN(n int) bool
Cap() int
}
func (Buffer) Reuse() bool {
return false
}
func (b *Buffer) Read(buf []byte) (n int, err error) {
if !b.CanReadN(len(buf)) {
copy(buf, *b)
n = b.Len()
*b = (*b)[n:]
return n, io.EOF
}
ret := b.ReadN(len(buf))
copy(buf, ret)
return len(ret), err
}
func (b *Buffer) ReadN(n int) Buffer {
l := b.Len()
if n > l {
n = l
}
r := (*b)[:n]
*b = (*b)[n:l]
return r
}
func (b *Buffer) ReadFloat64() float64 {
return math.Float64frombits(b.ReadUint64())
}
func (b *Buffer) ReadUint64() uint64 {
return binary.BigEndian.Uint64(b.ReadN(8))
}
func (b *Buffer) ReadUint32() uint32 {
return binary.BigEndian.Uint32(b.ReadN(4))
}
func (b *Buffer) ReadUint24() uint32 {
return ReadBE[uint32](b.ReadN(3))
}
func (b *Buffer) ReadUint16() uint16 {
return binary.BigEndian.Uint16(b.ReadN(2))
}
func (b *Buffer) ReadByte() byte {
return b.ReadN(1)[0]
}
func (b *Buffer) WriteFloat64(v float64) {
PutBE(b.Malloc(8), math.Float64bits(v))
}
func (b *Buffer) WriteUint32(v uint32) {
binary.BigEndian.PutUint32(b.Malloc(4), v)
}
func (b *Buffer) WriteUint24(v uint32) {
PutBE(b.Malloc(3), v)
}
func (b *Buffer) WriteUint16(v uint16) {
binary.BigEndian.PutUint16(b.Malloc(2), v)
}
func (b *Buffer) WriteByte(v byte) {
b.Malloc(1)[0] = v
}
func (b *Buffer) WriteString(a string) {
*b = append(*b, a...)
}
func (b *Buffer) Write(a []byte) (n int, err error) {
l := b.Len()
newL := l + len(a)
if newL > b.Cap() {
*b = append(*b, a...)
} else {
*b = b.SubBuf(0, newL)
copy((*b)[l:], a)
}
return len(a), nil
}
func (b Buffer) Clone() (result Buffer) {
return append(result, b...)
}
func (b Buffer) Bytes() []byte {
return b
}
func (b Buffer) Len() int {
return len(b)
}
func (b Buffer) CanRead() bool {
return b.CanReadN(1)
}
func (b Buffer) CanReadN(n int) bool {
return b.Len() >= n
}
func (b Buffer) Cap() int {
return cap(b)
}
func (b Buffer) SubBuf(start int, length int) Buffer {
return b[start : start+length]
}
// Malloc 扩大原来的buffer的长度返回新增的buffer
func (b *Buffer) Malloc(count int) Buffer {
l := b.Len()
newL := l + count
if newL > b.Cap() {
n := make(Buffer, newL)
copy(n, *b)
*b = n
} else {
*b = b.SubBuf(0, newL)
}
return b.SubBuf(l, count)
}
// Relloc 改变 buffer 到指定大小
func (b *Buffer) Relloc(count int) {
b.Reset()
b.Malloc(count)
}
func (b *Buffer) Reset() {
*b = b.SubBuf(0, 0)
}
func (b *Buffer) Split(n int) (result net.Buffers) {
origin := *b
for {
if b.CanReadN(n) {
result = append(result, b.ReadN(n))
} else {
result = append(result, *b)
*b = origin
return
}
}
}
// ConcatBuffers 合并碎片内存为一个完整内存
func ConcatBuffers[T ~[]byte](input []T) (out []byte) {
for _, v := range input {
out = append(out, v...)
}
return
}
// SizeOfBuffers 计算Buffers的内容长度
func SizeOfBuffers[T ~[]byte](buf []T) (size int) {
for _, b := range buf {
size += len(b)
}
return
}
// SplitBuffers 按照一定大小分割 Buffers
func SplitBuffers[T ~[]byte](buf []T, size int) (result [][]T) {
buf = append([]T(nil), buf...)
for total := SizeOfBuffers(buf); total > 0; {
if total <= size {
return append(result, buf)
} else {
var before []T
sizeOfBefore := 0
for _, b := range buf {
need := size - sizeOfBefore
if lenOfB := len(b); lenOfB > need {
before = append(before, b[:need])
result = append(result, before)
total -= need
buf[0] = b[need:]
break
} else {
sizeOfBefore += lenOfB
before = append(before, b)
total -= lenOfB
buf = buf[1:]
}
}
}
}
return
}