- Added BEncode project as a submodule
- Added Crypto framework wrapper project so allow use in swift without Objective-C code - Created TorrentMetaInfo class and implemented parsing of info dictionary
This commit is contained in:
@@ -0,0 +1,3 @@
|
|||||||
|
[submodule "Submodules/BEncodeSwift"]
|
||||||
|
path = Submodules/BEncodeSwift
|
||||||
|
url = git@github.com:imben123/BEncodeSwift.git
|
||||||
@@ -7,6 +7,12 @@
|
|||||||
objects = {
|
objects = {
|
||||||
|
|
||||||
/* Begin PBXBuildFile section */
|
/* Begin PBXBuildFile section */
|
||||||
|
B54D0C1F1CA53993004343BD /* BEncode.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = B54D0C1A1CA53983004343BD /* BEncode.framework */; };
|
||||||
|
B54D0C271CA56ADB004343BD /* TorrentMetaInfoTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = B54D0C261CA56ADB004343BD /* TorrentMetaInfoTests.swift */; };
|
||||||
|
B54D0C761CA58993004343BD /* CommonCrypto.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = B54D0C581CA58722004343BD /* CommonCrypto.framework */; settings = {ATTRIBUTES = (Weak, ); }; };
|
||||||
|
B54D0C7A1CA69FAD004343BD /* TorrentMetaInfo.swift in Sources */ = {isa = PBXBuildFile; fileRef = B54D0C231CA56A22004343BD /* TorrentMetaInfo.swift */; };
|
||||||
|
B54D0C7B1CA69FD8004343BD /* NSData+sha1.swift in Sources */ = {isa = PBXBuildFile; fileRef = B54D0C2B1CA5787E004343BD /* NSData+sha1.swift */; };
|
||||||
|
B55D3FC21CA81372005CBDFF /* TestText.torrent in Resources */ = {isa = PBXBuildFile; fileRef = B55D3FC11CA81372005CBDFF /* TestText.torrent */; };
|
||||||
B56A8A071C83539300426AC8 /* TestHelpers.swift in Sources */ = {isa = PBXBuildFile; fileRef = B56A8A061C83539300426AC8 /* TestHelpers.swift */; };
|
B56A8A071C83539300426AC8 /* TestHelpers.swift in Sources */ = {isa = PBXBuildFile; fileRef = B56A8A061C83539300426AC8 /* TestHelpers.swift */; };
|
||||||
B585AB781C3833450093FA41 /* BitTorrent.h in Headers */ = {isa = PBXBuildFile; fileRef = B585AB771C3833450093FA41 /* BitTorrent.h */; settings = {ATTRIBUTES = (Public, ); }; };
|
B585AB781C3833450093FA41 /* BitTorrent.h in Headers */ = {isa = PBXBuildFile; fileRef = B585AB771C3833450093FA41 /* BitTorrent.h */; settings = {ATTRIBUTES = (Public, ); }; };
|
||||||
B585AB7F1C3833450093FA41 /* BitTorrent.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = B585AB741C3833450093FA41 /* BitTorrent.framework */; };
|
B585AB7F1C3833450093FA41 /* BitTorrent.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = B585AB741C3833450093FA41 /* BitTorrent.framework */; };
|
||||||
@@ -14,6 +20,34 @@
|
|||||||
/* End PBXBuildFile section */
|
/* End PBXBuildFile section */
|
||||||
|
|
||||||
/* Begin PBXContainerItemProxy section */
|
/* Begin PBXContainerItemProxy section */
|
||||||
|
B54D0C191CA53983004343BD /* PBXContainerItemProxy */ = {
|
||||||
|
isa = PBXContainerItemProxy;
|
||||||
|
containerPortal = B54D0C141CA53983004343BD /* BEncode.xcodeproj */;
|
||||||
|
proxyType = 2;
|
||||||
|
remoteGlobalIDString = B54D0BDB1CA53299004343BD;
|
||||||
|
remoteInfo = BEncode;
|
||||||
|
};
|
||||||
|
B54D0C1B1CA53983004343BD /* PBXContainerItemProxy */ = {
|
||||||
|
isa = PBXContainerItemProxy;
|
||||||
|
containerPortal = B54D0C141CA53983004343BD /* BEncode.xcodeproj */;
|
||||||
|
proxyType = 2;
|
||||||
|
remoteGlobalIDString = B54D0BE51CA5329A004343BD;
|
||||||
|
remoteInfo = BEncodeTests;
|
||||||
|
};
|
||||||
|
B54D0C1D1CA5398F004343BD /* PBXContainerItemProxy */ = {
|
||||||
|
isa = PBXContainerItemProxy;
|
||||||
|
containerPortal = B54D0C141CA53983004343BD /* BEncode.xcodeproj */;
|
||||||
|
proxyType = 1;
|
||||||
|
remoteGlobalIDString = B54D0BDA1CA53299004343BD;
|
||||||
|
remoteInfo = BEncode;
|
||||||
|
};
|
||||||
|
B54D0C771CA589B4004343BD /* PBXContainerItemProxy */ = {
|
||||||
|
isa = PBXContainerItemProxy;
|
||||||
|
containerPortal = B585AB6B1C3833450093FA41 /* Project object */;
|
||||||
|
proxyType = 1;
|
||||||
|
remoteGlobalIDString = B54D0C571CA58722004343BD;
|
||||||
|
remoteInfo = CommonCrypto;
|
||||||
|
};
|
||||||
B585AB801C3833450093FA41 /* PBXContainerItemProxy */ = {
|
B585AB801C3833450093FA41 /* PBXContainerItemProxy */ = {
|
||||||
isa = PBXContainerItemProxy;
|
isa = PBXContainerItemProxy;
|
||||||
containerPortal = B585AB6B1C3833450093FA41 /* Project object */;
|
containerPortal = B585AB6B1C3833450093FA41 /* Project object */;
|
||||||
@@ -24,6 +58,17 @@
|
|||||||
/* End PBXContainerItemProxy section */
|
/* End PBXContainerItemProxy section */
|
||||||
|
|
||||||
/* Begin PBXFileReference section */
|
/* Begin PBXFileReference section */
|
||||||
|
B54D0C141CA53983004343BD /* BEncode.xcodeproj */ = {isa = PBXFileReference; lastKnownFileType = "wrapper.pb-project"; name = BEncode.xcodeproj; path = Submodules/BEncodeSwift/BEncode.xcodeproj; sourceTree = "<group>"; };
|
||||||
|
B54D0C231CA56A22004343BD /* TorrentMetaInfo.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; name = TorrentMetaInfo.swift; path = Models/TorrentMetaInfo.swift; sourceTree = "<group>"; };
|
||||||
|
B54D0C261CA56ADB004343BD /* TorrentMetaInfoTests.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; name = TorrentMetaInfoTests.swift; path = Models/TorrentMetaInfoTests.swift; sourceTree = "<group>"; };
|
||||||
|
B54D0C2B1CA5787E004343BD /* NSData+sha1.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; name = "NSData+sha1.swift"; path = "Utilities/NSData+sha1.swift"; sourceTree = "<group>"; };
|
||||||
|
B54D0C581CA58722004343BD /* CommonCrypto.framework */ = {isa = PBXFileReference; explicitFileType = wrapper.framework; includeInIndex = 0; path = CommonCrypto.framework; sourceTree = BUILT_PRODUCTS_DIR; };
|
||||||
|
B54D0C6F1CA58749004343BD /* Info.plist */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.plist.xml; path = Info.plist; sourceTree = "<group>"; };
|
||||||
|
B54D0C711CA58767004343BD /* CommonCrypto.xcconfig */ = {isa = PBXFileReference; lastKnownFileType = text.xcconfig; path = CommonCrypto.xcconfig; sourceTree = "<group>"; };
|
||||||
|
B54D0C721CA5879E004343BD /* iphoneos.modulemap */ = {isa = PBXFileReference; lastKnownFileType = "sourcecode.module-map"; path = iphoneos.modulemap; sourceTree = "<group>"; };
|
||||||
|
B54D0C731CA587A9004343BD /* iphonesimulator.modulemap */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = "sourcecode.module-map"; path = iphonesimulator.modulemap; sourceTree = "<group>"; };
|
||||||
|
B54D0C741CA587B5004343BD /* macosx.modulemap */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = "sourcecode.module-map"; path = macosx.modulemap; sourceTree = "<group>"; };
|
||||||
|
B55D3FC11CA81372005CBDFF /* TestText.torrent */ = {isa = PBXFileReference; lastKnownFileType = file; path = TestText.torrent; sourceTree = "<group>"; };
|
||||||
B56A8A061C83539300426AC8 /* TestHelpers.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; name = TestHelpers.swift; path = Utilities/TestHelpers.swift; sourceTree = "<group>"; };
|
B56A8A061C83539300426AC8 /* TestHelpers.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; name = TestHelpers.swift; path = Utilities/TestHelpers.swift; sourceTree = "<group>"; };
|
||||||
B585AB741C3833450093FA41 /* BitTorrent.framework */ = {isa = PBXFileReference; explicitFileType = wrapper.framework; includeInIndex = 0; path = BitTorrent.framework; sourceTree = BUILT_PRODUCTS_DIR; };
|
B585AB741C3833450093FA41 /* BitTorrent.framework */ = {isa = PBXFileReference; explicitFileType = wrapper.framework; includeInIndex = 0; path = BitTorrent.framework; sourceTree = BUILT_PRODUCTS_DIR; };
|
||||||
B585AB771C3833450093FA41 /* BitTorrent.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = BitTorrent.h; sourceTree = "<group>"; };
|
B585AB771C3833450093FA41 /* BitTorrent.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = BitTorrent.h; sourceTree = "<group>"; };
|
||||||
@@ -34,10 +79,19 @@
|
|||||||
/* End PBXFileReference section */
|
/* End PBXFileReference section */
|
||||||
|
|
||||||
/* Begin PBXFrameworksBuildPhase section */
|
/* Begin PBXFrameworksBuildPhase section */
|
||||||
|
B54D0C541CA58722004343BD /* Frameworks */ = {
|
||||||
|
isa = PBXFrameworksBuildPhase;
|
||||||
|
buildActionMask = 2147483647;
|
||||||
|
files = (
|
||||||
|
);
|
||||||
|
runOnlyForDeploymentPostprocessing = 0;
|
||||||
|
};
|
||||||
B585AB701C3833450093FA41 /* Frameworks */ = {
|
B585AB701C3833450093FA41 /* Frameworks */ = {
|
||||||
isa = PBXFrameworksBuildPhase;
|
isa = PBXFrameworksBuildPhase;
|
||||||
buildActionMask = 2147483647;
|
buildActionMask = 2147483647;
|
||||||
files = (
|
files = (
|
||||||
|
B54D0C761CA58993004343BD /* CommonCrypto.framework in Frameworks */,
|
||||||
|
B54D0C1F1CA53993004343BD /* BEncode.framework in Frameworks */,
|
||||||
);
|
);
|
||||||
runOnlyForDeploymentPostprocessing = 0;
|
runOnlyForDeploymentPostprocessing = 0;
|
||||||
};
|
};
|
||||||
@@ -52,11 +106,68 @@
|
|||||||
/* End PBXFrameworksBuildPhase section */
|
/* End PBXFrameworksBuildPhase section */
|
||||||
|
|
||||||
/* Begin PBXGroup section */
|
/* Begin PBXGroup section */
|
||||||
|
B54D0C131CA53979004343BD /* Frameworks */ = {
|
||||||
|
isa = PBXGroup;
|
||||||
|
children = (
|
||||||
|
B54D0C141CA53983004343BD /* BEncode.xcodeproj */,
|
||||||
|
);
|
||||||
|
name = Frameworks;
|
||||||
|
sourceTree = "<group>";
|
||||||
|
};
|
||||||
|
B54D0C151CA53983004343BD /* Products */ = {
|
||||||
|
isa = PBXGroup;
|
||||||
|
children = (
|
||||||
|
B54D0C1A1CA53983004343BD /* BEncode.framework */,
|
||||||
|
B54D0C1C1CA53983004343BD /* BEncodeTests.xctest */,
|
||||||
|
);
|
||||||
|
name = Products;
|
||||||
|
sourceTree = "<group>";
|
||||||
|
};
|
||||||
|
B54D0C211CA56619004343BD /* Torrents */ = {
|
||||||
|
isa = PBXGroup;
|
||||||
|
children = (
|
||||||
|
B55D3FC11CA81372005CBDFF /* TestText.torrent */,
|
||||||
|
);
|
||||||
|
name = Torrents;
|
||||||
|
sourceTree = "<group>";
|
||||||
|
};
|
||||||
|
B54D0C251CA56A25004343BD /* Models */ = {
|
||||||
|
isa = PBXGroup;
|
||||||
|
children = (
|
||||||
|
B54D0C231CA56A22004343BD /* TorrentMetaInfo.swift */,
|
||||||
|
B54D0C261CA56ADB004343BD /* TorrentMetaInfoTests.swift */,
|
||||||
|
);
|
||||||
|
name = Models;
|
||||||
|
sourceTree = "<group>";
|
||||||
|
};
|
||||||
|
B54D0C291CA5785F004343BD /* Utilities */ = {
|
||||||
|
isa = PBXGroup;
|
||||||
|
children = (
|
||||||
|
B54D0C2B1CA5787E004343BD /* NSData+sha1.swift */,
|
||||||
|
);
|
||||||
|
name = Utilities;
|
||||||
|
sourceTree = "<group>";
|
||||||
|
};
|
||||||
|
B54D0C591CA58722004343BD /* CommonCrypto */ = {
|
||||||
|
isa = PBXGroup;
|
||||||
|
children = (
|
||||||
|
B54D0C6F1CA58749004343BD /* Info.plist */,
|
||||||
|
B54D0C711CA58767004343BD /* CommonCrypto.xcconfig */,
|
||||||
|
B54D0C721CA5879E004343BD /* iphoneos.modulemap */,
|
||||||
|
B54D0C731CA587A9004343BD /* iphonesimulator.modulemap */,
|
||||||
|
B54D0C741CA587B5004343BD /* macosx.modulemap */,
|
||||||
|
);
|
||||||
|
path = CommonCrypto;
|
||||||
|
sourceTree = "<group>";
|
||||||
|
};
|
||||||
B585AB6A1C3833450093FA41 = {
|
B585AB6A1C3833450093FA41 = {
|
||||||
isa = PBXGroup;
|
isa = PBXGroup;
|
||||||
children = (
|
children = (
|
||||||
|
B54D0C211CA56619004343BD /* Torrents */,
|
||||||
B585AB761C3833450093FA41 /* BitTorrent */,
|
B585AB761C3833450093FA41 /* BitTorrent */,
|
||||||
B585AB821C3833450093FA41 /* BitTorrentTests */,
|
B585AB821C3833450093FA41 /* BitTorrentTests */,
|
||||||
|
B54D0C591CA58722004343BD /* CommonCrypto */,
|
||||||
|
B54D0C131CA53979004343BD /* Frameworks */,
|
||||||
B585AB751C3833450093FA41 /* Products */,
|
B585AB751C3833450093FA41 /* Products */,
|
||||||
);
|
);
|
||||||
sourceTree = "<group>";
|
sourceTree = "<group>";
|
||||||
@@ -66,6 +177,7 @@
|
|||||||
children = (
|
children = (
|
||||||
B585AB741C3833450093FA41 /* BitTorrent.framework */,
|
B585AB741C3833450093FA41 /* BitTorrent.framework */,
|
||||||
B585AB7E1C3833450093FA41 /* BitTorrentTests.xctest */,
|
B585AB7E1C3833450093FA41 /* BitTorrentTests.xctest */,
|
||||||
|
B54D0C581CA58722004343BD /* CommonCrypto.framework */,
|
||||||
);
|
);
|
||||||
name = Products;
|
name = Products;
|
||||||
sourceTree = "<group>";
|
sourceTree = "<group>";
|
||||||
@@ -75,6 +187,8 @@
|
|||||||
children = (
|
children = (
|
||||||
B585AB771C3833450093FA41 /* BitTorrent.h */,
|
B585AB771C3833450093FA41 /* BitTorrent.h */,
|
||||||
B585AB831C3833450093FA41 /* BitTorrentTests.swift */,
|
B585AB831C3833450093FA41 /* BitTorrentTests.swift */,
|
||||||
|
B54D0C251CA56A25004343BD /* Models */,
|
||||||
|
B54D0C291CA5785F004343BD /* Utilities */,
|
||||||
B585AB791C3833450093FA41 /* Info.plist */,
|
B585AB791C3833450093FA41 /* Info.plist */,
|
||||||
);
|
);
|
||||||
path = BitTorrent;
|
path = BitTorrent;
|
||||||
@@ -92,6 +206,13 @@
|
|||||||
/* End PBXGroup section */
|
/* End PBXGroup section */
|
||||||
|
|
||||||
/* Begin PBXHeadersBuildPhase section */
|
/* Begin PBXHeadersBuildPhase section */
|
||||||
|
B54D0C551CA58722004343BD /* Headers */ = {
|
||||||
|
isa = PBXHeadersBuildPhase;
|
||||||
|
buildActionMask = 2147483647;
|
||||||
|
files = (
|
||||||
|
);
|
||||||
|
runOnlyForDeploymentPostprocessing = 0;
|
||||||
|
};
|
||||||
B585AB711C3833450093FA41 /* Headers */ = {
|
B585AB711C3833450093FA41 /* Headers */ = {
|
||||||
isa = PBXHeadersBuildPhase;
|
isa = PBXHeadersBuildPhase;
|
||||||
buildActionMask = 2147483647;
|
buildActionMask = 2147483647;
|
||||||
@@ -103,6 +224,24 @@
|
|||||||
/* End PBXHeadersBuildPhase section */
|
/* End PBXHeadersBuildPhase section */
|
||||||
|
|
||||||
/* Begin PBXNativeTarget section */
|
/* Begin PBXNativeTarget section */
|
||||||
|
B54D0C571CA58722004343BD /* CommonCrypto */ = {
|
||||||
|
isa = PBXNativeTarget;
|
||||||
|
buildConfigurationList = B54D0C691CA58722004343BD /* Build configuration list for PBXNativeTarget "CommonCrypto" */;
|
||||||
|
buildPhases = (
|
||||||
|
B54D0C531CA58722004343BD /* Sources */,
|
||||||
|
B54D0C541CA58722004343BD /* Frameworks */,
|
||||||
|
B54D0C551CA58722004343BD /* Headers */,
|
||||||
|
B54D0C561CA58722004343BD /* Resources */,
|
||||||
|
);
|
||||||
|
buildRules = (
|
||||||
|
);
|
||||||
|
dependencies = (
|
||||||
|
);
|
||||||
|
name = CommonCrypto;
|
||||||
|
productName = CommonCrypto;
|
||||||
|
productReference = B54D0C581CA58722004343BD /* CommonCrypto.framework */;
|
||||||
|
productType = "com.apple.product-type.framework";
|
||||||
|
};
|
||||||
B585AB731C3833450093FA41 /* BitTorrent */ = {
|
B585AB731C3833450093FA41 /* BitTorrent */ = {
|
||||||
isa = PBXNativeTarget;
|
isa = PBXNativeTarget;
|
||||||
buildConfigurationList = B585AB881C3833450093FA41 /* Build configuration list for PBXNativeTarget "BitTorrent" */;
|
buildConfigurationList = B585AB881C3833450093FA41 /* Build configuration list for PBXNativeTarget "BitTorrent" */;
|
||||||
@@ -115,6 +254,8 @@
|
|||||||
buildRules = (
|
buildRules = (
|
||||||
);
|
);
|
||||||
dependencies = (
|
dependencies = (
|
||||||
|
B54D0C781CA589B4004343BD /* PBXTargetDependency */,
|
||||||
|
B54D0C1E1CA5398F004343BD /* PBXTargetDependency */,
|
||||||
);
|
);
|
||||||
name = BitTorrent;
|
name = BitTorrent;
|
||||||
productName = BitTorrent;
|
productName = BitTorrent;
|
||||||
@@ -146,10 +287,13 @@
|
|||||||
isa = PBXProject;
|
isa = PBXProject;
|
||||||
attributes = {
|
attributes = {
|
||||||
LastSwiftMigration = 0720;
|
LastSwiftMigration = 0720;
|
||||||
LastSwiftUpdateCheck = 0720;
|
LastSwiftUpdateCheck = 0730;
|
||||||
LastUpgradeCheck = 0720;
|
LastUpgradeCheck = 0720;
|
||||||
ORGANIZATIONNAME = "Ben Davis";
|
ORGANIZATIONNAME = "Ben Davis";
|
||||||
TargetAttributes = {
|
TargetAttributes = {
|
||||||
|
B54D0C571CA58722004343BD = {
|
||||||
|
CreatedOnToolsVersion = 7.3;
|
||||||
|
};
|
||||||
B585AB731C3833450093FA41 = {
|
B585AB731C3833450093FA41 = {
|
||||||
CreatedOnToolsVersion = 7.2;
|
CreatedOnToolsVersion = 7.2;
|
||||||
};
|
};
|
||||||
@@ -168,15 +312,46 @@
|
|||||||
mainGroup = B585AB6A1C3833450093FA41;
|
mainGroup = B585AB6A1C3833450093FA41;
|
||||||
productRefGroup = B585AB751C3833450093FA41 /* Products */;
|
productRefGroup = B585AB751C3833450093FA41 /* Products */;
|
||||||
projectDirPath = "";
|
projectDirPath = "";
|
||||||
|
projectReferences = (
|
||||||
|
{
|
||||||
|
ProductGroup = B54D0C151CA53983004343BD /* Products */;
|
||||||
|
ProjectRef = B54D0C141CA53983004343BD /* BEncode.xcodeproj */;
|
||||||
|
},
|
||||||
|
);
|
||||||
projectRoot = "";
|
projectRoot = "";
|
||||||
targets = (
|
targets = (
|
||||||
B585AB731C3833450093FA41 /* BitTorrent */,
|
B585AB731C3833450093FA41 /* BitTorrent */,
|
||||||
B585AB7D1C3833450093FA41 /* BitTorrentTests */,
|
B585AB7D1C3833450093FA41 /* BitTorrentTests */,
|
||||||
|
B54D0C571CA58722004343BD /* CommonCrypto */,
|
||||||
);
|
);
|
||||||
};
|
};
|
||||||
/* End PBXProject section */
|
/* End PBXProject section */
|
||||||
|
|
||||||
|
/* Begin PBXReferenceProxy section */
|
||||||
|
B54D0C1A1CA53983004343BD /* BEncode.framework */ = {
|
||||||
|
isa = PBXReferenceProxy;
|
||||||
|
fileType = wrapper.framework;
|
||||||
|
path = BEncode.framework;
|
||||||
|
remoteRef = B54D0C191CA53983004343BD /* PBXContainerItemProxy */;
|
||||||
|
sourceTree = BUILT_PRODUCTS_DIR;
|
||||||
|
};
|
||||||
|
B54D0C1C1CA53983004343BD /* BEncodeTests.xctest */ = {
|
||||||
|
isa = PBXReferenceProxy;
|
||||||
|
fileType = wrapper.cfbundle;
|
||||||
|
path = BEncodeTests.xctest;
|
||||||
|
remoteRef = B54D0C1B1CA53983004343BD /* PBXContainerItemProxy */;
|
||||||
|
sourceTree = BUILT_PRODUCTS_DIR;
|
||||||
|
};
|
||||||
|
/* End PBXReferenceProxy section */
|
||||||
|
|
||||||
/* Begin PBXResourcesBuildPhase section */
|
/* Begin PBXResourcesBuildPhase section */
|
||||||
|
B54D0C561CA58722004343BD /* Resources */ = {
|
||||||
|
isa = PBXResourcesBuildPhase;
|
||||||
|
buildActionMask = 2147483647;
|
||||||
|
files = (
|
||||||
|
);
|
||||||
|
runOnlyForDeploymentPostprocessing = 0;
|
||||||
|
};
|
||||||
B585AB721C3833450093FA41 /* Resources */ = {
|
B585AB721C3833450093FA41 /* Resources */ = {
|
||||||
isa = PBXResourcesBuildPhase;
|
isa = PBXResourcesBuildPhase;
|
||||||
buildActionMask = 2147483647;
|
buildActionMask = 2147483647;
|
||||||
@@ -188,16 +363,26 @@
|
|||||||
isa = PBXResourcesBuildPhase;
|
isa = PBXResourcesBuildPhase;
|
||||||
buildActionMask = 2147483647;
|
buildActionMask = 2147483647;
|
||||||
files = (
|
files = (
|
||||||
|
B55D3FC21CA81372005CBDFF /* TestText.torrent in Resources */,
|
||||||
);
|
);
|
||||||
runOnlyForDeploymentPostprocessing = 0;
|
runOnlyForDeploymentPostprocessing = 0;
|
||||||
};
|
};
|
||||||
/* End PBXResourcesBuildPhase section */
|
/* End PBXResourcesBuildPhase section */
|
||||||
|
|
||||||
/* Begin PBXSourcesBuildPhase section */
|
/* Begin PBXSourcesBuildPhase section */
|
||||||
|
B54D0C531CA58722004343BD /* Sources */ = {
|
||||||
|
isa = PBXSourcesBuildPhase;
|
||||||
|
buildActionMask = 2147483647;
|
||||||
|
files = (
|
||||||
|
);
|
||||||
|
runOnlyForDeploymentPostprocessing = 0;
|
||||||
|
};
|
||||||
B585AB6F1C3833450093FA41 /* Sources */ = {
|
B585AB6F1C3833450093FA41 /* Sources */ = {
|
||||||
isa = PBXSourcesBuildPhase;
|
isa = PBXSourcesBuildPhase;
|
||||||
buildActionMask = 2147483647;
|
buildActionMask = 2147483647;
|
||||||
files = (
|
files = (
|
||||||
|
B54D0C7A1CA69FAD004343BD /* TorrentMetaInfo.swift in Sources */,
|
||||||
|
B54D0C7B1CA69FD8004343BD /* NSData+sha1.swift in Sources */,
|
||||||
);
|
);
|
||||||
runOnlyForDeploymentPostprocessing = 0;
|
runOnlyForDeploymentPostprocessing = 0;
|
||||||
};
|
};
|
||||||
@@ -207,12 +392,23 @@
|
|||||||
files = (
|
files = (
|
||||||
B56A8A071C83539300426AC8 /* TestHelpers.swift in Sources */,
|
B56A8A071C83539300426AC8 /* TestHelpers.swift in Sources */,
|
||||||
B585AB841C3833450093FA41 /* BitTorrentTests.swift in Sources */,
|
B585AB841C3833450093FA41 /* BitTorrentTests.swift in Sources */,
|
||||||
|
B54D0C271CA56ADB004343BD /* TorrentMetaInfoTests.swift in Sources */,
|
||||||
);
|
);
|
||||||
runOnlyForDeploymentPostprocessing = 0;
|
runOnlyForDeploymentPostprocessing = 0;
|
||||||
};
|
};
|
||||||
/* End PBXSourcesBuildPhase section */
|
/* End PBXSourcesBuildPhase section */
|
||||||
|
|
||||||
/* Begin PBXTargetDependency section */
|
/* Begin PBXTargetDependency section */
|
||||||
|
B54D0C1E1CA5398F004343BD /* PBXTargetDependency */ = {
|
||||||
|
isa = PBXTargetDependency;
|
||||||
|
name = BEncode;
|
||||||
|
targetProxy = B54D0C1D1CA5398F004343BD /* PBXContainerItemProxy */;
|
||||||
|
};
|
||||||
|
B54D0C781CA589B4004343BD /* PBXTargetDependency */ = {
|
||||||
|
isa = PBXTargetDependency;
|
||||||
|
target = B54D0C571CA58722004343BD /* CommonCrypto */;
|
||||||
|
targetProxy = B54D0C771CA589B4004343BD /* PBXContainerItemProxy */;
|
||||||
|
};
|
||||||
B585AB811C3833450093FA41 /* PBXTargetDependency */ = {
|
B585AB811C3833450093FA41 /* PBXTargetDependency */ = {
|
||||||
isa = PBXTargetDependency;
|
isa = PBXTargetDependency;
|
||||||
target = B585AB731C3833450093FA41 /* BitTorrent */;
|
target = B585AB731C3833450093FA41 /* BitTorrent */;
|
||||||
@@ -221,6 +417,44 @@
|
|||||||
/* End PBXTargetDependency section */
|
/* End PBXTargetDependency section */
|
||||||
|
|
||||||
/* Begin XCBuildConfiguration section */
|
/* Begin XCBuildConfiguration section */
|
||||||
|
B54D0C6A1CA58722004343BD /* Debug */ = {
|
||||||
|
isa = XCBuildConfiguration;
|
||||||
|
baseConfigurationReference = B54D0C711CA58767004343BD /* CommonCrypto.xcconfig */;
|
||||||
|
buildSettings = {
|
||||||
|
CLANG_ANALYZER_NONNULL = YES;
|
||||||
|
DEFINES_MODULE = YES;
|
||||||
|
DYLIB_COMPATIBILITY_VERSION = 1;
|
||||||
|
DYLIB_CURRENT_VERSION = 1;
|
||||||
|
DYLIB_INSTALL_NAME_BASE = "@rpath";
|
||||||
|
INFOPLIST_FILE = CommonCrypto/Info.plist;
|
||||||
|
INSTALL_PATH = "$(LOCAL_LIBRARY_DIR)/Frameworks";
|
||||||
|
IPHONEOS_DEPLOYMENT_TARGET = 9.3;
|
||||||
|
LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks @loader_path/Frameworks";
|
||||||
|
PRODUCT_BUNDLE_IDENTIFIER = uk.co.bendavisapps.CommonCrypto;
|
||||||
|
PRODUCT_NAME = "$(TARGET_NAME)";
|
||||||
|
SKIP_INSTALL = YES;
|
||||||
|
};
|
||||||
|
name = Debug;
|
||||||
|
};
|
||||||
|
B54D0C6B1CA58722004343BD /* Release */ = {
|
||||||
|
isa = XCBuildConfiguration;
|
||||||
|
baseConfigurationReference = B54D0C711CA58767004343BD /* CommonCrypto.xcconfig */;
|
||||||
|
buildSettings = {
|
||||||
|
CLANG_ANALYZER_NONNULL = YES;
|
||||||
|
DEFINES_MODULE = YES;
|
||||||
|
DYLIB_COMPATIBILITY_VERSION = 1;
|
||||||
|
DYLIB_CURRENT_VERSION = 1;
|
||||||
|
DYLIB_INSTALL_NAME_BASE = "@rpath";
|
||||||
|
INFOPLIST_FILE = CommonCrypto/Info.plist;
|
||||||
|
INSTALL_PATH = "$(LOCAL_LIBRARY_DIR)/Frameworks";
|
||||||
|
IPHONEOS_DEPLOYMENT_TARGET = 9.3;
|
||||||
|
LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks @loader_path/Frameworks";
|
||||||
|
PRODUCT_BUNDLE_IDENTIFIER = uk.co.bendavisapps.CommonCrypto;
|
||||||
|
PRODUCT_NAME = "$(TARGET_NAME)";
|
||||||
|
SKIP_INSTALL = YES;
|
||||||
|
};
|
||||||
|
name = Release;
|
||||||
|
};
|
||||||
B585AB861C3833450093FA41 /* Debug */ = {
|
B585AB861C3833450093FA41 /* Debug */ = {
|
||||||
isa = XCBuildConfiguration;
|
isa = XCBuildConfiguration;
|
||||||
buildSettings = {
|
buildSettings = {
|
||||||
@@ -313,6 +547,7 @@
|
|||||||
B585AB891C3833450093FA41 /* Debug */ = {
|
B585AB891C3833450093FA41 /* Debug */ = {
|
||||||
isa = XCBuildConfiguration;
|
isa = XCBuildConfiguration;
|
||||||
buildSettings = {
|
buildSettings = {
|
||||||
|
CLANG_ALLOW_NON_MODULAR_INCLUDES_IN_FRAMEWORK_MODULES = NO;
|
||||||
CLANG_ENABLE_MODULES = YES;
|
CLANG_ENABLE_MODULES = YES;
|
||||||
DEFINES_MODULE = YES;
|
DEFINES_MODULE = YES;
|
||||||
DYLIB_COMPATIBILITY_VERSION = 1;
|
DYLIB_COMPATIBILITY_VERSION = 1;
|
||||||
@@ -320,10 +555,12 @@
|
|||||||
DYLIB_INSTALL_NAME_BASE = "@rpath";
|
DYLIB_INSTALL_NAME_BASE = "@rpath";
|
||||||
INFOPLIST_FILE = BitTorrent/Info.plist;
|
INFOPLIST_FILE = BitTorrent/Info.plist;
|
||||||
INSTALL_PATH = "$(LOCAL_LIBRARY_DIR)/Frameworks";
|
INSTALL_PATH = "$(LOCAL_LIBRARY_DIR)/Frameworks";
|
||||||
|
IPHONEOS_DEPLOYMENT_TARGET = 9.3;
|
||||||
LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks @loader_path/Frameworks";
|
LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks @loader_path/Frameworks";
|
||||||
PRODUCT_BUNDLE_IDENTIFIER = bendavis.BitTorrent;
|
PRODUCT_BUNDLE_IDENTIFIER = bendavis.BitTorrent;
|
||||||
PRODUCT_NAME = "$(TARGET_NAME)";
|
PRODUCT_NAME = "$(TARGET_NAME)";
|
||||||
SKIP_INSTALL = YES;
|
SKIP_INSTALL = YES;
|
||||||
|
SWIFT_OBJC_BRIDGING_HEADER = "";
|
||||||
SWIFT_OPTIMIZATION_LEVEL = "-Onone";
|
SWIFT_OPTIMIZATION_LEVEL = "-Onone";
|
||||||
};
|
};
|
||||||
name = Debug;
|
name = Debug;
|
||||||
@@ -331,6 +568,7 @@
|
|||||||
B585AB8A1C3833450093FA41 /* Release */ = {
|
B585AB8A1C3833450093FA41 /* Release */ = {
|
||||||
isa = XCBuildConfiguration;
|
isa = XCBuildConfiguration;
|
||||||
buildSettings = {
|
buildSettings = {
|
||||||
|
CLANG_ALLOW_NON_MODULAR_INCLUDES_IN_FRAMEWORK_MODULES = NO;
|
||||||
CLANG_ENABLE_MODULES = YES;
|
CLANG_ENABLE_MODULES = YES;
|
||||||
DEFINES_MODULE = YES;
|
DEFINES_MODULE = YES;
|
||||||
DYLIB_COMPATIBILITY_VERSION = 1;
|
DYLIB_COMPATIBILITY_VERSION = 1;
|
||||||
@@ -338,10 +576,12 @@
|
|||||||
DYLIB_INSTALL_NAME_BASE = "@rpath";
|
DYLIB_INSTALL_NAME_BASE = "@rpath";
|
||||||
INFOPLIST_FILE = BitTorrent/Info.plist;
|
INFOPLIST_FILE = BitTorrent/Info.plist;
|
||||||
INSTALL_PATH = "$(LOCAL_LIBRARY_DIR)/Frameworks";
|
INSTALL_PATH = "$(LOCAL_LIBRARY_DIR)/Frameworks";
|
||||||
|
IPHONEOS_DEPLOYMENT_TARGET = 9.3;
|
||||||
LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks @loader_path/Frameworks";
|
LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks @loader_path/Frameworks";
|
||||||
PRODUCT_BUNDLE_IDENTIFIER = bendavis.BitTorrent;
|
PRODUCT_BUNDLE_IDENTIFIER = bendavis.BitTorrent;
|
||||||
PRODUCT_NAME = "$(TARGET_NAME)";
|
PRODUCT_NAME = "$(TARGET_NAME)";
|
||||||
SKIP_INSTALL = YES;
|
SKIP_INSTALL = YES;
|
||||||
|
SWIFT_OBJC_BRIDGING_HEADER = "";
|
||||||
};
|
};
|
||||||
name = Release;
|
name = Release;
|
||||||
};
|
};
|
||||||
@@ -349,9 +589,11 @@
|
|||||||
isa = XCBuildConfiguration;
|
isa = XCBuildConfiguration;
|
||||||
buildSettings = {
|
buildSettings = {
|
||||||
INFOPLIST_FILE = BitTorrentTests/Info.plist;
|
INFOPLIST_FILE = BitTorrentTests/Info.plist;
|
||||||
|
IPHONEOS_DEPLOYMENT_TARGET = 9.3;
|
||||||
LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks @loader_path/Frameworks";
|
LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks @loader_path/Frameworks";
|
||||||
PRODUCT_BUNDLE_IDENTIFIER = bendavis.BitTorrentTests;
|
PRODUCT_BUNDLE_IDENTIFIER = bendavis.BitTorrentTests;
|
||||||
PRODUCT_NAME = "$(TARGET_NAME)";
|
PRODUCT_NAME = "$(TARGET_NAME)";
|
||||||
|
SWIFT_OBJC_BRIDGING_HEADER = "";
|
||||||
};
|
};
|
||||||
name = Debug;
|
name = Debug;
|
||||||
};
|
};
|
||||||
@@ -359,15 +601,26 @@
|
|||||||
isa = XCBuildConfiguration;
|
isa = XCBuildConfiguration;
|
||||||
buildSettings = {
|
buildSettings = {
|
||||||
INFOPLIST_FILE = BitTorrentTests/Info.plist;
|
INFOPLIST_FILE = BitTorrentTests/Info.plist;
|
||||||
|
IPHONEOS_DEPLOYMENT_TARGET = 9.3;
|
||||||
LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks @loader_path/Frameworks";
|
LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks @loader_path/Frameworks";
|
||||||
PRODUCT_BUNDLE_IDENTIFIER = bendavis.BitTorrentTests;
|
PRODUCT_BUNDLE_IDENTIFIER = bendavis.BitTorrentTests;
|
||||||
PRODUCT_NAME = "$(TARGET_NAME)";
|
PRODUCT_NAME = "$(TARGET_NAME)";
|
||||||
|
SWIFT_OBJC_BRIDGING_HEADER = "";
|
||||||
};
|
};
|
||||||
name = Release;
|
name = Release;
|
||||||
};
|
};
|
||||||
/* End XCBuildConfiguration section */
|
/* End XCBuildConfiguration section */
|
||||||
|
|
||||||
/* Begin XCConfigurationList section */
|
/* Begin XCConfigurationList section */
|
||||||
|
B54D0C691CA58722004343BD /* Build configuration list for PBXNativeTarget "CommonCrypto" */ = {
|
||||||
|
isa = XCConfigurationList;
|
||||||
|
buildConfigurations = (
|
||||||
|
B54D0C6A1CA58722004343BD /* Debug */,
|
||||||
|
B54D0C6B1CA58722004343BD /* Release */,
|
||||||
|
);
|
||||||
|
defaultConfigurationIsVisible = 0;
|
||||||
|
defaultConfigurationName = Release;
|
||||||
|
};
|
||||||
B585AB6E1C3833450093FA41 /* Build configuration list for PBXProject "BitTorrent" */ = {
|
B585AB6E1C3833450093FA41 /* Build configuration list for PBXProject "BitTorrent" */ = {
|
||||||
isa = XCConfigurationList;
|
isa = XCConfigurationList;
|
||||||
buildConfigurations = (
|
buildConfigurations = (
|
||||||
|
|||||||
@@ -15,5 +15,3 @@ FOUNDATION_EXPORT double BitTorrentVersionNumber;
|
|||||||
FOUNDATION_EXPORT const unsigned char BitTorrentVersionString[];
|
FOUNDATION_EXPORT const unsigned char BitTorrentVersionString[];
|
||||||
|
|
||||||
// In this header, you should import all the public headers of your framework using statements like #import <BitTorrent/PublicHeader.h>
|
// In this header, you should import all the public headers of your framework using statements like #import <BitTorrent/PublicHeader.h>
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
@@ -0,0 +1,170 @@
|
|||||||
|
//
|
||||||
|
// TorrentMetaInfo.swift
|
||||||
|
// BitTorrent
|
||||||
|
//
|
||||||
|
// Created by Ben Davis on 25/03/2016.
|
||||||
|
// Copyright © 2016 Ben Davis. All rights reserved.
|
||||||
|
//
|
||||||
|
|
||||||
|
import Foundation
|
||||||
|
import class BEncode.BEncoder
|
||||||
|
|
||||||
|
class TorrentMetaInfo {
|
||||||
|
|
||||||
|
var infoHash : NSData // this is the original bencoded dictionary, hashed
|
||||||
|
|
||||||
|
var info: TorrentInfoDictionary
|
||||||
|
// var announce: String
|
||||||
|
// var announceList: [String]?
|
||||||
|
// var creationDate: NSDate?
|
||||||
|
// var comment: String?
|
||||||
|
// var createdBy: String?
|
||||||
|
|
||||||
|
init?(data: NSData) {
|
||||||
|
print(try! BEncoder.decodeDictionaryKeysOnly(data)["info"]!)
|
||||||
|
self.infoHash = try! BEncoder.decodeDictionaryKeysOnly(data)["info"]!.sha1()
|
||||||
|
let decodedMetainfo = try! BEncoder.decodeStringKeyedDictionary(data)
|
||||||
|
if let info = TorrentInfoDictionary(decodedMetainfo["info"] as! [String : AnyObject]) {
|
||||||
|
self.info = info
|
||||||
|
} else {
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
class TorrentInfoDictionary {
|
||||||
|
|
||||||
|
let name : String
|
||||||
|
let pieceLength : Int
|
||||||
|
let isPrivate : Bool
|
||||||
|
let files: [TorrentFileInfo]
|
||||||
|
let pieces : [NSData]?
|
||||||
|
let length: Int
|
||||||
|
|
||||||
|
init?(_ dictionary: [String : AnyObject]) {
|
||||||
|
|
||||||
|
if let nameData = dictionary["name"] as? NSData, name = String(asciiData: nameData) {
|
||||||
|
self.name = name
|
||||||
|
} else {
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
if let pieceLength = dictionary["piece length"] as? Int {
|
||||||
|
self.pieceLength = pieceLength
|
||||||
|
} else {
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
if let pieces = dictionary["pieces"] as? NSData, piecesArray = TorrentInfoDictionary.seperatePieces(pieces) {
|
||||||
|
self.pieces = piecesArray
|
||||||
|
} else {
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
if let tuple = TorrentInfoDictionary.parseFilesAndLengthFromDictionary(dictionary, parsedName: name) {
|
||||||
|
self.files = tuple.files
|
||||||
|
self.length = tuple.totalLength
|
||||||
|
} else {
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
if let isPrivate = dictionary["private"] as? Int {
|
||||||
|
self.isPrivate = (isPrivate == 1)
|
||||||
|
} else {
|
||||||
|
self.isPrivate = false
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
private class func parseFilesAndLengthFromDictionary(dictionary: [ String : AnyObject ], parsedName name: String)
|
||||||
|
-> (files: [TorrentFileInfo], totalLength: Int)? {
|
||||||
|
|
||||||
|
if let files = dictionary["files"] as? [ [ String : AnyObject ] ] {
|
||||||
|
|
||||||
|
if let tuple = TorrentInfoDictionary.parseFilesDictionaries(files) {
|
||||||
|
return tuple
|
||||||
|
} else {
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
} else if let length = dictionary["length"] as? Int {
|
||||||
|
|
||||||
|
let md5sumData = dictionary["md5sum"] as? NSData
|
||||||
|
let md5sum = String(asciiData: md5sumData)
|
||||||
|
let files = [ TorrentFileInfo(path: name, length: length, md5sum: md5sum) ]
|
||||||
|
|
||||||
|
return (files, length)
|
||||||
|
|
||||||
|
} else {
|
||||||
|
|
||||||
|
return nil
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private class func parseFilesDictionaries(files: [ [ String : AnyObject ] ])
|
||||||
|
-> (files: [TorrentFileInfo], totalLength: Int)? {
|
||||||
|
|
||||||
|
var totalLength = 0
|
||||||
|
var result: [TorrentFileInfo] = []
|
||||||
|
|
||||||
|
for fileDictionary in files {
|
||||||
|
|
||||||
|
if let file = TorrentFileInfo(dictionary: fileDictionary) {
|
||||||
|
|
||||||
|
totalLength += file.length
|
||||||
|
result.append(file)
|
||||||
|
|
||||||
|
} else {
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
return (files: result, totalLength: totalLength)
|
||||||
|
}
|
||||||
|
|
||||||
|
private class func seperatePieces(pieces: NSData) -> [NSData]? {
|
||||||
|
if pieces.length % 20 != 0 {
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
var result: [NSData] = []
|
||||||
|
for index in 0.stride(to:pieces.length, by: 20) {
|
||||||
|
result.append(pieces.subdataWithRange(NSMakeRange(index, 20)))
|
||||||
|
}
|
||||||
|
return result
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
class TorrentFileInfo {
|
||||||
|
let path: String
|
||||||
|
let length: Int
|
||||||
|
let md5sum: String?
|
||||||
|
|
||||||
|
init(path: String, length: Int, md5sum: String?) {
|
||||||
|
self.path = path
|
||||||
|
self.length = length
|
||||||
|
self.md5sum = md5sum
|
||||||
|
}
|
||||||
|
|
||||||
|
convenience init?(dictionary: [ String : AnyObject ]) {
|
||||||
|
|
||||||
|
let pathData = dictionary["path"] as? NSData
|
||||||
|
let path = String(asciiData: pathData)
|
||||||
|
|
||||||
|
let length = dictionary["length"] as? Int
|
||||||
|
|
||||||
|
if let length = length, path = path {
|
||||||
|
|
||||||
|
let md5sumData = dictionary["md5sum"] as? NSData
|
||||||
|
let md5sum = String(asciiData: md5sumData)
|
||||||
|
|
||||||
|
self.init(path: path, length: length, md5sum: md5sum)
|
||||||
|
|
||||||
|
} else {
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,286 @@
|
|||||||
|
//
|
||||||
|
// TorrentMetaInfoTests.swift
|
||||||
|
// BitTorrent
|
||||||
|
//
|
||||||
|
// Created by Ben Davis on 25/03/2016.
|
||||||
|
// Copyright © 2016 Ben Davis. All rights reserved.
|
||||||
|
//
|
||||||
|
|
||||||
|
import XCTest
|
||||||
|
@testable import BitTorrent
|
||||||
|
import BEncode
|
||||||
|
|
||||||
|
class TorrentMetaInfoTests: XCTestCase {
|
||||||
|
|
||||||
|
let filePieceLength = 16384
|
||||||
|
let singleFilePiece = NSData(byteArray: [0x3f, 0x3f, 0x11, 0x09, 0x64, 0x07, 0x00, 0x3f, 0x42,
|
||||||
|
0x35, 0x3f, 0x3f, 0x59, 0x2e, 0x23, 0x13, 0x3f, 0x18, 0x23, 0x3e])
|
||||||
|
let torrentName = "Torrent Name"
|
||||||
|
let singleFileName = "test.txt"
|
||||||
|
let singleFileLength = 117
|
||||||
|
let singleFileMD5 = "c23d5ddec291bf9e27cb84657144388dc352472ca89709bbda80e680c82470e1"
|
||||||
|
let multipleFile1MD5 = "d8e624fda84296ba9e5af415faa5c2aa68960ce0578116a8507340438893bd85"
|
||||||
|
let multipleFile2MD5 = "e2ddfed708ea34db57b4a1ef7691776db5e24dff813706e4c695a6668f8fbabf"
|
||||||
|
let multipleFileLength1 = 116
|
||||||
|
let multipleFileLength2 = 115
|
||||||
|
let multipleFilePath1 = "/test/path"
|
||||||
|
let multipleFilePath2 = "/test/path2"
|
||||||
|
|
||||||
|
override func setUp() {
|
||||||
|
super.setUp()
|
||||||
|
}
|
||||||
|
|
||||||
|
override func tearDown() {
|
||||||
|
super.tearDown()
|
||||||
|
}
|
||||||
|
|
||||||
|
// MARK: - Create some example dictionaries
|
||||||
|
|
||||||
|
func singleFileInfoDictionary() -> [String:AnyObject] {
|
||||||
|
return [
|
||||||
|
"piece length" : filePieceLength,
|
||||||
|
"pieces" : createMultiplePieces(),
|
||||||
|
"name" : singleFileName,
|
||||||
|
"length" : singleFileLength,
|
||||||
|
]
|
||||||
|
}
|
||||||
|
|
||||||
|
func createMultiplePieces() -> NSData {
|
||||||
|
return NSMutableData(data: singleFilePiece).andData(singleFilePiece)
|
||||||
|
}
|
||||||
|
|
||||||
|
func multiFileInfoDictionary() -> [String:AnyObject] {
|
||||||
|
return multiFileInfoDictionary([
|
||||||
|
testFileDictionary(multipleFileLength1, path: multipleFilePath1, md5sum: multipleFile1MD5),
|
||||||
|
testFileDictionary(multipleFileLength2, path: multipleFilePath2, md5sum: multipleFile2MD5),
|
||||||
|
])
|
||||||
|
}
|
||||||
|
|
||||||
|
func multiFileInfoDictionary(files: [ [ String : AnyObject ] ]) -> [String:AnyObject] {
|
||||||
|
return [
|
||||||
|
"piece length" : filePieceLength,
|
||||||
|
"pieces" : createMultiplePieces(),
|
||||||
|
"name" : torrentName,
|
||||||
|
"files" : files,
|
||||||
|
]
|
||||||
|
}
|
||||||
|
|
||||||
|
func testFileDictionary(length: Int, path: String, md5sum: String?) -> [ String : AnyObject ] {
|
||||||
|
var result: [ String : AnyObject ] = [
|
||||||
|
"length" : length,
|
||||||
|
"path" : path,
|
||||||
|
]
|
||||||
|
if let md5sum = md5sum {
|
||||||
|
result.updateValue(md5sum, forKey:"md5sum")
|
||||||
|
}
|
||||||
|
return result
|
||||||
|
}
|
||||||
|
|
||||||
|
func exampleMetaInfoDictionary() -> NSData {
|
||||||
|
return self.metaInfoDictionaryWithInfoDictionary(singleFileInfoDictionary())
|
||||||
|
}
|
||||||
|
|
||||||
|
func metaInfoDictionaryWithInfoDictionary(infoDictionary: [String : AnyObject]) -> NSData {
|
||||||
|
return try! BEncode.BEncoder.encode( [ "info" : infoDictionary ] )
|
||||||
|
}
|
||||||
|
|
||||||
|
// MARK: -
|
||||||
|
|
||||||
|
func testCanInitialiseWithDictionary() {
|
||||||
|
let metaInfo = TorrentMetaInfo(data: self.exampleMetaInfoDictionary())!
|
||||||
|
let _ = metaInfo.infoHash
|
||||||
|
let _ = metaInfo.info
|
||||||
|
}
|
||||||
|
|
||||||
|
func testInfoDictionarySplitsPiecesInto20ByteChecksums() {
|
||||||
|
let metaInfo = TorrentMetaInfo(data: self.exampleMetaInfoDictionary())!
|
||||||
|
let info = metaInfo.info
|
||||||
|
XCTAssertEqual(info.pieces![0], singleFilePiece)
|
||||||
|
XCTAssertEqual(info.pieces![1], singleFilePiece)
|
||||||
|
}
|
||||||
|
|
||||||
|
func testProducesCorrectInfoHash() {
|
||||||
|
let path = NSBundle(forClass: self.dynamicType).pathForResource("TestText", ofType: "torrent")
|
||||||
|
let data = NSData(contentsOfFile: path!)!
|
||||||
|
let metaInfo = TorrentMetaInfo(data: data)!
|
||||||
|
|
||||||
|
let hash = NSData(byteArray:[ 0xf0, 0xb8, 0x71, 0x98, 0x99, 0x53, 0x97, 0x3f, 0xbf, 0xa9, 0x4d,
|
||||||
|
0xc8, 0x14, 0x98, 0xee, 0x8d, 0x20, 0x5b, 0xb2, 0x23])
|
||||||
|
|
||||||
|
XCTAssertEqual(hash, metaInfo.infoHash)
|
||||||
|
}
|
||||||
|
|
||||||
|
// MARK: - Test info dictionary
|
||||||
|
|
||||||
|
func testProducesCorrectCommonInfoDictionaryProperties() {
|
||||||
|
let metaInfo = TorrentMetaInfo(data: self.exampleMetaInfoDictionary())!
|
||||||
|
let info = metaInfo.info
|
||||||
|
|
||||||
|
XCTAssertEqual(info.name, singleFileName)
|
||||||
|
|
||||||
|
XCTAssertEqual(info.pieceLength, filePieceLength)
|
||||||
|
|
||||||
|
let piecesConcatenated = info.pieces!.reduce(NSMutableData()) {
|
||||||
|
(result: NSMutableData, item: NSData) in
|
||||||
|
return result.andData(item)
|
||||||
|
}
|
||||||
|
XCTAssertEqual(piecesConcatenated, createMultiplePieces())
|
||||||
|
}
|
||||||
|
|
||||||
|
func testIsPrivateIffPrivateKeyIsPresentAnd1() {
|
||||||
|
var infoDictionary = singleFileInfoDictionary()
|
||||||
|
|
||||||
|
infoDictionary.updateValue(1, forKey: "private")
|
||||||
|
var metainfo = TorrentMetaInfo(data: metaInfoDictionaryWithInfoDictionary(infoDictionary))!
|
||||||
|
XCTAssertTrue(metainfo.info.isPrivate)
|
||||||
|
|
||||||
|
infoDictionary.updateValue(0, forKey: "private")
|
||||||
|
metainfo = TorrentMetaInfo(data: metaInfoDictionaryWithInfoDictionary(infoDictionary))!
|
||||||
|
XCTAssertFalse(metainfo.info.isPrivate)
|
||||||
|
|
||||||
|
infoDictionary.removeValueForKey("private")
|
||||||
|
metainfo = TorrentMetaInfo(data: metaInfoDictionaryWithInfoDictionary(infoDictionary))!
|
||||||
|
XCTAssertFalse(metainfo.info.isPrivate)
|
||||||
|
}
|
||||||
|
|
||||||
|
// MARK: Single file info dictionary
|
||||||
|
|
||||||
|
func testInfoDictionaryForSingleFileTorrent() {
|
||||||
|
let metaInfo = TorrentMetaInfo(data: self.exampleMetaInfoDictionary())!
|
||||||
|
let info = metaInfo.info
|
||||||
|
|
||||||
|
XCTAssertEqual(info.length, singleFileLength)
|
||||||
|
|
||||||
|
XCTAssertEqual(info.files.count, 1)
|
||||||
|
|
||||||
|
let file = info.files[0]
|
||||||
|
XCTAssertEqual(file.length, singleFileLength)
|
||||||
|
XCTAssertEqual(file.path, singleFileName)
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
func testInfoDictionaryContainsMD5ChecksumIfPresentInSingleFile() {
|
||||||
|
var infoDictionary = singleFileInfoDictionary()
|
||||||
|
|
||||||
|
var metaInfo = TorrentMetaInfo(data: metaInfoDictionaryWithInfoDictionary(infoDictionary))!
|
||||||
|
var file = metaInfo.info.files[0]
|
||||||
|
XCTAssertNil(file.md5sum)
|
||||||
|
|
||||||
|
|
||||||
|
infoDictionary.updateValue(singleFileMD5, forKey: "md5sum")
|
||||||
|
metaInfo = TorrentMetaInfo(data: metaInfoDictionaryWithInfoDictionary(infoDictionary))!
|
||||||
|
file = metaInfo.info.files[0]
|
||||||
|
|
||||||
|
XCTAssertEqual(file.md5sum, singleFileMD5)
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
func testInitializerReturnsNilOnInvalidInfoDictionaryForSingleFile() {
|
||||||
|
|
||||||
|
var infoDictionary = singleFileInfoDictionary()
|
||||||
|
infoDictionary.removeValueForKey("name")
|
||||||
|
var metaInfoDictionary = metaInfoDictionaryWithInfoDictionary(infoDictionary)
|
||||||
|
|
||||||
|
XCTAssertNil(TorrentMetaInfo(data: metaInfoDictionary))
|
||||||
|
|
||||||
|
infoDictionary = singleFileInfoDictionary()
|
||||||
|
infoDictionary.removeValueForKey("piece length")
|
||||||
|
metaInfoDictionary = metaInfoDictionaryWithInfoDictionary(infoDictionary)
|
||||||
|
|
||||||
|
XCTAssertNil(TorrentMetaInfo(data: metaInfoDictionary))
|
||||||
|
|
||||||
|
infoDictionary = singleFileInfoDictionary()
|
||||||
|
infoDictionary.removeValueForKey("pieces")
|
||||||
|
metaInfoDictionary = metaInfoDictionaryWithInfoDictionary(infoDictionary)
|
||||||
|
|
||||||
|
XCTAssertNil(TorrentMetaInfo(data: metaInfoDictionary))
|
||||||
|
|
||||||
|
infoDictionary = singleFileInfoDictionary()
|
||||||
|
infoDictionary.updateValue(NSData(byteArray: [1,2,3]), forKey: "pieces")
|
||||||
|
metaInfoDictionary = metaInfoDictionaryWithInfoDictionary(infoDictionary)
|
||||||
|
|
||||||
|
XCTAssertNil(TorrentMetaInfo(data: metaInfoDictionary))
|
||||||
|
|
||||||
|
infoDictionary = singleFileInfoDictionary()
|
||||||
|
infoDictionary.updateValue(NSMutableData(length: 21)!, forKey: "pieces")
|
||||||
|
metaInfoDictionary = metaInfoDictionaryWithInfoDictionary(infoDictionary)
|
||||||
|
|
||||||
|
XCTAssertNil(TorrentMetaInfo(data: metaInfoDictionary))
|
||||||
|
}
|
||||||
|
|
||||||
|
// MARK: Multiple file info dictionary
|
||||||
|
|
||||||
|
func testInfoDictionaryForMultipleFileTorrent() {
|
||||||
|
let infoDictionary = multiFileInfoDictionary()
|
||||||
|
let metaInfoDictionary = metaInfoDictionaryWithInfoDictionary(infoDictionary)
|
||||||
|
let metaInfo = TorrentMetaInfo(data: metaInfoDictionary)!
|
||||||
|
let info = metaInfo.info
|
||||||
|
|
||||||
|
XCTAssertEqual(info.length, multipleFileLength1 + multipleFileLength2)
|
||||||
|
|
||||||
|
XCTAssertEqual(info.files.count, 2)
|
||||||
|
|
||||||
|
let file1 = info.files[0]
|
||||||
|
XCTAssertEqual(file1.length, multipleFileLength1)
|
||||||
|
XCTAssertEqual(file1.path, multipleFilePath1)
|
||||||
|
|
||||||
|
let file2 = info.files[1]
|
||||||
|
XCTAssertEqual(file2.length, multipleFileLength2)
|
||||||
|
XCTAssertEqual(file2.path, multipleFilePath2)
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
func testInfoDictionaryContainsMD5ChecksumIfPresentInMultipleFiles() {
|
||||||
|
|
||||||
|
var infoDictionary = multiFileInfoDictionary()
|
||||||
|
var metaInfoDictionary = metaInfoDictionaryWithInfoDictionary(infoDictionary)
|
||||||
|
var metaInfo = TorrentMetaInfo(data: metaInfoDictionary)!
|
||||||
|
var file1 = metaInfo.info.files[0]
|
||||||
|
var file2 = metaInfo.info.files[1]
|
||||||
|
|
||||||
|
XCTAssertEqual(file1.md5sum, multipleFile1MD5)
|
||||||
|
XCTAssertEqual(file2.md5sum, multipleFile2MD5)
|
||||||
|
|
||||||
|
|
||||||
|
infoDictionary.updateValue(multipleFile1MD5, forKey: "md5sum")
|
||||||
|
|
||||||
|
infoDictionary = multiFileInfoDictionary([
|
||||||
|
[ "length" : multipleFileLength1, "path" : multipleFilePath1 ],
|
||||||
|
[ "length" : multipleFileLength2, "path" : multipleFilePath2 ],
|
||||||
|
])
|
||||||
|
metaInfoDictionary = metaInfoDictionaryWithInfoDictionary(infoDictionary)
|
||||||
|
metaInfo = TorrentMetaInfo(data: metaInfoDictionary)!
|
||||||
|
file1 = metaInfo.info.files[0]
|
||||||
|
file2 = metaInfo.info.files[1]
|
||||||
|
|
||||||
|
XCTAssertNil(file1.md5sum)
|
||||||
|
XCTAssertNil(file2.md5sum)
|
||||||
|
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
func testInitializerReturnsNilOnInvalidInfoDictionaryForMultipleFiles() {
|
||||||
|
|
||||||
|
var infoDictionary = multiFileInfoDictionary()
|
||||||
|
infoDictionary.removeValueForKey("files")
|
||||||
|
var metaInfoDictionary = metaInfoDictionaryWithInfoDictionary(infoDictionary)
|
||||||
|
XCTAssertNil(TorrentMetaInfo(data: metaInfoDictionary))
|
||||||
|
|
||||||
|
infoDictionary = multiFileInfoDictionary([
|
||||||
|
[ "length" : multipleFileLength1, "path" : multipleFilePath1 ],
|
||||||
|
[ "length" : multipleFileLength2 ],
|
||||||
|
])
|
||||||
|
metaInfoDictionary = metaInfoDictionaryWithInfoDictionary(infoDictionary)
|
||||||
|
XCTAssertNil(TorrentMetaInfo(data: metaInfoDictionary))
|
||||||
|
|
||||||
|
infoDictionary = multiFileInfoDictionary([
|
||||||
|
[ "length" : multipleFileLength1, "path" : multipleFilePath1 ],
|
||||||
|
[ "path" : multipleFilePath2 ],
|
||||||
|
])
|
||||||
|
metaInfoDictionary = metaInfoDictionaryWithInfoDictionary(infoDictionary)
|
||||||
|
XCTAssertNil(TorrentMetaInfo(data: metaInfoDictionary))
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
}
|
||||||
@@ -0,0 +1,22 @@
|
|||||||
|
//
|
||||||
|
// NSData+sha1.swift
|
||||||
|
// BitTorrent
|
||||||
|
//
|
||||||
|
// Created by Ben Davis on 25/03/2016.
|
||||||
|
// Copyright © 2016 Ben Davis. All rights reserved.
|
||||||
|
//
|
||||||
|
|
||||||
|
import Foundation
|
||||||
|
import CommonCrypto
|
||||||
|
|
||||||
|
extension NSData {
|
||||||
|
|
||||||
|
func sha1() -> NSData {
|
||||||
|
let outputLength = Int(CC_SHA1_DIGEST_LENGTH)
|
||||||
|
var digest = [UInt8](count:Int(CC_SHA1_DIGEST_LENGTH), repeatedValue: 0)
|
||||||
|
CC_SHA1(self.bytes, CC_LONG(self.length), &digest)
|
||||||
|
let bytesPointer = UnsafePointer<Void>(digest)
|
||||||
|
return NSData(bytes: bytesPointer, length: outputLength)
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
@@ -0,0 +1,11 @@
|
|||||||
|
//
|
||||||
|
// CommonCrypto.xcconfig
|
||||||
|
// BitTorrent
|
||||||
|
//
|
||||||
|
// Created by Ben Davis on 25/03/2016.
|
||||||
|
// Copyright © 2016 Ben Davis. All rights reserved.
|
||||||
|
//
|
||||||
|
|
||||||
|
MODULEMAP_FILE[sdk=iphoneos*] = $(SRCROOT)/CommonCrypto/iphoneos.modulemap
|
||||||
|
MODULEMAP_FILE[sdk=iphonesimulator*] = $(SRCROOT)/CommonCrypto/iphonesimulator.modulemap
|
||||||
|
MODULEMAP_FILE[sdk=macosx*] = $(SRCROOT)/CommonCrypto/macosx.modulemap
|
||||||
@@ -0,0 +1,26 @@
|
|||||||
|
<?xml version="1.0" encoding="UTF-8"?>
|
||||||
|
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
|
||||||
|
<plist version="1.0">
|
||||||
|
<dict>
|
||||||
|
<key>CFBundleDevelopmentRegion</key>
|
||||||
|
<string>en</string>
|
||||||
|
<key>CFBundleExecutable</key>
|
||||||
|
<string>$(EXECUTABLE_NAME)</string>
|
||||||
|
<key>CFBundleIdentifier</key>
|
||||||
|
<string>$(PRODUCT_BUNDLE_IDENTIFIER)</string>
|
||||||
|
<key>CFBundleInfoDictionaryVersion</key>
|
||||||
|
<string>6.0</string>
|
||||||
|
<key>CFBundleName</key>
|
||||||
|
<string>$(PRODUCT_NAME)</string>
|
||||||
|
<key>CFBundlePackageType</key>
|
||||||
|
<string>FMWK</string>
|
||||||
|
<key>CFBundleShortVersionString</key>
|
||||||
|
<string>1.0</string>
|
||||||
|
<key>CFBundleSignature</key>
|
||||||
|
<string>????</string>
|
||||||
|
<key>CFBundleVersion</key>
|
||||||
|
<string>$(CURRENT_PROJECT_VERSION)</string>
|
||||||
|
<key>NSPrincipalClass</key>
|
||||||
|
<string></string>
|
||||||
|
</dict>
|
||||||
|
</plist>
|
||||||
@@ -0,0 +1,4 @@
|
|||||||
|
module CommonCrypto [system] {
|
||||||
|
header "/Applications/Xcode.app/Contents/Developer/Platforms/iPhoneOS.platform/Developer/SDKs/iPhoneOS.sdk/usr/include/CommonCrypto/CommonCrypto.h"
|
||||||
|
export *
|
||||||
|
}
|
||||||
@@ -0,0 +1,4 @@
|
|||||||
|
module CommonCrypto [system] {
|
||||||
|
header "/Applications/Xcode.app/Contents/Developer/Platforms/iPhoneSimulator.platform/Developer/SDKs/iPhoneSimulator.sdk/usr/include/CommonCrypto/CommonCrypto.h"
|
||||||
|
export *
|
||||||
|
}
|
||||||
@@ -0,0 +1,4 @@
|
|||||||
|
module CommonCrypto [system] {
|
||||||
|
header "/Applications/Xcode.app/Contents/Developer/Platforms/MacOSX.platform/Developer/SDKs/MacOSX10.11.sdk/usr/include/CommonCrypto/CommonCrypto.h"
|
||||||
|
export *
|
||||||
|
}
|
||||||
Binary file not shown.
Reference in New Issue
Block a user