aboutsummaryrefslogtreecommitdiff
path: root/objectivec/GPBExtensionRegistry.m
diff options
context:
space:
mode:
authorThomas Van Lenten <thomasvl@google.com>2017-05-17 13:38:51 -0400
committerThomas Van Lenten <thomasvl@google.com>2017-05-17 14:51:02 -0400
commit49e4ba6098ae4c01f4af35183f9b6f5e6739fb52 (patch)
treebc0c8bea973bf77e0f995d863b95e415bab20535 /objectivec/GPBExtensionRegistry.m
parentb28617b813b4ba4845164a1f5190f762f5b91832 (diff)
downloadprotobuf-49e4ba6098ae4c01f4af35183f9b6f5e6739fb52.tar.gz
protobuf-49e4ba6098ae4c01f4af35183f9b6f5e6739fb52.tar.bz2
protobuf-49e4ba6098ae4c01f4af35183f9b6f5e6739fb52.zip
Fix ExtensionRegistry copying and add tests.
- Fix up -copyWithZone: to not leave the two registries sharing some of the storage by using -addExtensions:. - Improve -addExtensions: to clone the sub dict when there is nothing to merge into. - A ExtensionRegistry unittests. - Update project schemes to not have extra things in perf scheme.
Diffstat (limited to 'objectivec/GPBExtensionRegistry.m')
-rw-r--r--objectivec/GPBExtensionRegistry.m37
1 files changed, 18 insertions, 19 deletions
diff --git a/objectivec/GPBExtensionRegistry.m b/objectivec/GPBExtensionRegistry.m
index 65534b67..b056a52d 100644
--- a/objectivec/GPBExtensionRegistry.m
+++ b/objectivec/GPBExtensionRegistry.m
@@ -57,14 +57,16 @@
- (instancetype)copyWithZone:(NSZone *)zone {
GPBExtensionRegistry *result = [[[self class] allocWithZone:zone] init];
- if (result && mutableClassMap_.count) {
- [result->mutableClassMap_ addEntriesFromDictionary:mutableClassMap_];
- }
+ [result addExtensions:self];
return result;
}
-- (CFMutableDictionaryRef)extensionMapForContainingMessageClass:
- (Class)containingMessageClass {
+- (void)addExtension:(GPBExtensionDescriptor *)extension {
+ if (extension == nil) {
+ return;
+ }
+
+ Class containingMessageClass = extension.containingMessageClass;
CFMutableDictionaryRef extensionMap = (CFMutableDictionaryRef)
[mutableClassMap_ objectForKey:containingMessageClass];
if (extensionMap == nil) {
@@ -74,18 +76,9 @@
&kCFTypeDictionaryValueCallBacks);
[mutableClassMap_ setObject:(id)extensionMap
forKey:(id<NSCopying>)containingMessageClass];
+ CFRelease(extensionMap);
}
- return extensionMap;
-}
-- (void)addExtension:(GPBExtensionDescriptor *)extension {
- if (extension == nil) {
- return;
- }
-
- Class containingMessageClass = extension.containingMessageClass;
- CFMutableDictionaryRef extensionMap =
- [self extensionMapForContainingMessageClass:containingMessageClass];
ssize_t key = extension.fieldNumber;
CFDictionarySetValue(extensionMap, (const void *)key, extension);
}
@@ -119,10 +112,16 @@ static void CopyKeyValue(const void *key, const void *value, void *context) {
Class containingMessageClass = key;
CFMutableDictionaryRef otherExtensionMap = (CFMutableDictionaryRef)value;
- CFMutableDictionaryRef extensionMap =
- [self extensionMapForContainingMessageClass:containingMessageClass];
-
- CFDictionaryApplyFunction(otherExtensionMap, CopyKeyValue, extensionMap);
+ 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);
+ }
}];
}