ソースを参照

Update to Swift 3.0

Norio Nomura 9 年 前
コミット
a4514c4e08

+ 4 - 18
Base32.xcodeproj/project.pbxproj

@@ -15,11 +15,8 @@
 		6C122F7E1A85E52C004FD458 /* StringExtension.swift in Sources */ = {isa = PBXBuildFile; fileRef = 6C122F7C1A85E52C004FD458 /* StringExtension.swift */; };
 		6C122F801A85E885004FD458 /* Base16Tests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 6C122F7F1A85E885004FD458 /* Base16Tests.swift */; };
 		6C122F811A85E885004FD458 /* Base16Tests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 6C122F7F1A85E885004FD458 /* Base16Tests.swift */; };
-		6C122F821A85EA0A004FD458 /* StringExtension.swift in Sources */ = {isa = PBXBuildFile; fileRef = 6C122F7C1A85E52C004FD458 /* StringExtension.swift */; };
-		6C122F831A85EA0B004FD458 /* StringExtension.swift in Sources */ = {isa = PBXBuildFile; fileRef = 6C122F7C1A85E52C004FD458 /* StringExtension.swift */; };
 		6C122F851A85EA52004FD458 /* StringExtensionTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 6C122F841A85EA52004FD458 /* StringExtensionTests.swift */; };
 		6C122F861A85EA52004FD458 /* StringExtensionTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 6C122F841A85EA52004FD458 /* StringExtensionTests.swift */; };
-		6C122F871A85F332004FD458 /* StringExtension.swift in Sources */ = {isa = PBXBuildFile; fileRef = 6C122F7C1A85E52C004FD458 /* StringExtension.swift */; };
 		6CA0A79E1A74E80600AC539F /* Base32.h in Headers */ = {isa = PBXBuildFile; fileRef = 6CA0A79D1A74E80600AC539F /* Base32.h */; settings = {ATTRIBUTES = (Public, ); }; };
 		6CA0A7A41A74E80600AC539F /* Base32.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 6CA0A7981A74E80600AC539F /* Base32.framework */; };
 		6CA0A7AB1A74E80600AC539F /* Base32Tests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 6CA0A7AA1A74E80600AC539F /* Base32Tests.swift */; };
@@ -609,7 +606,6 @@
 				6C122F851A85EA52004FD458 /* StringExtensionTests.swift in Sources */,
 				6CA0A7AB1A74E80600AC539F /* Base32Tests.swift in Sources */,
 				6C122F801A85E885004FD458 /* Base16Tests.swift in Sources */,
-				6C122F821A85EA0A004FD458 /* StringExtension.swift in Sources */,
 			);
 			runOnlyForDeploymentPostprocessing = 0;
 		};
@@ -630,7 +626,6 @@
 				6C122F861A85EA52004FD458 /* StringExtensionTests.swift in Sources */,
 				6CA0A7EE1A74ECD700AC539F /* Base32Tests.swift in Sources */,
 				6C122F811A85E885004FD458 /* Base16Tests.swift in Sources */,
-				6C122F831A85EA0B004FD458 /* StringExtension.swift in Sources */,
 			);
 			runOnlyForDeploymentPostprocessing = 0;
 		};
@@ -640,7 +635,6 @@
 			files = (
 				6CA0A80C1A75135D00AC539F /* SecEncodeTransformTests.swift in Sources */,
 				6C10E91A1A754346006EED90 /* TTTDataTransformer.m in Sources */,
-				6C122F871A85F332004FD458 /* StringExtension.swift in Sources */,
 			);
 			runOnlyForDeploymentPostprocessing = 0;
 		};
@@ -688,6 +682,7 @@
 				IPHONEOS_DEPLOYMENT_TARGET = 8.0;
 				MACOSX_DEPLOYMENT_TARGET = 10.9;
 				ONLY_ACTIVE_ARCH = YES;
+				SWIFT_VERSION = 3.0;
 				TARGETED_DEVICE_FAMILY = "1,2";
 				VERSIONING_SYSTEM = "apple-generic";
 				VERSION_INFO_PREFIX = "";
@@ -705,6 +700,7 @@
 				GCC_NO_COMMON_BLOCKS = YES;
 				IPHONEOS_DEPLOYMENT_TARGET = 8.0;
 				MACOSX_DEPLOYMENT_TARGET = 10.9;
+				SWIFT_VERSION = 3.0;
 				TARGETED_DEVICE_FAMILY = "1,2";
 				VERSIONING_SYSTEM = "apple-generic";
 				VERSION_INFO_PREFIX = "";
@@ -720,7 +716,7 @@
 				DYLIB_CURRENT_VERSION = 1;
 				INFOPLIST_FILE = Base32/Info.plist;
 				PRODUCT_BUNDLE_IDENTIFIER = "io.github.norio-nomura.$(PRODUCT_NAME:rfc1034identifier)";
-				SWIFT_VERSION = 2.3;
+				SWIFT_VERSION = 3.0;
 			};
 			name = Debug;
 		};
@@ -733,7 +729,7 @@
 				DYLIB_CURRENT_VERSION = 1;
 				INFOPLIST_FILE = Base32/Info.plist;
 				PRODUCT_BUNDLE_IDENTIFIER = "io.github.norio-nomura.$(PRODUCT_NAME:rfc1034identifier)";
-				SWIFT_VERSION = 2.3;
+				SWIFT_VERSION = 3.0;
 			};
 			name = Release;
 		};
