Files
2025-05-26 04:34:59 +03:00

648 lines
17 KiB
Go

package uio
import (
"math"
)
// Buffer is an interface that represents a source that can be read and written to in a buffered manner.
// Basically provides Random Access to the data.
type Buffer interface {
BufferedSource
BufferedSink
ReaderCursor() Cursor
WriterCursor() Cursor
AdvanceReaderCursor(n int) (Cursor, error)
AdvanceWriterCursor(n int) (Cursor, error)
ResetReaderCursor() Cursor
ResetWriterCursor() Cursor
RemainingReaderBytes() int
RemainingWriterBytes() int
Capacity() int
}
type byteBuffer struct {
data []byte
readerCursor Cursor
writerCursor Cursor
}
func (b *byteBuffer) WriteShortByteArray(data []byte) error {
if len(data) > 0xFFFF {
return ErrOutOfBounds.CreateEmpty()
}
if b.RemainingWriterBytes() < 2+len(data) {
return ErrOutOfBounds.CreateEmpty()
}
if err := b.WriteShortLE(int16(len(data))); err != nil {
return err
}
n, err := b.Write(data)
if err != nil {
return err
}
if n != len(data) {
return ErrOutOfBounds.CreateEmpty()
}
return nil
}
func (b *byteBuffer) WriteByteArray(data []byte) error {
if len(data) > 0xFFFFFFFF {
return ErrOutOfBounds.CreateEmpty()
}
if b.RemainingWriterBytes() < 4+len(data) {
return ErrOutOfBounds.CreateEmpty()
}
if err := b.WriteIntLE(int32(len(data))); err != nil {
return err
}
n, err := b.Write(data)
if err != nil {
return err
}
if n != len(data) {
return ErrOutOfBounds.CreateEmpty()
}
return nil
}
func (b *byteBuffer) WriteShortString(s string) error {
return b.WriteByteArray([]byte(s))
}
func (b *byteBuffer) WriteString(s string) error {
return b.WriteByteArray([]byte(s))
}
func (b *byteBuffer) ReadShortByteArray() ([]byte, error) {
if b.RemainingReaderBytes() < 2 {
return nil, ErrOutOfBounds.CreateEmpty()
}
size, err := b.ReadShortLE()
if err != nil {
return nil, err
}
if size < 0 || int(size) > b.RemainingReaderBytes() {
return nil, ErrOutOfBounds.CreateEmpty()
}
data := make([]byte, size)
n, err := b.Read(data)
if err != nil {
return nil, err
}
if n != int(size) {
return nil, ErrOutOfBounds.CreateEmpty()
}
return data, nil
}
func (b *byteBuffer) ReadByteArray() ([]byte, error) {
if b.RemainingReaderBytes() < 4 {
return nil, ErrOutOfBounds.CreateEmpty()
}
size, err := b.ReadIntLE()
if err != nil {
return nil, err
}
if size < 0 || int(size) > b.RemainingReaderBytes() {
return nil, ErrOutOfBounds.CreateEmpty()
}
data := make([]byte, size)
n, err := b.Read(data)
if err != nil {
return nil, err
}
if n != int(size) {
return nil, ErrOutOfBounds.CreateEmpty()
}
return data, nil
}
func (b *byteBuffer) ReadShortString() (string, error) {
byteArray, err := b.ReadShortByteArray()
if err != nil {
return "", err
}
if len(byteArray) == 0 {
return "", nil // Return empty string for zero-length byte array
}
return string(byteArray), nil
}
func (b *byteBuffer) ReadString() (string, error) {
byteArray, err := b.ReadByteArray()
if err != nil {
return "", err
}
if len(byteArray) == 0 {
return "", nil // Return empty string for zero-length byte array
}
return string(byteArray), nil
}
func (b *byteBuffer) ReaderCursor() Cursor {
return b.readerCursor
}
func (b *byteBuffer) WriterCursor() Cursor {
return b.writerCursor
}
func (b *byteBuffer) AdvanceReaderCursor(n int) (Cursor, error) {
if n < 0 || int(b.readerCursor)+n > len(b.data) {
return b.readerCursor, ErrOutOfBounds.CreateEmpty()
}
b.readerCursor += Cursor(n)
return b.readerCursor, nil
}
func (b *byteBuffer) AdvanceWriterCursor(n int) (Cursor, error) {
if n < 0 || int(b.writerCursor)+n > len(b.data) {
return b.writerCursor, ErrOutOfBounds.CreateEmpty()
}
b.writerCursor += Cursor(n)
return b.writerCursor, nil
}
func (b *byteBuffer) ResetReaderCursor() Cursor {
b.readerCursor = 0
return b.readerCursor
}
func (b *byteBuffer) ResetWriterCursor() Cursor {
b.writerCursor = 0
return b.writerCursor
}
func (b *byteBuffer) RemainingReaderBytes() int {
return len(b.data) - int(b.readerCursor)
}
func (b *byteBuffer) RemainingWriterBytes() int {
return len(b.data) - int(b.writerCursor)
}
func (b *byteBuffer) Capacity() int {
return len(b.data)
}
func (b *byteBuffer) Read(dst []byte) (n int, err error) {
if len(dst) > b.RemainingReaderBytes() {
return 0, ErrOutOfBounds.CreateEmpty()
}
n = copy(dst, b.data[b.readerCursor:])
b.readerCursor += Cursor(n)
return n, nil
}
func (b *byteBuffer) Write(src []byte) (n int, err error) {
if len(src) > b.RemainingWriterBytes() {
return 0, ErrOutOfBounds.CreateEmpty()
}
n = copy(b.data[b.writerCursor:], src)
b.writerCursor += Cursor(n)
return n, nil
}
func (b *byteBuffer) ReadByte() (byte, error) {
if b.RemainingReaderBytes() < 1 {
return 0, ErrOutOfBounds.CreateEmpty()
}
b.readerCursor++
return b.data[b.readerCursor-1], nil
}
func (b *byteBuffer) ReadUByte() (uint8, error) {
if b.RemainingReaderBytes() < 1 {
return 0, ErrOutOfBounds.CreateEmpty()
}
b.readerCursor++
return b.data[b.readerCursor-1], nil
}
func (b *byteBuffer) WriteByte(v byte) error {
if b.RemainingWriterBytes() < 1 {
return ErrOutOfBounds.CreateEmpty()
}
b.data[b.writerCursor] = v
b.writerCursor++
return nil
}
func (b *byteBuffer) WriteUByte(v uint8) error {
if b.RemainingWriterBytes() < 1 {
return ErrOutOfBounds.CreateEmpty()
}
b.data[b.writerCursor] = v
b.writerCursor++
return nil
}
func (b *byteBuffer) ReadShortLE() (int16, error) {
if b.RemainingReaderBytes() < 2 {
return 0, ErrOutOfBounds.CreateEmpty()
}
value := int16(b.data[b.readerCursor]) | int16(b.data[b.readerCursor+1])<<8
b.readerCursor += 2
return value, nil
}
func (b *byteBuffer) WriteShortLE(v int16) error {
if b.RemainingWriterBytes() < 2 {
return ErrOutOfBounds.CreateEmpty()
}
b.data[b.writerCursor] = byte(v)
b.data[b.writerCursor+1] = byte(v >> 8)
b.writerCursor += 2
return nil
}
func (b *byteBuffer) ReadShortBE() (int16, error) {
if b.RemainingReaderBytes() < 2 {
return 0, ErrOutOfBounds.CreateEmpty()
}
value := int16(b.data[b.readerCursor+1]) | int16(b.data[b.readerCursor])<<8
b.readerCursor += 2
return value, nil
}
func (b *byteBuffer) WriteShortBE(v int16) error {
if b.RemainingWriterBytes() < 2 {
return ErrOutOfBounds.CreateEmpty()
}
b.data[b.writerCursor] = byte(v >> 8)
b.data[b.writerCursor+1] = byte(v)
b.writerCursor += 2
return nil
}
func (b *byteBuffer) ReadUShortLE() (uint16, error) {
if b.RemainingReaderBytes() < 2 {
return 0, ErrOutOfBounds.CreateEmpty()
}
value := uint16(b.data[b.readerCursor]) | uint16(b.data[b.readerCursor+1])<<8
b.readerCursor += 2
return value, nil
}
func (b *byteBuffer) WriteUShortLE(v uint16) error {
if b.RemainingWriterBytes() < 2 {
return ErrOutOfBounds.CreateEmpty()
}
b.data[b.writerCursor] = byte(v)
b.data[b.writerCursor+1] = byte(v >> 8)
b.writerCursor += 2
return nil
}
func (b *byteBuffer) ReadUShortBE() (uint16, error) {
if b.RemainingReaderBytes() < 2 {
return 0, ErrOutOfBounds.CreateEmpty()
}
value := uint16(b.data[b.readerCursor+1]) | uint16(b.data[b.readerCursor])<<8
b.readerCursor += 2
return value, nil
}
func (b *byteBuffer) WriteUShortBE(v uint16) error {
if b.RemainingWriterBytes() < 2 {
return ErrOutOfBounds.CreateEmpty()
}
b.data[b.writerCursor] = byte(v >> 8)
b.data[b.writerCursor+1] = byte(v)
b.writerCursor += 2
return nil
}
func (b *byteBuffer) ReadIntLE() (int32, error) {
if b.RemainingReaderBytes() < 4 {
return 0, ErrOutOfBounds.CreateEmpty()
}
value := int32(b.data[b.readerCursor]) | int32(b.data[b.readerCursor+1])<<8 |
int32(b.data[b.readerCursor+2])<<16 | int32(b.data[b.readerCursor+3])<<24
b.readerCursor += 4
return value, nil
}
func (b *byteBuffer) WriteIntLE(v int32) error {
if b.RemainingWriterBytes() < 4 {
return ErrOutOfBounds.CreateEmpty()
}
b.data[b.writerCursor] = byte(v)
b.data[b.writerCursor+1] = byte(v >> 8)
b.data[b.writerCursor+2] = byte(v >> 16)
b.data[b.writerCursor+3] = byte(v >> 24)
b.writerCursor += 4
return nil
}
func (b *byteBuffer) ReadIntBE() (int32, error) {
if b.RemainingReaderBytes() < 4 {
return 0, ErrOutOfBounds.CreateEmpty()
}
value := int32(b.data[b.readerCursor+3]) | int32(b.data[b.readerCursor+2])<<8 |
int32(b.data[b.readerCursor+1])<<16 | int32(b.data[b.readerCursor])<<24
b.readerCursor += 4
return value, nil
}
func (b *byteBuffer) WriteIntBE(v int32) error {
if b.RemainingWriterBytes() < 4 {
return ErrOutOfBounds.CreateEmpty()
}
b.data[b.writerCursor] = byte(v >> 24)
b.data[b.writerCursor+1] = byte(v >> 16)
b.data[b.writerCursor+2] = byte(v >> 8)
b.data[b.writerCursor+3] = byte(v)
b.writerCursor += 4
return nil
}
func (b *byteBuffer) ReadUIntLE() (uint32, error) {
if b.RemainingReaderBytes() < 4 {
return 0, ErrOutOfBounds.CreateEmpty()
}
value := uint32(b.data[b.readerCursor]) | uint32(b.data[b.readerCursor+1])<<8 |
uint32(b.data[b.readerCursor+2])<<16 | uint32(b.data[b.readerCursor+3])<<24
b.readerCursor += 4
return value, nil
}
func (b *byteBuffer) WriteUIntLE(v uint32) error {
if b.RemainingWriterBytes() < 4 {
return ErrOutOfBounds.CreateEmpty()
}
b.data[b.writerCursor] = byte(v)
b.data[b.writerCursor+1] = byte(v >> 8)
b.data[b.writerCursor+2] = byte(v >> 16)
b.data[b.writerCursor+3] = byte(v >> 24)
b.writerCursor += 4
return nil
}
func (b *byteBuffer) ReadUIntBE() (uint32, error) {
if b.RemainingReaderBytes() < 4 {
return 0, ErrOutOfBounds.CreateEmpty()
}
value := uint32(b.data[b.readerCursor+3]) | uint32(b.data[b.readerCursor+2])<<8 |
uint32(b.data[b.readerCursor+1])<<16 | uint32(b.data[b.readerCursor])<<24
b.readerCursor += 4
return value, nil
}
func (b *byteBuffer) WriteUIntBE(v uint32) error {
if b.RemainingWriterBytes() < 4 {
return ErrOutOfBounds.CreateEmpty()
}
b.data[b.writerCursor] = byte(v >> 24)
b.data[b.writerCursor+1] = byte(v >> 16)
b.data[b.writerCursor+2] = byte(v >> 8)
b.data[b.writerCursor+3] = byte(v)
b.writerCursor += 4
return nil
}
func (b *byteBuffer) ReadLongLE() (int64, error) {
if b.RemainingReaderBytes() < 8 {
return 0, ErrOutOfBounds.CreateEmpty()
}
value := int64(b.data[b.readerCursor]) | int64(b.data[b.readerCursor+1])<<8 |
int64(b.data[b.readerCursor+2])<<16 | int64(b.data[b.readerCursor+3])<<24 |
int64(b.data[b.readerCursor+4])<<32 | int64(b.data[b.readerCursor+5])<<40 |
int64(b.data[b.readerCursor+6])<<48 | int64(b.data[b.readerCursor+7])<<56
b.readerCursor += 8
return value, nil
}
func (b *byteBuffer) WriteLongLE(v int64) error {
if b.RemainingWriterBytes() < 8 {
return ErrOutOfBounds.CreateEmpty()
}
b.data[b.writerCursor] = byte(v)
b.data[b.writerCursor+1] = byte(v >> 8)
b.data[b.writerCursor+2] = byte(v >> 16)
b.data[b.writerCursor+3] = byte(v >> 24)
b.data[b.writerCursor+4] = byte(v >> 32)
b.data[b.writerCursor+5] = byte(v >> 40)
b.data[b.writerCursor+6] = byte(v >> 48)
b.data[b.writerCursor+7] = byte(v >> 56)
b.writerCursor += 8
return nil
}
func (b *byteBuffer) ReadLongBE() (int64, error) {
if b.RemainingReaderBytes() < 8 {
return 0, ErrOutOfBounds.CreateEmpty()
}
value := int64(b.data[b.readerCursor+7]) | int64(b.data[b.readerCursor+6])<<8 |
int64(b.data[b.readerCursor+5])<<16 | int64(b.data[b.readerCursor+4])<<24 |
int64(b.data[b.readerCursor+3])<<32 | int64(b.data[b.readerCursor+2])<<40 |
int64(b.data[b.readerCursor+1])<<48 | int64(b.data[b.readerCursor])<<56
b.readerCursor += 8
return value, nil
}
func (b *byteBuffer) WriteLongBE(v int64) error {
if b.RemainingWriterBytes() < 8 {
return ErrOutOfBounds.CreateEmpty()
}
b.data[b.writerCursor] = byte(v >> 56)
b.data[b.writerCursor+1] = byte(v >> 48)
b.data[b.writerCursor+2] = byte(v >> 40)
b.data[b.writerCursor+3] = byte(v >> 32)
b.data[b.writerCursor+4] = byte(v >> 24)
b.data[b.writerCursor+5] = byte(v >> 16)
b.data[b.writerCursor+6] = byte(v >> 8)
b.data[b.writerCursor+7] = byte(v)
b.writerCursor += 8
return nil
}
func (b *byteBuffer) ReadULongLE() (uint64, error) {
if b.RemainingReaderBytes() < 8 {
return 0, ErrOutOfBounds.CreateEmpty()
}
value := uint64(b.data[b.readerCursor]) | uint64(b.data[b.readerCursor+1])<<8 |
uint64(b.data[b.readerCursor+2])<<16 | uint64(b.data[b.readerCursor+3])<<24 |
uint64(b.data[b.readerCursor+4])<<32 | uint64(b.data[b.readerCursor+5])<<40 |
uint64(b.data[b.readerCursor+6])<<48 | uint64(b.data[b.readerCursor+7])<<56
b.readerCursor += 8
return value, nil
}
func (b *byteBuffer) WriteULongLE(v uint64) error {
if b.RemainingWriterBytes() < 8 {
return ErrOutOfBounds.CreateEmpty()
}
b.data[b.writerCursor] = byte(v)
b.data[b.writerCursor+1] = byte(v >> 8)
b.data[b.writerCursor+2] = byte(v >> 16)
b.data[b.writerCursor+3] = byte(v >> 24)
b.data[b.writerCursor+4] = byte(v >> 32)
b.data[b.writerCursor+5] = byte(v >> 40)
b.data[b.writerCursor+6] = byte(v >> 48)
b.data[b.writerCursor+7] = byte(v >> 56)
b.writerCursor += 8
return nil
}
func (b *byteBuffer) ReadULongBE() (uint64, error) {
if b.RemainingReaderBytes() < 8 {
return 0, ErrOutOfBounds.CreateEmpty()
}
value := uint64(b.data[b.readerCursor+7]) | uint64(b.data[b.readerCursor+6])<<8 |
uint64(b.data[b.readerCursor+5])<<16 | uint64(b.data[b.readerCursor+4])<<24 |
uint64(b.data[b.readerCursor+3])<<32 | uint64(b.data[b.readerCursor+2])<<40 |
uint64(b.data[b.readerCursor+1])<<48 | uint64(b.data[b.readerCursor])<<56
b.readerCursor += 8
return value, nil
}
func (b *byteBuffer) WriteULongBE(v uint64) error {
if b.RemainingWriterBytes() < 8 {
return ErrOutOfBounds.CreateEmpty()
}
b.data[b.writerCursor] = byte(v >> 56)
b.data[b.writerCursor+1] = byte(v >> 48)
b.data[b.writerCursor+2] = byte(v >> 40)
b.data[b.writerCursor+3] = byte(v >> 32)
b.data[b.writerCursor+4] = byte(v >> 24)
b.data[b.writerCursor+5] = byte(v >> 16)
b.data[b.writerCursor+6] = byte(v >> 8)
b.data[b.writerCursor+7] = byte(v)
b.writerCursor += 8
return nil
}
func (b *byteBuffer) ReadFloatLE() (float32, error) {
if b.RemainingReaderBytes() < 4 {
return 0, ErrOutOfBounds.CreateEmpty()
}
bits, err := b.ReadUIntLE()
if err != nil {
return 0, err
}
value := math.Float32frombits(bits)
b.readerCursor += 4
return value, nil
}
func (b *byteBuffer) WriteFloatLE(v float32) error {
if b.RemainingWriterBytes() < 4 {
return ErrOutOfBounds.CreateEmpty()
}
bits := math.Float32bits(v)
b.data[b.writerCursor] = byte(bits)
b.data[b.writerCursor+1] = byte(bits >> 8)
b.data[b.writerCursor+2] = byte(bits >> 16)
b.data[b.writerCursor+3] = byte(bits >> 24)
b.writerCursor += 4
return nil
}
func (b *byteBuffer) ReadFloatBE() (float32, error) {
if b.RemainingReaderBytes() < 4 {
return 0, ErrOutOfBounds.CreateEmpty()
}
bits, err := b.ReadUIntBE()
if err != nil {
return 0, err
}
value := math.Float32frombits(bits)
b.readerCursor += 4
return value, nil
}
func (b *byteBuffer) WriteFloatBE(v float32) error {
if b.RemainingWriterBytes() < 4 {
return ErrOutOfBounds.CreateEmpty()
}
bits := math.Float32bits(v)
b.data[b.writerCursor] = byte(bits >> 24)
b.data[b.writerCursor+1] = byte(bits >> 16)
b.data[b.writerCursor+2] = byte(bits >> 8)
b.data[b.writerCursor+3] = byte(bits)
b.writerCursor += 4
return nil
}
func (b *byteBuffer) ReadDoubleLE() (float64, error) {
if b.RemainingReaderBytes() < 8 {
return 0, ErrOutOfBounds.CreateEmpty()
}
bits, err := b.ReadULongLE()
if err != nil {
return 0, err
}
value := math.Float64frombits(bits)
b.readerCursor += 8
return value, nil
}
func (b *byteBuffer) WriteDoubleLE(v float64) error {
if b.RemainingWriterBytes() < 8 {
return ErrOutOfBounds.CreateEmpty()
}
bits := math.Float64bits(v)
b.data[b.writerCursor] = byte(bits)
b.data[b.writerCursor+1] = byte(bits >> 8)
b.data[b.writerCursor+2] = byte(bits >> 16)
b.data[b.writerCursor+3] = byte(bits >> 24)
b.data[b.writerCursor+4] = byte(bits >> 32)
b.data[b.writerCursor+5] = byte(bits >> 40)
b.data[b.writerCursor+6] = byte(bits >> 48)
b.data[b.writerCursor+7] = byte(bits >> 56)
b.writerCursor += 8
return nil
}
func (b *byteBuffer) ReadDoubleBE() (float64, error) {
if b.RemainingReaderBytes() < 8 {
return 0, ErrOutOfBounds.CreateEmpty()
}
bits, err := b.ReadULongBE()
if err != nil {
return 0, err
}
value := math.Float64frombits(bits)
b.readerCursor += 8
return value, nil
}
func (b *byteBuffer) WriteDoubleBE(v float64) error {
if b.RemainingWriterBytes() < 8 {
return ErrOutOfBounds.CreateEmpty()
}
bits := math.Float64bits(v)
b.data[b.writerCursor] = byte(bits >> 56)
b.data[b.writerCursor+1] = byte(bits >> 48)
b.data[b.writerCursor+2] = byte(bits >> 40)
b.data[b.writerCursor+3] = byte(bits >> 32)
b.data[b.writerCursor+4] = byte(bits >> 24)
b.data[b.writerCursor+5] = byte(bits >> 16)
b.data[b.writerCursor+6] = byte(bits >> 8)
b.data[b.writerCursor+7] = byte(bits)
b.writerCursor += 8
return nil
}
func NewByteBuffer(size int) Buffer {
if size <= 0 {
size = 1024 // default size
}
data := make([]byte, size)
return &byteBuffer{
data: data,
readerCursor: 0,
writerCursor: 0,
}
}