chore: better handwritten addons parsing

This commit is contained in:
wwqgtxx 2025-09-09 15:16:57 +08:00
parent 1d09ed82f1
commit 318b3524c3

View File

@ -11,35 +11,48 @@ func ReadAddons(data []byte) (*Addons, error) {
reader := bytes.NewReader(data)
var addons Addons
for reader.Len() > 0 {
protoHeader, err := reader.ReadByte()
tag, err := binary.ReadUvarint(reader)
if err != nil {
return nil, err
}
switch protoHeader {
case (1 << 3) | 2:
flowLen, err := binary.ReadUvarint(reader)
number, typ := int32(tag>>3), int8(tag&7)
switch typ {
case 0: // VARINT
_, err = binary.ReadUvarint(reader)
if err != nil {
return nil, err
}
flowBytes := make([]byte, flowLen)
_, err = io.ReadFull(reader, flowBytes)
case 5: // I32
var i32 [4]byte
_, err = io.ReadFull(reader, i32[:])
if err != nil {
return nil, err
}
addons.Flow = string(flowBytes)
case (2 << 3) | 2:
seedLen, err := binary.ReadUvarint(reader)
case 1: // I64
var i64 [8]byte
_, err = io.ReadFull(reader, i64[:])
if err != nil {
return nil, err
}
seedBytes := make([]byte, seedLen)
_, err = io.ReadFull(reader, seedBytes)
case 2: // LEN
var bytesLen uint64
bytesLen, err = binary.ReadUvarint(reader)
if err != nil {
return nil, err
}
addons.Seed = seedBytes
default:
return nil, fmt.Errorf("unknown protobuf message header: %v", protoHeader)
bytesData := make([]byte, bytesLen)
_, err = io.ReadFull(reader, bytesData)
if err != nil {
return nil, err
}
switch number {
case 1:
addons.Flow = string(bytesData)
case 2:
addons.Seed = bytesData
}
default: // group (3,4) has been deprecated we unneeded support
return nil, fmt.Errorf("unknown protobuf message tag: %v", tag)
}
}
return &addons, nil
@ -48,14 +61,22 @@ func ReadAddons(data []byte) (*Addons, error) {
func WriteAddons(addons *Addons) []byte {
var writer bytes.Buffer
if len(addons.Flow) > 0 {
writer.WriteByte((1 << 3) | 2)
writer.Write(binary.AppendUvarint(nil, uint64(len(addons.Flow))))
WriteUvarint(&writer, (1<<3)|2) // (field << 3) bit-or wire_type encoded as uint32 varint
WriteUvarint(&writer, uint64(len(addons.Flow)))
writer.WriteString(addons.Flow)
}
if len(addons.Seed) > 0 {
writer.WriteByte((2 << 3) | 2)
writer.Write(binary.AppendUvarint(nil, uint64(len(addons.Seed))))
WriteUvarint(&writer, (2<<3)|2) // (field << 3) bit-or wire_type encoded as uint32 varint
WriteUvarint(&writer, uint64(len(addons.Seed)))
writer.Write(addons.Seed)
}
return writer.Bytes()
}
func WriteUvarint(writer *bytes.Buffer, x uint64) {
for x >= 0x80 {
writer.WriteByte(byte(x) | 0x80)
x >>= 7
}
writer.WriteByte(byte(x))
}