Skip to content

Commit 188a4e1

Browse files
committed
Add a structural implementation of Data
1 parent 7f85f73 commit 188a4e1

30 files changed

+956
-259
lines changed

Foundation/Data.swift

Lines changed: 648 additions & 0 deletions
Large diffs are not rendered by default.

Foundation/NSArray.swift

Lines changed: 9 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -349,14 +349,19 @@ public class NSArray : NSObject, NSCopying, NSMutableCopying, NSSecureCoding, NS
349349
return NSGeneratorEnumerator(Iterator(self, reverse: true))
350350
}
351351

352-
/*@NSCopying*/ public var sortedArrayHint: NSData {
353-
let buffer = UnsafeMutablePointer<Int32>(allocatingCapacity: count)
352+
/*@NSCopying*/ public var sortedArrayHint: Data {
353+
let size = count
354+
let buffer = UnsafeMutablePointer<Int32>(allocatingCapacity: size)
354355
for idx in 0..<count {
355356
let item = objectAtIndex(idx) as! NSObject
356357
let hash = item.hash
357358
buffer.advanced(by: idx).pointee = Int32(hash).littleEndian
358359
}
359-
return NSData(bytesNoCopy: unsafeBitCast(buffer, to: UnsafeMutablePointer<Void>.self), length: count * sizeof(Int), freeWhenDone: true)
360+
fatalError("TODO: FIXME")
361+
// return Data(bytesNoCopy: unsafeBitCast(buffer, to: UnsafeMutablePointer<Void>.self), count: count * sizeof(Int)) { _ in
362+
// buffer.deallocateCapacity(size)
363+
// buffer.deinitialize(count: size)
364+
// }
360365
}
361366

362367
public func sortedArrayUsingFunction(_ comparator: @convention(c) (AnyObject, AnyObject, UnsafeMutablePointer<Void>?) -> Int, context: UnsafeMutablePointer<Void>?) -> [AnyObject] {
@@ -365,7 +370,7 @@ public class NSArray : NSObject, NSCopying, NSMutableCopying, NSSecureCoding, NS
365370
}
366371
}
367372

