// 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 NewBufDagReader(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 NewPBFileReader(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") } }
// cacheNode caches a node into d.childDirs or d.files and returns the FSNode. func (d *Directory) cacheNode(name string, nd node.Node) (FSNode, error) { switch nd := nd.(type) { case *dag.ProtoNode: i, err := ft.FromBytes(nd.Data()) if err != nil { return nil, err } switch i.GetType() { case ufspb.Data_Directory: ndir := NewDirectory(d.ctx, name, nd, d, d.dserv) d.childDirs[name] = ndir return ndir, nil case ufspb.Data_File, ufspb.Data_Raw, ufspb.Data_Symlink: nfi, err := NewFile(name, nd, d, d.dserv) if err != nil { return nil, err } d.files[name] = nfi return nfi, nil case ufspb.Data_Metadata: return nil, ErrNotYetImplemented default: return nil, ErrInvalidChild } case *dag.RawNode: nfi, err := NewFile(name, nd, d, d.dserv) if err != nil { return nil, err } d.files[name] = nfi return nfi, nil default: return nil, fmt.Errorf("unrecognized node type in cache node") } }