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

import (
	"context"

	ft "github.com/ipfs/go-ipfs/unixfs"
7
	hamt "github.com/ipfs/go-ipfs/unixfs/hamt"
8
	dag "gx/ipfs/QmRy4Qk9hbgFX9NGJRm8rBThrA8PZhNCitMgeRYyZ67s59/go-merkledag"
9

Steven Allen's avatar
Steven Allen committed
10
	ipld "gx/ipfs/QmZtNq8dArGfnpCZfx2pUNY7UcjGhVp5qqwQ4hH6mpTMRQ/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 18 19 20
	switch nd := nd.(type) {
	case *dag.ProtoNode:
		upb, err := ft.FromBytes(nd.Data())
		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 29
		}

		switch upb.GetType() {
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
	}
}