2020-09-08 15:58:35 -04:00
|
|
|
package d2datautils
|
2020-01-26 00:39:13 -05:00
|
|
|
|
2020-06-22 18:56:20 -04:00
|
|
|
import "bytes"
|
|
|
|
|
2020-01-26 00:39:13 -05:00
|
|
|
// StreamWriter allows you to create a byte array by streaming in writes of various sizes
|
|
|
|
type StreamWriter struct {
|
2021-02-05 08:45:22 -05:00
|
|
|
data *bytes.Buffer
|
|
|
|
bitOffset int
|
|
|
|
bitCache byte
|
2020-01-26 00:39:13 -05:00
|
|
|
}
|
|
|
|
|
|
|
|
// CreateStreamWriter creates a new StreamWriter instance
|
|
|
|
func CreateStreamWriter() *StreamWriter {
|
|
|
|
result := &StreamWriter{
|
2020-06-22 18:56:20 -04:00
|
|
|
data: new(bytes.Buffer),
|
2020-01-26 00:39:13 -05:00
|
|
|
}
|
2020-07-08 09:16:56 -04:00
|
|
|
|
2020-01-26 00:39:13 -05:00
|
|
|
return result
|
|
|
|
}
|
|
|
|
|
2020-12-23 04:39:58 -05:00
|
|
|
// GetBytes returns the the byte slice of the underlying data
|
|
|
|
func (v *StreamWriter) GetBytes() []byte {
|
|
|
|
return v.data.Bytes()
|
|
|
|
}
|
|
|
|
|
2021-02-01 05:20:44 -05:00
|
|
|
// PushBytes writes a bytes to the stream
|
2021-02-01 05:15:42 -05:00
|
|
|
func (v *StreamWriter) PushBytes(b ...byte) {
|
2021-01-31 12:57:57 -05:00
|
|
|
for _, i := range b {
|
2021-02-01 05:20:44 -05:00
|
|
|
v.data.WriteByte(i)
|
2021-01-31 12:57:57 -05:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2021-02-05 08:45:22 -05:00
|
|
|
func (v *StreamWriter) PushBit(b bool) {
|
|
|
|
if b {
|
|
|
|
v.bitCache |= (1 << v.bitOffset)
|
|
|
|
}
|
|
|
|
v.bitOffset++
|
|
|
|
|
|
|
|
if v.bitOffset != bitsPerByte {
|
|
|
|
return
|
|
|
|
}
|
|
|
|
|
|
|
|
v.PushBytes(v.bitCache)
|
|
|
|
v.bitCache = 0
|
|
|
|
v.bitOffset = 0
|
|
|
|
}
|
|
|
|
|
|
|
|
func (v *StreamWriter) PushBits(b byte, bits int) {
|
|
|
|
val := b
|
|
|
|
for i := 0; i < bits; i++ {
|
|
|
|
if val&1 == 1 {
|
|
|
|
v.PushBit(true)
|
|
|
|
} else {
|
|
|
|
v.PushBit(false)
|
|
|
|
}
|
|
|
|
|
|
|
|
val >>= 1
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
func (v *StreamWriter) PushBits16(b uint16, bits int) {
|
|
|
|
val := b
|
|
|
|
for i := 0; i < bits; i++ {
|
|
|
|
if val&1 == 1 {
|
|
|
|
v.PushBit(true)
|
|
|
|
} else {
|
|
|
|
v.PushBit(false)
|
|
|
|
}
|
|
|
|
val >>= 1
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
func (v *StreamWriter) PushBits32(b uint32, bits int) {
|
|
|
|
val := b
|
|
|
|
for i := 0; i < bits; i++ {
|
|
|
|
if val&1 == 1 {
|
|
|
|
v.PushBit(true)
|
|
|
|
} else {
|
|
|
|
v.PushBit(false)
|
|
|
|
}
|
|
|
|
val >>= 1
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
func (v *StreamWriter) ForcePushBits() {
|
|
|
|
for i := 0; i < bitsPerByte-v.bitOffset; i++ {
|
|
|
|
v.PushBit(0 != 0)
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2020-12-23 04:39:58 -05:00
|
|
|
// PushInt16 writes a int16 word to the stream
|
|
|
|
func (v *StreamWriter) PushInt16(val int16) {
|
|
|
|
v.PushUint16(uint16(val))
|
|
|
|
}
|
|
|
|
|
2020-01-26 00:39:13 -05:00
|
|
|
// PushUint16 writes an uint16 word to the stream
|
2020-12-23 04:39:58 -05:00
|
|
|
//nolint
|
2020-01-26 00:39:13 -05:00
|
|
|
func (v *StreamWriter) PushUint16(val uint16) {
|
2020-12-23 04:39:58 -05:00
|
|
|
v.data.WriteByte(byte(val))
|
|
|
|
v.data.WriteByte(byte(val >> 8))
|
2020-01-26 00:39:13 -05:00
|
|
|
}
|
|
|
|
|
2020-12-23 04:39:58 -05:00
|
|
|
// PushInt32 writes a int32 dword to the stream
|
|
|
|
func (v *StreamWriter) PushInt32(val int32) {
|
|
|
|
v.PushUint32(uint32(val))
|
2020-01-26 00:39:13 -05:00
|
|
|
}
|
|
|
|
|
|
|
|
// PushUint32 writes a uint32 dword to the stream
|
2020-12-23 04:39:58 -05:00
|
|
|
//nolint
|
2020-01-26 00:39:13 -05:00
|
|
|
func (v *StreamWriter) PushUint32(val uint32) {
|
2020-12-23 04:39:58 -05:00
|
|
|
v.data.WriteByte(byte(val))
|
|
|
|
v.data.WriteByte(byte(val >> 8))
|
|
|
|
v.data.WriteByte(byte(val >> 16))
|
|
|
|
v.data.WriteByte(byte(val >> 24))
|
2020-01-26 00:39:13 -05:00
|
|
|
}
|
|
|
|
|
|
|
|
// PushInt64 writes a uint64 qword to the stream
|
|
|
|
func (v *StreamWriter) PushInt64(val int64) {
|
2020-06-22 18:56:20 -04:00
|
|
|
v.PushUint64(uint64(val))
|
2020-01-26 00:39:13 -05:00
|
|
|
}
|
|
|
|
|
2020-12-23 04:39:58 -05:00
|
|
|
// 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))
|
2020-01-26 00:39:13 -05:00
|
|
|
}
|