| OLD | NEW |
| 1 // Protocol Buffers - Google's data interchange format | 1 // Protocol Buffers - Google's data interchange format |
| 2 // Copyright 2008 Google Inc. All rights reserved. | 2 // Copyright 2008 Google Inc. All rights reserved. |
| 3 // https://developers.google.com/protocol-buffers/ | 3 // https://developers.google.com/protocol-buffers/ |
| 4 // | 4 // |
| 5 // Redistribution and use in source and binary forms, with or without | 5 // Redistribution and use in source and binary forms, with or without |
| 6 // modification, are permitted provided that the following conditions are | 6 // modification, are permitted provided that the following conditions are |
| 7 // met: | 7 // met: |
| 8 // | 8 // |
| 9 // * Redistributions of source code must retain the above copyright | 9 // * Redistributions of source code must retain the above copyright |
| 10 // notice, this list of conditions and the following disclaimer. | 10 // notice, this list of conditions and the following disclaimer. |
| (...skipping 18 matching lines...) Expand all Loading... |
| 29 // OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. | 29 // OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. |
| 30 | 30 |
| 31 #import "GPBUnknownFieldSet_PackagePrivate.h" | 31 #import "GPBUnknownFieldSet_PackagePrivate.h" |
| 32 | 32 |
| 33 #import "GPBCodedInputStream_PackagePrivate.h" | 33 #import "GPBCodedInputStream_PackagePrivate.h" |
| 34 #import "GPBCodedOutputStream.h" | 34 #import "GPBCodedOutputStream.h" |
| 35 #import "GPBUnknownField_PackagePrivate.h" | 35 #import "GPBUnknownField_PackagePrivate.h" |
| 36 #import "GPBUtilities.h" | 36 #import "GPBUtilities.h" |
| 37 #import "GPBWireFormat.h" | 37 #import "GPBWireFormat.h" |
| 38 | 38 |
| 39 #pragma mark CFDictionaryKeyCallBacks | |
| 40 | |
| 41 // We use a custom dictionary here because our keys are numbers and | |
| 42 // conversion back and forth from NSNumber was costing us performance. | |
| 43 // If/when we move to C++ this could be done using a std::map and some | |
| 44 // careful retain/release calls. | |
| 45 | |
| 46 static const void *GPBUnknownFieldSetKeyRetain(CFAllocatorRef allocator, | |
| 47 const void *value) { | |
| 48 #pragma unused(allocator) | |
| 49 return value; | |
| 50 } | |
| 51 | |
| 52 static void GPBUnknownFieldSetKeyRelease(CFAllocatorRef allocator, | |
| 53 const void *value) { | |
| 54 #pragma unused(allocator) | |
| 55 #pragma unused(value) | |
| 56 } | |
| 57 | |
| 58 static CFStringRef GPBUnknownFieldSetCopyKeyDescription(const void *value) { | |
| 59 return CFStringCreateWithFormat(kCFAllocatorDefault, NULL, CFSTR("%d"), | |
| 60 (int)value); | |
| 61 } | |
| 62 | |
| 63 static Boolean GPBUnknownFieldSetKeyEqual(const void *value1, | |
| 64 const void *value2) { | |
| 65 return value1 == value2; | |
| 66 } | |
| 67 | |
| 68 static CFHashCode GPBUnknownFieldSetKeyHash(const void *value) { | |
| 69 return (CFHashCode)value; | |
| 70 } | |
| 71 | |
| 72 #pragma mark Helpers | 39 #pragma mark Helpers |
| 73 | 40 |
| 74 static void checkNumber(int32_t number) { | 41 static void checkNumber(int32_t number) { |
| 75 if (number == 0) { | 42 if (number == 0) { |
| 76 [NSException raise:NSInvalidArgumentException | 43 [NSException raise:NSInvalidArgumentException |
| 77 format:@"Zero is not a valid field number."]; | 44 format:@"Zero is not a valid field number."]; |
| 78 } | 45 } |
| 79 } | 46 } |
| 80 | 47 |
| 81 @implementation GPBUnknownFieldSet { | 48 @implementation GPBUnknownFieldSet { |
| 82 @package | 49 @package |
| 83 CFMutableDictionaryRef fields_; | 50 CFMutableDictionaryRef fields_; |
| 84 } | 51 } |
| 85 | 52 |
| 86 static void CopyWorker(const void *key, const void *value, void *context) { | 53 static void CopyWorker(const void *key, const void *value, void *context) { |
| 87 #pragma unused(key) | 54 #pragma unused(key) |
| 88 GPBUnknownField *field = value; | 55 GPBUnknownField *field = value; |
| 89 GPBUnknownFieldSet *result = context; | 56 GPBUnknownFieldSet *result = context; |
| 90 | 57 |
| 91 GPBUnknownField *copied = [field copy]; | 58 GPBUnknownField *copied = [field copy]; |
| 92 [result addField:copied]; | 59 [result addField:copied]; |
| 93 [copied release]; | 60 [copied release]; |
| 94 } | 61 } |
| 95 | 62 |
| 63 // Direct access is use for speed, to avoid even internally declaring things |
| 64 // read/write, etc. The warning is enabled in the project to ensure code calling |
| 65 // protos can turn on -Wdirect-ivar-access without issues. |
| 66 #pragma clang diagnostic push |
| 67 #pragma clang diagnostic ignored "-Wdirect-ivar-access" |
| 68 |
| 96 - (id)copyWithZone:(NSZone *)zone { | 69 - (id)copyWithZone:(NSZone *)zone { |
| 97 GPBUnknownFieldSet *result = [[GPBUnknownFieldSet allocWithZone:zone] init]; | 70 GPBUnknownFieldSet *result = [[GPBUnknownFieldSet allocWithZone:zone] init]; |
| 98 if (fields_) { | 71 if (fields_) { |
| 99 CFDictionaryApplyFunction(fields_, CopyWorker, result); | 72 CFDictionaryApplyFunction(fields_, CopyWorker, result); |
| 100 } | 73 } |
| 101 return result; | 74 return result; |
| 102 } | 75 } |
| 103 | 76 |
| 104 - (void)dealloc { | 77 - (void)dealloc { |
| 105 if (fields_) { | 78 if (fields_) { |
| (...skipping 35 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 141 GPBUnknownField *result = | 114 GPBUnknownField *result = |
| 142 fields_ ? CFDictionaryGetValue(fields_, (void *)key) : nil; | 115 fields_ ? CFDictionaryGetValue(fields_, (void *)key) : nil; |
| 143 return result; | 116 return result; |
| 144 } | 117 } |
| 145 | 118 |
| 146 - (NSUInteger)countOfFields { | 119 - (NSUInteger)countOfFields { |
| 147 return fields_ ? CFDictionaryGetCount(fields_) : 0; | 120 return fields_ ? CFDictionaryGetCount(fields_) : 0; |
| 148 } | 121 } |
| 149 | 122 |
| 150 - (NSArray *)sortedFields { | 123 - (NSArray *)sortedFields { |
| 151 if (!fields_) return nil; | 124 if (!fields_) return [NSArray array]; |
| 152 size_t count = CFDictionaryGetCount(fields_); | 125 size_t count = CFDictionaryGetCount(fields_); |
| 153 ssize_t keys[count]; | 126 ssize_t keys[count]; |
| 154 GPBUnknownField *values[count]; | 127 GPBUnknownField *values[count]; |
| 155 CFDictionaryGetKeysAndValues(fields_, (const void **)keys, | 128 CFDictionaryGetKeysAndValues(fields_, (const void **)keys, |
| 156 (const void **)values); | 129 (const void **)values); |
| 157 struct GPBFieldPair { | 130 struct GPBFieldPair { |
| 158 ssize_t key; | 131 ssize_t key; |
| 159 GPBUnknownField *value; | 132 GPBUnknownField *value; |
| 160 } pairs[count]; | 133 } pairs[count]; |
| 161 for (size_t i = 0; i < count; ++i) { | 134 for (size_t i = 0; i < count; ++i) { |
| (...skipping 116 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 278 } | 251 } |
| 279 | 252 |
| 280 + (BOOL)isFieldTag:(int32_t)tag { | 253 + (BOOL)isFieldTag:(int32_t)tag { |
| 281 return GPBWireFormatGetTagWireType(tag) != GPBWireFormatEndGroup; | 254 return GPBWireFormatGetTagWireType(tag) != GPBWireFormatEndGroup; |
| 282 } | 255 } |
| 283 | 256 |
| 284 - (void)addField:(GPBUnknownField *)field { | 257 - (void)addField:(GPBUnknownField *)field { |
| 285 int32_t number = [field number]; | 258 int32_t number = [field number]; |
| 286 checkNumber(number); | 259 checkNumber(number); |
| 287 if (!fields_) { | 260 if (!fields_) { |
| 288 CFDictionaryKeyCallBacks keyCallBacks = { | 261 // Use a custom dictionary here because the keys are numbers and conversion |
| 289 // See description above for reason for using custom dictionary. | 262 // back and forth from NSNumber isn't worth the cost. |
| 290 0, GPBUnknownFieldSetKeyRetain, GPBUnknownFieldSetKeyRelease, | 263 fields_ = CFDictionaryCreateMutable(kCFAllocatorDefault, 0, NULL, |
| 291 GPBUnknownFieldSetCopyKeyDescription, GPBUnknownFieldSetKeyEqual, | |
| 292 GPBUnknownFieldSetKeyHash, | |
| 293 }; | |
| 294 fields_ = CFDictionaryCreateMutable(kCFAllocatorDefault, 0, &keyCallBacks, | |
| 295 &kCFTypeDictionaryValueCallBacks); | 264 &kCFTypeDictionaryValueCallBacks); |
| 296 } | 265 } |
| 297 ssize_t key = number; | 266 ssize_t key = number; |
| 298 CFDictionarySetValue(fields_, (const void *)key, field); | 267 CFDictionarySetValue(fields_, (const void *)key, field); |
| 299 } | 268 } |
| 300 | 269 |
| 301 - (GPBUnknownField *)mutableFieldForNumber:(int32_t)number create:(BOOL)create { | 270 - (GPBUnknownField *)mutableFieldForNumber:(int32_t)number create:(BOOL)create { |
| 302 ssize_t key = number; | 271 ssize_t key = number; |
| 303 GPBUnknownField *existing = | 272 GPBUnknownField *existing = |
| 304 fields_ ? CFDictionaryGetValue(fields_, (const void *)key) : nil; | 273 fields_ ? CFDictionaryGetValue(fields_, (const void *)key) : nil; |
| (...skipping 41 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 346 [input checkLastTagWas:0]; | 315 [input checkLastTagWas:0]; |
| 347 [input release]; | 316 [input release]; |
| 348 } | 317 } |
| 349 | 318 |
| 350 - (void)mergeVarintField:(int32_t)number value:(int32_t)value { | 319 - (void)mergeVarintField:(int32_t)number value:(int32_t)value { |
| 351 checkNumber(number); | 320 checkNumber(number); |
| 352 [[self mutableFieldForNumber:number create:YES] addVarint:value]; | 321 [[self mutableFieldForNumber:number create:YES] addVarint:value]; |
| 353 } | 322 } |
| 354 | 323 |
| 355 - (BOOL)mergeFieldFrom:(int32_t)tag input:(GPBCodedInputStream *)input { | 324 - (BOOL)mergeFieldFrom:(int32_t)tag input:(GPBCodedInputStream *)input { |
| 325 NSAssert(GPBWireFormatIsValidTag(tag), @"Got passed an invalid tag"); |
| 356 int32_t number = GPBWireFormatGetTagFieldNumber(tag); | 326 int32_t number = GPBWireFormatGetTagFieldNumber(tag); |
| 357 GPBCodedInputStreamState *state = &input->state_; | 327 GPBCodedInputStreamState *state = &input->state_; |
| 358 switch (GPBWireFormatGetTagWireType(tag)) { | 328 switch (GPBWireFormatGetTagWireType(tag)) { |
| 359 case GPBWireFormatVarint: { | 329 case GPBWireFormatVarint: { |
| 360 GPBUnknownField *field = [self mutableFieldForNumber:number create:YES]; | 330 GPBUnknownField *field = [self mutableFieldForNumber:number create:YES]; |
| 361 [field addVarint:GPBCodedInputStreamReadInt64(state)]; | 331 [field addVarint:GPBCodedInputStreamReadInt64(state)]; |
| 362 return YES; | 332 return YES; |
| 363 } | 333 } |
| 364 case GPBWireFormatFixed64: { | 334 case GPBWireFormatFixed64: { |
| 365 GPBUnknownField *field = [self mutableFieldForNumber:number create:YES]; | 335 GPBUnknownField *field = [self mutableFieldForNumber:number create:YES]; |
| (...skipping 47 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 413 - (void)getTags:(int32_t *)tags { | 383 - (void)getTags:(int32_t *)tags { |
| 414 if (!fields_) return; | 384 if (!fields_) return; |
| 415 size_t count = CFDictionaryGetCount(fields_); | 385 size_t count = CFDictionaryGetCount(fields_); |
| 416 ssize_t keys[count]; | 386 ssize_t keys[count]; |
| 417 CFDictionaryGetKeysAndValues(fields_, (const void **)keys, NULL); | 387 CFDictionaryGetKeysAndValues(fields_, (const void **)keys, NULL); |
| 418 for (size_t i = 0; i < count; ++i) { | 388 for (size_t i = 0; i < count; ++i) { |
| 419 tags[i] = (int32_t)keys[i]; | 389 tags[i] = (int32_t)keys[i]; |
| 420 } | 390 } |
| 421 } | 391 } |
| 422 | 392 |
| 393 #pragma clang diagnostic pop |
| 394 |
| 423 @end | 395 @end |
| OLD | NEW |