resolve.go 1.28 KB
Newer Older
1 2 3 4 5
package io

import (
	"context"

Jeromy's avatar
Jeromy committed
6 7 8
	dag "github.com/ipfs/go-merkledag"
	ft "github.com/ipfs/go-unixfs"
	hamt "github.com/ipfs/go-unixfs/hamt"
9

Jeromy's avatar
Jeromy committed
10
	ipld "github.com/ipfs/go-ipld-format"
11 12
)

Jeromy's avatar
Jeromy committed
13 14
// ResolveUnixfsOnce resolves a single hop of a path through a graph in a
// unixfs context. This includes handling traversing sharded directories.
Jeromy's avatar
Jeromy committed
15
func ResolveUnixfsOnce(ctx context.Context, ds ipld.NodeGetter, nd ipld.Node, names []string) (*ipld.Link, []string, error) {
16 17
	switch nd := nd.(type) {
	case *dag.ProtoNode:
Overbool's avatar
Overbool committed
18
		fsn, err := ft.FSNodeFromBytes(nd.Data())
19 20
		if err != nil {
			// Not a unixfs node, use standard object traversal code
Jeromy's avatar
Jeromy committed
21 22 23 24 25 26
			lnk, err := nd.GetNodeLink(names[0])
			if err != nil {
				return nil, nil, err
			}

			return lnk, names[1:], nil
27 28
		}

Overbool's avatar
Overbool committed
29
		switch fsn.Type() {
30
		case ft.THAMTShard:
Jeromy's avatar
Jeromy committed
31 32
			rods := dag.NewReadOnlyDagService(ds)
			s, err := hamt.NewHamtFromDag(rods, nd)
33
			if err != nil {
Jeromy's avatar
Jeromy committed
34
				return nil, nil, err
35 36
			}

Jeromy's avatar
Jeromy committed
37
			out, err := s.Find(ctx, names[0])
38
			if err != nil {
Jeromy's avatar
Jeromy committed
39
				return nil, nil, err
40 41
			}

Jeromy's avatar
Jeromy committed
42
			return out, names[1:], nil
43
		default:
Jeromy's avatar
Jeromy committed
44 45 46 47 48 49
			lnk, err := nd.GetNodeLink(names[0])
			if err != nil {
				return nil, nil, err
			}

			return lnk, names[1:], nil
50
		}
51
	default:
Jeromy's avatar
Jeromy committed
52
		lnk, rest, err := nd.ResolveLink(names)
53
		if err != nil {
Jeromy's avatar
Jeromy committed
54
			return nil, nil, err
55
		}
Jeromy's avatar
Jeromy committed
56
		return lnk, rest, nil
57 58
	}
}