importer.go 1.89 KB
Newer Older
Juan Batiz-Benet's avatar
Juan Batiz-Benet committed
1 2 3 4 5
package importer

import (
	"fmt"
	"io"
6
	"os"
7 8

	dag "github.com/jbenet/go-ipfs/merkledag"
Juan Batiz-Benet's avatar
Juan Batiz-Benet committed
9 10
)

Juan Batiz-Benet's avatar
go lint  
Juan Batiz-Benet committed
11
// BlockSizeLimit specifies the maximum size an imported block can have.
Juan Batiz-Benet's avatar
Juan Batiz-Benet committed
12
var BlockSizeLimit = int64(1048576) // 1 MB
Juan Batiz-Benet's avatar
go lint  
Juan Batiz-Benet committed
13 14 15

// ErrSizeLimitExceeded signals that a block is larger than BlockSizeLimit.
var ErrSizeLimitExceeded = fmt.Errorf("object size limit exceeded")
Juan Batiz-Benet's avatar
Juan Batiz-Benet committed
16

17 18
var DefaultSplitter = &SizeSplitter{1024 * 512}

Juan Batiz-Benet's avatar
Juan Batiz-Benet committed
19 20 21
// todo: incremental construction with an ipfs node. dumping constructed
// objects into the datastore, to avoid buffering all in memory

Juan Batiz-Benet's avatar
go lint  
Juan Batiz-Benet committed
22 23
// NewDagFromReader constructs a Merkle DAG from the given io.Reader.
// size required for block construction.
24
func NewDagFromReader(r io.Reader) (*dag.Node, error) {
25
	return NewDagFromReaderWithSplitter(r, DefaultSplitter)
26 27 28
}

func NewDagFromReaderWithSplitter(r io.Reader, spl BlockSplitter) (*dag.Node, error) {
29
	blkChan := spl.Split(r)
30 31
	first := <-blkChan
	root := &dag.Node{Data: dag.FilePBData(first)}
32

Jeromy's avatar
Jeromy committed
33
	i := 0
34
	for blk := range blkChan {
35
		child := &dag.Node{Data: dag.WrapData(blk)}
Jeromy's avatar
Jeromy committed
36
		err := root.AddNodeLink(fmt.Sprintf("%d", i), child)
37 38 39
		if err != nil {
			return nil, err
		}
Jeromy's avatar
Jeromy committed
40
		i++
Juan Batiz-Benet's avatar
Juan Batiz-Benet committed
41
	}
42

Juan Batiz-Benet's avatar
Juan Batiz-Benet committed
43 44
	return root, nil
}
45

Juan Batiz-Benet's avatar
go lint  
Juan Batiz-Benet committed
46
// NewDagFromFile constructs a Merkle DAG from the file at given path.
47 48 49 50 51 52 53
func NewDagFromFile(fpath string) (*dag.Node, error) {
	stat, err := os.Stat(fpath)
	if err != nil {
		return nil, err
	}

	if stat.IsDir() {
54
		return nil, fmt.Errorf("`%s` is a directory", fpath)
55 56 57 58 59 60 61 62
	}

	f, err := os.Open(fpath)
	if err != nil {
		return nil, err
	}
	defer f.Close()

63
	return NewDagFromReader(f)
64
}
65 66 67 68 69 70 71

// TODO: this needs a better name
func NewDagInNode(r io.Reader, n *dag.Node) error {
	n.Links = nil

	blkChan := DefaultSplitter.Split(r)
	first := <-blkChan
72
	n.Data = dag.FilePBData(first)
73

Jeromy's avatar
Jeromy committed
74
	i := 0
75 76
	for blk := range blkChan {
		child := &dag.Node{Data: dag.WrapData(blk)}
Jeromy's avatar
Jeromy committed
77
		err := n.AddNodeLink(fmt.Sprintf("%d", i), child)
78 79 80
		if err != nil {
			return err
		}
Jeromy's avatar
Jeromy committed
81
		i++
82 83 84 85
	}

	return nil
}