368-
public func sortedArrayUsingFunction(_ comparator: @convention(c) (AnyObject, AnyObject, UnsafeMutablePointer<Void>?) -> Int, context: UnsafeMutablePointer<Void>?, hint: NSData?) -> [AnyObject] {
373+
public func sortedArrayUsingFunction(_ comparator: @convention(c) (AnyObject, AnyObject, UnsafeMutablePointer<Void>?) -> Int, context: UnsafeMutablePointer<Void>?, hint: Data?) -> [AnyObject] {
369374
return sortedArrayWithOptions([]) { lhs, rhs in
370375
return NSComparisonResult(rawValue: comparator(lhs, rhs, context))!
371376
}

Foundation/NSCharacterSet.swift

Lines changed: 6 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -135,15 +135,16 @@ public class NSCharacterSet : NSObject, NSCopying, NSMutableCopying, NSCoding {
135135
_CFCharacterSetInitWithCharactersInString(_cfMutableObject, aString._cfObject)
136136
}
137137

138-
public init(bitmapRepresentation data: NSData) {
138+
public init(bitmapRepresentation data: Data) {
139139
super.init()
140140
_CFCharacterSetInitWithBitmapRepresentation(_cfMutableObject, data._cfObject)
141141
}
142142

143143
public convenience init?(contentsOfFile fName: String) {
144-
if let data = NSData(contentsOfFile: fName) {
144+
do {
145+
let data = try Data(contentsOf: URL(fileURLWithPath: fName))
145146
self.init(bitmapRepresentation: data)
146-
} else {
147+
} catch {
147148
return nil
148149
}
149150
}
@@ -156,8 +157,8 @@ public class NSCharacterSet : NSObject, NSCopying, NSMutableCopying, NSCoding {
156157
return CFCharacterSetIsCharacterMember(_cfObject, UniChar(aCharacter))
157158
}
158159

159-
public var bitmapRepresentation: NSData {
160-
return CFCharacterSetCreateBitmapRepresentation(kCFAllocatorSystemDefault, _cfObject)._nsObject
160+
public var bitmapRepresentation: Data {
161+
return CFCharacterSetCreateBitmapRepresentation(kCFAllocatorSystemDefault, _cfObject)._swiftObject
161162
}
162163

163164
public var inverted: NSCharacterSet {

Foundation/NSCoder.swift

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -30,15 +30,15 @@ public class NSCoder : NSObject {
3030
NSRequiresConcreteImplementation()
3131
}
3232

33-
public func encodeDataObject(_ data: NSData) {
33+
public func encodeDataObject(_ data: Data) {
3434
NSRequiresConcreteImplementation()
3535
}
3636

3737
public func decodeValueOfObjCType(_ type: UnsafePointer<Int8>, at data: UnsafeMutablePointer<Void>) {
3838
NSRequiresConcreteImplementation()
3939
}
4040

41-
public func decodeDataObject() -> NSData? {
41+
public func decodeDataObject() -> Data? {
4242
NSRequiresConcreteImplementation()
4343
}
4444

Foundation/NSConcreteValue.swift

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -113,7 +113,7 @@ internal class NSConcreteValue : NSValue {
113113
}
114114

115115
override var description : String {
116-
return NSData.init(bytes: self.value, length: self._size).description
116+
return Data(bytes: self.value, count: self._size).description
117117
}
118118

119119
convenience required init?(coder aDecoder: NSCoder) {

Foundation/NSData.swift

Lines changed: 77 additions & 61 deletions
Original file line numberDiff line numberDiff line change
@@ -15,47 +15,50 @@ import Darwin
1515
import Glibc
1616
#endif
1717

18-
public struct NSDataReadingOptions : OptionSet {
19-
public let rawValue : UInt
20-
public init(rawValue: UInt) { self.rawValue = rawValue }
21-
22-
public static let dataReadingMappedIfSafe = NSDataReadingOptions(rawValue: UInt(1 << 0))
23-
public static let dataReadingUncached = NSDataReadingOptions(rawValue: UInt(1 << 1))
24-
public static let dataReadingMappedAlways = NSDataReadingOptions(rawValue: UInt(1 << 2))
25-
}
18+
extension NSData {
2619

27-
public struct NSDataWritingOptions : OptionSet {
28-
public let rawValue : UInt
29-
public init(rawValue: UInt) { self.rawValue = rawValue }
30-
31-
public static let dataWritingAtomic = NSDataWritingOptions(rawValue: UInt(1 << 0))
32-
public static let dataWritingWithoutOverwriting = NSDataWritingOptions(rawValue: UInt(1 << 1))
33-
}
20+
public struct ReadingOptions : OptionSet {
21+
public let rawValue : UInt
22+
public init(rawValue: UInt) { self.rawValue = rawValue }
23+
24+
public static let dataReadingMappedIfSafe = ReadingOptions(rawValue: UInt(1 << 0))
25+
public static let dataReadingUncached = ReadingOptions(rawValue: UInt(1 << 1))
26+
public static let dataReadingMappedAlways = ReadingOptions(rawValue: UInt(1 << 2))
27+
}
3428

35-
public struct NSDataSearchOptions : OptionSet {
36-
public let rawValue : UInt
37-
public init(rawValue: UInt) { self.rawValue = rawValue }
38-
39-
public static let backwards = NSDataSearchOptions(rawValue: UInt(1 << 0))
40-
public static let anchored = NSDataSearchOptions(rawValue: UInt(1 << 1))
41-
}
29+
public struct WritingOptions : OptionSet {
30+
public let rawValue : UInt
31+
public init(rawValue: UInt) { self.rawValue = rawValue }
32+
33+
public static let dataWritingAtomic = WritingOptions(rawValue: UInt(1 << 0))
34+
public static let dataWritingWithoutOverwriting = WritingOptions(rawValue: UInt(1 << 1))
35+
}
4236

43-
public struct NSDataBase64EncodingOptions : OptionSet {
44-
public let rawValue : UInt
45-
public init(rawValue: UInt) { self.rawValue = rawValue }
46-
47-
public static let encoding64CharacterLineLength = NSDataBase64EncodingOptions(rawValue: UInt(1 << 0))
48-
public static let encoding76CharacterLineLength = NSDataBase64EncodingOptions(rawValue: UInt(1 << 1))
49-
public static let encodingEndLineWithCarriageReturn = NSDataBase64EncodingOptions(rawValue: UInt(1 << 4))
50-
public static let encodingEndLineWithLineFeed = NSDataBase64EncodingOptions(rawValue: UInt(1 << 5))
51-
}
37+
public struct SearchOptions : OptionSet {
38+
public let rawValue : UInt
39+
public init(rawValue: UInt) { self.rawValue = rawValue }
40+
41+
public static let backwards = SearchOptions(rawValue: UInt(1 << 0))
42+
public static let anchored = SearchOptions(rawValue: UInt(1 << 1))
43+
}
5244

53-
public struct NSDataBase64DecodingOptions : OptionSet {
54-
public let rawValue : UInt
55-
public init(rawValue: UInt) { self.rawValue = rawValue }
56-
57-
public static let ignoreUnknownCharacters = NSDataBase64DecodingOptions(rawValue: UInt(1 << 0))
58-
public static let anchored = NSDataSearchOptions(rawValue: UInt(1 << 1))
45+
public struct Base64EncodingOptions : OptionSet {
46+
public let rawValue : UInt
47+
public init(rawValue: UInt) { self.rawValue = rawValue }
48+
49+
public static let encoding64CharacterLineLength = Base64EncodingOptions(rawValue: UInt(1 << 0))
50+
public static let encoding76CharacterLineLength = Base64EncodingOptions(rawValue: UInt(1 << 1))
51+
public static let encodingEndLineWithCarriageReturn = Base64EncodingOptions(rawValue: UInt(1 << 4))
52+
public static let encodingEndLineWithLineFeed = Base64EncodingOptions(rawValue: UInt(1 << 5))
53+
}
54+
55+
public struct Base64DecodingOptions : OptionSet {
56+
public let rawValue : UInt
57+
public init(rawValue: UInt) { self.rawValue = rawValue }
58+
59+
public static let ignoreUnknownCharacters = Base64DecodingOptions(rawValue: UInt(1 << 0))
60+
public static let anchored = Base64DecodingOptions(rawValue: UInt(1 << 1))
61+
}
5962
}
6063

6164
private final class _NSDataDeallocator {
@@ -252,7 +255,7 @@ extension NSData {
252255
var deallocator: ((buffer: UnsafeMutablePointer<Void>, length: Int) -> Void)?
253256
}
254257

255-
internal static func readBytesFromFileWithExtendedAttributes(_ path: String, options: NSDataReadingOptions) throws -> NSDataReadResult {
258+
internal static func readBytesFromFileWithExtendedAttributes(_ path: String, options: ReadingOptions) throws -> NSDataReadResult {
256259
let fd = _CFOpenFile(path, O_RDONLY)
257260
if fd < 0 {
258261
throw NSError(domain: NSPOSIXErrorDomain, code: Int(errno), userInfo: nil)
@@ -308,7 +311,7 @@ extension NSData {
308311
}
309312
}
310313

311-
public convenience init(contentsOfFile path: String, options readOptionsMask: NSDataReadingOptions) throws {
314+
public convenience init(contentsOfFile path: String, options readOptionsMask: ReadingOptions) throws {
312315
let readResult = try NSData.readBytesFromFileWithExtendedAttributes(path, options: readOptionsMask)
313316
self.init(bytes: readResult.bytes, length: readResult.length, copy: false, deallocator: readResult.deallocator)
314317
}
@@ -326,15 +329,15 @@ extension NSData {
326329
self.init(bytes:data.bytes, length: data.length)
327330
}
328331

329-
public convenience init(contentsOfURL url: URL, options readOptionsMask: NSDataReadingOptions) throws {
332+
public convenience init(contentsOfURL url: URL, options readOptionsMask: ReadingOptions) throws {
330333
if url.isFileURL {
331334
try self.init(contentsOfFile: url.path!, options: readOptionsMask)
332335
} else {
333336
let session = URLSession(configuration: URLSessionConfiguration.defaultSessionConfiguration())
334337
let cond = NSCondition()
335338
var resError: NSError?
336339
var resData: NSData?
337-
let task = session.dataTaskWithURL(url, completionHandler: { (data: NSData?, response: URLResponse?, error: NSError?) -> Void in
340+
let task = session.dataTaskWithURL(url, completionHandler: { (data: Data?, response: URLResponse?, error: NSError?) -> Void in
338341
resData = data
339342
resError = error
340343
cond.broadcast()
@@ -383,14 +386,15 @@ extension NSData {
383386

384387
return memcmp(bytes1, bytes2, length) == 0
385388
}
386-
public func subdata(with range: NSRange) -> NSData {
389+
390+
public func subdata(with range: NSRange) -> Data {
387391
if range.length == 0 {
388-
return NSData()
392+
return Data()
389393
}
390394
if range.location == 0 && range.length == self.length {
391-
return copy(with: nil) as! NSData
395+
return Data(_bridged: self)
392396
}
393-
return NSData(bytes: bytes.advanced(by: range.location), length: range.length)
397+
return Data(bytes: bytes.advanced(by: range.location), count: range.length)
394398
}
395399

396400
internal func makeTemporaryFileInDirectory(_ dirPath: String) throws -> (Int32, String) {
@@ -425,7 +429,7 @@ extension NSData {
425429
}
426430
}
427431

428-
public func write(toFile path: String, options writeOptionsMask: NSDataWritingOptions = []) throws {
432+
public func write(toFile path: String, options writeOptionsMask: WritingOptions = []) throws {
429433
var fd : Int32
430434
var mode : mode_t? = nil
431435
let useAuxiliaryFile = writeOptionsMask.contains(.dataWritingAtomic)
@@ -512,7 +516,7 @@ extension NSData {
512516
/// - throws: This method returns Void and is marked with the `throws` keyword to indicate that it throws an error in the event of failure.
513517
///
514518
/// This method is invoked in a `try` expression and the caller is responsible for handling any errors in the `catch` clauses of a `do` statement, as described in [Error Handling](https://developer.apple.com/library/prerelease/ios/documentation/Swift/Conceptual/Swift_Programming_Language/ErrorHandling.html#//apple_ref/doc/uid/TP40014097-CH42) in [The Swift Programming Language](https://developer.apple.com/library/prerelease/ios/documentation/Swift/Conceptual/Swift_Programming_Language/index.html#//apple_ref/doc/uid/TP40014097) and [Error Handling](https://developer.apple.com/library/prerelease/ios/documentation/Swift/Conceptual/BuildingCocoaApps/AdoptingCocoaDesignPatterns.html#//apple_ref/doc/uid/TP40014216-CH7-ID10) in [Using Swift with Cocoa and Objective-C](https://developer.apple.com/library/prerelease/ios/documentation/Swift/Conceptual/BuildingCocoaApps/index.html#//apple_ref/doc/uid/TP40014216).
515-
public func write(to url: URL, options writeOptionsMask: NSDataWritingOptions = []) throws {
519+
public func write(to url: URL, options writeOptionsMask: WritingOptions = []) throws {
516520
guard let path = url.path where url.isFileURL == true else {
517521
let userInfo = [NSLocalizedDescriptionKey : "The folder at “\(url)” does not exist or is not a file URL.", // NSLocalizedString() not yet available
518522
NSURLErrorKey : url.absoluteString ?? ""] as Dictionary<String, Any>
@@ -521,7 +525,7 @@ extension NSData {
521525
try write(toFile: path, options: writeOptionsMask)
522526
}
523527

524-
public func range(of dataToFind: NSData, options mask: NSDataSearchOptions = [], in searchRange: NSRange) -> NSRange {
528+
public func range(of dataToFind: NSData, options mask: SearchOptions = [], in searchRange: NSRange) -> NSRange {
525529
guard dataToFind.length > 0 else {return NSRange(location: NSNotFound, length: 0)}
526530
guard let searchRange = searchRange.toRange() else {fatalError("invalid range")}
527531

@@ -549,7 +553,7 @@ extension NSData {
549553
return nil
550554
}
551555

552-
internal func enumerateByteRangesUsingBlockRethrows(_ block: (UnsafePointer<Void>, NSRange, UnsafeMutablePointer<Bool>) throws -> Void) throws {
556+
internal func enumerateByteRangesUsingBlockRethrows(_ block: @noescape (UnsafePointer<Void>, NSRange, UnsafeMutablePointer<Bool>) throws -> Void) throws {
553557
var err : ErrorProtocol? = nil
554558
self.enumerateBytes() { (buf, range, stop) -> Void in
555559
do {
@@ -563,19 +567,31 @@ extension NSData {
563567
}
564568
}
565569

566-
public func enumerateBytes(_ block: (UnsafePointer<Void>, NSRange, UnsafeMutablePointer<Bool>) -> Void) {
570+
public func enumerateBytes(_ block: @noescape (UnsafePointer<Void>, NSRange, UnsafeMutablePointer<Bool>) -> Void) {
567571
var stop = false
568572
withUnsafeMutablePointer(&stop) { stopPointer in
569573
block(bytes, NSMakeRange(0, length), stopPointer)
570574
}
571575
}
572576
}
573577

574-
extension NSData : _CFBridgable { }
578+
extension NSData : _CFBridgable, _SwiftBridgable {
579+
typealias SwiftType = Data
580+
internal var _swiftObject: SwiftType { return Data(_bridged: self) }
581+
}
582+
583+
extension Data : _NSBridgable, _CFBridgable {
584+
typealias CFType = CFData
585+
typealias NSType = NSData
586+
internal var _cfObject: CFType { return _nsObject._cfObject }
587+
internal var _nsObject: NSType { return _bridgeToObjectiveC() }
588+
}
575589

576-
extension CFData : _NSBridgable {
590+
extension CFData : _NSBridgable, _SwiftBridgable {
577591
typealias NSType = NSData
592+
typealias SwiftType = Data
578593
internal var _nsObject: NSType { return unsafeBitCast(self, to: NSType.self) }
594+
internal var _swiftObject: SwiftType { return Data(_bridged: self._nsObject) }
579595
}
580596

581597
extension NSMutableData {
@@ -614,7 +630,7 @@ extension NSData {
614630

615631
/* Create an NSData from a Base-64 encoded NSString using the given options. By default, returns nil when the input is not recognized as valid Base-64.
616632
*/
617-
public convenience init?(base64Encoded base64String: String, options: NSDataBase64DecodingOptions) {
633+
public convenience init?(base64Encoded base64String: String, options: Base64DecodingOptions) {
618634
let encodedBytes = Array(base64String.utf8)
619635
guard let decodedBytes = NSData.base64DecodeBytes(encodedBytes, options: options) else {
620636
return nil
@@ -624,7 +640,7 @@ extension NSData {
624640

625641
/* Create a Base-64 encoded NSString from the receiver's contents using the given options.
626642
*/
627-
public func base64EncodedString(_ options: NSDataBase64EncodingOptions = []) -> String {
643+
public func base64EncodedString(_ options: Base64EncodingOptions = []) -> String {
628644
var decodedBytes = [UInt8](repeating: 0, count: self.length)
629645
getBytes(&decodedBytes, length: decodedBytes.count)
630646
let encodedBytes = NSData.base64EncodeBytes(decodedBytes, options: options)
@@ -634,9 +650,9 @@ extension NSData {
634650

635651
/* Create an NSData from a Base-64, UTF-8 encoded NSData. By default, returns nil when the input is not recognized as valid Base-64.
636652
*/
637-
public convenience init?(base64Encoded base64Data: NSData, options: NSDataBase64DecodingOptions) {
638-
var encodedBytes = [UInt8](repeating: 0, count: base64Data.length)
639-
base64Data.getBytes(&encodedBytes, length: encodedBytes.count)
653+
public convenience init?(base64Encoded base64Data: Data, options: Base64DecodingOptions) {
654+
var encodedBytes = [UInt8](repeating: 0, count: base64Data.count)
655+
base64Data._nsObject.getBytes(&encodedBytes, length: encodedBytes.count)
640656
guard let decodedBytes = NSData.base64DecodeBytes(encodedBytes, options: options) else {
641657
return nil
642658
}
@@ -645,11 +661,11 @@ extension NSData {
645661

646662
/* Create a Base-64, UTF-8 encoded NSData from the receiver's contents using the given options.
647663
*/
648-
public func base64EncodedData(_ options: NSDataBase64EncodingOptions = []) -> NSData {
664+
public func base64EncodedData(_ options: Base64EncodingOptions = []) -> Data {
649665
var decodedBytes = [UInt8](repeating: 0, count: self.length)
650666
getBytes(&decodedBytes, length: decodedBytes.count)
651667
let encodedBytes = NSData.base64EncodeBytes(decodedBytes, options: options)
652-
return NSData(bytes: encodedBytes, length: encodedBytes.count)
668+
return Data(bytes: encodedBytes, count: encodedBytes.count)
653669
}
654670

655671
/**
@@ -726,7 +742,7 @@ extension NSData {
726742
- parameter options: Options for handling invalid input
727743
- returns: The decoded bytes.
728744
*/
729-
private static func base64DecodeBytes(_ bytes: [UInt8], options: NSDataBase64DecodingOptions = []) -> [UInt8]? {
745+
private static func base64DecodeBytes(_ bytes: [UInt8], options: Base64DecodingOptions = []) -> [UInt8]? {
730746
var decodedBytes = [UInt8]()
731747
decodedBytes.reserveCapacity((bytes.count/3)*2)
732748

@@ -796,7 +812,7 @@ extension NSData {
796812
- parameter options: Options for formatting the result
797813
- returns: The Base64-encoding for those bytes.
798814
*/
799-
private static func base64EncodeBytes(_ bytes: [UInt8], options: NSDataBase64EncodingOptions = []) -> [UInt8] {
815+
private static func base64EncodeBytes(_ bytes: [UInt8], options: Base64EncodingOptions = []) -> [UInt8] {
800816
var result = [UInt8]()
801817
result.reserveCapacity((bytes.count/3)*4)
802818

0 commit comments

Comments
 (0)