Index: third_party/protobuf/objectivec/GPBUnknownFieldSet.m |
diff --git a/third_party/protobuf/objectivec/GPBUnknownFieldSet.m b/third_party/protobuf/objectivec/GPBUnknownFieldSet.m |
index a7335f050bcc4f4b681a2478abd7f9aa4ecc5afd..4ddc0d2a4892fc43e53bbecba669d488b301c8de 100644 |
--- a/third_party/protobuf/objectivec/GPBUnknownFieldSet.m |
+++ b/third_party/protobuf/objectivec/GPBUnknownFieldSet.m |
@@ -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) { |
@@ -60,12 +93,6 @@ static void CopyWorker(const void *key, const void *value, void *context) { |
[copied release]; |
} |
-// Direct access is use for speed, to avoid even internally declaring things |
-// read/write, etc. The warning is enabled in the project to ensure code calling |
-// protos can turn on -Wdirect-ivar-access without issues. |
-#pragma clang diagnostic push |
-#pragma clang diagnostic ignored "-Wdirect-ivar-access" |
- |
- (id)copyWithZone:(NSZone *)zone { |
GPBUnknownFieldSet *result = [[GPBUnknownFieldSet allocWithZone:zone] init]; |
if (fields_) { |
@@ -121,7 +148,7 @@ static void CopyWorker(const void *key, const void *value, void *context) { |
} |
- (NSArray *)sortedFields { |
- if (!fields_) return [NSArray array]; |
+ if (!fields_) return nil; |
size_t count = CFDictionaryGetCount(fields_); |
ssize_t keys[count]; |
GPBUnknownField *values[count]; |
@@ -258,9 +285,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; |
@@ -322,7 +353,6 @@ static void GPBUnknownFieldSetMergeUnknownFields(const void *key, |
} |
- (BOOL)mergeFieldFrom:(int32_t)tag input:(GPBCodedInputStream *)input { |
- NSAssert(GPBWireFormatIsValidTag(tag), @"Got passed an invalid tag"); |
int32_t number = GPBWireFormatGetTagFieldNumber(tag); |
GPBCodedInputStreamState *state = &input->state_; |
switch (GPBWireFormatGetTagWireType(tag)) { |
@@ -390,6 +420,4 @@ static void GPBUnknownFieldSetMergeUnknownFields(const void *key, |
} |
} |
-#pragma clang diagnostic pop |
- |
@end |