// ReadPropertyMap reads a PropertyMap from the buffer. `context` and // friends behave the same way that they do for ReadKey. func ReadPropertyMap(buf Buffer, context KeyContext, appid, namespace string) (pm ds.PropertyMap, err error) { defer recoverTo(&err) numRows := uint64(0) numRows, _, e := cmpbin.ReadUint(buf) panicIf(e) if numRows > ReadPropertyMapReasonableLimit { err = fmt.Errorf("helper: tried to decode map with huge number of rows %d", numRows) return } pm = make(ds.PropertyMap, numRows) name, prop := "", ds.Property{} for i := uint64(0); i < numRows; i++ { name, _, e = cmpbin.ReadString(buf) panicIf(e) numProps, _, e := cmpbin.ReadUint(buf) panicIf(e) if numProps > ReadPropertyMapReasonableLimit { err = fmt.Errorf("helper: tried to decode map with huge number of properties %d", numProps) return } props := make([]ds.Property, 0, numProps) for j := uint64(0); j < numProps; j++ { prop, err = ReadProperty(buf, context, appid, namespace) panicIf(err) props = append(props, prop) } pm[name] = props } return }
// decode returns the encoded IndexColumns, the raw row (cursor) data, or an // error. func (q queryCursor) decode() ([]ds.IndexColumn, []byte, error) { buf := bytes.NewBuffer([]byte(q)) count, _, err := cmpbin.ReadUint(buf) if err != nil { return nil, nil, fmt.Errorf("invalid cursor: bad prefix number") } if count == 0 || count > MaxIndexColumns { return nil, nil, fmt.Errorf("invalid cursor: bad column count %d", count) } if count == 0 { return nil, nil, fmt.Errorf("invalid cursor: zero prefix number") } cols := make([]ds.IndexColumn, count) for i := range cols { if cols[i], err = serialize.ReadIndexColumn(buf); err != nil { return nil, nil, fmt.Errorf("invalid cursor: unable to decode IndexColumn %d: %s", i, err) } } if cols[len(cols)-1].Property != "__key__" { return nil, nil, fmt.Errorf("invalid cursor: last column was not __key__: %v", cols[len(cols)-1]) } return cols, buf.Bytes(), nil }
// ReadTime reads a time.Time from the buffer. func ReadTime(buf Buffer) (time.Time, error) { v, _, err := cmpbin.ReadUint(buf) if err != nil { return time.Time{}, err } return time.Unix(int64(v/1e6), int64((v%1e6)*1e3)).UTC(), nil }