mirror of
https://github.com/PretendoNetwork/nex-go.git
synced 2025-04-02 11:02:14 -04:00
This requires a lot of refactor but it brings back the option of getting events when a connection disconnects.
177 lines
4.6 KiB
Go
177 lines
4.6 KiB
Go
package nex
|
|
|
|
import (
|
|
"errors"
|
|
|
|
crunch "github.com/superwhiskers/crunch/v3"
|
|
)
|
|
|
|
// ByteStreamIn is an input stream abstraction of github.com/superwhiskers/crunch/v3 with nex type support
|
|
type ByteStreamIn struct {
|
|
*crunch.Buffer
|
|
LibraryVersions *LibraryVersions
|
|
Settings *ByteStreamSettings
|
|
}
|
|
|
|
// StringLengthSize returns the expected size of String length fields
|
|
func (bsi *ByteStreamIn) StringLengthSize() int {
|
|
size := 2
|
|
|
|
if bsi.Settings != nil {
|
|
size = bsi.Settings.StringLengthSize
|
|
}
|
|
|
|
return size
|
|
}
|
|
|
|
// PIDSize returns the size of PID types
|
|
func (bsi *ByteStreamIn) PIDSize() int {
|
|
size := 4
|
|
|
|
if bsi.Settings != nil {
|
|
size = bsi.Settings.PIDSize
|
|
}
|
|
|
|
return size
|
|
}
|
|
|
|
// UseStructureHeader determines if Structure headers should be used
|
|
func (bsi *ByteStreamIn) UseStructureHeader() bool {
|
|
useStructureHeader := false
|
|
|
|
if bsi.Settings != nil {
|
|
useStructureHeader = bsi.Settings.UseStructureHeader
|
|
}
|
|
|
|
return useStructureHeader
|
|
}
|
|
|
|
// Remaining returns the amount of data left to be read in the buffer
|
|
func (bsi *ByteStreamIn) Remaining() uint64 {
|
|
return uint64(len(bsi.Bytes()[bsi.ByteOffset():]))
|
|
}
|
|
|
|
// ReadRemaining reads all the data left to be read in the buffer
|
|
func (bsi *ByteStreamIn) ReadRemaining() []byte {
|
|
// * Can safely ignore this error, since bsi.Remaining() will never be less than itself
|
|
remaining, _ := bsi.Read(uint64(bsi.Remaining()))
|
|
|
|
return remaining
|
|
}
|
|
|
|
// Read reads the specified number of bytes. Returns an error if OOB
|
|
func (bsi *ByteStreamIn) Read(length uint64) ([]byte, error) {
|
|
if bsi.Remaining() < length {
|
|
return []byte{}, errors.New("Read is OOB")
|
|
}
|
|
|
|
return bsi.ReadBytesNext(int64(length)), nil
|
|
}
|
|
|
|
// ReadPrimitiveUInt8 reads a uint8
|
|
func (bsi *ByteStreamIn) ReadPrimitiveUInt8() (uint8, error) {
|
|
if bsi.Remaining() < 1 {
|
|
return 0, errors.New("Not enough data to read uint8")
|
|
}
|
|
|
|
return uint8(bsi.ReadByteNext()), nil
|
|
}
|
|
|
|
// ReadPrimitiveUInt16LE reads a Little-Endian encoded uint16
|
|
func (bsi *ByteStreamIn) ReadPrimitiveUInt16LE() (uint16, error) {
|
|
if bsi.Remaining() < 2 {
|
|
return 0, errors.New("Not enough data to read uint16")
|
|
}
|
|
|
|
return bsi.ReadU16LENext(1)[0], nil
|
|
}
|
|
|
|
// ReadPrimitiveUInt32LE reads a Little-Endian encoded uint32
|
|
func (bsi *ByteStreamIn) ReadPrimitiveUInt32LE() (uint32, error) {
|
|
if bsi.Remaining() < 4 {
|
|
return 0, errors.New("Not enough data to read uint32")
|
|
}
|
|
|
|
return bsi.ReadU32LENext(1)[0], nil
|
|
}
|
|
|
|
// ReadPrimitiveUInt64LE reads a Little-Endian encoded uint64
|
|
func (bsi *ByteStreamIn) ReadPrimitiveUInt64LE() (uint64, error) {
|
|
if bsi.Remaining() < 8 {
|
|
return 0, errors.New("Not enough data to read uint64")
|
|
}
|
|
|
|
return bsi.ReadU64LENext(1)[0], nil
|
|
}
|
|
|
|
// ReadPrimitiveInt8 reads a uint8
|
|
func (bsi *ByteStreamIn) ReadPrimitiveInt8() (int8, error) {
|
|
if bsi.Remaining() < 1 {
|
|
return 0, errors.New("Not enough data to read int8")
|
|
}
|
|
|
|
return int8(bsi.ReadByteNext()), nil
|
|
}
|
|
|
|
// ReadPrimitiveInt16LE reads a Little-Endian encoded int16
|
|
func (bsi *ByteStreamIn) ReadPrimitiveInt16LE() (int16, error) {
|
|
if bsi.Remaining() < 2 {
|
|
return 0, errors.New("Not enough data to read int16")
|
|
}
|
|
|
|
return int16(bsi.ReadU16LENext(1)[0]), nil
|
|
}
|
|
|
|
// ReadPrimitiveInt32LE reads a Little-Endian encoded int32
|
|
func (bsi *ByteStreamIn) ReadPrimitiveInt32LE() (int32, error) {
|
|
if bsi.Remaining() < 4 {
|
|
return 0, errors.New("Not enough data to read int32")
|
|
}
|
|
|
|
return int32(bsi.ReadU32LENext(1)[0]), nil
|
|
}
|
|
|
|
// ReadPrimitiveInt64LE reads a Little-Endian encoded int64
|
|
func (bsi *ByteStreamIn) ReadPrimitiveInt64LE() (int64, error) {
|
|
if bsi.Remaining() < 8 {
|
|
return 0, errors.New("Not enough data to read int64")
|
|
}
|
|
|
|
return int64(bsi.ReadU64LENext(1)[0]), nil
|
|
}
|
|
|
|
// ReadPrimitiveFloat32LE reads a Little-Endian encoded float32
|
|
func (bsi *ByteStreamIn) ReadPrimitiveFloat32LE() (float32, error) {
|
|
if bsi.Remaining() < 4 {
|
|
return 0, errors.New("Not enough data to read float32")
|
|
}
|
|
|
|
return bsi.ReadF32LENext(1)[0], nil
|
|
}
|
|
|
|
// ReadPrimitiveFloat64LE reads a Little-Endian encoded float64
|
|
func (bsi *ByteStreamIn) ReadPrimitiveFloat64LE() (float64, error) {
|
|
if bsi.Remaining() < 8 {
|
|
return 0, errors.New("Not enough data to read float64")
|
|
}
|
|
|
|
return bsi.ReadF64LENext(1)[0], nil
|
|
}
|
|
|
|
// ReadPrimitiveBool reads a bool
|
|
func (bsi *ByteStreamIn) ReadPrimitiveBool() (bool, error) {
|
|
if bsi.Remaining() < 1 {
|
|
return false, errors.New("Not enough data to read bool")
|
|
}
|
|
|
|
return bsi.ReadByteNext() == 1, nil
|
|
}
|
|
|
|
// NewByteStreamIn returns a new NEX input byte stream
|
|
func NewByteStreamIn(data []byte, libraryVersions *LibraryVersions, settings *ByteStreamSettings) *ByteStreamIn {
|
|
return &ByteStreamIn{
|
|
Buffer: crunch.NewBuffer(data),
|
|
LibraryVersions: libraryVersions,
|
|
Settings: settings,
|
|
}
|
|
}
|