|
@@ -34,8 +34,6 @@
|
|
#import "GPBDescriptor.h"
|
|
#import "GPBDescriptor.h"
|
|
|
|
|
|
@implementation GPBExtensionRegistry {
|
|
@implementation GPBExtensionRegistry {
|
|
- // TODO(dmaclach): Reimplement with CFDictionaries that don't use
|
|
|
|
- // objects as keys.
|
|
|
|
NSMutableDictionary *mutableClassMap_;
|
|
NSMutableDictionary *mutableClassMap_;
|
|
}
|
|
}
|
|
|
|
|
|
@@ -65,13 +63,16 @@
|
|
return result;
|
|
return result;
|
|
}
|
|
}
|
|
|
|
|
|
-- (NSMutableDictionary *)extensionMapForContainingMessageClass:
|
|
|
|
|
|
+- (CFMutableDictionaryRef)extensionMapForContainingMessageClass:
|
|
(Class)containingMessageClass {
|
|
(Class)containingMessageClass {
|
|
- NSMutableDictionary *extensionMap =
|
|
|
|
|
|
+ CFMutableDictionaryRef extensionMap = (CFMutableDictionaryRef)
|
|
[mutableClassMap_ objectForKey:containingMessageClass];
|
|
[mutableClassMap_ objectForKey:containingMessageClass];
|
|
if (extensionMap == nil) {
|
|
if (extensionMap == nil) {
|
|
- extensionMap = [NSMutableDictionary dictionary];
|
|
|
|
- [mutableClassMap_ setObject:extensionMap
|
|
|
|
|
|
+ // Use a custom dictionary here because the keys are numbers and conversion
|
|
|
|
+ // back and forth from NSNumber isn't worth the cost.
|
|
|
|
+ extensionMap = CFDictionaryCreateMutable(kCFAllocatorDefault, 0, NULL,
|
|
|
|
+ &kCFTypeDictionaryValueCallBacks);
|
|
|
|
+ [mutableClassMap_ setObject:(id)extensionMap
|
|
forKey:(id<NSCopying>)containingMessageClass];
|
|
forKey:(id<NSCopying>)containingMessageClass];
|
|
}
|
|
}
|
|
return extensionMap;
|
|
return extensionMap;
|
|
@@ -83,17 +84,28 @@
|
|
}
|
|
}
|
|
|
|
|
|
Class containingMessageClass = extension.containingMessageClass;
|
|
Class containingMessageClass = extension.containingMessageClass;
|
|
- NSMutableDictionary *extensionMap =
|
|
|
|
|
|
+ CFMutableDictionaryRef extensionMap =
|
|
[self extensionMapForContainingMessageClass:containingMessageClass];
|
|
[self extensionMapForContainingMessageClass:containingMessageClass];
|
|
- [extensionMap setObject:extension forKey:@(extension.fieldNumber)];
|
|
|
|
|
|
+ ssize_t key = extension.fieldNumber;
|
|
|
|
+ CFDictionarySetValue(extensionMap, (const void *)key, extension);
|
|
}
|
|
}
|
|
|
|
|
|
- (GPBExtensionDescriptor *)extensionForDescriptor:(GPBDescriptor *)descriptor
|
|
- (GPBExtensionDescriptor *)extensionForDescriptor:(GPBDescriptor *)descriptor
|
|
fieldNumber:(NSInteger)fieldNumber {
|
|
fieldNumber:(NSInteger)fieldNumber {
|
|
Class messageClass = descriptor.messageClass;
|
|
Class messageClass = descriptor.messageClass;
|
|
- NSDictionary *extensionMap =
|
|
|
|
|
|
+ CFMutableDictionaryRef extensionMap = (CFMutableDictionaryRef)
|
|
[mutableClassMap_ objectForKey:messageClass];
|
|
[mutableClassMap_ objectForKey:messageClass];
|
|
- return [extensionMap objectForKey:@(fieldNumber)];
|
|
|
|
|
|
+ ssize_t key = fieldNumber;
|
|
|
|
+ GPBExtensionDescriptor *result =
|
|
|
|
+ (extensionMap
|
|
|
|
+ ? CFDictionaryGetValue(extensionMap, (const void *)key)
|
|
|
|
+ : nil);
|
|
|
|
+ return result;
|
|
|
|
+}
|
|
|
|
+
|
|
|
|
+static void CopyKeyValue(const void *key, const void *value, void *context) {
|
|
|
|
+ CFMutableDictionaryRef extensionMap = (CFMutableDictionaryRef)context;
|
|
|
|
+ CFDictionarySetValue(extensionMap, key, value);
|
|
}
|
|
}
|
|
|
|
|
|
- (void)addExtensions:(GPBExtensionRegistry *)registry {
|
|
- (void)addExtensions:(GPBExtensionRegistry *)registry {
|
|
@@ -102,13 +114,16 @@
|
|
return;
|
|
return;
|
|
}
|
|
}
|
|
NSMutableDictionary *otherClassMap = registry->mutableClassMap_;
|
|
NSMutableDictionary *otherClassMap = registry->mutableClassMap_;
|
|
- for (Class containingMessageClass in otherClassMap) {
|
|
|
|
- NSMutableDictionary *extensionMap =
|
|
|
|
|
|
+ [otherClassMap enumerateKeysAndObjectsUsingBlock:^(id key, id value, BOOL * stop) {
|
|
|
|
+#pragma unused(stop)
|
|
|
|
+ Class containingMessageClass = key;
|
|
|
|
+ CFMutableDictionaryRef otherExtensionMap = (CFMutableDictionaryRef)value;
|
|
|
|
+
|
|
|
|
+ CFMutableDictionaryRef extensionMap =
|
|
[self extensionMapForContainingMessageClass:containingMessageClass];
|
|
[self extensionMapForContainingMessageClass:containingMessageClass];
|
|
- NSMutableDictionary *otherExtensionMap =
|
|
|
|
- [registry extensionMapForContainingMessageClass:containingMessageClass];
|
|
|
|
- [extensionMap addEntriesFromDictionary:otherExtensionMap];
|
|
|
|
- }
|
|
|
|
|
|
+
|
|
|
|
+ CFDictionaryApplyFunction(otherExtensionMap, CopyKeyValue, extensionMap);
|
|
|
|
+ }];
|
|
}
|
|
}
|
|
|
|
|
|
#pragma clang diagnostic pop
|
|
#pragma clang diagnostic pop
|