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 }