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, } }