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 }