abx: Accept independent attr

This commit is contained in:
世界 2023-07-15 14:41:05 +08:00
parent 37622ea16f
commit 8807070904
No known key found for this signature in database
GPG key ID: CD109927C34A63C4

View file

@ -18,7 +18,6 @@ var _ xml.TokenReader = (*Reader)(nil)
type Reader struct { type Reader struct {
reader *bytes.Reader reader *bytes.Reader
stringRefs []string stringRefs []string
attrs []xml.Attr
} }
func NewReader(content []byte) (xml.TokenReader, bool) { func NewReader(content []byte) (xml.TokenReader, bool) {
@ -47,7 +46,7 @@ func (r *Reader) Token() (token xml.Token, err error) {
return return
} }
var attrs []xml.Attr var attrs []xml.Attr
attrs, err = r.pullAttributes() attrs, err = r.readAttributes()
if err != nil { if err != nil {
return return
} }
@ -93,35 +92,41 @@ func (r *Reader) Token() (token xml.Token, err error) {
_, err = r.readUTF() _, err = r.readUTF()
return return
case ATTRIBUTE: case ATTRIBUTE:
return nil, E.New("unexpected attribute") _, err = r.readAttribute()
return
} }
return nil, E.New("unknown token type ", tokenType, " with type ", eventType) return nil, E.New("unknown token type ", tokenType, " with type ", eventType)
} }
func (r *Reader) pullAttributes() ([]xml.Attr, error) { func (r *Reader) readAttributes() ([]xml.Attr, error) {
err := r.pullAttribute() var attrs []xml.Attr
if err != nil { for {
return nil, err attr, err := r.readAttribute()
if err == io.EOF {
break
}
attrs = append(attrs, attr)
} }
attrs := r.attrs
r.attrs = nil
return attrs, nil return attrs, nil
} }
func (r *Reader) pullAttribute() error { func (r *Reader) readAttribute() (xml.Attr, error) {
event, err := r.reader.ReadByte() event, err := r.reader.ReadByte()
if err != nil { if err != nil {
return nil return xml.Attr{}, nil
} }
tokenType := event & 0x0f tokenType := event & 0x0f
eventType := event & 0xf0 eventType := event & 0xf0
if tokenType != ATTRIBUTE { if tokenType != ATTRIBUTE {
return r.reader.UnreadByte() err = r.reader.UnreadByte()
if err != nil {
return xml.Attr{}, nil
}
return xml.Attr{}, io.EOF
} }
var name string name, err := r.readInternedUTF()
name, err = r.readInternedUTF()
if err != nil { if err != nil {
return err return xml.Attr{}, err
} }
var value string var value string
switch eventType { switch eventType {
@ -134,74 +139,73 @@ func (r *Reader) pullAttribute() error {
case TypeString: case TypeString:
value, err = r.readUTF() value, err = r.readUTF()
if err != nil { if err != nil {
return err return xml.Attr{}, err
} }
case TypeStringInterned: case TypeStringInterned:
value, err = r.readInternedUTF() value, err = r.readInternedUTF()
if err != nil { if err != nil {
return err return xml.Attr{}, err
} }
case TypeBytesHex: case TypeBytesHex:
var data []byte var data []byte
data, err = r.readBytes() data, err = r.readBytes()
if err != nil { if err != nil {
return err return xml.Attr{}, err
} }
value = hex.EncodeToString(data) value = hex.EncodeToString(data)
case TypeBytesBase64: case TypeBytesBase64:
var data []byte var data []byte
data, err = r.readBytes() data, err = r.readBytes()
if err != nil { if err != nil {
return err return xml.Attr{}, err
} }
value = base64.StdEncoding.EncodeToString(data) value = base64.StdEncoding.EncodeToString(data)
case TypeInt: case TypeInt:
var data int32 var data int32
err = binary.Read(r.reader, binary.BigEndian, &data) err = binary.Read(r.reader, binary.BigEndian, &data)
if err != nil { if err != nil {
return err return xml.Attr{}, err
} }
value = strconv.FormatInt(int64(data), 10) value = strconv.FormatInt(int64(data), 10)
case TypeIntHex: case TypeIntHex:
var data int32 var data int32
err = binary.Read(r.reader, binary.BigEndian, &data) err = binary.Read(r.reader, binary.BigEndian, &data)
if err != nil { if err != nil {
return err return xml.Attr{}, err
} }
value = "0x" + strconv.FormatInt(int64(data), 16) value = "0x" + strconv.FormatInt(int64(data), 16)
case TypeLong: case TypeLong:
var data int64 var data int64
err = binary.Read(r.reader, binary.BigEndian, &data) err = binary.Read(r.reader, binary.BigEndian, &data)
if err != nil { if err != nil {
return err return xml.Attr{}, err
} }
value = strconv.FormatInt(data, 10) value = strconv.FormatInt(data, 10)
case TypeLongHex: case TypeLongHex:
var data int64 var data int64
err = binary.Read(r.reader, binary.BigEndian, &data) err = binary.Read(r.reader, binary.BigEndian, &data)
if err != nil { if err != nil {
return err return xml.Attr{}, err
} }
value = "0x" + strconv.FormatInt(data, 16) value = "0x" + strconv.FormatInt(data, 16)
case TypeFloat: case TypeFloat:
var data float32 var data float32
err = binary.Read(r.reader, binary.BigEndian, &data) err = binary.Read(r.reader, binary.BigEndian, &data)
if err != nil { if err != nil {
return err return xml.Attr{}, err
} }
value = strconv.FormatFloat(float64(data), 'g', -1, 32) value = strconv.FormatFloat(float64(data), 'g', -1, 32)
case TypeDouble: case TypeDouble:
var data float64 var data float64
err = binary.Read(r.reader, binary.BigEndian, &data) err = binary.Read(r.reader, binary.BigEndian, &data)
if err != nil { if err != nil {
return err return xml.Attr{}, err
} }
value = strconv.FormatFloat(data, 'g', -1, 64) value = strconv.FormatFloat(data, 'g', -1, 64)
default: default:
return E.New("unexpected attribute type, ", eventType) return xml.Attr{}, E.New("unexpected attribute type, ", eventType)
} }
r.attrs = append(r.attrs, xml.Attr{Name: xml.Name{Local: name}, Value: value}) return xml.Attr{Name: xml.Name{Local: name}, Value: value}, nil
return r.pullAttribute()
} }
func (r *Reader) readUnsignedShort() (uint16, error) { func (r *Reader) readUnsignedShort() (uint16, error) {