Compare commits

...
Sign in to create a new pull request.

2 commits

Author SHA1 Message Date
Paul Yang
8ada60c24c Revert "ObjC Extension tweaks to 3 1 branch" 2016-09-19 14:45:18 -07:00
Thomas Van Lenten
db81a9ad98 Merge pull request #2138 from thomasvl/extension_tweak_to_3_1_branch
ObjC Extension tweaks to 3.1 branch
2016-09-19 17:18:51 -04:00
2 changed files with 56 additions and 34 deletions

View file

@ -34,6 +34,8 @@
#import "GPBDescriptor.h"
@implementation GPBExtensionRegistry {
// TODO(dmaclach): Reimplement with CFDictionaries that don't use
// objects as keys.
NSMutableDictionary *mutableClassMap_;
}
@ -63,16 +65,13 @@
return result;
}
- (CFMutableDictionaryRef)extensionMapForContainingMessageClass:
- (NSMutableDictionary *)extensionMapForContainingMessageClass:
(Class)containingMessageClass {
CFMutableDictionaryRef extensionMap = (CFMutableDictionaryRef)
NSMutableDictionary *extensionMap =
[mutableClassMap_ objectForKey:containingMessageClass];
if (extensionMap == nil) {
// 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
extensionMap = [NSMutableDictionary dictionary];
[mutableClassMap_ setObject:extensionMap
forKey:(id<NSCopying>)containingMessageClass];
}
return extensionMap;
@ -84,28 +83,17 @@
}
Class containingMessageClass = extension.containingMessageClass;
CFMutableDictionaryRef extensionMap =
NSMutableDictionary *extensionMap =
[self extensionMapForContainingMessageClass:containingMessageClass];
ssize_t key = extension.fieldNumber;
CFDictionarySetValue(extensionMap, (const void *)key, extension);
[extensionMap setObject:extension forKey:@(extension.fieldNumber)];
}
- (GPBExtensionDescriptor *)extensionForDescriptor:(GPBDescriptor *)descriptor
fieldNumber:(NSInteger)fieldNumber {
Class messageClass = descriptor.messageClass;
CFMutableDictionaryRef extensionMap = (CFMutableDictionaryRef)
NSDictionary *extensionMap =
[mutableClassMap_ objectForKey:messageClass];
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);
return [extensionMap objectForKey:@(fieldNumber)];
}
- (void)addExtensions:(GPBExtensionRegistry *)registry {
@ -114,16 +102,13 @@ static void CopyKeyValue(const void *key, const void *value, void *context) {
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 =
for (Class containingMessageClass in otherClassMap) {
NSMutableDictionary *extensionMap =
[self extensionMapForContainingMessageClass:containingMessageClass];
CFDictionaryApplyFunction(otherExtensionMap, CopyKeyValue, extensionMap);
}];
NSMutableDictionary *otherExtensionMap =
[registry extensionMapForContainingMessageClass:containingMessageClass];
[extensionMap addEntriesFromDictionary:otherExtensionMap];
}
}
#pragma clang diagnostic pop

View file

@ -36,6 +36,39 @@
#import "GPBUtilities.h"
#import "GPBWireFormat.h"
#pragma mark CFDictionaryKeyCallBacks
// We use a custom dictionary here because our keys are numbers and
// conversion back and forth from NSNumber was costing us performance.
// If/when we move to C++ this could be done using a std::map and some
// careful retain/release calls.
static const void *GPBUnknownFieldSetKeyRetain(CFAllocatorRef allocator,
const void *value) {
#pragma unused(allocator)
return value;
}
static void GPBUnknownFieldSetKeyRelease(CFAllocatorRef allocator,
const void *value) {
#pragma unused(allocator)
#pragma unused(value)
}
static CFStringRef GPBUnknownFieldSetCopyKeyDescription(const void *value) {
return CFStringCreateWithFormat(kCFAllocatorDefault, NULL, CFSTR("%d"),
(int)value);
}
static Boolean GPBUnknownFieldSetKeyEqual(const void *value1,
const void *value2) {
return value1 == value2;
}
static CFHashCode GPBUnknownFieldSetKeyHash(const void *value) {
return (CFHashCode)value;
}
#pragma mark Helpers
static void checkNumber(int32_t number) {
@ -258,9 +291,13 @@ static void GPBUnknownFieldSetSerializedSizeAsMessageSet(const void *key,
int32_t number = [field number];
checkNumber(number);
if (!fields_) {
// Use a custom dictionary here because the keys are numbers and conversion
// back and forth from NSNumber isn't worth the cost.
fields_ = CFDictionaryCreateMutable(kCFAllocatorDefault, 0, NULL,
CFDictionaryKeyCallBacks keyCallBacks = {
// See description above for reason for using custom dictionary.
0, GPBUnknownFieldSetKeyRetain, GPBUnknownFieldSetKeyRelease,
GPBUnknownFieldSetCopyKeyDescription, GPBUnknownFieldSetKeyEqual,
GPBUnknownFieldSetKeyHash,
};
fields_ = CFDictionaryCreateMutable(kCFAllocatorDefault, 0, &keyCallBacks,
&kCFTypeDictionaryValueCallBacks);
}
ssize_t key = number;