commit cb32f24dfda31004dec52e19733cf3a5ece34efb Author: Artёm Mishin Date: Mon May 26 03:15:35 2025 +0300 chore: Initial commit diff --git a/.idea/.gitignore b/.idea/.gitignore new file mode 100644 index 0000000..13566b8 --- /dev/null +++ b/.idea/.gitignore @@ -0,0 +1,8 @@ +# Default ignored files +/shelf/ +/workspace.xml +# Editor-based HTTP Client requests +/httpRequests/ +# Datasource local storage ignored files +/dataSources/ +/dataSources.local.xml diff --git a/.idea/modules.xml b/.idea/modules.xml new file mode 100644 index 0000000..86d48d5 --- /dev/null +++ b/.idea/modules.xml @@ -0,0 +1,8 @@ + + + + + + + + \ No newline at end of file diff --git a/.idea/universe_io.iml b/.idea/universe_io.iml new file mode 100644 index 0000000..5e764c4 --- /dev/null +++ b/.idea/universe_io.iml @@ -0,0 +1,9 @@ + + + + + + + + + \ No newline at end of file diff --git a/buffer.go b/buffer.go new file mode 100644 index 0000000..aa9012e --- /dev/null +++ b/buffer.go @@ -0,0 +1,599 @@ +package universe_io + +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) 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, + } +} diff --git a/errors.go b/errors.go new file mode 100644 index 0000000..3a6fdf7 --- /dev/null +++ b/errors.go @@ -0,0 +1,9 @@ +package universe_io + +import ( + "universe.mrlokop.dev/core/errors" +) + +var ( + ErrOutOfBounds = errors.Type("ErrOutOfBounds", "out of bounds access") +) diff --git a/go.mod b/go.mod new file mode 100644 index 0000000..9a4b452 --- /dev/null +++ b/go.mod @@ -0,0 +1,5 @@ +module universe_io + +go 1.24 + +require universe.mrlokop.dev/core v0.0.0-20250425135238-956d1fe8230e diff --git a/go.sum b/go.sum new file mode 100644 index 0000000..e4b1180 --- /dev/null +++ b/go.sum @@ -0,0 +1,2 @@ +universe.mrlokop.dev/core v0.0.0-20250425135238-956d1fe8230e h1:JLfkFszZKNyDDUthg0CD26r7PGaELxZxOZ3ldRgA1I8= +universe.mrlokop.dev/core v0.0.0-20250425135238-956d1fe8230e/go.mod h1:VfXat6pLrr0uagvx8zwJ6kHCI7RWVWFE0/m1RBfa4zI= diff --git a/sink.go b/sink.go new file mode 100644 index 0000000..2c52c9b --- /dev/null +++ b/sink.go @@ -0,0 +1,9 @@ +package universe_io + +type Sink interface { + Write(src []byte) (n int, err error) +} + +type BufferedSink interface { + Sink +} diff --git a/source.go b/source.go new file mode 100644 index 0000000..4a20eb3 --- /dev/null +++ b/source.go @@ -0,0 +1,42 @@ +package universe_io + +type Source interface { + Read(dst []byte) (n int, err error) +} + +type BufferedSource interface { + Source + + ReadByte() (byte, error) + ReadUByte() (uint8, error) + + ReadShortLE() (int16, error) + ReadShortBE() (int16, error) + ReadIntLE() (int32, error) + ReadIntBE() (int32, error) + ReadLongLE() (int64, error) + ReadLongBE() (int64, error) + + ReadUShortLE() (uint16, error) + ReadUShortBE() (uint16, error) + ReadUIntLE() (uint32, error) + ReadUIntBE() (uint32, error) + ReadULongLE() (uint64, error) + ReadULongBE() (uint64, error) + + ReadFloatLE() (float32, error) + ReadFloatBE() (float32, error) + ReadDoubleLE() (float64, error) + ReadDoubleBE() (float64, error) + + // ReadShortByteArray reads a size-prefixed byte array. + // Structure: [ShortLE : size][size bytes data] + ReadShortByteArray() ([]byte, error) + + // ReadByteArray reads a size-prefixed byte array. + // Structure: [IntLE : size][size bytes data] + ReadByteArray() ([]byte, error) + + ReadShortString() (string, error) + ReadString() (string, error) +} diff --git a/types.go b/types.go new file mode 100644 index 0000000..2d0ed63 --- /dev/null +++ b/types.go @@ -0,0 +1,3 @@ +package universe_io + +type Cursor uint