diff --git a/d2common/d2datautils/stream_reader.go b/d2common/d2datautils/stream_reader.go index c66d8212..31e06c96 100644 --- a/d2common/d2datautils/stream_reader.go +++ b/d2common/d2datautils/stream_reader.go @@ -4,12 +4,6 @@ import ( "io" ) -const ( - bytesPerInt16 = 2 - bytesPerInt32 = 4 - bytesPerInt64 = 8 -) - // StreamReader allows you to read data from a byte array in various formats type StreamReader struct { data []byte @@ -26,16 +20,6 @@ func CreateStreamReader(source []byte) *StreamReader { return result } -// GetPosition returns the current stream position -func (v *StreamReader) GetPosition() uint64 { - return v.position -} - -// GetSize returns the total size of the stream in bytes -func (v *StreamReader) GetSize() uint64 { - return uint64(len(v.data)) -} - // GetByte returns a byte from the stream func (v *StreamReader) GetByte() byte { result := v.data[v.position] @@ -44,32 +28,46 @@ func (v *StreamReader) GetByte() byte { return result } -// GetUInt16 returns a uint16 word from the stream -func (v *StreamReader) GetUInt16() uint16 { - var result uint16 - - for offset := uint64(0); offset < bytesPerInt16; offset++ { - shift := uint8(bitsPerByte * offset) - result += uint16(v.data[v.position+offset]) << shift - } - - v.position += bytesPerInt16 - - return result -} - // GetInt16 returns a int16 word from the stream func (v *StreamReader) GetInt16() int16 { - var result int16 + return int16(v.GetUInt16()) +} - for offset := uint64(0); offset < bytesPerInt16; offset++ { - shift := uint8(bitsPerByte * offset) - result += int16(v.data[v.position+offset]) << shift - } +// GetUInt16 returns a uint16 word from the stream +//nolint +func (v *StreamReader) GetUInt16() uint16 { + b := v.ReadBytes(2) + return uint16(b[0]) | uint16(b[1])<<8 +} - v.position += bytesPerInt16 +// GetInt32 returns an int32 dword from the stream +func (v *StreamReader) GetInt32() int32 { + return int32(v.GetUInt32()) +} - return result +// GetUInt32 returns a uint32 dword from the stream +//nolint +func (v *StreamReader) GetUInt32() uint32 { + b := v.ReadBytes(4) + return uint32(b[0]) | uint32(b[1])<<8 | uint32(b[2])<<16 | uint32(b[3])<<24 +} + +// GetInt64 returns a uint64 qword from the stream +func (v *StreamReader) GetInt64() int64 { + return int64(v.GetUInt64()) +} + +// GetUInt64 returns a uint64 qword from the stream +//nolint +func (v *StreamReader) GetUInt64() uint64 { + b := v.ReadBytes(8) + return uint64(b[0]) | uint64(b[1])<<8 | uint64(b[2])<<16 | uint64(b[3])<<24 | + uint64(b[4])<<32 | uint64(b[5])<<40 | uint64(b[6])<<48 | uint64(b[7])<<56 +} + +// GetPosition returns the current stream position +func (v *StreamReader) GetPosition() uint64 { + return v.position } // SetPosition sets the stream position with the given position @@ -77,51 +75,9 @@ func (v *StreamReader) SetPosition(newPosition uint64) { v.position = newPosition } -// GetUInt32 returns a uint32 dword from the stream -func (v *StreamReader) GetUInt32() uint32 { - var result uint32 - - for offset := uint64(0); offset < bytesPerInt32; offset++ { - shift := uint8(bitsPerByte * offset) - result += uint32(v.data[v.position+offset]) << shift - } - - v.position += bytesPerInt32 - - return result -} - -// GetInt32 returns an int32 dword from the stream -func (v *StreamReader) GetInt32() int32 { - var result int32 - - for offset := uint64(0); offset < bytesPerInt32; offset++ { - shift := uint8(bitsPerByte * offset) - result += int32(v.data[v.position+offset]) << shift - } - - v.position += bytesPerInt32 - - return result -} - -// GetUint64 returns a uint64 qword from the stream -func (v *StreamReader) GetUint64() uint64 { - var result uint64 - - for offset := uint64(0); offset < bytesPerInt64; offset++ { - shift := uint8(bitsPerByte * offset) - result += uint64(v.data[v.position+offset]) << shift - } - - v.position += bytesPerInt64 - - return result -} - -// GetInt64 returns a uint64 qword from the stream -func (v *StreamReader) GetInt64() int64 { - return int64(v.GetUint64()) +// GetSize returns the total size of the stream in bytes +func (v *StreamReader) GetSize() uint64 { + return uint64(len(v.data)) } // ReadByte implements io.ByteReader diff --git a/d2common/d2datautils/stream_writer.go b/d2common/d2datautils/stream_writer.go index 10870a73..849cbdb2 100644 --- a/d2common/d2datautils/stream_writer.go +++ b/d2common/d2datautils/stream_writer.go @@ -2,10 +2,6 @@ package d2datautils import "bytes" -const ( - byteMask = 0xFF -) - // StreamWriter allows you to create a byte array by streaming in writes of various sizes type StreamWriter struct { data *bytes.Buffer @@ -20,41 +16,40 @@ func CreateStreamWriter() *StreamWriter { return result } +// GetBytes returns the the byte slice of the underlying data +func (v *StreamWriter) GetBytes() []byte { + return v.data.Bytes() +} + // PushByte writes a byte to the stream func (v *StreamWriter) PushByte(val byte) { v.data.WriteByte(val) } -// PushUint16 writes an uint16 word to the stream -func (v *StreamWriter) PushUint16(val uint16) { - for count := 0; count < bytesPerInt16; count++ { - shift := count * bitsPerByte - v.data.WriteByte(byte(val>>shift) & byteMask) - } -} - // PushInt16 writes a int16 word to the stream func (v *StreamWriter) PushInt16(val int16) { - for count := 0; count < bytesPerInt16; count++ { - shift := count * bitsPerByte - v.data.WriteByte(byte(val>>shift) & byteMask) - } + v.PushUint16(uint16(val)) +} + +// PushUint16 writes an uint16 word to the stream +//nolint +func (v *StreamWriter) PushUint16(val uint16) { + v.data.WriteByte(byte(val)) + v.data.WriteByte(byte(val >> 8)) +} + +// PushInt32 writes a int32 dword to the stream +func (v *StreamWriter) PushInt32(val int32) { + v.PushUint32(uint32(val)) } // PushUint32 writes a uint32 dword to the stream +//nolint func (v *StreamWriter) PushUint32(val uint32) { - for count := 0; count < bytesPerInt32; count++ { - shift := count * bitsPerByte - v.data.WriteByte(byte(val>>shift) & byteMask) - } -} - -// PushUint64 writes a uint64 qword to the stream -func (v *StreamWriter) PushUint64(val uint64) { - for count := 0; count < bytesPerInt64; count++ { - shift := count * bitsPerByte - v.data.WriteByte(byte(val>>shift) & byteMask) - } + v.data.WriteByte(byte(val)) + v.data.WriteByte(byte(val >> 8)) + v.data.WriteByte(byte(val >> 16)) + v.data.WriteByte(byte(val >> 24)) } // PushInt64 writes a uint64 qword to the stream @@ -62,7 +57,15 @@ func (v *StreamWriter) PushInt64(val int64) { v.PushUint64(uint64(val)) } -// GetBytes returns the the byte slice of the underlying data -func (v *StreamWriter) GetBytes() []byte { - return v.data.Bytes() +// PushUint64 writes a uint64 qword to the stream +//nolint +func (v *StreamWriter) PushUint64(val uint64) { + v.data.WriteByte(byte(val)) + v.data.WriteByte(byte(val >> 8)) + v.data.WriteByte(byte(val >> 16)) + v.data.WriteByte(byte(val >> 24)) + v.data.WriteByte(byte(val >> 32)) + v.data.WriteByte(byte(val >> 40)) + v.data.WriteByte(byte(val >> 48)) + v.data.WriteByte(byte(val >> 56)) }