10 "bitbucket.org/anacrolix/go.torrent/peer_protocol"
11 metainfo "github.com/nsf/libtorgo/torrent"
12 "launchpad.net/gommap"
16 PieceHash = crypto.SHA1
18 chunkSize = 0x4000 // 16KiB
20 dialTimeout = time.Second * 15
23 type InfoHash [20]byte
25 type pieceSum [20]byte
27 func copyHashSum(dst, src []byte) {
28 if len(dst) != len(src) || copy(dst, src) != len(dst) {
29 panic("hash sum sizes differ")
33 func BytesInfoHash(b []byte) (ih InfoHash) {
34 if len(b) != len(ih) || copy(ih[:], b) != len(ih) {
35 panic("bad infohash bytes")
42 PendingChunkSpecs map[ChunkSpec]struct{}
48 func (p *piece) Complete() bool {
49 return len(p.PendingChunkSpecs) == 0 && p.EverHashed
52 func lastChunkSpec(pieceLength peer_protocol.Integer) (cs ChunkSpec) {
53 cs.Begin = (pieceLength - 1) / chunkSize * chunkSize
54 cs.Length = pieceLength - cs.Begin
58 type ChunkSpec struct {
59 Begin, Length peer_protocol.Integer
63 Index peer_protocol.Integer
67 type pieceByBytesPendingSlice struct {
68 Pending, Indices []peer_protocol.Integer
71 func (pcs pieceByBytesPendingSlice) Len() int {
72 return len(pcs.Indices)
75 func (me pieceByBytesPendingSlice) Less(i, j int) bool {
76 return me.Pending[me.Indices[i]] < me.Pending[me.Indices[j]]
79 func (me pieceByBytesPendingSlice) Swap(i, j int) {
80 me.Indices[i], me.Indices[j] = me.Indices[j], me.Indices[i]
84 ErrDataNotReady = errors.New("data not ready")
87 func mmapTorrentData(metaInfo *metainfo.MetaInfo, location string) (mms MMapSpan, err error) {
94 for _, miFile := range metaInfo.Files {
95 fileName := filepath.Join(append([]string{location, metaInfo.Name}, miFile.Path...)...)
96 err = os.MkdirAll(filepath.Dir(fileName), 0777)
101 file, err = os.OpenFile(fileName, os.O_CREATE|os.O_RDWR, 0666)
108 fi, err = file.Stat()
112 if fi.Size() < miFile.Length {
113 err = file.Truncate(miFile.Length)
119 mMap, err = gommap.MapRegion(file.Fd(), 0, miFile.Length, gommap.PROT_READ|gommap.PROT_WRITE, gommap.MAP_SHARED)
123 if int64(len(mMap)) != miFile.Length {
124 panic("mmap has wrong length")
126 mms = append(mms, MMap{mMap})