@ -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
CFDictionarySetValue ( mutableClassMap_ , containingMessageClass , extensionMap ) ;
forKey : ( id < NSCopying > ) containingMessageClass ] ;
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_ ;
CFDictionaryApplyFunction ( registry - > mutableClassMap_ , CopySubDictionary , 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 ) ;
}
} ] ;
}
}
#pragma clang diagnostic pop
#pragma clang diagnostic pop