nex-go/nex_stream.go
2018-10-02 17:10:59 -04:00

201 lines
4.3 KiB
Go

package nex
import (
"bytes"
"encoding/binary"
)
// InputStream represents a readable NEX stream
type InputStream struct {
data []byte
pos int
}
// OutputStream represents a writeable NEX stream
type OutputStream struct {
data []byte
}
// NewInputStream returns a new InputStream
func NewInputStream(data []byte) InputStream {
return InputStream{
data: data,
pos: 0,
}
}
// NewOutputStream returns a new OutputStream
func NewOutputStream() OutputStream {
return OutputStream{
data: []byte{},
}
}
/*
InputStream methods
*/
// Seek sets the stream pointer to the given position
func (stream *InputStream) Seek(pos int) {
stream.pos = pos
}
// Skip skips the given number of bytes
func (stream *InputStream) Skip(len int) {
stream.pos += len
}
// Read returns a slice of the given length starting from the pointer position
func (stream *InputStream) Read(len int) []byte {
data := stream.data[stream.pos : stream.pos+len]
stream.pos += len
return data
}
// Bytes reads the given number of bytes
func (stream *InputStream) Bytes(len int) []byte {
return stream.Read(len)
}
// Byte returns a single byte
func (stream *InputStream) Byte() []byte {
return stream.Read(1)
}
// UInt8 reads an unsigned 1 byte integer
func (stream *InputStream) UInt8() (ret uint8) {
data := stream.Byte()
buf := bytes.NewBuffer(data)
binary.Read(buf, binary.LittleEndian, &ret)
return
}
// UInt16LE reads an unsigned 2 byte integer in little endian
func (stream *InputStream) UInt16LE() (ret uint16) {
data := stream.Bytes(2)
buf := bytes.NewBuffer(data)
binary.Read(buf, binary.LittleEndian, &ret)
return
}
// UInt32LE reads an unsigned 4 byte integer in little endian
func (stream *InputStream) UInt32LE() (ret uint32) {
data := stream.Bytes(4)
buf := bytes.NewBuffer(data)
binary.Read(buf, binary.LittleEndian, &ret)
return
}
// UInt64LE reads an unsigned 8 byte integer in little endian
func (stream *InputStream) UInt64LE() (ret uint64) {
data := stream.Bytes(8)
buf := bytes.NewBuffer(data)
binary.Read(buf, binary.LittleEndian, &ret)
return
}
// String reads a NEX string
func (stream *InputStream) String() string {
length := stream.UInt16LE()
str := stream.Bytes(int(length))
return string(str[:])[:length-1]
}
// Buffer reads a NEX buffer
func (stream *InputStream) Buffer() []byte {
return stream.Bytes(int(stream.UInt32LE()))
}
// QBuffer reads a NEX qBuffer
func (stream *InputStream) QBuffer() []byte {
return stream.Bytes(int(stream.UInt16LE()))
}
// DataHolder returns a NEX DataHolder
func (stream *InputStream) DataHolder() DataHolder {
data := DataHolder{
Name: stream.String(),
Length: stream.UInt32LE(),
DataLength: stream.UInt32LE(),
}
data.Data = stream.Bytes(int(data.DataLength))
return data
}
/*
OutputStream methods
*/
// Bytes returns the streams raw bytes
func (stream *OutputStream) Bytes() []byte {
return stream.data
}
// Write directly writes to the buffer
func (stream *OutputStream) Write(data []byte) {
stream.data = append(stream.data, data...)
}
// UInt8 writes a single unsigned byte to to the buffer
func (stream *OutputStream) UInt8(val uint8) {
stream.Write([]byte{val})
}
// UInt16LE writes a 2 byte unsigned integer in little endian
func (stream *OutputStream) UInt16LE(val uint16) {
data := make([]byte, 2)
binary.LittleEndian.PutUint16(data, val)
stream.Write(data)
}
// UInt32LE writes a 4 byte unsigned integer in little endian
func (stream *OutputStream) UInt32LE(val uint32) {
data := make([]byte, 4)
binary.LittleEndian.PutUint32(data, val)
stream.Write(data)
}
// UInt64LE writes a 8 byte unsigned integer in little endian
func (stream *OutputStream) UInt64LE(val uint64) {
data := make([]byte, 8)
binary.LittleEndian.PutUint64(data, val)
stream.Write(data)
}
// String writes a NEX string
func (stream *OutputStream) String(str string) {
if len(str) <= 0 {
stream.UInt16LE(uint16(0))
} else {
str = str + "\000"
length := len(str)
stream.UInt16LE(uint16(length))
data := []byte(str)
stream.Write(data)
}
}
// Buffer writes a NEX buffer
func (stream *OutputStream) Buffer(buffer []byte) {
length := len(buffer)
stream.UInt32LE(uint32(length))
stream.Write(buffer)
}
// QBuffer writes a NEX qBuffer
func (stream *OutputStream) QBuffer(buffer []byte) {
length := len(buffer)
stream.UInt16LE(uint16(length))
stream.Write(buffer)
}