@@ -744,7 +740,6 @@
 				INFOPLIST_FILE = Base32Tests/Info.plist;
 				PRODUCT_BUNDLE_IDENTIFIER = "io.github.norio-nomura.$(PRODUCT_NAME:rfc1034identifier)";
 				PRODUCT_NAME = "$(TARGET_NAME)";
-				SWIFT_VERSION = 2.3;
 			};
 			name = Debug;
 		};
@@ -755,7 +750,6 @@
 				INFOPLIST_FILE = Base32Tests/Info.plist;
 				PRODUCT_BUNDLE_IDENTIFIER = "io.github.norio-nomura.$(PRODUCT_NAME:rfc1034identifier)";
 				PRODUCT_NAME = "$(TARGET_NAME)";
-				SWIFT_VERSION = 2.3;
 			};
 			name = Release;
 		};
@@ -769,7 +763,6 @@
 				DYLIB_CURRENT_VERSION = 1;
 				INFOPLIST_FILE = Base32/Info.plist;
 				PRODUCT_BUNDLE_IDENTIFIER = "io.github.norio-nomura.$(PRODUCT_NAME:rfc1034identifier)";
-				SWIFT_VERSION = 2.3;
 			};
 			name = Debug;
 		};
@@ -783,7 +776,6 @@
 				DYLIB_CURRENT_VERSION = 1;
 				INFOPLIST_FILE = Base32/Info.plist;
 				PRODUCT_BUNDLE_IDENTIFIER = "io.github.norio-nomura.$(PRODUCT_NAME:rfc1034identifier)";
-				SWIFT_VERSION = 2.3;
 			};
 			name = Release;
 		};
@@ -794,7 +786,6 @@
 				INFOPLIST_FILE = Base32Tests/Info.plist;
 				PRODUCT_BUNDLE_IDENTIFIER = "io.github.norio-nomura.$(PRODUCT_NAME:rfc1034identifier)";
 				PRODUCT_NAME = "$(TARGET_NAME)";
-				SWIFT_VERSION = 2.3;
 			};
 			name = Debug;
 		};
@@ -805,7 +796,6 @@
 				INFOPLIST_FILE = Base32Tests/Info.plist;
 				PRODUCT_BUNDLE_IDENTIFIER = "io.github.norio-nomura.$(PRODUCT_NAME:rfc1034identifier)";
 				PRODUCT_NAME = "$(TARGET_NAME)";
-				SWIFT_VERSION = 2.3;
 			};
 			name = Release;
 		};
@@ -817,7 +807,6 @@
 				PRODUCT_BUNDLE_IDENTIFIER = "io.github.norio-nomura.$(PRODUCT_NAME:rfc1034identifier)";
 				PRODUCT_NAME = "$(TARGET_NAME)";
 				SWIFT_OBJC_BRIDGING_HEADER = "SecEncodeTransformTests/SecEncodeTransformTests-Bridging-Header.h";
-				SWIFT_VERSION = 2.3;
 			};
 			name = Debug;
 		};
@@ -829,7 +818,6 @@
 				PRODUCT_BUNDLE_IDENTIFIER = "io.github.norio-nomura.$(PRODUCT_NAME:rfc1034identifier)";
 				PRODUCT_NAME = "$(TARGET_NAME)";
 				SWIFT_OBJC_BRIDGING_HEADER = "SecEncodeTransformTests/SecEncodeTransformTests-Bridging-Header.h";
-				SWIFT_VERSION = 2.3;
 			};
 			name = Release;
 		};
@@ -843,7 +831,6 @@
 				DYLIB_CURRENT_VERSION = 1;
 				INFOPLIST_FILE = Base32/Info.plist;
 				PRODUCT_BUNDLE_IDENTIFIER = "io.github.norio-nomura.$(PRODUCT_NAME:rfc1034identifier)";
-				SWIFT_VERSION = 2.3;
 				TARGETED_DEVICE_FAMILY = 4;
 				WATCHOS_DEPLOYMENT_TARGET = 2.0;
 			};
@@ -859,7 +846,6 @@
 				DYLIB_CURRENT_VERSION = 1;
 				INFOPLIST_FILE = Base32/Info.plist;
 				PRODUCT_BUNDLE_IDENTIFIER = "io.github.norio-nomura.$(PRODUCT_NAME:rfc1034identifier)";
-				SWIFT_VERSION = 2.3;
 				TARGETED_DEVICE_FAMILY = 4;
 				WATCHOS_DEPLOYMENT_TARGET = 2.0;
 			};

+ 3 - 2
Base32.xcodeproj/xcshareddata/xcschemes/Base32-Mac.xcscheme

@@ -37,10 +37,11 @@
       </BuildActionEntries>
    </BuildAction>
    <TestAction
-      buildConfiguration = "Release"
+      buildConfiguration = "Debug"
       selectedDebuggerIdentifier = "Xcode.DebuggerFoundation.Debugger.LLDB"
       selectedLauncherIdentifier = "Xcode.DebuggerFoundation.Launcher.LLDB"
-      shouldUseLaunchSchemeArgsEnv = "YES">
+      shouldUseLaunchSchemeArgsEnv = "YES"
+      codeCoverageEnabled = "YES">
       <Testables>
          <TestableReference
             skipped = "NO">

+ 3 - 2
Base32.xcodeproj/xcshareddata/xcschemes/Base32-iOS.xcscheme

@@ -37,10 +37,11 @@
       </BuildActionEntries>
    </BuildAction>
    <TestAction
