// Adds the torrent to the client.
func (me *Client) AddTorrent(metaInfo *metainfo.MetaInfo) (err error) {
- t, err := newTorrent(BytesInfoHash(metaInfo.Info.Hash), metaInfo.AnnounceList)
+ var ih InfoHash
+ CopyExact(&ih, metaInfo.Info.Hash)
+ t, err := newTorrent(ih, metaInfo.AnnounceList)
if err != nil {
return
}
package torrent
import (
- "bitbucket.org/anacrolix/go.torrent/testutil"
- "github.com/anacrolix/libtorgo/bencode"
"os"
"testing"
+
+ "bitbucket.org/anacrolix/go.torrent/testutil"
+ "bitbucket.org/anacrolix/go.torrent/util"
+ "github.com/anacrolix/libtorgo/bencode"
)
func TestClientDefault(t *testing.T) {
func TestTorrentInitialState(t *testing.T) {
dir, mi := testutil.GreetingTestTorrent()
defer os.RemoveAll(dir)
- tor, err := newTorrent(BytesInfoHash(mi.Info.Hash), nil)
+ tor, err := newTorrent(func() (ih InfoHash) {
+ util.CopyExact(ih[:], mi.Info.Hash)
+ return
+ }(), nil)
if err != nil {
t.Fatal(err)
}
"bitbucket.org/anacrolix/go.torrent"
"bitbucket.org/anacrolix/go.torrent/tracker"
_ "bitbucket.org/anacrolix/go.torrent/tracker/udp"
+ "bitbucket.org/anacrolix/go.torrent/util"
metainfo "github.com/nsf/libtorgo/torrent"
)
if err != nil {
log.Fatal(err)
}
- resp, err := tr.Announce(&tracker.AnnounceRequest{
- NumWant: -1,
- InfoHash: torrent.BytesInfoHash(mi.InfoHash),
- })
+ ar := tracker.AnnounceRequest{
+ NumWant: -1,
+ }
+ util.CopyExact(ar.InfoHash, mi.InfoHash)
+ resp, err := tr.Announce(&ar)
if err != nil {
log.Fatal(err)
}
if err != nil {
log.Fatal(err)
}
- ih = torrent.BytesInfoHash(metaInfo.Info.Hash)
+ util.CopyExact(&ih, metaInfo.Info.Hash)
}
client.PrioritizeDataRegion(ih, 0, 999999999)
err := client.AddPeers(ih, func() []torrent.Peer {
dialTimeout = time.Second * 15
)
-type InfoHash [20]byte
-
-type pieceSum [20]byte
-
-func copyHashSum(dst, src []byte) {
- if len(dst) != len(src) || copy(dst, src) != len(dst) {
- panic("hash sum sizes differ")
- }
-}
-
-func BytesInfoHash(b []byte) (ih InfoHash) {
- if len(b) != len(ih) || copy(ih[:], b) != len(ih) {
- panic("bad infohash bytes")
- }
- return
-}
+type (
+ InfoHash [20]byte
+ pieceSum [20]byte
+)
type piece struct {
Hash pieceSum
})
for index, hash := range infoPieceHashes(&md) {
piece := &torrentPiece{}
- copyHashSum(piece.Hash[:], []byte(hash))
+ util.CopyExact(piece.Hash[:], hash)
t.Pieces = append(t.Pieces, piece)
piece.bytesLeftElement = t.PiecesByBytesLeft.Insert(index)
t.pendAllChunkSpecs(pp.Integer(index))
// log.Print(t.Info)
panic(fmt.Sprintf("hashed wrong number of bytes: expected %d; did %d; piece %d", t.PieceLength(piece), n, piece))
}
- copyHashSum(ps[:], hash.Sum(nil))
+ util.CopyExact(ps[:], hash.Sum(nil))
return
}
func (t *torrent) haveAllPieces() bool {
--- /dev/null
+package util
+
+import (
+ "fmt"
+ "reflect"
+)
+
+func CopyExact(dest interface{}, src interface{}) {
+ dV := reflect.ValueOf(dest)
+ sV := reflect.ValueOf(src)
+ if dV.Kind() == reflect.Ptr {
+ dV = dV.Elem()
+ }
+ if dV.Kind() == reflect.Array && !dV.CanAddr() {
+ panic(fmt.Sprintf("dest not addressable: %T", dest))
+ }
+ if sV.Kind() == reflect.String {
+ sV = sV.Convert(dV.Type())
+ }
+ if dV.Len() != sV.Len() {
+ panic(fmt.Sprintf("dest len (%d) != src len (%d)", dV.Len(), sV.Len()))
+ }
+ if dV.Len() != reflect.Copy(dV, sV) {
+ panic("dammit")
+ }
+}
--- /dev/null
+package util
+
+import (
+ "bytes"
+ "testing"
+)
+
+func TestCopyToArray(t *testing.T) {
+ var arr [3]byte
+ bb := []byte{1, 2, 3}
+ CopyExact(&arr, bb)
+ if !bytes.Equal(arr[:], bb) {
+ t.FailNow()
+ }
+}
+
+func TestCopyToSlicedArray(t *testing.T) {
+ var arr [5]byte
+ CopyExact(arr[:], "hello")
+ if !bytes.Equal(arr[:], []byte("hello")) {
+ t.FailNow()
+ }
+}
+
+func TestCopyDestNotAddr(t *testing.T) {
+ defer func() {
+ r := recover()
+ if r == nil {
+ t.FailNow()
+ }
+ t.Log(r)
+ }()
+ var arr [3]byte
+ CopyExact(arr, "nope")
+}
+
+func TestCopyLenMismatch(t *testing.T) {
+ defer func() {
+ r := recover()
+ if r == nil {
+ t.FailNow()
+ }
+ t.Log(r)
+ }()
+ CopyExact(make([]byte, 2), "abc")
+}