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