2021-12-16 19:45:32 -05:00
|
|
|
package oscar
|
2021-12-16 17:41:17 -05:00
|
|
|
|
|
|
|
import (
|
|
|
|
"encoding"
|
|
|
|
"encoding/binary"
|
2021-12-18 21:02:47 -05:00
|
|
|
"io"
|
2021-12-16 17:41:17 -05:00
|
|
|
)
|
|
|
|
|
2021-12-18 21:02:47 -05:00
|
|
|
// Buffer is a handy byte slice that reads from the front and writes on the end
|
2021-12-16 17:41:17 -05:00
|
|
|
type Buffer struct {
|
|
|
|
d []byte
|
|
|
|
}
|
|
|
|
|
2021-12-18 21:02:47 -05:00
|
|
|
// Seek moves the read cursor forward. If the cursor is beyond the length of the byte
|
|
|
|
// slice then the buffer slice is just replaced with an empty slice
|
|
|
|
func (b *Buffer) Seek(n int) {
|
|
|
|
if n > len(b.d) {
|
|
|
|
b.d = make([]byte, 0)
|
|
|
|
return
|
|
|
|
}
|
|
|
|
b.d = b.d[n:]
|
|
|
|
}
|
|
|
|
|
|
|
|
func (b *Buffer) Read(d []byte) (int, error) {
|
|
|
|
if len(d) > len(b.d) {
|
|
|
|
return 0, io.EOF
|
|
|
|
}
|
|
|
|
|
|
|
|
n := copy(d, b.d[0:len(d)])
|
|
|
|
return n, nil
|
|
|
|
}
|
|
|
|
|
|
|
|
func (b *Buffer) ReadUint8() (uint8, error) {
|
|
|
|
if len(b.d) < 1 {
|
|
|
|
return 0, io.EOF
|
|
|
|
}
|
|
|
|
ret := uint8(b.d[0])
|
|
|
|
b.d = b.d[1:]
|
|
|
|
return ret, nil
|
|
|
|
}
|
|
|
|
|
|
|
|
func (b *Buffer) ReadUint16() (uint16, error) {
|
|
|
|
if len(b.d) < 2 {
|
|
|
|
return 0, io.EOF
|
|
|
|
}
|
|
|
|
ret := binary.BigEndian.Uint16(b.d[0:2])
|
|
|
|
b.d = b.d[2:]
|
|
|
|
return ret, nil
|
|
|
|
}
|
|
|
|
|
|
|
|
func (b *Buffer) ReadUint32() (uint32, error) {
|
|
|
|
if len(b.d) < 4 {
|
|
|
|
return 0, io.EOF
|
|
|
|
}
|
|
|
|
ret := binary.BigEndian.Uint32(b.d[0:4])
|
|
|
|
b.d = b.d[4:]
|
|
|
|
return ret, nil
|
|
|
|
}
|
|
|
|
|
|
|
|
func (b *Buffer) ReadUint64() (uint64, error) {
|
|
|
|
if len(b.d) < 8 {
|
|
|
|
return 0, io.EOF
|
|
|
|
}
|
|
|
|
ret := binary.BigEndian.Uint64(b.d[0:8])
|
|
|
|
b.d = b.d[8:]
|
|
|
|
return ret, nil
|
|
|
|
}
|
|
|
|
|
|
|
|
// ReadLPString reads a length-prefixed string. The first byte should be the string length
|
|
|
|
// followed by that many bytes. Returns io.EOF if there are less bytes than indicated.
|
|
|
|
func (b *Buffer) ReadLPString() (string, error) {
|
|
|
|
length, err := b.ReadUint8()
|
|
|
|
if err != nil {
|
|
|
|
return "", nil
|
|
|
|
}
|
|
|
|
|
|
|
|
if len(b.d) < int(length) {
|
|
|
|
return "", io.EOF
|
|
|
|
}
|
|
|
|
|
|
|
|
str := string(b.d[:length])
|
|
|
|
b.d = b.d[length:]
|
|
|
|
return str, nil
|
|
|
|
}
|
|
|
|
|
2021-12-16 17:41:17 -05:00
|
|
|
func (b *Buffer) WriteUint8(x uint8) {
|
|
|
|
b.d = append(b.d, x)
|
|
|
|
}
|
|
|
|
|
|
|
|
func (b *Buffer) WriteUint16(x uint16) {
|
|
|
|
b.d = append(b.d, 0, 0)
|
|
|
|
binary.BigEndian.PutUint16(b.d[len(b.d)-2:], x)
|
|
|
|
}
|
|
|
|
|
|
|
|
func (b *Buffer) WriteUint32(x uint32) {
|
|
|
|
b.d = append(b.d, 0, 0, 0, 0)
|
|
|
|
binary.BigEndian.PutUint32(b.d[len(b.d)-4:], x)
|
|
|
|
}
|
|
|
|
|
|
|
|
func (b *Buffer) WriteUint64(x uint64) {
|
|
|
|
b.d = append(b.d, 0, 0, 0, 0, 0, 0, 0, 0)
|
|
|
|
binary.BigEndian.PutUint64(b.d[len(b.d)-8:], x)
|
|
|
|
}
|
|
|
|
|
|
|
|
func (b *Buffer) WriteString(x string) {
|
|
|
|
b.d = append(b.d, []byte(x)...)
|
|
|
|
}
|
|
|
|
|
2021-12-18 21:02:47 -05:00
|
|
|
func (b *Buffer) WriteLPString(x string) {
|
|
|
|
b.WriteUint8(uint8(len(x)))
|
|
|
|
b.WriteString(x)
|
|
|
|
}
|
|
|
|
|
2021-12-16 17:41:17 -05:00
|
|
|
func (b *Buffer) Write(x []byte) (int, error) {
|
|
|
|
b.d = append(b.d, x...)
|
|
|
|
return len(x), nil
|
|
|
|
}
|
|
|
|
|
|
|
|
func (b *Buffer) WriteBinary(e encoding.BinaryMarshaler) {
|
|
|
|
d, err := e.MarshalBinary()
|
2022-02-03 14:06:33 -05:00
|
|
|
if err != nil {
|
|
|
|
panic(err)
|
|
|
|
}
|
2021-12-16 17:41:17 -05:00
|
|
|
b.d = append(b.d, d...)
|
|
|
|
}
|
|
|
|
|
|
|
|
func (b *Buffer) Bytes() []byte {
|
|
|
|
return b.d
|
|
|
|
}
|