-      buildConfiguration = "Release"
+      buildConfiguration = "Debug"
       selectedDebuggerIdentifier = "Xcode.DebuggerFoundation.Debugger.LLDB"
       selectedLauncherIdentifier = "Xcode.DebuggerFoundation.Launcher.LLDB"
-      shouldUseLaunchSchemeArgsEnv = "YES">
+      shouldUseLaunchSchemeArgsEnv = "YES"
+      codeCoverageEnabled = "YES">
       <Testables>
          <TestableReference
             skipped = "NO">

+ 2 - 1
Base32.xcodeproj/xcshareddata/xcschemes/Base32-watchOS.xcscheme

@@ -26,7 +26,8 @@
       buildConfiguration = "Debug"
       selectedDebuggerIdentifier = "Xcode.DebuggerFoundation.Debugger.LLDB"
       selectedLauncherIdentifier = "Xcode.DebuggerFoundation.Launcher.LLDB"
-      shouldUseLaunchSchemeArgsEnv = "YES">
+      shouldUseLaunchSchemeArgsEnv = "YES"
+      codeCoverageEnabled = "YES">
       <Testables>
       </Testables>
       <AdditionalOptions>

+ 2 - 1
Base32.xcodeproj/xcshareddata/xcschemes/SecEncodeTransformTests.xcscheme

@@ -26,7 +26,8 @@
       buildConfiguration = "Release"
       selectedDebuggerIdentifier = "Xcode.DebuggerFoundation.Debugger.LLDB"
       selectedLauncherIdentifier = "Xcode.DebuggerFoundation.Launcher.LLDB"
-      shouldUseLaunchSchemeArgsEnv = "YES">
+      shouldUseLaunchSchemeArgsEnv = "YES"
+      codeCoverageEnabled = "YES">
       <Testables>
          <TestableReference
             skipped = "NO">

+ 29 - 37
Base32/Base16.swift

@@ -26,27 +26,25 @@
 
 import Foundation
 
-// MARK: - Base16 NSData <-> String
+// MARK: - Base16 Data <-> String
 
