151 lines
3.6 KiB
Go
151 lines
3.6 KiB
Go
package types
|
|
|
|
import (
|
|
"encoding/binary"
|
|
"io"
|
|
)
|
|
|
|
// EQ2String8 represents a string with an 8-bit length prefix
|
|
type EQ2String8 string
|
|
|
|
// Serialize writes the string with 8-bit length prefix
|
|
func (s EQ2String8) Serialize(w io.Writer) error {
|
|
if len(s) > 255 {
|
|
return io.ErrShortWrite
|
|
}
|
|
|
|
// Write length byte
|
|
if err := binary.Write(w, binary.LittleEndian, uint8(len(s))); err != nil {
|
|
return err
|
|
}
|
|
|
|
// Write string data
|
|
_, err := w.Write([]byte(s))
|
|
return err
|
|
}
|
|
|
|
// SerializeToBytes writes the string to a byte slice at the given offset
|
|
func (s EQ2String8) SerializeToBytes(dest []byte, offset *uint32) {
|
|
dest[*offset] = uint8(len(s))
|
|
*offset++
|
|
copy(dest[*offset:], []byte(s))
|
|
*offset += uint32(len(s))
|
|
}
|
|
|
|
// Size returns the serialized size (1 byte length + string data)
|
|
func (s EQ2String8) Size() uint32 {
|
|
return 1 + uint32(len(s))
|
|
}
|
|
|
|
// Deserialize reads a string with 8-bit length prefix
|
|
func (s *EQ2String8) Deserialize(r io.Reader) error {
|
|
var length uint8
|
|
if err := binary.Read(r, binary.LittleEndian, &length); err != nil {
|
|
return err
|
|
}
|
|
|
|
data := make([]byte, length)
|
|
if _, err := io.ReadFull(r, data); err != nil {
|
|
return err
|
|
}
|
|
|
|
*s = EQ2String8(data)
|
|
return nil
|
|
}
|
|
|
|
// EQ2String16 represents a string with a 16-bit length prefix
|
|
type EQ2String16 string
|
|
|
|
// Serialize writes the string with 16-bit length prefix
|
|
func (s EQ2String16) Serialize(w io.Writer) error {
|
|
if len(s) > 65535 {
|
|
return io.ErrShortWrite
|
|
}
|
|
|
|
// Write length as uint16
|
|
if err := binary.Write(w, binary.LittleEndian, uint16(len(s))); err != nil {
|
|
return err
|
|
}
|
|
|
|
// Write string data
|
|
_, err := w.Write([]byte(s))
|
|
return err
|
|
}
|
|
|
|
// SerializeToBytes writes the string to a byte slice at the given offset
|
|
func (s EQ2String16) SerializeToBytes(dest []byte, offset *uint32) {
|
|
binary.LittleEndian.PutUint16(dest[*offset:], uint16(len(s)))
|
|
*offset += 2
|
|
copy(dest[*offset:], []byte(s))
|
|
*offset += uint32(len(s))
|
|
}
|
|
|
|
// Size returns the serialized size (2 bytes length + string data)
|
|
func (s EQ2String16) Size() uint32 {
|
|
return 2 + uint32(len(s))
|
|
}
|
|
|
|
// Deserialize reads a string with 16-bit length prefix
|
|
func (s *EQ2String16) Deserialize(r io.Reader) error {
|
|
var length uint16
|
|
if err := binary.Read(r, binary.LittleEndian, &length); err != nil {
|
|
return err
|
|
}
|
|
|
|
data := make([]byte, length)
|
|
if _, err := io.ReadFull(r, data); err != nil {
|
|
return err
|
|
}
|
|
|
|
*s = EQ2String16(data)
|
|
return nil
|
|
}
|
|
|
|
// EQ2String32 represents a string with a 32-bit length prefix
|
|
type EQ2String32 string
|
|
|
|
// Serialize writes the string with 32-bit length prefix
|
|
func (s EQ2String32) Serialize(w io.Writer) error {
|
|
// Write length as uint32
|
|
if err := binary.Write(w, binary.LittleEndian, uint32(len(s))); err != nil {
|
|
return err
|
|
}
|
|
|
|
// Write string data
|
|
_, err := w.Write([]byte(s))
|
|
return err
|
|
}
|
|
|
|
// SerializeToBytes writes the string to a byte slice at the given offset
|
|
func (s EQ2String32) SerializeToBytes(dest []byte, offset *uint32) {
|
|
binary.LittleEndian.PutUint32(dest[*offset:], uint32(len(s)))
|
|
*offset += 4
|
|
copy(dest[*offset:], []byte(s))
|
|
*offset += uint32(len(s))
|
|
}
|
|
|
|
// Size returns the serialized size (4 bytes length + string data)
|
|
func (s EQ2String32) Size() uint32 {
|
|
return 4 + uint32(len(s))
|
|
}
|
|
|
|
// Deserialize reads a string with 32-bit length prefix
|
|
func (s *EQ2String32) Deserialize(r io.Reader) error {
|
|
var length uint32
|
|
if err := binary.Read(r, binary.LittleEndian, &length); err != nil {
|
|
return err
|
|
}
|
|
|
|
// Sanity check to prevent huge allocations
|
|
if length > 1024*1024 { // 1MB limit
|
|
return io.ErrUnexpectedEOF
|
|
}
|
|
|
|
data := make([]byte, length)
|
|
if _, err := io.ReadFull(r, data); err != nil {
|
|
return err
|
|
}
|
|
|
|
*s = EQ2String32(data)
|
|
return nil
|
|
} |