func (br *Reader) readList(off int64) (wire.ValueList, int64, error) { typ, off, err := br.readByte(off) if err != nil { return nil, off, err } count, off, err := br.readInt32(off) if err != nil { return nil, off, err } if count < 0 { return nil, off, decodeErrorf("negative length %d requested for list", count) } start := off for i := int32(0); i < count; i++ { off, err = br.skipValue(wire.Type(typ), off) if err != nil { return nil, off, err } } items := borrowLazyValueList() items.count = count items.typ = wire.Type(typ) items.reader = br items.startOffset = start return items, off, err }
func (br *Reader) readStruct(off int64) (wire.Struct, int64, error) { var fields []wire.Field // TODO(abg) add a lazy FieldList type instead of []Field. typ, off, err := br.readByte(off) if err != nil { return wire.Struct{}, off, err } for typ != 0 { var fid int16 var val wire.Value fid, off, err = br.readInt16(off) if err != nil { return wire.Struct{}, off, err } val, off, err = br.ReadValue(wire.Type(typ), off) if err != nil { return wire.Struct{}, off, err } fields = append(fields, wire.Field{ID: fid, Value: val}) typ, off, err = br.readByte(off) if err != nil { return wire.Struct{}, off, err } } return wire.Struct{Fields: fields}, off, err }
func (br *Reader) skipList(off int64) (int64, error) { vtByte, off, err := br.readByte(off) if err != nil { return off, err } vt := wire.Type(vtByte) count, off, err := br.readInt32(off) if err != nil { return off, err } if count < 0 { return off, decodeErrorf("negative length %d requested for collection", count) } vw := fixedWidth(vt) if vw > 0 { // value is fixed width. can calculate new offset right away. off += int64(count) * vw return off, err } for i := int32(0); i < count; i++ { off, err = br.skipValue(vt, off) if err != nil { return off, err } } return off, err }
func (br *Reader) readMap(off int64) (wire.MapItemList, int64, error) { ktByte, off, err := br.readByte(off) if err != nil { return nil, off, err } vtByte, off, err := br.readByte(off) if err != nil { return nil, off, err } count, off, err := br.readInt32(off) if err != nil { return nil, off, err } if count < 0 { return nil, off, decodeErrorf("negative length %d requested for map", count) } kt := wire.Type(ktByte) vt := wire.Type(vtByte) start := off for i := int32(0); i < count; i++ { off, err = br.skipValue(kt, off) if err != nil { return nil, off, err } off, err = br.skipValue(vt, off) if err != nil { return nil, off, err } } items := borrowLazyMapItemList() items.ktype = kt items.vtype = vt items.count = count items.reader = br items.startOffset = start return items, off, err }
func (br *Reader) skipMap(off int64) (int64, error) { ktByte, off, err := br.readByte(off) if err != nil { return off, err } vtByte, off, err := br.readByte(off) if err != nil { return off, err } kt := wire.Type(ktByte) vt := wire.Type(vtByte) count, off, err := br.readInt32(off) if err != nil { return off, err } if count < 0 { return off, decodeErrorf("negative length %d requested for map", count) } kw := fixedWidth(kt) vw := fixedWidth(vt) if kw > 0 && vw > 0 { // key and value are fixed width. calculate exact offset increase. off += int64(count) * (kw + vw) return off, err } for i := int32(0); i < count; i++ { off, err = br.skipValue(kt, off) if err != nil { return off, err } off, err = br.skipValue(vt, off) if err != nil { return off, err } } return off, err }
func (br *Reader) skipStruct(off int64) (int64, error) { typ, off, err := br.readByte(off) if err != nil { return off, err } for typ != 0 { off += 2 // field ID off, err = br.skipValue(wire.Type(typ), off) if err != nil { return off, err } typ, off, err = br.readByte(off) if err != nil { return off, err } } return off, err }