-public func base16Encode(data: NSData, uppercase: Bool = true) -> String {
-    return base16encode(data.bytes, data.length, uppercase)
+public func base16Encode(_ data: Data, uppercase: Bool = true) -> String {
+    return data.withUnsafeBytes {
+        base16encode(UnsafeRawPointer($0), data.count, uppercase)
+    }
 }
 
-public func base16DecodeToData(string: String) -> NSData? {
-    if let array = base16decode(string) {
-        return NSData(bytes: array, length: array.count)
-    } else {
-        return nil
-    }
+public func base16DecodeToData(_ string: String) -> Data? {
+    return base16decode(string)?.withUnsafeBufferPointer(Data.init(buffer:))
 }
 
 // MARK: - Base16 [UInt8] <-> String
 
-public func base16Encode(array: [UInt8], uppercase: Bool = true) -> String {
+public func base16Encode(_ array: [UInt8], uppercase: Bool = true) -> String {
     return base16encode(array, array.count, uppercase)
 }
 
-public func base16Decode(string: String) -> [UInt8]? {
+public func base16Decode(_ string: String) -> [UInt8]? {
     return base16decode(string)
 }
 
@@ -54,57 +52,51 @@ public func base16Decode(string: String) -> [UInt8]? {
 
 extension String {
     // base16
-    public var base16DecodedData: NSData? {
+    public var base16DecodedData: Data? {
         return base16DecodeToData(self)
     }
     
     public var base16EncodedString: String {
-        return nulTerminatedUTF8.withUnsafeBufferPointer {
-            return base16encode($0.baseAddress, $0.count - 1)
+        return utf8CString.withUnsafeBufferPointer {
+            base16encode($0.baseAddress!, $0.count - 1)
         }
     }
     
-    public func base16DecodedString(encoding: NSStringEncoding = NSUTF8StringEncoding) -> String? {
-        if let data = self.base16DecodedData {
-            return NSString(data: data, encoding: NSUTF8StringEncoding) as? String
-        } else {
-            return nil
+    public func base16DecodedString(_ encoding: String.Encoding = .utf8) -> String? {
+        return base16DecodedData.flatMap {
+            String(data: $0, encoding: .utf8)
         }
     }
 }
 
-extension NSData {
+extension Data {
     // base16
     public var base16EncodedString: String {
         return base16Encode(self)
     }
     
-    public var base16EncodedData: NSData {
+    public var base16EncodedData: Data {
         return base16EncodedString.dataUsingUTF8StringEncoding
     }
     
-    public var base16DecodedData: NSData? {
-        if let string = NSString(data: self, encoding: NSUTF8StringEncoding) as? String {
-            return base16DecodeToData(string)
-        } else {
-            return nil
-        }
+    public var base16DecodedData: Data? {
+        return String(data: self, encoding: .utf8).flatMap(base16DecodeToData)
     }
 }
 
 // MARK: encode
-private func base16encode(data: UnsafePointer<Void>, _ length: Int, _ uppercase: Bool = true) -> String {
-    let array = UnsafeBufferPointer<UInt8>(start: UnsafePointer<UInt8>(data), count: length)
-    return array.map { String(format: uppercase ? "%02X" : "%02x", $0) }.reduce("", combine: +)
+private func base16encode(_ data: UnsafeRawPointer, _ length: Int, _ uppercase: Bool = true) -> String {
+    let array = UnsafeBufferPointer.init(start: data.bindMemory(to: UInt8.self, capacity: length), count: length)
+    return array.map { String(format: uppercase ? "%02X" : "%02x", $0) }.reduce("", +)
 }
 
 // MARK: decode
 extension UnicodeScalar {
-    private var hexToUInt8: UInt8? {
+    fileprivate var hexToUInt8: UInt8? {
         switch self {
         case "0"..."9": return UInt8(value - UnicodeScalar("0").value)
-        case "a"..."f": return UInt8(value - UnicodeScalar("a").value + 0xa)
-        case "A"..."F": return UInt8(value - UnicodeScalar("A").value + 0xa)
+        case "a"..."f": return 0xa + UInt8(value - UnicodeScalar("a").value)
+        case "A"..."F": return 0xa + UInt8(value - UnicodeScalar("A").value)
         default:
             print("base16decode: Invalid hex character \(self)")
             return nil
@@ -112,15 +104,15 @@ extension UnicodeScalar {
     }
 }
 
-private func base16decode(string: String) -> [UInt8]? {
+private func base16decode(_ string: String) -> [UInt8]? {
     // validate length
-    let lenght = string.nulTerminatedUTF8.count - 1
+    let lenght = string.utf8CString.count - 1
     if lenght % 2 != 0 {
         print("base16decode: String must contain even number of characters")
         return nil
     }
-    var g = string.unicodeScalars.generate()
-    var buffer = Array<UInt8>(count: lenght / 2, repeatedValue: 0)
+    var g = string.unicodeScalars.makeIterator()
+    var buffer = Array<UInt8>(repeating: 0, count: lenght / 2)
     var index = 0
     while let msn = g.next() {
         if let msn = msn.hexToUInt8 {

+ 67 - 84
Base32/Base32.swift

@@ -28,47 +28,47 @@ import Foundation
 
 // https://tools.ietf.org/html/rfc4648
 
-// MARK: - Base32 NSData <-> String
+// MARK: - Base32 Data <-> String
 
-public func base32Encode(data: NSData) -> String {
-    return base32encode(data.bytes, data.length, alphabetEncodeTable)
+public func base32Encode(_ data: Data) -> String {
+    return data.withUnsafeBytes {
+        base32encode(UnsafeRawPointer($0), data.count, alphabetEncodeTable)
+    }
 }
 
-public func base32HexEncode(data: NSData) -> String {
-    return base32encode(data.bytes, data.length, extendedHexAlphabetEncodeTable)
+public func base32HexEncode(_ data: Data) -> String {
+    return data.withUnsafeBytes {
+        base32encode(UnsafeRawPointer($0), data.count, extendedHexAlphabetEncodeTable)
+    }
 }
 
-public func base32DecodeToData(string: String) -> NSData? {
-    if let array = base32decode(string, alphabetDecodeTable) {
-        return NSData(bytes: array, length: array.count)
-    } else {
-        return nil
+public func base32DecodeToData(_ string: String) -> Data? {
+    return base32decode(string, alphabetDecodeTable).flatMap {
+        Data(bytes: UnsafePointer<UInt8>($0), count: $0.count)
     }
 }
 
-public func base32HexDecodeToData(string: String) -> NSData? {
-    if let array = base32decode(string, extendedHexAlphabetDecodeTable) {
-        return NSData(bytes: array, length: array.count)
-    } else {
-        return nil
+public func base32HexDecodeToData(_ string: String) -> Data? {
+    return base32decode(string, extendedHexAlphabetDecodeTable).flatMap {
+        Data(bytes: UnsafePointer<UInt8>($0), count: $0.count)
     }
 }
 
 // MARK: - Base32 [UInt8] <-> String
 
-public func base32Encode(array: [UInt8]) -> String {
+public func base32Encode(_ array: [UInt8]) -> String {
     return base32encode(array, array.count, alphabetEncodeTable)
 }
 
-public func base32HexEncode(array: [UInt8]) -> String {
+public func base32HexEncode(_ array: [UInt8]) -> String {
     return base32encode(array, array.count, extendedHexAlphabetEncodeTable)
 }
 
-public func base32Decode(string: String) -> [UInt8]? {
+public func base32Decode(_ string: String) -> [UInt8]? {
     return base32decode(string, alphabetDecodeTable)
 }
 
-public func base32HexDecode(string: String) -> [UInt8]? {
+public func base32HexDecode(_ string: String) -> [UInt8]? {
     return base32decode(string, extendedHexAlphabetDecodeTable)
 }
 
@@ -76,60 +76,52 @@ public func base32HexDecode(string: String) -> [UInt8]? {
 
 extension String {
     // base32
-    public var base32DecodedData: NSData? {
+    public var base32DecodedData: Data? {
         return base32DecodeToData(self)
     }
     
     public var base32EncodedString: String {
-        return nulTerminatedUTF8.withUnsafeBufferPointer {
-            return base32encode($0.baseAddress, $0.count - 1, alphabetEncodeTable)
+        return utf8CString.withUnsafeBufferPointer {
+            base32encode($0.baseAddress!, $0.count - 1, alphabetEncodeTable)
         }
     }
     
-    public func base32DecodedString(encoding: NSStringEncoding = NSUTF8StringEncoding) -> String? {
-        if let data = self.base32DecodedData {
-            return NSString(data: data, encoding: NSUTF8StringEncoding) as? String
-        } else {
-            return nil
+    public func base32DecodedString(_ encoding: String.Encoding = .utf8) -> String? {
+        return base32DecodedData.flatMap {
+            String(data: $0, encoding: .utf8)
         }
     }
 
     // base32Hex
-    public var base32HexDecodedData: NSData? {
+    public var base32HexDecodedData: Data? {
         return base32HexDecodeToData(self)
     }
     
     public var base32HexEncodedString: String {
-        return nulTerminatedUTF8.withUnsafeBufferPointer {
-            return base32encode($0.baseAddress, $0.count - 1, extendedHexAlphabetEncodeTable)
+        return utf8CString.withUnsafeBufferPointer {
+            base32encode($0.baseAddress!, $0.count - 1, extendedHexAlphabetEncodeTable)
         }
     }
     
-    public func base32HexDecodedString(encoding: NSStringEncoding = NSUTF8StringEncoding) -> String? {
-        if let data = self.base32HexDecodedData {
-            return NSString(data: data, encoding: NSUTF8StringEncoding) as? String
-        } else {
-            return nil
+    public func base32HexDecodedString(_ encoding: String.Encoding = .utf8) -> String? {
+        return base32HexDecodedData.flatMap {
+            String(data: $0, encoding: .utf8)
         }
     }
 }
 
-extension NSData {
+extension Data {
     // base32
     public var base32EncodedString: String {
         return base32Encode(self)
     }
     
-    public var base32EncodedData: NSData {
+    public var base32EncodedData: Data {
         return base32EncodedString.dataUsingUTF8StringEncoding
     }
     
-    public var base32DecodedData: NSData? {
-        if let string = NSString(data: self, encoding: NSUTF8StringEncoding) as? String {
-            return base32DecodeToData(string)
-        } else {
-            return nil
-        }
+    public var base32DecodedData: Data? {
+        return String(data: self, encoding: .utf8).flatMap(base32DecodeToData)
     }
 
     // base32Hex
@@ -137,16 +129,12 @@ extension NSData {
         return base32HexEncode(self)
     }
     
-    public var base32HexEncodedData: NSData {
+    public var base32HexEncodedData: Data {
         return base32HexEncodedString.dataUsingUTF8StringEncoding
     }
     
-    public var base32HexDecodedData: NSData? {
-        if let string = NSString(data: self, encoding: NSUTF8StringEncoding) as? String {
-            return base32HexDecodeToData(string)
-        } else {
-            return nil
-        }
+    public var base32HexDecodedData: Data? {
+        return String(data: self, encoding: .utf8).flatMap(base32HexDecodeToData)
     }
 }
 
@@ -154,26 +142,20 @@ extension NSData {
 
 // MARK: encode
 
-extension Int8: UnicodeScalarLiteralConvertible {
-    public init(unicodeScalarLiteral value: UnicodeScalar) {
-        self.init(value.value)
-    }
-}
-
-let alphabetEncodeTable: [Int8] = ["A","B","C","D","E","F","G","H","I","J","K","L","M","N","O","P","Q","R","S","T","U","V","W","X","Y","Z","2","3","4","5","6","7"]
+let alphabetEncodeTable: [Int8] = ["A","B","C","D","E","F","G","H","I","J","K","L","M","N","O","P","Q","R","S","T","U","V","W","X","Y","Z","2","3","4","5","6","7"].map { (c: UnicodeScalar) -> Int8 in Int8(c.value) }
 
-let extendedHexAlphabetEncodeTable: [Int8] = ["0","1","2","3","4","5","6","7","8","9","A","B","C","D","E","F","G","H","I","J","K","L","M","N","O","P","Q","R","S","T","U","V"]
+let extendedHexAlphabetEncodeTable: [Int8] = ["0","1","2","3","4","5","6","7","8","9","A","B","C","D","E","F","G","H","I","J","K","L","M","N","O","P","Q","R","S","T","U","V"].map { (c: UnicodeScalar) -> Int8 in Int8(c.value) }
 
-private func base32encode(data: UnsafePointer<Void>, _ length: Int, _ table: [Int8]) -> String {
+private func base32encode(_ data: UnsafeRawPointer, _ length: Int, _ table: [Int8]) -> String {
     if length == 0 {
         return ""
     }
     var length = length
     
-    var bytes = UnsafePointer<UInt8>(data)
+    var bytes = data.assumingMemoryBound(to: UInt8.self)
     
     let resultBufferSize = Int(ceil(Double(length) / 5)) * 8 + 1    // need null termination
-    let resultBuffer = UnsafeMutablePointer<Int8>.alloc(resultBufferSize)
+    let resultBuffer = UnsafeMutablePointer<Int8>.allocate(capacity: resultBufferSize)
     var encoded = resultBuffer
     
     // encode regular blocks
@@ -187,8 +169,8 @@ private func base32encode(data: UnsafePointer<Void>, _ length: Int, _ table: [In
         encoded[6] = table[Int((bytes[3] & 0b00000011) << 3 | bytes[4] >> 5)]
         encoded[7] = table[Int((bytes[4] & 0b00011111))]
         length -= 5
-        encoded = encoded.advancedBy(8)
-        bytes = bytes.advancedBy(5)
+        encoded = encoded.advanced(by: 8)
+        bytes = bytes.advanced(by: 5)
     }
     
     // encode last block
@@ -215,24 +197,25 @@ private func base32encode(data: UnsafePointer<Void>, _ length: Int, _ table: [In
         encoded[0] = table[Int(byte0 >> 3)]
     default: break
     }
-    
+
     // padding
+    let pad = Int8(UnicodeScalar("=").value)
     switch length {
     case 0:
         encoded[0] = 0
     case 1:
-        encoded[2] = "="
-        encoded[3] = "="
+        encoded[2] = pad
+        encoded[3] = pad
         fallthrough
     case 2:
-        encoded[4] = "="
+        encoded[4] = pad
         fallthrough
     case 3:
-        encoded[5] = "="
-        encoded[6] = "="
+        encoded[5] = pad
+        encoded[6] = pad
         fallthrough
     case 4:
-        encoded[7] = "="
+        encoded[7] = pad
         fallthrough
     default:
         encoded[8] = 0
@@ -240,11 +223,11 @@ private func base32encode(data: UnsafePointer<Void>, _ length: Int, _ table: [In
     }
     
     // return
-    if let base32Encoded = String(UTF8String: resultBuffer) {
-        resultBuffer.dealloc(resultBufferSize)
+    if let base32Encoded = String(validatingUTF8: resultBuffer) {
+        resultBuffer.deallocate(capacity: resultBufferSize)
         return base32Encoded
     } else {
-        resultBuffer.dealloc(resultBufferSize)
+        resultBuffer.deallocate(capacity: resultBufferSize)
         fatalError("internal error")
     }
 }
@@ -291,14 +274,14 @@ let extendedHexAlphabetDecodeTable: [UInt8] = [
 ]
 
 
-private func base32decode(string: String, _ table: [UInt8]) -> [UInt8]? {
+private func base32decode(_ string: String, _ table: [UInt8]) -> [UInt8]? {
     let length = string.unicodeScalars.count
     if length == 0 {
         return []
     }
     
     // calc padding length
-    func getLeastPaddingLength(string: String) -> Int {
+    func getLeastPaddingLength(_ string: String) -> Int {
         if string.hasSuffix("======") {
             return 6
         } else if string.hasSuffix("====") {
@@ -314,9 +297,9 @@ private func base32decode(string: String, _ table: [UInt8]) -> [UInt8]? {
     
     // validate string
     let leastPaddingLength = getLeastPaddingLength(string)
-    if let index = string.unicodeScalars.indexOf({$0.value > 0xff || table[Int($0.value)] > 31}) {
+    if let index = string.unicodeScalars.index(where: {$0.value > 0xff || table[Int($0.value)] > 31}) {
         // index points padding "=" or invalid character that table does not contain.
-        let pos = string.unicodeScalars.startIndex.distanceTo(index)
+        let pos = string.unicodeScalars.distance(from: string.unicodeScalars.startIndex, to: index)
         // if pos points padding "=", it's valid.
         if pos != length - leastPaddingLength {
             print("string contains some invalid characters.")
@@ -342,12 +325,12 @@ private func base32decode(string: String, _ table: [UInt8]) -> [UInt8]? {
     let dataSize = remainEncodedLength / 8 * 5 + additionalBytes
     
     // Use UnsafePointer<UInt8>
-    return string.nulTerminatedUTF8.withUnsafeBufferPointer {
-        (data: UnsafeBufferPointer<UInt8>) -> [UInt8] in
-        var encoded = data.baseAddress
+    return string.utf8CString.withUnsafeBufferPointer {
+        (data: UnsafeBufferPointer<CChar>) -> [UInt8] in
+        var encoded = data.baseAddress!
         
-        let result = Array<UInt8>(count: dataSize, repeatedValue: 0)
-        var decoded = UnsafeMutablePointer<UInt8>(result)
+        let result = Array<UInt8>(repeating: 0, count: dataSize)
+        var decoded = UnsafeMutablePointer<UInt8>(mutating: result)
         
         // decode regular blocks
         var value0, value1, value2, value3, value4, value5, value6, value7: UInt8
@@ -369,8 +352,8 @@ private func base32decode(string: String, _ table: [UInt8]) -> [UInt8]? {
             decoded[4] = value6 << 5 | value7
             
             remainEncodedLength -= 8
-            decoded = decoded.advancedBy(5)
-            encoded = encoded.advancedBy(8)
+            decoded = decoded.advanced(by: 5)
+            encoded = encoded.advanced(by: 8)
         }
         
         // decode last block

+ 6 - 6
Base32/StringExtension.swift

@@ -29,17 +29,17 @@ import Foundation
 // MARK: - private
 
 extension String {
-    /// NSData never nil
-    internal var dataUsingUTF8StringEncoding: NSData {
-        return nulTerminatedUTF8.withUnsafeBufferPointer {
-            return NSData(bytes: $0.baseAddress, length: $0.count - 1)
+    /// Data never nil
+    internal var dataUsingUTF8StringEncoding: Data {
+        return utf8CString.withUnsafeBufferPointer {
+            return Data(bytes: $0.dropLast().map { UInt8.init($0) })
         }
     }
     
     /// Array<UInt8>
     internal var arrayUsingUTF8StringEncoding: [UInt8] {
-        return nulTerminatedUTF8.withUnsafeBufferPointer {
-            return Array(UnsafeBufferPointer(start: $0.baseAddress, count: $0.count - 1))
+        return utf8CString.withUnsafeBufferPointer {
+            return $0.dropLast().map { UInt8.init($0) }
         }
     }
 }

+ 6 - 6
Base32Tests/Base16Tests.swift

@@ -26,7 +26,7 @@
 
 import Foundation
 import XCTest
-import Base32
+@testable import Base32
 
 class Base16Tests: XCTestCase {
 
@@ -55,7 +55,7 @@ class Base16Tests: XCTestCase {
 
     func test_RFC4648_base16Encode() {
         let convertedVectors = self.vectors.map {($0.dataUsingUTF8StringEncoding, $1)}
-        self.measureBlock{
+        self.measure{
             for _ in 0...100 {
                 for (test, expect) in convertedVectors {
                     let result = base16Encode(test)
@@ -67,7 +67,7 @@ class Base16Tests: XCTestCase {
     
     func test_RFC4648_base16Decode() {
         let convertedVectors = self.vectors.map {($0.dataUsingUTF8StringEncoding, $1)}
-        self.measureBlock{
+        self.measure{
             for _ in 0...100 {
                 for (expect, test) in convertedVectors {
                     let result = base16DecodeToData(test)
@@ -80,7 +80,7 @@ class Base16Tests: XCTestCase {
     // MARK: -
     
     func test_Base16ExtensionString() {
-        self.measureBlock{
+        self.measure{
             for _ in 0...100 {
                 for (test, expect) in self.vectors {
                     let result = test.base16EncodedString
@@ -99,7 +99,7 @@ class Base16Tests: XCTestCase {
                 $1.dataUsingUTF8StringEncoding
             )
         }
-        self.measureBlock{
+        self.measure{
             for _ in 0...100 {
                 for (test, expect) in dataVectors {
                     let result = test.base16EncodedData
@@ -113,7 +113,7 @@ class Base16Tests: XCTestCase {
     
     func test_Base16ExtensionDataAndString() {
         let dataAndStringVectors = vectors.map {($0.dataUsingUTF8StringEncoding, $1)}
-        self.measureBlock{
+        self.measure{
             for _ in 0...100 {
                 for (test, expect) in dataAndStringVectors {
                     let result = test.base16EncodedString

+ 12 - 12
Base32Tests/Base32Tests.swift

@@ -26,7 +26,7 @@
 
 import Foundation
 import XCTest
-import Base32
+@testable import Base32
 
 class Base32Tests: XCTestCase {
     
@@ -54,7 +54,7 @@ class Base32Tests: XCTestCase {
     
     func test_RFC4648_base32Encode() {
         let convertedVectors = self.vectors.map {($0.dataUsingUTF8StringEncoding, $1, $2)}
-        self.measureBlock{
+        self.measure{
             for _ in 0...100 {
                 for (test, expect, _) in convertedVectors {
                     let result = base32Encode(test)
@@ -66,7 +66,7 @@ class Base32Tests: XCTestCase {
     
     func test_RFC4648_base32Decode() {
         let convertedVectors = self.vectors.map {($0.dataUsingUTF8StringEncoding, $1, $2)}
-        self.measureBlock{
+        self.measure{
             for _ in 0...100 {
                 for (expect, test, _) in convertedVectors {
                     let result = base32DecodeToData(test)
@@ -78,7 +78,7 @@ class Base32Tests: XCTestCase {
     
     func test_RFC4648_base32HexEncode() {
         let convertedVectors = self.vectors.map {($0.dataUsingUTF8StringEncoding, $1, $2)}
-        self.measureBlock{
+        self.measure{
             for _ in 0...100 {
                 for (test, _, expectHex) in convertedVectors {
                     let resultHex = base32HexEncode(test)
@@ -90,7 +90,7 @@ class Base32Tests: XCTestCase {
     
     func test_RFC4648_base32HexDecode() {
         let convertedVectors = self.vectors.map {($0.dataUsingUTF8StringEncoding, $1, $2)}
-        self.measureBlock{
+        self.measure{
             for _ in 0...100 {
                 for (expect, _, testHex) in convertedVectors {
                     let resultHex = base32HexDecodeToData(testHex)
@@ -103,7 +103,7 @@ class Base32Tests: XCTestCase {
     // MARK: -
     
     func test_base32ExtensionString() {
-        self.measureBlock{
+        self.measure{
             for _ in 0...100 {
                 for (test, expect, expectHex) in self.vectors {
                     let result = test.base32EncodedString
@@ -127,7 +127,7 @@ class Base32Tests: XCTestCase {
                 $2.dataUsingUTF8StringEncoding
             )
         }
-        self.measureBlock{
+        self.measure{
             for _ in 0...100 {
                 for (test, expect, expectHex) in dataVectors {
                     let result = test.base32EncodedData
@@ -145,7 +145,7 @@ class Base32Tests: XCTestCase {
     
     func test_base32ExtensionDataAndString() {
         let dataAndStringVectors = vectors.map {($0.dataUsingUTF8StringEncoding, $1, $2)}
-        self.measureBlock{
+        self.measure{
             for _ in 0...100 {
                 for (test, expect, expectHex) in dataAndStringVectors {
                     let result = test.base32EncodedString
@@ -168,8 +168,8 @@ class Base32Tests: XCTestCase {
         let strippedVectors = vectors.map {
             (
                 $0.dataUsingUTF8StringEncoding,
-                $1.stringByReplacingOccurrencesOfString("=", withString:""),
-                $2.stringByReplacingOccurrencesOfString("=", withString:"")
+                $1.replacingOccurrences(of: "=", with:""),
+                $2.replacingOccurrences(of: "=", with:"")
             )
         }
         for (expect, test, testHex) in strippedVectors {
@@ -196,8 +196,8 @@ class Base32Tests: XCTestCase {
         // invalid length string without padding
         let invalidVectorWithoutPaddings = invalidVectorWithPaddings.map {
             (
-                $0.stringByReplacingOccurrencesOfString("=", withString:""),
-                $1.stringByReplacingOccurrencesOfString("=", withString:"")
+                $0.replacingOccurrences(of: "=", with:""),
+                $1.replacingOccurrences(of: "=", with:"")
             )
         }
         for (test, testHex) in invalidVectorWithoutPaddings {

+ 3 - 2
Base32Tests/StringExtensionTests.swift

@@ -26,6 +26,7 @@
 
 import Foundation
 import XCTest
+@testable import Base32
 
 class StringExtensionTests: XCTestCase {
 
@@ -41,9 +42,9 @@ class StringExtensionTests: XCTestCase {
 
     func test_dataUsingUTF8StringEncoding() {
         let emptyString = ""
-        XCTAssertEqual(emptyString.dataUsingUTF8StringEncoding, emptyString.dataUsingEncoding(NSUTF8StringEncoding, allowLossyConversion: false)!)
+        XCTAssertEqual(emptyString.dataUsingUTF8StringEncoding, emptyString.data(using: .utf8, allowLossyConversion: false)!)
 
         let string = "0112233445566778899AABBCCDDEEFFaabbccddeefff"
-        XCTAssertEqual(string.dataUsingUTF8StringEncoding, string.dataUsingEncoding(NSUTF8StringEncoding, allowLossyConversion: false)!)
+        XCTAssertEqual(string.dataUsingUTF8StringEncoding, string.data(using: .utf8, allowLossyConversion: false)!)
     }
 }

+ 17 - 17
SecEncodeTransformTests/SecEncodeTransformTests.swift

@@ -21,7 +21,7 @@ let vectors: [(String, String, String)] = [
     ("foobar", "MZXW6YTBOI======", "CPNMUOJ1E8======"),
 ]
 
-let convertedVectors = vectors.map {($0.dataUsingUTF8StringEncoding, $1, $2)}
+let convertedVectors = vectors.map {($0.data(using:.utf8)!, $1, $2)}
 
 class SecEncodeTransformTests: XCTestCase {
     
@@ -40,62 +40,62 @@ class SecEncodeTransformTests: XCTestCase {
 
     // MARK: Using SecEncodeTransform
     func test_RFC4648_Encode_UsingSecEncodeTransform() {
-        var results = Array<String>(count: convertedVectors.count, repeatedValue: "")
-        let vectorsAndIndices = Zip2Sequence(convertedVectors, results.indices)
-        self.measureBlock{
+        var results = Array<String>(repeating: "", count: convertedVectors.count)
+        let vectorsAndIndices = zip(convertedVectors, results.indices)
+        self.measure{
             for _ in 0...100 {
                 for ((test, _, _), index) in vectorsAndIndices {
                     results[index] = TTTBase32EncodedStringFromData(test)
                 }
             }
         }
-        for ((test, expect, _), result) in Zip2Sequence(convertedVectors, results) {
+        for ((test, expect, _), result) in zip(convertedVectors, results) {
             XCTAssertEqual(result, expect, "TTTBase32EncodedStringFromData for \(test)")
         }
     }
     
     func test_RFC4648_Decode_UsingSecEncodeTransform() {
-        var results = Array<NSData>(count: convertedVectors.count, repeatedValue: NSData())
-        let vectorsAndIndices = Zip2Sequence(convertedVectors, results.indices)
-        self.measureBlock{
+        var results = Array<Data>(repeating: Data(), count: convertedVectors.count)
+        let vectorsAndIndices = zip(convertedVectors, results.indices)
+        self.measure{
             for _ in 0...100 {
                 for ((_, test, _), index) in vectorsAndIndices {
                     results[index] = TTTDataFromBase32EncodedString(test)
                 }
             }
         }
-        for ((expect, test, _), result) in Zip2Sequence(convertedVectors, results) {
+        for ((expect, test, _), result) in zip(convertedVectors, results) {
             XCTAssertEqual(result, expect, "TTTDataFromBase32EncodedString for \(test)")
         }
     }
     
     // MARK: Using Base32
     func test_RFC4648_Encode_UsingBase32() {
-        var results = Array<String>(count: convertedVectors.count, repeatedValue: "")
-        let vectorsAndIndices = Zip2Sequence(convertedVectors, results.indices)
-        self.measureBlock{
+        var results = Array<String>(repeating: "", count: convertedVectors.count)
+        let vectorsAndIndices = zip(convertedVectors, results.indices)
+        self.measure{
             for _ in 0...100 {
                 for ((test, _, _), index) in vectorsAndIndices {
                     results[index] = base32Encode(test)
                 }
             }
         }
-        for ((test, expect, _), result) in Zip2Sequence(convertedVectors, results) {
+        for ((test, expect, _), result) in zip(convertedVectors, results) {
             XCTAssertEqual(result, expect, "base32Encode for \(test)")
         }
     }
     
     func test_RFC4648_Decode_UsingBase32() {
-        var results = Array<NSData>(count: convertedVectors.count, repeatedValue: NSData())
-        let vectorsAndIndices = Zip2Sequence(convertedVectors, results.indices)
-        self.measureBlock{
+        var results = Array<Data>(repeating: Data(), count: convertedVectors.count)
+        let vectorsAndIndices = zip(convertedVectors, results.indices)
+        self.measure{
             for _ in 0...100 {
                 for ((_, test, _), index) in vectorsAndIndices {
                     results[index] = base32DecodeToData(test)!
                 }
             }
         }
-        for ((expect, test, _), result) in Zip2Sequence(convertedVectors, results) {
+        for ((expect, test, _), result) in zip(convertedVectors, results) {
             XCTAssertEqual(result, expect, "base32Decode for \(test)")
         }
     }