splitting.go 1.12 KB
Newer Older
1
// package chunk implements streaming block splitters
2 3 4 5 6 7 8 9 10 11
package chunk

import (
	"io"

	"github.com/jbenet/go-ipfs/util"
)

var log = util.Logger("chunk")

Jeromy's avatar
Jeromy committed
12
var DefaultSplitter = &SizeSplitter{Size: 1024 * 256}
13 14 15 16 17 18 19 20 21 22 23 24 25

type BlockSplitter interface {
	Split(r io.Reader) chan []byte
}

type SizeSplitter struct {
	Size int
}

func (ss *SizeSplitter) Split(r io.Reader) chan []byte {
	out := make(chan []byte)
	go func() {
		defer close(out)
26 27

		// all-chunks loop (keep creating chunks)
28
		for {
29
			// log.Infof("making chunk with size: %d", ss.Size)
30
			chunk := make([]byte, ss.Size)
31 32 33 34 35 36
			sofar := 0

			// this-chunk loop (keep reading until this chunk full)
			for {
				nread, err := r.Read(chunk[sofar:])
				sofar += nread
37
				if err == io.EOF {
38 39 40
					if sofar > 0 {
						// log.Infof("sending out chunk with size: %d", sofar)
						out <- chunk[:sofar]
41 42 43
					}
					return
				}
44 45 46 47 48 49 50 51 52
				if err != nil {
					log.Errorf("Block split error: %s", err)
					return
				}
				if sofar == ss.Size {
					// log.Infof("sending out chunk with size: %d", sofar)
					out <- chunk[:sofar]
					break // break out of this-chunk loop
				}
53 54 55 56 57
			}
		}
	}()
	return out
}