| // Protocol Buffers - Google's data interchange format |
| // Copyright 2008 Google Inc. All rights reserved. |
| // |
| // Use of this source code is governed by a BSD-style |
| // license that can be found in the LICENSE file or at |
| // https://developers.google.com/open-source/licenses/bsd |
| |
| #import "GPBUnknownField.h" |
| #import "GPBUnknownField_PackagePrivate.h" |
| |
| #import "GPBCodedOutputStream.h" |
| #import "GPBCodedOutputStream_PackagePrivate.h" |
| #import "GPBUnknownFields.h" |
| #import "GPBUnknownFields_PackagePrivate.h" |
| #import "GPBWireFormat.h" |
| |
| #define ASSERT_FIELD_TYPE(type) \ |
| if (type_ != type) { \ |
| [NSException raise:NSInternalInconsistencyException \ |
| format:@"GPBUnknownField is the wrong type"]; \ |
| } |
| |
| @implementation GPBUnknownField |
| |
| @synthesize number = number_; |
| @synthesize type = type_; |
| |
| - (instancetype)initWithNumber:(int32_t)number varint:(uint64_t)varint { |
| if ((self = [super init])) { |
| number_ = number; |
| type_ = GPBUnknownFieldTypeVarint; |
| storage_.intValue = varint; |
| } |
| return self; |
| } |
| |
| - (instancetype)initWithNumber:(int32_t)number fixed32:(uint32_t)fixed32 { |
| if ((self = [super init])) { |
| number_ = number; |
| type_ = GPBUnknownFieldTypeFixed32; |
| storage_.intValue = fixed32; |
| } |
| return self; |
| } |
| |
| - (instancetype)initWithNumber:(int32_t)number fixed64:(uint64_t)fixed64 { |
| if ((self = [super init])) { |
| number_ = number; |
| type_ = GPBUnknownFieldTypeFixed64; |
| storage_.intValue = fixed64; |
| } |
| return self; |
| } |
| |
| - (instancetype)initWithNumber:(int32_t)number lengthDelimited:(nonnull NSData *)data { |
| if ((self = [super init])) { |
| number_ = number; |
| type_ = GPBUnknownFieldTypeLengthDelimited; |
| storage_.lengthDelimited = [data copy]; |
| } |
| return self; |
| } |
| |
| - (instancetype)initWithNumber:(int32_t)number group:(nonnull GPBUnknownFields *)group { |
| if ((self = [super init])) { |
| number_ = number; |
| type_ = GPBUnknownFieldTypeGroup; |
| // Taking ownership of the group; so retain, not copy. |
| storage_.group = [group retain]; |
| } |
| return self; |
| } |
| |
| - (void)dealloc { |
| switch (type_) { |
| case GPBUnknownFieldTypeVarint: |
| case GPBUnknownFieldTypeFixed32: |
| case GPBUnknownFieldTypeFixed64: |
| break; |
| case GPBUnknownFieldTypeLengthDelimited: |
| [storage_.lengthDelimited release]; |
| break; |
| case GPBUnknownFieldTypeGroup: |
| [storage_.group release]; |
| break; |
| } |
| |
| [super dealloc]; |
| } |
| |
| // 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" |
| |
| - (uint64_t)varint { |
| ASSERT_FIELD_TYPE(GPBUnknownFieldTypeVarint); |
| return storage_.intValue; |
| } |
| |
| - (uint32_t)fixed32 { |
| ASSERT_FIELD_TYPE(GPBUnknownFieldTypeFixed32); |
| return (uint32_t)storage_.intValue; |
| } |
| |
| - (uint64_t)fixed64 { |
| ASSERT_FIELD_TYPE(GPBUnknownFieldTypeFixed64); |
| return storage_.intValue; |
| } |
| |
| - (NSData *)lengthDelimited { |
| ASSERT_FIELD_TYPE(GPBUnknownFieldTypeLengthDelimited); |
| return storage_.lengthDelimited; |
| } |
| |
| - (GPBUnknownFields *)group { |
| ASSERT_FIELD_TYPE(GPBUnknownFieldTypeGroup); |
| return storage_.group; |
| } |
| |
| - (id)copyWithZone:(NSZone *)zone { |
| switch (type_) { |
| case GPBUnknownFieldTypeVarint: |
| case GPBUnknownFieldTypeFixed32: |
| case GPBUnknownFieldTypeFixed64: |
| case GPBUnknownFieldTypeLengthDelimited: |
| // In these modes, the object isn't mutable, so just return self. |
| return [self retain]; |
| case GPBUnknownFieldTypeGroup: { |
| // The `GPBUnknownFields` for the group is mutable, so a new instance of this object and |
| // the group is needed. |
| GPBUnknownFields *copyGroup = [storage_.group copyWithZone:zone]; |
| GPBUnknownField *copy = [[GPBUnknownField allocWithZone:zone] initWithNumber:number_ |
| group:copyGroup]; |
| [copyGroup release]; |
| return copy; |
| } |
| } |
| } |
| |
| - (BOOL)isEqual:(id)object { |
| if (self == object) return YES; |
| if (![object isKindOfClass:[GPBUnknownField class]]) return NO; |
| GPBUnknownField *field = (GPBUnknownField *)object; |
| if (number_ != field->number_) return NO; |
| if (type_ != field->type_) return NO; |
| switch (type_) { |
| case GPBUnknownFieldTypeVarint: |
| case GPBUnknownFieldTypeFixed32: |
| case GPBUnknownFieldTypeFixed64: |
| return storage_.intValue == field->storage_.intValue; |
| case GPBUnknownFieldTypeLengthDelimited: |
| return [storage_.lengthDelimited isEqual:field->storage_.lengthDelimited]; |
| case GPBUnknownFieldTypeGroup: |
| return [storage_.group isEqual:field->storage_.group]; |
| } |
| } |
| |
| - (NSUInteger)hash { |
| const int prime = 31; |
| NSUInteger result = prime * number_ + type_; |
| switch (type_) { |
| case GPBUnknownFieldTypeVarint: |
| case GPBUnknownFieldTypeFixed32: |
| case GPBUnknownFieldTypeFixed64: |
| result = prime * result + (NSUInteger)storage_.intValue; |
| break; |
| case GPBUnknownFieldTypeLengthDelimited: |
| result = prime * result + [storage_.lengthDelimited hash]; |
| break; |
| case GPBUnknownFieldTypeGroup: |
| result = prime * result + [storage_.group hash]; |
| } |
| return result; |
| } |
| |
| - (NSString *)description { |
| NSMutableString *description = |
| [NSMutableString stringWithFormat:@"<%@ %p>: Field: %d", [self class], self, number_]; |
| switch (type_) { |
| case GPBUnknownFieldTypeVarint: |
| [description appendFormat:@" varint: %llu", storage_.intValue]; |
| break; |
| case GPBUnknownFieldTypeFixed32: |
| [description appendFormat:@" fixed32: %u", (uint32_t)storage_.intValue]; |
| break; |
| case GPBUnknownFieldTypeFixed64: |
| [description appendFormat:@" fixed64: %llu", storage_.intValue]; |
| break; |
| case GPBUnknownFieldTypeLengthDelimited: |
| [description appendFormat:@" fixed64: %@", storage_.lengthDelimited]; |
| break; |
| case GPBUnknownFieldTypeGroup: |
| [description appendFormat:@" group: %@", storage_.group]; |
| break; |
| } |
| return description; |
| } |
| |
| #pragma clang diagnostic pop |
| |
| @end |