|
@@ -34,18 +34,20 @@
|
|
#import "GPBDescriptor.h"
|
|
#import "GPBDescriptor.h"
|
|
|
|
|
|
@implementation GPBExtensionRegistry {
|
|
@implementation GPBExtensionRegistry {
|
|
- NSMutableDictionary *mutableClassMap_;
|
|
|
|
|
|
+ CFMutableDictionaryRef mutableClassMap_;
|
|
}
|
|
}
|
|
|
|
|
|
- (instancetype)init {
|
|
- (instancetype)init {
|
|
if ((self = [super init])) {
|
|
if ((self = [super init])) {
|
|
- mutableClassMap_ = [[NSMutableDictionary alloc] init];
|
|
|
|
|
|
+ // The keys are ObjC classes, so straight up ptr comparisons are fine.
|
|
|
|
+ mutableClassMap_ = CFDictionaryCreateMutable(kCFAllocatorDefault, 0, NULL,
|
|
|
|
+ &kCFTypeDictionaryValueCallBacks);
|
|
}
|
|
}
|
|
return self;
|
|
return self;
|
|
}
|
|
}
|
|
|
|
|
|
- (void)dealloc {
|
|
- (void)dealloc {
|
|
- [mutableClassMap_ release];
|
|
|
|
|
|
+ CFRelease(mutableClassMap_);
|
|
[super dealloc];
|
|
[super dealloc];
|
|
}
|
|
}
|
|
|
|
|
|
@@ -68,14 +70,13 @@
|
|
|
|
|
|
Class containingMessageClass = extension.containingMessageClass;
|
|
Class containingMessageClass = extension.containingMessageClass;
|
|
CFMutableDictionaryRef extensionMap = (CFMutableDictionaryRef)
|
|
CFMutableDictionaryRef extensionMap = (CFMutableDictionaryRef)
|
|
- [mutableClassMap_ objectForKey:containingMessageClass];
|
|
|
|
|
|
+ CFDictionaryGetValue(mutableClassMap_, containingMessageClass);
|
|
if (extensionMap == nil) {
|
|
if (extensionMap == nil) {
|
|
// Use a custom dictionary here because the keys are numbers and conversion
|
|
// Use a custom dictionary here because the keys are numbers and conversion
|
|
// back and forth from NSNumber isn't worth the cost.
|
|
// back and forth from NSNumber isn't worth the cost.
|
|
extensionMap = CFDictionaryCreateMutable(kCFAllocatorDefault, 0, NULL,
|
|
extensionMap = CFDictionaryCreateMutable(kCFAllocatorDefault, 0, NULL,
|
|
&kCFTypeDictionaryValueCallBacks);
|
|
&kCFTypeDictionaryValueCallBacks);
|
|
- [mutableClassMap_ setObject:(id)extensionMap
|
|
|
|
- forKey:(id<NSCopying>)containingMessageClass];
|
|
|
|
|
|
+ CFDictionarySetValue(mutableClassMap_, containingMessageClass, extensionMap);
|
|
CFRelease(extensionMap);
|
|
CFRelease(extensionMap);
|
|
}
|
|
}
|
|
|
|
|
|
@@ -87,7 +88,7 @@
|
|
fieldNumber:(NSInteger)fieldNumber {
|
|
fieldNumber:(NSInteger)fieldNumber {
|
|
Class messageClass = descriptor.messageClass;
|
|
Class messageClass = descriptor.messageClass;
|
|
CFMutableDictionaryRef extensionMap = (CFMutableDictionaryRef)
|
|
CFMutableDictionaryRef extensionMap = (CFMutableDictionaryRef)
|
|
- [mutableClassMap_ objectForKey:messageClass];
|
|
|
|
|
|
+ CFDictionaryGetValue(mutableClassMap_, messageClass);
|
|
ssize_t key = fieldNumber;
|
|
ssize_t key = fieldNumber;
|
|
GPBExtensionDescriptor *result =
|
|
GPBExtensionDescriptor *result =
|
|
(extensionMap
|
|
(extensionMap
|
|
@@ -101,28 +102,28 @@ static void CopyKeyValue(const void *key, const void *value, void *context) {
|
|
CFDictionarySetValue(extensionMap, key, value);
|
|
CFDictionarySetValue(extensionMap, key, value);
|
|
}
|
|
}
|
|
|
|
|
|
|
|
+static void CopySubDictionary(const void *key, const void *value, void *context) {
|
|
|
|
+ CFMutableDictionaryRef mutableClassMap = (CFMutableDictionaryRef)context;
|
|
|
|
+ Class containingMessageClass = key;
|
|
|
|
+ CFMutableDictionaryRef otherExtensionMap = (CFMutableDictionaryRef)value;
|
|
|
|
+
|
|
|
|
+ CFMutableDictionaryRef extensionMap = (CFMutableDictionaryRef)
|
|
|
|
+ CFDictionaryGetValue(mutableClassMap, containingMessageClass);
|
|
|
|
+ if (extensionMap == nil) {
|
|
|
|
+ extensionMap = CFDictionaryCreateMutableCopy(kCFAllocatorDefault, 0, otherExtensionMap);
|
|
|
|
+ CFDictionarySetValue(mutableClassMap, containingMessageClass, extensionMap);
|
|
|
|
+ CFRelease(extensionMap);
|
|
|
|
+ } else {
|
|
|
|
+ CFDictionaryApplyFunction(otherExtensionMap, CopyKeyValue, extensionMap);
|
|
|
|
+ }
|
|
|
|
+}
|
|
|
|
+
|
|
- (void)addExtensions:(GPBExtensionRegistry *)registry {
|
|
- (void)addExtensions:(GPBExtensionRegistry *)registry {
|
|
if (registry == nil) {
|
|
if (registry == nil) {
|
|
// In the case where there are no extensions just ignore.
|
|
// In the case where there are no extensions just ignore.
|
|
return;
|
|
return;
|
|
}
|
|
}
|
|
- NSMutableDictionary *otherClassMap = registry->mutableClassMap_;
|
|
|
|
- [otherClassMap enumerateKeysAndObjectsUsingBlock:^(id key, id value, BOOL * stop) {
|
|
|
|
-#pragma unused(stop)
|
|
|
|
- Class containingMessageClass = key;
|
|
|
|
- CFMutableDictionaryRef otherExtensionMap = (CFMutableDictionaryRef)value;
|
|
|
|
-
|
|
|
|
- CFMutableDictionaryRef extensionMap = (CFMutableDictionaryRef)
|
|
|
|
- [mutableClassMap_ objectForKey:containingMessageClass];
|
|
|
|
- if (extensionMap == nil) {
|
|
|
|
- extensionMap = CFDictionaryCreateMutableCopy(kCFAllocatorDefault, 0, otherExtensionMap);
|
|
|
|
- [mutableClassMap_ setObject:(id)extensionMap
|
|
|
|
- forKey:(id<NSCopying>)containingMessageClass];
|
|
|
|
- CFRelease(extensionMap);
|
|
|
|
- } else {
|
|
|
|
- CFDictionaryApplyFunction(otherExtensionMap, CopyKeyValue, extensionMap);
|
|
|
|
- }
|
|
|
|
- }];
|
|
|
|
|
|
+ CFDictionaryApplyFunction(registry->mutableClassMap_, CopySubDictionary, mutableClassMap_);
|
|
}
|
|
}
|
|
|
|
|
|
#pragma clang diagnostic pop
|
|
#pragma clang diagnostic pop
|