package taf import ( "bytes" "encoding/binary" "errors" "fmt" "io" "math" ) // Reader 负责从 TAF/JCE 字节流中按 tag 顺序读取字段。 type Reader struct { buf *bytes.Reader } func NewReader(data []byte) *Reader { return &Reader{buf: bytes.NewReader(data)} } func (r *Reader) Position() int64 { pos, _ := r.buf.Seek(0, io.SeekCurrent) return pos } func (r *Reader) Seek(pos int64) error { _, err := r.buf.Seek(pos, io.SeekStart) return err } func (r *Reader) ReadHead() (int, Type, error) { b, err := r.buf.ReadByte() if err != nil { return 0, 0, err } tag := int((b >> 4) & 0x0f) typ := Type(b & 0x0f) if tag == 15 { ext, err := r.buf.ReadByte() if err != nil { return 0, 0, err } tag = int(ext) } return tag, typ, nil } func (r *Reader) PeekHead() (int, Type, error) { pos := r.Position() tag, typ, err := r.ReadHead() _ = r.Seek(pos) return tag, typ, err } func (r *Reader) ReadIntValue(typ Type) (int64, error) { switch typ { case TypeZero: return 0, nil case TypeInt8: b, err := r.buf.ReadByte() return int64(int8(b)), err case TypeInt16: var b [2]byte if _, err := io.ReadFull(r.buf, b[:]); err != nil { return 0, err } return int64(int16(binary.BigEndian.Uint16(b[:]))), nil case TypeInt32: var b [4]byte if _, err := io.ReadFull(r.buf, b[:]); err != nil { return 0, err } return int64(int32(binary.BigEndian.Uint32(b[:]))), nil case TypeInt64: var b [8]byte if _, err := io.ReadFull(r.buf, b[:]); err != nil { return 0, err } return int64(binary.BigEndian.Uint64(b[:])), nil default: return 0, fmt.Errorf("taf: 期望整数类型,实际 0x%02x", byte(typ)) } } func (r *Reader) ReadStringValue(typ Type) (string, error) { var n uint32 switch typ { case TypeString1: b, err := r.buf.ReadByte() if err != nil { return "", err } n = uint32(b) case TypeString4: var b [4]byte if _, err := io.ReadFull(r.buf, b[:]); err != nil { return "", err } n = binary.BigEndian.Uint32(b[:]) default: return "", fmt.Errorf("taf: 期望字符串类型,实际 0x%02x", byte(typ)) } raw := make([]byte, n) if _, err := io.ReadFull(r.buf, raw); err != nil { return "", err } return string(raw), nil } func (r *Reader) ReadBytesValue(typ Type) ([]byte, error) { if typ != TypeSimpleList { return nil, fmt.Errorf("taf: 期望 bytes,实际 0x%02x", byte(typ)) } _, itemType, err := r.ReadHead() if err != nil { return nil, err } if itemType != TypeInt8 { return nil, fmt.Errorf("taf: bytes 元素类型不是 int8: 0x%02x", byte(itemType)) } n, err := r.readLength() if err != nil { return nil, err } if n < 0 || n > math.MaxInt32 { return nil, fmt.Errorf("taf: bytes 长度异常: %d", n) } raw := make([]byte, int(n)) _, err = io.ReadFull(r.buf, raw) return raw, err } func (r *Reader) Skip(typ Type) error { switch typ { case TypeZero: return nil case TypeInt8: _, err := r.buf.ReadByte() return err case TypeInt16: _, err := r.buf.Seek(2, io.SeekCurrent) return err case TypeInt32, TypeFloat: _, err := r.buf.Seek(4, io.SeekCurrent) return err case TypeInt64, TypeDouble: _, err := r.buf.Seek(8, io.SeekCurrent) return err case TypeString1: b, err := r.buf.ReadByte() if err != nil { return err } _, err = r.buf.Seek(int64(b), io.SeekCurrent) return err case TypeString4: var b [4]byte if _, err := io.ReadFull(r.buf, b[:]); err != nil { return err } _, err := r.buf.Seek(int64(binary.BigEndian.Uint32(b[:])), io.SeekCurrent) return err case TypeMap: n, err := r.readLength() if err != nil { return err } for i := int64(0); i < n; i++ { if _, kt, err := r.ReadHead(); err != nil { return err } else if err := r.Skip(kt); err != nil { return err } if _, vt, err := r.ReadHead(); err != nil { return err } else if err := r.Skip(vt); err != nil { return err } } return nil case TypeList: n, err := r.readLength() if err != nil { return err } for i := int64(0); i < n; i++ { if _, it, err := r.ReadHead(); err != nil { return err } else if err := r.Skip(it); err != nil { return err } } return nil case TypeStructBegin: return r.SkipToStructEnd() case TypeStructEnd: return nil case TypeSimpleList: _, itemType, err := r.ReadHead() if err != nil { return err } if itemType != TypeInt8 { return fmt.Errorf("taf: simple list 元素类型异常: 0x%02x", byte(itemType)) } n, err := r.readLength() if err != nil { return err } _, err = r.buf.Seek(n, io.SeekCurrent) return err default: return fmt.Errorf("taf: 未知字段类型 0x%02x", byte(typ)) } } func (r *Reader) readLength() (int64, error) { _, typ, err := r.ReadHead() if err != nil { return 0, err } return r.ReadIntValue(typ) } func (r *Reader) findTag(target int, required bool) (Type, bool, error) { for { pos := r.Position() tag, typ, err := r.ReadHead() if err != nil { if errors.Is(err, io.EOF) && !required { return 0, false, nil } return 0, false, err } if typ == TypeStructEnd { _ = r.Seek(pos) if required { return 0, false, fmt.Errorf("taf: 未找到 tag=%d,已到结构尾", target) } return 0, false, nil } if tag == target { return typ, true, nil } if tag > target { _ = r.Seek(pos) if required { return 0, false, fmt.Errorf("taf: 未找到 tag=%d,遇到 tag=%d", target, tag) } return 0, false, nil } if err := r.Skip(typ); err != nil { return 0, false, err } } } func (r *Reader) ReadInt64(tag int, required bool, def int64) (int64, error) { typ, ok, err := r.findTag(tag, required) if err != nil || !ok { return def, err } return r.ReadIntValue(typ) } func (r *Reader) ReadInt32(tag int, required bool, def int32) (int32, error) { value, err := r.ReadInt64(tag, required, int64(def)) return int32(value), err } func (r *Reader) ReadString(tag int, required bool, def string) (string, error) { typ, ok, err := r.findTag(tag, required) if err != nil || !ok { return def, err } return r.ReadStringValue(typ) } func (r *Reader) ReadBytes(tag int, required bool, def []byte) ([]byte, error) { typ, ok, err := r.findTag(tag, required) if err != nil || !ok { return def, err } return r.ReadBytesValue(typ) } func (r *Reader) ReadMapStringString(tag int, required bool) (map[string]string, error) { typ, ok, err := r.findTag(tag, required) if err != nil || !ok { return map[string]string{}, err } if typ != TypeMap { return nil, fmt.Errorf("taf: tag=%d 不是 map: 0x%02x", tag, byte(typ)) } n, err := r.readLength() if err != nil { return nil, err } out := make(map[string]string, n) for i := int64(0); i < n; i++ { _, kt, err := r.ReadHead() if err != nil { return nil, err } k, err := r.ReadStringValue(kt) if err != nil { return nil, err } _, vt, err := r.ReadHead() if err != nil { return nil, err } v, err := r.ReadStringValue(vt) if err != nil { return nil, err } out[k] = v } return out, nil } // ReadMapStringInt64 读取 map,供 launch.pingSignal 这类响应使用。 func (r *Reader) ReadMapStringInt64(tag int, required bool) (map[string]int64, error) { typ, ok, err := r.findTag(tag, required) if err != nil || !ok { return map[string]int64{}, err } if typ != TypeMap { return nil, fmt.Errorf("taf: tag=%d 不是 map: 0x%02x", tag, byte(typ)) } n, err := r.readLength() if err != nil { return nil, err } out := make(map[string]int64, n) for i := int64(0); i < n; i++ { _, kt, err := r.ReadHead() if err != nil { return nil, err } k, err := r.ReadStringValue(kt) if err != nil { return nil, err } _, vt, err := r.ReadHead() if err != nil { return nil, err } v, err := r.ReadIntValue(vt) if err != nil { return nil, err } out[k] = v } return out, nil } // ReadMapStringStruct 读取 map,value 由 factory 创建后自行 ReadFrom。 func (r *Reader) ReadMapStringStruct(tag int, required bool, factory func() Unmarshaler) (map[string]Unmarshaler, error) { typ, ok, err := r.findTag(tag, required) if err != nil || !ok { return map[string]Unmarshaler{}, err } if typ != TypeMap { return nil, fmt.Errorf("taf: tag=%d 不是 map: 0x%02x", tag, byte(typ)) } n, err := r.readLength() if err != nil { return nil, err } out := make(map[string]Unmarshaler, n) for i := int64(0); i < n; i++ { _, kt, err := r.ReadHead() if err != nil { return nil, err } k, err := r.ReadStringValue(kt) if err != nil { return nil, err } _, vt, err := r.ReadHead() if err != nil { return nil, err } if vt != TypeStructBegin { if err := r.Skip(vt); err != nil { return nil, err } continue } obj := factory() if err := obj.ReadFrom(r); err != nil { return nil, err } if err := r.SkipToStructEnd(); err != nil { return nil, err } out[k] = obj } return out, nil } // ReadListString 读取 list;非字符串元素会被跳过而不是报错。 func (r *Reader) ReadListString(tag int, required bool) ([]string, error) { typ, ok, err := r.findTag(tag, required) if err != nil || !ok { return nil, err } if typ != TypeList { return nil, fmt.Errorf("taf: tag=%d 不是 list: 0x%02x", tag, byte(typ)) } n, err := r.readLength() if err != nil { return nil, err } out := make([]string, 0, n) for i := int64(0); i < n; i++ { _, it, err := r.ReadHead() if err != nil { return nil, err } if it != TypeString1 && it != TypeString4 { if err := r.Skip(it); err != nil { return nil, err } continue } value, err := r.ReadStringValue(it) if err != nil { return nil, err } out = append(out, value) } return out, nil } func (r *Reader) ReadMapStringBytes(tag int, required bool) (map[string][]byte, error) { typ, ok, err := r.findTag(tag, required) if err != nil || !ok { return map[string][]byte{}, err } if typ != TypeMap { return nil, fmt.Errorf("taf: tag=%d 不是 map: 0x%02x", tag, byte(typ)) } n, err := r.readLength() if err != nil { return nil, err } out := make(map[string][]byte, n) for i := int64(0); i < n; i++ { _, kt, err := r.ReadHead() if err != nil { return nil, err } k, err := r.ReadStringValue(kt) if err != nil { return nil, err } _, vt, err := r.ReadHead() if err != nil { return nil, err } v, err := r.ReadBytesValue(vt) if err != nil { return nil, err } out[k] = v } return out, nil } func (r *Reader) ReadStruct(tag int, required bool, obj Unmarshaler) (bool, error) { typ, ok, err := r.findTag(tag, required) if err != nil || !ok { return false, err } if typ != TypeStructBegin { return false, fmt.Errorf("taf: tag=%d 不是结构体: 0x%02x", tag, byte(typ)) } if err := obj.ReadFrom(r); err != nil { return false, err } return true, r.SkipToStructEnd() } func (r *Reader) ReadListStruct(tag int, required bool, factory func() Unmarshaler) ([]Unmarshaler, error) { typ, ok, err := r.findTag(tag, required) if err != nil || !ok { return nil, err } if typ != TypeList { return nil, fmt.Errorf("taf: tag=%d 不是 list: 0x%02x", tag, byte(typ)) } n, err := r.readLength() if err != nil { return nil, err } out := make([]Unmarshaler, 0, n) for i := int64(0); i < n; i++ { _, it, err := r.ReadHead() if err != nil { return nil, err } if it != TypeStructBegin { if err := r.Skip(it); err != nil { return nil, err } continue } obj := factory() if err := obj.ReadFrom(r); err != nil { return nil, err } if err := r.SkipToStructEnd(); err != nil { return nil, err } out = append(out, obj) } return out, nil } func (r *Reader) SkipToStructEnd() error { for { _, typ, err := r.ReadHead() if err != nil { return err } if typ == TypeStructEnd { return nil } if err := r.Skip(typ); err != nil { return err } } }