Files
g365sfu/bytebuffer/bytebuffer.go

219 lines
4.0 KiB
Go

package bytebuffer
import (
"encoding/binary"
"errors"
)
var (
ErrBufferUnderflow = errors.New("bytebuffer: buffer underflow")
ErrBufferOverflow = errors.New("bytebuffer: buffer overflow")
ErrInvalidPosition = errors.New("bytebuffer: invalid position")
ErrInvalidLimit = errors.New("bytebuffer: invalid limit")
)
type ByteBuffer struct {
buf []byte
pos int
limit int
order binary.ByteOrder
}
func Allocate(capacity int) *ByteBuffer {
if capacity < 0 {
capacity = 0
}
b := make([]byte, capacity)
return &ByteBuffer{
buf: b,
pos: 0,
limit: capacity,
order: binary.BigEndian,
}
}
func Wrap(data []byte) *ByteBuffer {
return &ByteBuffer{
buf: data,
pos: 0,
limit: len(data),
order: binary.BigEndian,
}
}
func (b *ByteBuffer) Order(order binary.ByteOrder) *ByteBuffer {
if order != nil {
b.order = order
}
return b
}
func (b *ByteBuffer) Capacity() int { return len(b.buf) }
func (b *ByteBuffer) Position() int { return b.pos }
func (b *ByteBuffer) Limit() int { return b.limit }
func (b *ByteBuffer) SetPosition(pos int) error {
if pos < 0 || pos > b.limit {
return ErrInvalidPosition
}
b.pos = pos
return nil
}
func (b *ByteBuffer) SetLimit(limit int) error {
if limit < 0 || limit > len(b.buf) {
return ErrInvalidLimit
}
b.limit = limit
if b.pos > b.limit {
b.pos = b.limit
}
return nil
}
func (b *ByteBuffer) Remaining() int {
return b.limit - b.pos
}
func (b *ByteBuffer) HasRemaining() bool {
return b.Remaining() > 0
}
// Clear: position=0, limit=capacity
func (b *ByteBuffer) Clear() *ByteBuffer {
b.pos = 0
b.limit = len(b.buf)
return b
}
// Flip: limit=position, position=0
func (b *ByteBuffer) Flip() *ByteBuffer {
b.limit = b.pos
b.pos = 0
return b
}
// Rewind: position=0
func (b *ByteBuffer) Rewind() *ByteBuffer {
b.pos = 0
return b
}
// Array возвращает весь underlying массив.
func (b *ByteBuffer) Array() []byte {
return b.buf
}
// Bytes возвращает readable срез [position:limit].
func (b *ByteBuffer) Bytes() []byte {
return b.buf[b.pos:b.limit]
}
func (b *ByteBuffer) ensureWrite(n int) error {
if b.pos+n > b.limit {
return ErrBufferOverflow
}
return nil
}
func (b *ByteBuffer) ensureRead(n int) error {
if b.pos+n > b.limit {
return ErrBufferUnderflow
}
return nil
}
func (b *ByteBuffer) Put(v byte) error {
if err := b.ensureWrite(1); err != nil {
return err
}
b.buf[b.pos] = v
b.pos++
return nil
}
func (b *ByteBuffer) PutBytes(p []byte) error {
if err := b.ensureWrite(len(p)); err != nil {
return err
}
copy(b.buf[b.pos:], p)
b.pos += len(p)
return nil
}
func (b *ByteBuffer) PutUint16(v uint16) error {
if err := b.ensureWrite(2); err != nil {
return err
}
b.order.PutUint16(b.buf[b.pos:b.pos+2], v)
b.pos += 2
return nil
}
func (b *ByteBuffer) PutUint32(v uint32) error {
if err := b.ensureWrite(4); err != nil {
return err
}
b.order.PutUint32(b.buf[b.pos:b.pos+4], v)
b.pos += 4
return nil
}
func (b *ByteBuffer) PutUint64(v uint64) error {
if err := b.ensureWrite(8); err != nil {
return err
}
b.order.PutUint64(b.buf[b.pos:b.pos+8], v)
b.pos += 8
return nil
}
func (b *ByteBuffer) Get() (byte, error) {
if err := b.ensureRead(1); err != nil {
return 0, err
}
v := b.buf[b.pos]
b.pos++
return v, nil
}
func (b *ByteBuffer) GetBytes(n int) ([]byte, error) {
if n < 0 {
return nil, ErrBufferUnderflow
}
if err := b.ensureRead(n); err != nil {
return nil, err
}
out := make([]byte, n)
copy(out, b.buf[b.pos:b.pos+n])
b.pos += n
return out, nil
}
func (b *ByteBuffer) GetUint16() (uint16, error) {
if err := b.ensureRead(2); err != nil {
return 0, err
}
v := b.order.Uint16(b.buf[b.pos : b.pos+2])
b.pos += 2
return v, nil
}
func (b *ByteBuffer) GetUint32() (uint32, error) {
if err := b.ensureRead(4); err != nil {
return 0, err
}
v := b.order.Uint32(b.buf[b.pos : b.pos+4])
b.pos += 4
return v, nil
}
func (b *ByteBuffer) GetUint64() (uint64, error) {
if err := b.ensureRead(8); err != nil {
return 0, err
}
v := b.order.Uint64(b.buf[b.pos : b.pos+8])
b.pos += 8
return v, nil
}