buffer ints and strings

This commit is contained in:
mykola2312 2024-12-29 12:24:06 +02:00
parent ad775cc1ff
commit 7f5337ac04
2 changed files with 125 additions and 3 deletions

View file

@ -10,7 +10,7 @@ func TestWriteGrow(t *testing.T) {
first, second := []byte{1, 2, 3, 4}, []byte{5, 6, 7, 8}
must := []byte{1, 2, 3, 4, 5, 6, 7, 8}
buf := types.NewLuxBuffer(4)
buf := types.AllocLuxBuffer(4)
buf.WriteBytes(first)
t.Log(buf.AllBytes())
@ -21,3 +21,40 @@ func TestWriteGrow(t *testing.T) {
t.Fail()
}
}
func TestInts(t *testing.T) {
wd := types.AllocLuxBuffer(1)
wd.WriteUint16(1234)
wd.WriteUint16(4321)
wd.WriteUint64(69)
wd.WriteUint32(2967279234)
if rd := wd.ReadUint16(); rd != 1234 {
t.Fatal(rd)
}
if rd := wd.ReadUint16(); rd != 4321 {
t.Fatal(rd)
}
if rd := wd.ReadUint64(); rd != 69 {
t.Fatal(rd)
}
if rd := wd.ReadUint32(); rd != 2967279234 {
t.Fatal(rd)
}
}
func TestStrings(t *testing.T) {
wd := types.AllocLuxBuffer(1)
wd.WriteString("a") // 4
wd.WriteString("hello") // 8
if rd := wd.ReadString(); rd != "a" {
t.Fatal(rd)
}
if rd := wd.ReadString(); rd != "hello" {
t.Fatal(rd)
}
if wd.Length() != 12 {
t.Fatalf("string misaligned size: %d\n", wd.Length())
}
}

View file

@ -14,7 +14,7 @@ type LuxBuffer struct {
len int
}
func NewLuxBuffer(cap int) *LuxBuffer {
func AllocLuxBuffer(cap int) *LuxBuffer {
return &LuxBuffer{
data: make([]byte, cap),
offset: 0,
@ -22,6 +22,10 @@ func NewLuxBuffer(cap int) *LuxBuffer {
}
}
func NewLuxBuffer() *LuxBuffer {
return AllocLuxBuffer(MIN_BUFFER_SIZE)
}
func FromSlice(bytes []byte) *LuxBuffer {
return &LuxBuffer{
data: bytes,
@ -42,8 +46,14 @@ func (buf *LuxBuffer) Length() int {
return buf.len
}
// available capacity to write (before growing)
func (buf *LuxBuffer) Available() int {
return buf.Capacity() - buf.Length()
return buf.Capacity() - buf.len
}
// available length to read
func (buf *LuxBuffer) Remaining() int {
return buf.len - buf.offset
}
func (buf *LuxBuffer) Grow(grow int) {
@ -74,3 +84,78 @@ func (buf *LuxBuffer) WriteNext(size int) []byte {
func (buf *LuxBuffer) WriteBytes(bytes []byte) {
copy(buf.WriteNext(len(bytes)), bytes)
}
func (buf *LuxBuffer) ReadNext(size int) []byte {
next := buf.data[buf.offset : buf.offset+size]
buf.offset += size
return next
}
func (buf *LuxBuffer) Skip(skip int) {
buf.offset += skip
}
// explicit copy of read bytes
func (buf *LuxBuffer) CopyBytes(size int) []byte {
read := make([]byte, size)
copy(read, buf.ReadNext(size))
return read
}
func (buf *LuxBuffer) ReadUint16() uint16 {
return NO.Uint16(buf.ReadNext(2))
}
func (buf *LuxBuffer) ReadUint32() uint32 {
return NO.Uint32(buf.ReadNext(4))
}
func (buf *LuxBuffer) ReadUint64() uint64 {
return NO.Uint64(buf.ReadNext(8))
}
func (buf *LuxBuffer) WriteUint16(val uint16) {
NO.PutUint16(buf.WriteNext(2), val)
}
func (buf *LuxBuffer) WriteUint32(val uint32) {
NO.PutUint32(buf.WriteNext(4), val)
}
func (buf *LuxBuffer) WriteUint64(val uint64) {
NO.PutUint64(buf.WriteNext(8), val)
}
// variable-length blocks can cause misaligned size,
// so we make method for them, forcing padding
func (buf *LuxBuffer) ReadVarBlock() []byte {
len := buf.ReadUint16()
bytes := buf.ReadNext(int(len))
if len%2 != 0 {
buf.Skip(1) // skip padding
}
return bytes
}
func (buf *LuxBuffer) WriteVarBlock(bytes []byte) {
len := uint16(len(bytes))
buf.WriteUint16(len)
buf.WriteBytes(bytes)
if len%2 != 0 {
buf.WriteNext(1) // padding
}
}
// strings in LUX protocol format will be padded to align of 2
func (buf *LuxBuffer) ReadString() string {
return string(buf.ReadVarBlock())
}
func (buf *LuxBuffer) WriteString(val string) {
buf.WriteVarBlock([]byte(val))
}