// getLocal attempts to retrieve the value from the datastore func (dht *IpfsDHT) getLocal(key key.Key) (*pb.Record, error) { log.Debug("getLocal %s", key) v, err := dht.datastore.Get(key.DsKey()) if err != nil { return nil, err } log.Debug("found in db") byt, ok := v.([]byte) if !ok { return nil, errors.New("value stored in datastore not []byte") } rec := new(pb.Record) err = proto.Unmarshal(byt, rec) if err != nil { return nil, err } err = dht.verifyRecordLocally(rec) if err != nil { log.Debugf("local record verify failed: %s (discarded)", err) return nil, err } return rec, nil }
// NewDagReader creates a new reader object that reads the data represented by // the given node, using the passed in DAGService for data retreival func NewDagReader(ctx context.Context, n *mdag.Node, serv mdag.DAGService) (*DagReader, error) { pb := new(ftpb.Data) if err := proto.Unmarshal(n.Data, pb); err != nil { return nil, err } switch pb.GetType() { case ftpb.Data_Directory: // Dont allow reading directories return nil, ErrIsDir case ftpb.Data_Raw: fallthrough case ftpb.Data_File: return NewDataFileReader(ctx, n, pb, serv), nil case ftpb.Data_Metadata: if len(n.Links) == 0 { return nil, errors.New("incorrectly formatted metadata object") } child, err := n.Links[0].GetNode(ctx, serv) if err != nil { return nil, err } return NewDagReader(ctx, child, serv) case ftpb.Data_Symlink: return nil, ErrCantReadSymlinks default: return nil, ft.ErrUnrecognizedType } }
func (this *fullReader) ReadMsg(msg proto.Message) error { length, err := this.r.Read(this.buf) if err != nil { return err } return proto.Unmarshal(this.buf[:length], msg) }
func TestPBLinkMarshalTo(t *testing.T) { popr := math_rand.New(math_rand.NewSource(time.Now().UnixNano())) p := NewPopulatedPBLink(popr, false) size := p.Size() data := make([]byte, size) for i := range data { data[i] = byte(popr.Intn(256)) } _, err := p.MarshalTo(data) if err != nil { panic(err) } msg := &PBLink{} if err := github_com_gogo_protobuf_proto.Unmarshal(data, msg); err != nil { panic(err) } for i := range data { data[i] = byte(popr.Intn(256)) } if err := p.VerboseEqual(msg); err != nil { t.Fatalf("%#v !VerboseProto %#v, since %v", msg, p, err) } if !p.Equal(msg) { t.Fatalf("%#v !Proto %#v", msg, p) } }
func readHdr(n *merkledag.ProtoNode) (*pb.Set, error) { hdrLenRaw, consumed := binary.Uvarint(n.Data()) if consumed <= 0 { return nil, errors.New("invalid Set header length") } pbdata := n.Data()[consumed:] if hdrLenRaw > uint64(len(pbdata)) { return nil, errors.New("impossibly large Set header length") } // as hdrLenRaw was <= an int, we now know it fits in an int hdrLen := int(hdrLenRaw) var hdr pb.Set if err := proto.Unmarshal(pbdata[:hdrLen], &hdr); err != nil { return nil, err } if v := hdr.GetVersion(); v != 1 { return nil, fmt.Errorf("unsupported Set version: %d", v) } if uint64(hdr.GetFanout()) > uint64(len(n.Links())) { return nil, errors.New("impossibly large Fanout") } return &hdr, nil }
func readMsgCtx(ctx context.Context, r msgio.Reader, p proto.Message) ([]byte, error) { var msg []byte // read in a goroutine so we can exit when our context is cancelled. done := make(chan error) go func() { var err error msg, err = r.ReadMsg() select { case done <- err: case <-ctx.Done(): } }() select { case <-ctx.Done(): return nil, ctx.Err() case e := <-done: if e != nil { return nil, e } } return msg, proto.Unmarshal(msg, p) }
func TestFSNode(t *testing.T) { fsn := new(FSNode) fsn.Type = TFile for i := 0; i < 15; i++ { fsn.AddBlockSize(100) } fsn.Data = make([]byte, 128) b, err := fsn.GetBytes() if err != nil { t.Fatal(err) } pbn := new(pb.Data) err = proto.Unmarshal(b, pbn) if err != nil { t.Fatal(err) } ds, err := DataSize(b) if err != nil { t.Fatal(err) } if ds != (100*15)+128 { t.Fatal("Datasize calculations incorrect!") } }
func FromBytes(data []byte) (*pb.Data, error) { pbdata := new(pb.Data) err := proto.Unmarshal(data, pbdata) if err != nil { return nil, err } return pbdata, nil }
func UnwrapData(data []byte) ([]byte, error) { pbdata := new(pb.Data) err := proto.Unmarshal(data, pbdata) if err != nil { return nil, err } return pbdata.GetData(), nil }
//MetadataFromBytes Unmarshals a protobuf message into Metadata. func MetadataFromBytes(b []byte) (*Metadata, error) { pbd := new(pb.Data) err := proto.Unmarshal(b, pbd) if err != nil { return nil, err } if pbd.GetType() != pb.Data_Metadata { return nil, errors.New("incorrect node type") } pbm := new(pb.Metadata) err = proto.Unmarshal(pbd.Data, pbm) if err != nil { return nil, err } md := new(Metadata) md.MimeType = pbm.GetMimeType() return md, nil }
func (p *ipnsPublisher) getPreviousSeqNo(ctx context.Context, ipnskey key.Key) (uint64, error) { prevrec, err := p.ds.Get(ipnskey.DsKey()) if err != nil && err != ds.ErrNotFound { // None found, lets start at zero! return 0, err } var val []byte if err == nil { prbytes, ok := prevrec.([]byte) if !ok { return 0, fmt.Errorf("unexpected type returned from datastore: %#v", prevrec) } dhtrec := new(dhtpb.Record) err := proto.Unmarshal(prbytes, dhtrec) if err != nil { return 0, err } val = dhtrec.GetValue() } else { // try and check the dht for a record ctx, cancel := context.WithTimeout(ctx, time.Second*30) defer cancel() rv, err := p.routing.GetValue(ctx, ipnskey) if err != nil { // no such record found, start at zero! return 0, nil } val = rv } e := new(pb.IpnsEntry) err = proto.Unmarshal(val, e) if err != nil { return 0, err } return e.GetSequence(), nil }
func (rp *Republisher) getLastVal(k key.Key) (path.Path, uint64, error) { ival, err := rp.ds.Get(k.DsKey()) if err != nil { // not found means we dont have a previously published entry return "", 0, errNoEntry } val := ival.([]byte) dhtrec := new(dhtpb.Record) err = proto.Unmarshal(val, dhtrec) if err != nil { return "", 0, err } // extract published data from record e := new(pb.IpnsEntry) err = proto.Unmarshal(dhtrec.GetValue(), e) if err != nil { return "", 0, err } return path.Path(e.Value), e.GetSequence(), nil }
func FSNodeFromBytes(b []byte) (*FSNode, error) { pbn := new(pb.Data) err := proto.Unmarshal(b, pbn) if err != nil { return nil, err } n := new(FSNode) n.Data = pbn.Data n.blocksizes = pbn.Blocksizes n.subtotal = pbn.GetFilesize() - uint64(len(n.Data)) n.Type = pbn.GetType() return n, nil }
func IpnsSelectorFunc(k key.Key, vals [][]byte) (int, error) { var recs []*pb.IpnsEntry for _, v := range vals { e := new(pb.IpnsEntry) err := proto.Unmarshal(v, e) if err == nil { recs = append(recs, e) } else { recs = append(recs, nil) } } return selectRecord(recs, vals) }
// UnmarshalPrivateKey converts a protobuf serialized private key into its // representative object func UnmarshalPrivateKey(data []byte) (PrivKey, error) { pmes := new(pb.PrivateKey) err := proto.Unmarshal(data, pmes) if err != nil { return nil, err } switch pmes.GetType() { case pb.KeyType_RSA: return UnmarshalRsaPrivateKey(pmes.GetData()) default: return nil, ErrBadKeyType } }
func getRoutingProviders(ds datastore.Datastore, k key.Key) ([]*dhtpb.Message_Peer, error) { e := log.EventBegin(context.Background(), "getProviders", &k) defer e.Done() var providers []*dhtpb.Message_Peer if v, err := ds.Get(providerKey(k)); err == nil { if data, ok := v.([]byte); ok { var msg dhtpb.Message if err := proto.Unmarshal(data, &msg); err != nil { return nil, err } providers = append(providers, msg.GetProviderPeers()...) } } return providers, nil }
func TestPBNodeVerboseEqual(t *testing.T) { popr := math_rand.New(math_rand.NewSource(time.Now().UnixNano())) p := NewPopulatedPBNode(popr, false) data, err := github_com_gogo_protobuf_proto.Marshal(p) if err != nil { panic(err) } msg := &PBNode{} if err := github_com_gogo_protobuf_proto.Unmarshal(data, msg); err != nil { panic(err) } if err := p.VerboseEqual(msg); err != nil { t.Fatalf("%#v !VerboseEqual %#v, since %v", msg, p, err) } }
func getRoutingRecord(ds datastore.Datastore, k key.Key) (*pb.Record, error) { dskey := k.DsKey() val, err := ds.Get(dskey) if err != nil { return nil, err } recordBytes, ok := val.([]byte) if !ok { return nil, fmt.Errorf("datastore had non byte-slice value for %v", dskey) } var record pb.Record if err := proto.Unmarshal(recordBytes, &record); err != nil { return nil, errors.New("failed to unmarshal dht record from datastore") } return &record, nil }
func (this *varintReader) ReadMsg(msg proto.Message) error { length64, err := binary.ReadUvarint(this.r) if err != nil { return err } length := int(length64) if length < 0 || length > this.maxSize { return io.ErrShortBuffer } if len(this.buf) < length { this.buf = make([]byte, length) } buf := this.buf[:length] if _, err := io.ReadFull(this.r, buf); err != nil { return err } return proto.Unmarshal(buf, msg) }
func DataSize(data []byte) (uint64, error) { pbdata := new(pb.Data) err := proto.Unmarshal(data, pbdata) if err != nil { return 0, err } switch pbdata.GetType() { case pb.Data_Directory: return 0, errors.New("Cant get data size of directory!") case pb.Data_File: return pbdata.GetFilesize(), nil case pb.Data_Raw: return uint64(len(pbdata.GetData())), nil default: return 0, errors.New("Unrecognized node data type!") } }
func (this *uint32Reader) ReadMsg(msg proto.Message) error { if _, err := io.ReadFull(this.r, this.lenBuf); err != nil { return err } length32 := this.byteOrder.Uint32(this.lenBuf) length := int(length32) if length < 0 || length > this.maxSize { return io.ErrShortBuffer } if length >= len(this.buf) { this.buf = make([]byte, length) } _, err := io.ReadFull(this.r, this.buf[:length]) if err != nil { return err } return proto.Unmarshal(this.buf[:length], msg) }
func (c *offlineRouting) GetValue(ctx context.Context, key key.Key) ([]byte, error) { v, err := c.datastore.Get(key.DsKey()) if err != nil { return nil, err } byt, ok := v.([]byte) if !ok { return nil, errors.New("value stored in datastore not []byte") } rec := new(pb.Record) err = proto.Unmarshal(byt, rec) if err != nil { return nil, err } return rec.GetValue(), nil }
// precalcNextBuf follows the next link in line and loads it from the // DAGService, setting the next buffer to read from func (dr *DagReader) precalcNextBuf(ctx context.Context) error { dr.buf.Close() // Just to make sure if dr.linkPosition >= len(dr.promises) { return io.EOF } nxt, err := dr.promises[dr.linkPosition].Get(ctx) if err != nil { return err } dr.linkPosition++ switch nxt := nxt.(type) { case *mdag.ProtoNode: pb := new(ftpb.Data) err = proto.Unmarshal(nxt.Data(), pb) if err != nil { return fmt.Errorf("incorrectly formatted protobuf: %s", err) } switch pb.GetType() { case ftpb.Data_Directory: // A directory should not exist within a file return ft.ErrInvalidDirLocation case ftpb.Data_File: dr.buf = NewDataFileReader(dr.ctx, nxt, pb, dr.serv) return nil case ftpb.Data_Raw: dr.buf = NewRSNCFromBytes(pb.GetData()) return nil case ftpb.Data_Metadata: return errors.New("shouldnt have had metadata object inside file") case ftpb.Data_Symlink: return errors.New("shouldnt have had symlink inside file") default: return ft.ErrUnrecognizedType } case *mdag.RawNode: dr.buf = NewRSNCFromBytes(nxt.RawData()) return nil default: return errors.New("unrecognized node type in DagReader") } }
func TestFSNode(t *testing.T) { fsn := new(FSNode) fsn.Type = TFile for i := 0; i < 16; i++ { fsn.AddBlockSize(100) } fsn.RemoveBlockSize(15) fsn.Data = make([]byte, 128) b, err := fsn.GetBytes() if err != nil { t.Fatal(err) } pbn := new(pb.Data) err = proto.Unmarshal(b, pbn) if err != nil { t.Fatal(err) } ds, err := DataSize(b) if err != nil { t.Fatal(err) } nKids := fsn.NumChildren() if nKids != 15 { t.Fatal("Wrong number of child nodes") } if ds != (100*15)+128 { t.Fatal("Datasize calculations incorrect!") } nfsn, err := FSNodeFromBytes(b) if err != nil { t.Fatal(err) } if nfsn.FileSize() != (100*15)+128 { t.Fatal("fsNode FileSize calculations incorrect") } }
// FIXME(brian): is this method meant to simulate getting a value from the network? func (c *client) GetValue(ctx context.Context, key key.Key) ([]byte, error) { log.Debugf("GetValue: %s", key) v, err := c.datastore.Get(key.DsKey()) if err != nil { return nil, err } data, ok := v.([]byte) if !ok { return nil, errors.New("could not cast value from datastore") } rec := new(dhtpb.Record) err = proto.Unmarshal(data, rec) if err != nil { return nil, err } return rec.GetValue(), nil }
func (c *offlineRouting) GetValues(ctx context.Context, key string, _ int) ([]routing.RecvdVal, error) { v, err := c.datastore.Get(dshelp.NewKeyFromBinary(key)) if err != nil { return nil, err } byt, ok := v.([]byte) if !ok { return nil, errors.New("value stored in datastore not []byte") } rec := new(pb.Record) err = proto.Unmarshal(byt, rec) if err != nil { return nil, err } return []routing.RecvdVal{ {Val: rec.GetValue()}, }, nil }
// NewDagReader creates a new reader object that reads the data represented by // the given node, using the passed in DAGService for data retreival func NewDagReader(ctx context.Context, n node.Node, serv mdag.DAGService) (*DagReader, error) { switch n := n.(type) { case *mdag.RawNode: return &DagReader{ buf: NewRSNCFromBytes(n.RawData()), }, nil case *mdag.ProtoNode: pb := new(ftpb.Data) if err := proto.Unmarshal(n.Data(), pb); err != nil { return nil, err } switch pb.GetType() { case ftpb.Data_Directory: // Dont allow reading directories return nil, ErrIsDir case ftpb.Data_File, ftpb.Data_Raw: return NewDataFileReader(ctx, n, pb, serv), nil case ftpb.Data_Metadata: if len(n.Links()) == 0 { return nil, errors.New("incorrectly formatted metadata object") } child, err := n.Links()[0].GetNode(ctx, serv) if err != nil { return nil, err } childpb, ok := child.(*mdag.ProtoNode) if !ok { return nil, mdag.ErrNotProtobuf } return NewDagReader(ctx, childpb, serv) case ftpb.Data_Symlink: return nil, ErrCantReadSymlinks default: return nil, ft.ErrUnrecognizedType } default: return nil, fmt.Errorf("unrecognized node type") } }
func BenchmarkPBLinkProtoUnmarshal(b *testing.B) { popr := math_rand.New(math_rand.NewSource(616)) total := 0 datas := make([][]byte, 10000) for i := 0; i < 10000; i++ { data, err := github_com_gogo_protobuf_proto.Marshal(NewPopulatedPBLink(popr, false)) if err != nil { panic(err) } datas[i] = data } msg := &PBLink{} b.ResetTimer() for i := 0; i < b.N; i++ { total += len(datas[i%10000]) if err := github_com_gogo_protobuf_proto.Unmarshal(datas[i%10000], msg); err != nil { panic(err) } } b.SetBytes(int64(total / b.N)) }
func (w *Writer) WriteNode(nd *mdag.ProtoNode, fpath string) error { pb := new(upb.Data) if err := proto.Unmarshal(nd.Data(), pb); err != nil { return err } switch pb.GetType() { case upb.Data_Metadata: fallthrough case upb.Data_Directory: return w.writeDir(nd, fpath) case upb.Data_Raw: fallthrough case upb.Data_File: return w.writeFile(nd, pb, fpath) case upb.Data_Symlink: return writeSymlinkHeader(w.TarW, string(pb.GetData()), fpath) default: return ft.ErrUnrecognizedType } }
// ValidateIpnsRecord implements ValidatorFunc and verifies that the // given 'val' is an IpnsEntry and that that entry is valid. func ValidateIpnsRecord(k key.Key, val []byte) error { entry := new(pb.IpnsEntry) err := proto.Unmarshal(val, entry) if err != nil { return err } switch entry.GetValidityType() { case pb.IpnsEntry_EOL: t, err := u.ParseRFC3339(string(entry.GetValidity())) if err != nil { log.Debug("Failed parsing time for ipns record EOL") return err } if time.Now().After(t) { return ErrExpiredRecord } default: return ErrUnrecognizedValidity } return nil }