Skip to content

Commit c6e4e2c

Browse files
authored
Merge pull request #2216 from millenomi/nsindexset-nscoding
Parity: NSCoding: NSIndexSet
2 parents 4f228b7 + 4c2d939 commit c6e4e2c

15 files changed

+386
-76
lines changed

CoreFoundation/Base.subproj/CFInternal.h

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -788,11 +788,12 @@ extern void _CFRuntimeSetInstanceTypeIDAndIsa(CFTypeRef cf, CFTypeID newTypeID);
788788
#if DEPLOYMENT_RUNTIME_SWIFT
789789
#define CF_IS_SWIFT(type, obj) (_CFIsSwift(type, (CFSwiftRef)obj))
790790

791-
#define CF_SWIFT_FUNCDISPATCHV(type, ret, obj, fn, ...) do { \
792-
if (CF_IS_SWIFT(type, obj)) { \
791+
#define CF_SWIFT_FUNCDISPATCHV_CHECK(check, type, ret, obj, fn, ...) do { \
792+
if (check(type, obj)) { \
793793
return (ret)__CFSwiftBridge.fn((CFSwiftRef)obj, ##__VA_ARGS__); \
794794
} \
795795
} while (0)
796+
#define CF_SWIFT_FUNCDISPATCHV(type, ret, obj, fn, ...) CF_SWIFT_FUNCDISPATCHV_CHECK(CF_IS_SWIFT, type, ret, obj, fn, ## __VA_ARGS__)
796797

797798
#define CF_SWIFT_CALLV(obj, fn, ...) __CFSwiftBridge.fn((CFSwiftRef)obj, ##__VA_ARGS__)
798799
#else

CoreFoundation/Base.subproj/ForFoundationOnly.h

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -673,6 +673,9 @@ CF_EXPORT void *_CFCreateArrayStorage(size_t numPointers, Boolean zeroed, size_t
673673
#define STATIC_CLASS_NAME_LENGTH_LOOKUP___NSCFNumber 8
674674
#define STATIC_CLASS_NAME_LOOKUP___NSCFNumber NSNumberCN
675675

676+
#define STATIC_CLASS_NAME_LENGTH_LOOKUP_NSMutableData 13
677+
#define STATIC_CLASS_NAME_LOOKUP_NSMutableData NSMutableDataCN
678+
676679
#define STATIC_CLASS_NAME_CONCAT_INNER(x,y) x ## y
677680
#define STATIC_CLASS_NAME_CONCAT(x,y) STATIC_CLASS_NAME_CONCAT_INNER(x,y)
678681

CoreFoundation/Base.subproj/ForSwiftFoundationOnly.h

Lines changed: 8 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -80,14 +80,6 @@ struct __CFSwiftObject {
8080

8181
typedef struct __CFSwiftObject *CFSwiftRef;
8282

83-
#define CF_IS_SWIFT(type, obj) (_CFIsSwift(type, (CFSwiftRef)obj))
84-
85-
#define CF_SWIFT_FUNCDISPATCHV(type, ret, obj, fn, ...) do { \
86-
if (CF_IS_SWIFT(type, obj)) { \
87-
return (ret)__CFSwiftBridge.fn((CFSwiftRef)obj, ##__VA_ARGS__); \
88-
} \
89-
} while (0)
90-
9183
CF_EXPORT bool _CFIsSwift(CFTypeID type, CFSwiftRef obj);
9284
CF_EXPORT void _CFDeinit(CFTypeRef cf);
9385

@@ -276,6 +268,14 @@ struct _NSNumberBridge {
276268

277269
struct _NSDataBridge {
278270
_Nonnull CFTypeRef (*_Nonnull copy)(CFTypeRef obj);
271+
CFIndex (*_Nonnull length)(CFTypeRef obj);
272+
const void *_Nullable (*_Nonnull bytes)(CFTypeRef obj);
273+
void *_Nullable (*_Nonnull mutableBytes)(CFTypeRef obj);
274+
void (*_Nonnull getBytes)(CFTypeRef obj, CFRange range, void *buffer);
275+
void (*_Nonnull setLength)(CFTypeRef obj, CFIndex newLength);
276+
void (*_Nonnull increaseLengthBy)(CFTypeRef obj, CFIndex extraLength);
277+
void (*_Nonnull appendBytes)(CFTypeRef obj, const void *bytes, CFIndex length);
278+
void (*_Nonnull replaceBytes)(CFTypeRef obj, CFRange range, const void *_Nullable newBytes, CFIndex newLength);
279279
};
280280

281281
struct _NSCalendarBridge {

CoreFoundation/Collections.subproj/CFData.c

Lines changed: 26 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -15,7 +15,17 @@
1515
#include "CFRuntime_Internal.h"
1616
#include <string.h>
1717

18+
#if DEPLOYMENT_RUNTIME_SWIFT
19+
20+
DECLARE_STATIC_CLASS_REF(NSMutableData);
21+
static const void *_NSMutableData = STATIC_CLASS_REF(NSMutableData);
22+
static Boolean _CFDataShouldBridgeToSwift(CFTypeID type, CFDataRef data);
23+
24+
#define CF_SWIFT_NSDATA_FUNCDISPATCHV(type, ret, obj, fn, ...) CF_SWIFT_FUNCDISPATCHV_CHECK(_CFDataShouldBridgeToSwift, type, ret, obj, fn, ## __VA_ARGS__)
1825

26+
#else
27+
#define CF_SWIFT_NSDATA_FUNCDISPATCHV(...)
28+
#endif
1929

2030

2131
#if TARGET_RT_64_BIT
@@ -53,6 +63,12 @@ struct __CFData {
5363
uint8_t *_bytes; /* compaction: direct access to _bytes is only valid when data is not inline */
5464
};
5565

66+
#if DEPLOYMENT_RUNTIME_SWIFT
67+
static Boolean _CFDataShouldBridgeToSwift(CFTypeID type, CFDataRef data) {
68+
return CF_IS_SWIFT(type, data) && data->_base._cfisa != (uintptr_t)_NSMutableData;
69+
}
70+
#endif
71+
5672
/*
5773
Bit 0 = is mutable
5874
Bit 1 = growable
@@ -458,7 +474,7 @@ CFDataRef CFDataCreateCopy(CFAllocatorRef allocator, CFDataRef data) {
458474
Boolean allowRetain = true;
459475
if (allowRetain) {
460476
CF_OBJC_FUNCDISPATCHV(CFDataGetTypeID(), CFDataRef, (NSData *)data, copy);
461-
CF_SWIFT_FUNCDISPATCHV(CFDataGetTypeID(), CFDataRef, (CFSwiftRef)data, NSData.copy);
477+
CF_SWIFT_NSDATA_FUNCDISPATCHV(CFDataGetTypeID(), CFDataRef, (CFSwiftRef)data, NSData.copy);
462478

463479
// If the data isn't mutable...
464480
if (!__CFDataIsMutable(data)) {
@@ -499,6 +515,7 @@ CFMutableDataRef CFDataCreateMutableCopy(CFAllocatorRef allocator, CFIndex capac
499515

500516
CFIndex CFDataGetLength(CFDataRef data) {
501517
CF_OBJC_FUNCDISPATCHV(CFDataGetTypeID(), CFIndex, (NSData *)data, length);
518+
CF_SWIFT_NSDATA_FUNCDISPATCHV(_kCFRuntimeIDCFData, CFIndex, data, NSData.length);
502519
__CFGenericValidateType(data, CFDataGetTypeID());
503520
return __CFDataLength(data);
504521
}
@@ -510,17 +527,20 @@ CF_PRIVATE uint8_t *_CFDataGetBytePtrNonObjC(CFDataRef data) {
510527

511528
const uint8_t *CFDataGetBytePtr(CFDataRef data) {
512529
CF_OBJC_FUNCDISPATCHV(CFDataGetTypeID(), const uint8_t *, (NSData *)data, bytes);
530+
CF_SWIFT_NSDATA_FUNCDISPATCHV(_kCFRuntimeIDCFData, const uint8_t *, data, NSData.bytes);
513531
return _CFDataGetBytePtrNonObjC(data);
514532
}
515533

516534
uint8_t *CFDataGetMutableBytePtr(CFMutableDataRef data) {
517535
CF_OBJC_FUNCDISPATCHV(CFDataGetTypeID(), uint8_t *, (NSMutableData *)data, mutableBytes);
536+
CF_SWIFT_NSDATA_FUNCDISPATCHV(_kCFRuntimeIDCFData, uint8_t *, data, NSData.mutableBytes);
518537
CFAssert1(__CFDataIsMutable(data), __kCFLogAssertion, "%s(): data is immutable", __PRETTY_FUNCTION__);
519538
return _CFDataGetBytePtrNonObjC(data);
520539
}
521540

522541
void CFDataGetBytes(CFDataRef data, CFRange range, uint8_t *buffer) {
523542
CF_OBJC_FUNCDISPATCHV(CFDataGetTypeID(), void, (NSData *)data, getBytes:(void *)buffer range:NSMakeRange(range.location, range.length));
543+
CF_SWIFT_NSDATA_FUNCDISPATCHV(_kCFRuntimeIDCFData, void, data, NSData.getBytes, range, buffer);
524544
__CFDataValidateRange(data, range, __PRETTY_FUNCTION__);
525545
memmove(buffer, _CFDataGetBytePtrNonObjC(data) + range.location, range.length);
526546
}
@@ -566,6 +586,7 @@ void CFDataSetLength(CFMutableDataRef data, CFIndex newLength) {
566586
CFIndex oldLength, capacity;
567587
Boolean isGrowable;
568588
CF_OBJC_FUNCDISPATCHV(CFDataGetTypeID(), void, (NSMutableData *)data, setLength:(NSUInteger)newLength);
589+
CF_SWIFT_NSDATA_FUNCDISPATCHV(_kCFRuntimeIDCFData, void, data, NSData.setLength, newLength);
569590
CFAssert1(__CFDataIsMutable(data), __kCFLogAssertion, "%s(): data is immutable", __PRETTY_FUNCTION__);
570591
oldLength = __CFDataLength(data);
571592
capacity = __CFDataCapacity(data);
@@ -597,25 +618,29 @@ void CFDataSetLength(CFMutableDataRef data, CFIndex newLength) {
597618

598619
void CFDataIncreaseLength(CFMutableDataRef data, CFIndex extraLength) {
599620
CF_OBJC_FUNCDISPATCHV(CFDataGetTypeID(), void, (NSMutableData *)data, increaseLengthBy:(NSUInteger)extraLength);
621+
CF_SWIFT_NSDATA_FUNCDISPATCHV(_kCFRuntimeIDCFData, void, data, NSData.increaseLengthBy, extraLength);
600622
CFAssert1(__CFDataIsMutable(data), __kCFLogAssertion, "%s(): data is immutable", __PRETTY_FUNCTION__);
601623
if (extraLength < 0) HALT; // Avoid integer overflow.
602624
CFDataSetLength(data, __CFDataLength(data) + extraLength);
603625
}
604626

605627
void CFDataAppendBytes(CFMutableDataRef data, const uint8_t *bytes, CFIndex length) {
606628
CF_OBJC_FUNCDISPATCHV(CFDataGetTypeID(), void, (NSMutableData *)data, appendBytes:(const void *)bytes length:(NSUInteger)length);
629+
CF_SWIFT_NSDATA_FUNCDISPATCHV(_kCFRuntimeIDCFData, void, data, NSData.appendBytes, bytes, length);
607630
CFAssert1(__CFDataIsMutable(data), __kCFLogAssertion, "%s(): data is immutable", __PRETTY_FUNCTION__);
608631
CFDataReplaceBytes(data, CFRangeMake(__CFDataLength(data), 0), bytes, length);
609632
}
610633

611634
void CFDataDeleteBytes(CFMutableDataRef data, CFRange range) {
612635
CF_OBJC_FUNCDISPATCHV(CFDataGetTypeID(), void, (NSMutableData *)data, replaceBytesInRange:NSMakeRange(range.location, range.length) withBytes:NULL length:0);
636+
CF_SWIFT_NSDATA_FUNCDISPATCHV(_kCFRuntimeIDCFData, void, data, NSData.replaceBytes, range, NULL, 0);
613637
CFAssert1(__CFDataIsMutable(data), __kCFLogAssertion, "%s(): data is immutable", __PRETTY_FUNCTION__);
614638
CFDataReplaceBytes(data, range, NULL, 0);
615639
}
616640

617641
void CFDataReplaceBytes(CFMutableDataRef data, CFRange range, const uint8_t *newBytes, CFIndex newLength) {
618642
CF_OBJC_FUNCDISPATCHV(CFDataGetTypeID(), void, (NSMutableData *)data, replaceBytesInRange:NSMakeRange(range.location, range.length) withBytes:(const void *)newBytes length:(NSUInteger)newLength);
643+
CF_SWIFT_NSDATA_FUNCDISPATCHV(_kCFRuntimeIDCFData, void, data, NSData.replaceBytes, range, newBytes, newLength);
619644
__CFGenericValidateType(data, CFDataGetTypeID());
620645
__CFDataValidateRange(data, range, __PRETTY_FUNCTION__);
621646
CFAssert1(__CFDataIsMutable(data), __kCFLogAssertion, "%s(): data is immutable", __PRETTY_FUNCTION__);

Foundation/NSData.swift

Lines changed: 105 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -271,11 +271,13 @@ open class NSData : NSObject, NSCopying, NSMutableCopying, NSSecureCoding {
271271

272272
/// The number of bytes contained by the data object.
273273
open var length: Int {
274+
requireFunnelOverridden()
274275
return CFDataGetLength(_cfObject)
275276
}
276277

277278
/// A pointer to the data object's contents.
278279
open var bytes: UnsafeRawPointer {
280+
requireFunnelOverridden()
279281
guard let bytePtr = CFDataGetBytePtr(_cfObject) else {
280282
//This could occure on empty data being encoded.
281283
//TODO: switch with nil when signature is fixed
@@ -520,14 +522,29 @@ open class NSData : NSObject, NSCopying, NSMutableCopying, NSSecureCoding {
520522
// MARK: - Bytes
521523
/// Copies a number of bytes from the start of the data object into a given buffer.
522524
open func getBytes(_ buffer: UnsafeMutableRawPointer, length: Int) {
523-
let bytePtr = buffer.bindMemory(to: UInt8.self, capacity: length)
524-
CFDataGetBytes(_cfObject, CFRangeMake(0, length), bytePtr)
525+
if funnelsAreAbstract {
526+
let actualCount = Swift.min(length, self.length)
527+
let sourceBuffer = UnsafeRawBufferPointer(start: bytes, count: actualCount)
528+
let destinationBuffer = UnsafeMutableRawBufferPointer(start: buffer, count: actualCount)
529+
sourceBuffer.copyBytes(to: destinationBuffer)
530+
} else {
531+
let bytePtr = buffer.bindMemory(to: UInt8.self, capacity: length)
532+
CFDataGetBytes(_cfObject, CFRangeMake(0, length), bytePtr)
533+
}
525534
}
526535

527536
/// Copies a range of bytes from the data object into a given buffer.
528537
open func getBytes(_ buffer: UnsafeMutableRawPointer, range: NSRange) {
529-
let bytePtr = buffer.bindMemory(to: UInt8.self, capacity: range.length)
530-
CFDataGetBytes(_cfObject, CFRangeMake(range.location, range.length), bytePtr)
538+
if funnelsAreAbstract {
539+
precondition(range.location >= 0 && range.length >= 0)
540+
let actualCount = Swift.min(range.length, self.length - range.location)
541+
let sourceBuffer = UnsafeRawBufferPointer(start: bytes.advanced(by: range.location), count: actualCount)
542+
let destinationBuffer = UnsafeMutableRawBufferPointer(start: buffer, count: actualCount)
543+
sourceBuffer.copyBytes(to: destinationBuffer)
544+
} else {
545+
let bytePtr = buffer.bindMemory(to: UInt8.self, capacity: range.length)
546+
CFDataGetBytes(_cfObject, CFRangeMake(range.location, range.length), bytePtr)
547+
}
531548
}
532549

533550
/// Returns a new data object containing the data object's bytes that fall within the limits specified by a given range.
@@ -930,15 +947,18 @@ open class NSMutableData : NSData {
930947
// MARK: - Funnel Methods
931948
/// A pointer to the data contained by the mutable data object.
932949
open var mutableBytes: UnsafeMutableRawPointer {
950+
requireFunnelOverridden()
933951
return UnsafeMutableRawPointer(CFDataGetMutableBytePtr(_cfMutableObject))
934952
}
935953

936954
/// The number of bytes contained in the mutable data object.
937955
open override var length: Int {
938956
get {
957+
requireFunnelOverridden()
939958
return CFDataGetLength(_cfObject)
940959
}
941960
set {
961+
requireFunnelOverridden()
942962
CFDataSetLength(_cfMutableObject, newValue)
943963
}
944964
}
@@ -951,8 +971,15 @@ open class NSMutableData : NSData {
951971
// MARK: - Mutability
952972
/// Appends to the data object a given number of bytes from a given buffer.
953973
open func append(_ bytes: UnsafeRawPointer, length: Int) {
954-
let bytePtr = bytes.bindMemory(to: UInt8.self, capacity: length)
955-
CFDataAppendBytes(_cfMutableObject, bytePtr, length)
974+
guard length > 0 else { return }
975+
976+
if funnelsAreAbstract {
977+
self.length += length
978+
UnsafeRawBufferPointer(start: bytes, count: length).copyBytes(to: UnsafeMutableRawBufferPointer(start: mutableBytes, count: length))
979+
} else {
980+
let bytePtr = bytes.bindMemory(to: UInt8.self, capacity: length)
981+
CFDataAppendBytes(_cfMutableObject, bytePtr, length)
982+
}
956983
}
957984

958985
/// Appends the content of another data object to the data object.
@@ -965,13 +992,21 @@ open class NSMutableData : NSData {
965992

966993
/// Increases the length of the data object by a given number of bytes.
967994
open func increaseLength(by extraLength: Int) {
968-
CFDataSetLength(_cfMutableObject, CFDataGetLength(_cfObject) + extraLength)
995+
if funnelsAreAbstract {
996+
self.length += extraLength
997+
} else {
998+
CFDataSetLength(_cfMutableObject, CFDataGetLength(_cfObject) + extraLength)
999+
}
9691000
}
9701001

9711002
/// Replaces with a given set of bytes a given range within the contents of the data object.
9721003
open func replaceBytes(in range: NSRange, withBytes bytes: UnsafeRawPointer) {
973-
let bytePtr = bytes.bindMemory(to: UInt8.self, capacity: length)
974-
CFDataReplaceBytes(_cfMutableObject, CFRangeMake(range.location, range.length), bytePtr, length)
1004+
if funnelsAreAbstract {
1005+
replaceBytes(in: range, withBytes: bytes, length: range.length)
1006+
} else {
1007+
let bytePtr = bytes.bindMemory(to: UInt8.self, capacity: length)
1008+
CFDataReplaceBytes(_cfMutableObject, CFRangeMake(range.location, range.length), bytePtr, length)
1009+
}
9751010
}
9761011

9771012
/// Replaces with zeroes the contents of the data object in a given range.
@@ -989,8 +1024,22 @@ open class NSMutableData : NSData {
9891024

9901025
/// Replaces with a given set of bytes a given range within the contents of the data object.
9911026
open func replaceBytes(in range: NSRange, withBytes replacementBytes: UnsafeRawPointer?, length replacementLength: Int) {
992-
let bytePtr = replacementBytes?.bindMemory(to: UInt8.self, capacity: replacementLength)
993-
CFDataReplaceBytes(_cfMutableObject, CFRangeMake(range.location, range.length), bytePtr, replacementLength)
1027+
precondition(range.location + range.length <= self.length)
1028+
if funnelsAreAbstract {
1029+
let delta = replacementLength - range.length
1030+
if delta != 0 {
1031+
let originalLength = self.length
1032+
self.length += delta
1033+
1034+
if delta > 0 {
1035+
UnsafeRawBufferPointer(start: mutableBytes.advanced(by: range.location), count: originalLength).copyBytes(to: UnsafeMutableRawBufferPointer(start: mutableBytes.advanced(by: range.location + range.length), count: originalLength))
1036+
}
1037+
}
1038+
UnsafeRawBufferPointer(start: replacementBytes, count: replacementLength).copyBytes(to: UnsafeMutableRawBufferPointer(start: mutableBytes.advanced(by: range.location), count: replacementLength))
1039+
} else {
1040+
let bytePtr = replacementBytes?.bindMemory(to: UInt8.self, capacity: replacementLength)
1041+
CFDataReplaceBytes(_cfMutableObject, CFRangeMake(range.location, range.length), bytePtr, replacementLength)
1042+
}
9941043
}
9951044
}
9961045

@@ -1014,6 +1063,50 @@ extension NSData : _StructTypeBridgeable {
10141063
}
10151064
}
10161065

1017-
internal func _CFSwiftDataCreateCopy(_ data: AnyObject) -> Unmanaged<AnyObject> {
1066+
internal func _CFSwiftDataCreateCopy(_ data: CFTypeRef) -> Unmanaged<AnyObject> {
10181067
return Unmanaged<AnyObject>.passRetained((data as! NSData).copy() as! NSObject)
10191068
}
1069+
1070+
internal func _CFSwiftDataGetLength(_ data: CFTypeRef) -> CFIndex {
1071+
return (data as! NSData).length
1072+
}
1073+
1074+
internal func _CFSwiftDataGetBytesPtr(_ data: CFTypeRef) -> UnsafeRawPointer? {
1075+
return (data as! NSData).bytes
1076+
}
1077+
1078+
internal func _CFSwiftDataGetMutableBytesPtr(_ data: CFTypeRef) -> UnsafeMutableRawPointer? {
1079+
return (data as! NSMutableData).mutableBytes
1080+
}
1081+
1082+
internal func _CFSwiftDataGetBytes(_ data: CFTypeRef, _ range: CFRange, _ buffer: UnsafeMutableRawPointer) -> Void {
1083+
(data as! NSData).getBytes(buffer, range: NSMakeRange(range.location, range.length))
1084+
}
1085+
1086+
internal func _CFSwiftDataSetLength(_ data: CFTypeRef, _ newLength: CFIndex) {
1087+
(data as! NSMutableData).length = newLength
1088+
}
1089+
1090+
internal func _CFSwiftDataIncreaseLength(_ data: CFTypeRef, _ extraLength: CFIndex) {
1091+
(data as! NSMutableData).increaseLength(by: extraLength)
1092+
}
1093+
1094+
internal func _CFSwiftDataAppendBytes(_ data: CFTypeRef, _ buffer: UnsafeRawPointer, length: CFIndex) {
1095+
(data as! NSMutableData).append(buffer, length: length)
1096+
}
1097+
1098+
internal func _CFSwiftDataReplaceBytes(_ data: CFTypeRef, _ range: CFRange, _ buffer: UnsafeRawPointer?, _ count: CFIndex) {
1099+
(data as! NSMutableData).replaceBytes(in: NSMakeRange(range.location, range.length), withBytes: buffer, length: count)
1100+
}
1101+
1102+
extension NSData {
1103+
var funnelsAreAbstract: Bool {
1104+
return type(of: self) != NSData.self && type(of: self) != NSMutableData.self
1105+
}
1106+
1107+
func requireFunnelOverridden() {
1108+
if funnelsAreAbstract {
1109+
NSRequiresConcreteImplementation()
1110+
}
1111+
}
1112+
}

0 commit comments

Comments
 (0)