1 // Protocol Buffers - Google's data interchange format
2 // Copyright 2008 Google Inc. All rights reserved.
4 // Use of this source code is governed by a BSD-style
5 // license that can be found in the LICENSE file or at
6 // https://developers.google.com/open-source/licenses/bsd
8 #import "GPBUnknownField.h"
9 #import "GPBUnknownField_PackagePrivate.h"
11 #import "GPBCodedOutputStream.h"
12 #import "GPBCodedOutputStream_PackagePrivate.h"
13 #import "GPBUnknownFields.h"
14 #import "GPBUnknownFields_PackagePrivate.h"
15 #import "GPBWireFormat.h"
17 #define ASSERT_FIELD_TYPE(type) \
18 if (type_ != type) { \
19 [NSException raise:NSInternalInconsistencyException \
20 format:@"GPBUnknownField is the wrong type"]; \
23 @implementation GPBUnknownField
25 @synthesize number = number_;
26 @synthesize type = type_;
28 - (instancetype)initWithNumber:(int32_t)number varint:(uint64_t)varint {
29 if ((self = [super init])) {
31 type_ = GPBUnknownFieldTypeVarint;
32 storage_.intValue = varint;
37 - (instancetype)initWithNumber:(int32_t)number fixed32:(uint32_t)fixed32 {
38 if ((self = [super init])) {
40 type_ = GPBUnknownFieldTypeFixed32;
41 storage_.intValue = fixed32;
46 - (instancetype)initWithNumber:(int32_t)number fixed64:(uint64_t)fixed64 {
47 if ((self = [super init])) {
49 type_ = GPBUnknownFieldTypeFixed64;
50 storage_.intValue = fixed64;
55 - (instancetype)initWithNumber:(int32_t)number lengthDelimited:(nonnull NSData *)data {
56 if ((self = [super init])) {
58 type_ = GPBUnknownFieldTypeLengthDelimited;
59 storage_.lengthDelimited = [data copy];
64 - (instancetype)initWithNumber:(int32_t)number group:(nonnull GPBUnknownFields *)group {
65 if ((self = [super init])) {
67 type_ = GPBUnknownFieldTypeGroup;
68 // Taking ownership of the group; so retain, not copy.
69 storage_.group = [group retain];
76 case GPBUnknownFieldTypeVarint:
77 case GPBUnknownFieldTypeFixed32:
78 case GPBUnknownFieldTypeFixed64:
80 case GPBUnknownFieldTypeLengthDelimited:
81 [storage_.lengthDelimited release];
83 case GPBUnknownFieldTypeGroup:
84 [storage_.group release];
91 // Direct access is use for speed, to avoid even internally declaring things
92 // read/write, etc. The warning is enabled in the project to ensure code calling
93 // protos can turn on -Wdirect-ivar-access without issues.
94 #pragma clang diagnostic push
95 #pragma clang diagnostic ignored "-Wdirect-ivar-access"
98 ASSERT_FIELD_TYPE(GPBUnknownFieldTypeVarint);
99 return storage_.intValue;
102 - (uint32_t)fixed32 {
103 ASSERT_FIELD_TYPE(GPBUnknownFieldTypeFixed32);
104 return (uint32_t)storage_.intValue;
107 - (uint64_t)fixed64 {
108 ASSERT_FIELD_TYPE(GPBUnknownFieldTypeFixed64);
109 return storage_.intValue;
112 - (NSData *)lengthDelimited {
113 ASSERT_FIELD_TYPE(GPBUnknownFieldTypeLengthDelimited);
114 return storage_.lengthDelimited;
117 - (GPBUnknownFields *)group {
118 ASSERT_FIELD_TYPE(GPBUnknownFieldTypeGroup);
119 return storage_.group;
122 - (id)copyWithZone:(NSZone *)zone {
124 case GPBUnknownFieldTypeVarint:
125 case GPBUnknownFieldTypeFixed32:
126 case GPBUnknownFieldTypeFixed64:
127 case GPBUnknownFieldTypeLengthDelimited:
128 // In these modes, the object isn't mutable, so just return self.
129 return [self retain];
130 case GPBUnknownFieldTypeGroup: {
131 // The `GPBUnknownFields` for the group is mutable, so a new instance of this object and
132 // the group is needed.
133 GPBUnknownFields *copyGroup = [storage_.group copyWithZone:zone];
134 GPBUnknownField *copy = [[GPBUnknownField allocWithZone:zone] initWithNumber:number_
142 - (BOOL)isEqual:(id)object {
143 if (self == object) return YES;
144 if (![object isKindOfClass:[GPBUnknownField class]]) return NO;
145 GPBUnknownField *field = (GPBUnknownField *)object;
146 if (number_ != field->number_) return NO;
147 if (type_ != field->type_) return NO;
149 case GPBUnknownFieldTypeVarint:
150 case GPBUnknownFieldTypeFixed32:
151 case GPBUnknownFieldTypeFixed64:
152 return storage_.intValue == field->storage_.intValue;
153 case GPBUnknownFieldTypeLengthDelimited:
154 return [storage_.lengthDelimited isEqual:field->storage_.lengthDelimited];
155 case GPBUnknownFieldTypeGroup:
156 return [storage_.group isEqual:field->storage_.group];
161 const int prime = 31;
162 NSUInteger result = prime * number_ + type_;
164 case GPBUnknownFieldTypeVarint:
165 case GPBUnknownFieldTypeFixed32:
166 case GPBUnknownFieldTypeFixed64:
167 result = prime * result + (NSUInteger)storage_.intValue;
169 case GPBUnknownFieldTypeLengthDelimited:
170 result = prime * result + [storage_.lengthDelimited hash];
172 case GPBUnknownFieldTypeGroup:
173 result = prime * result + [storage_.group hash];
178 - (NSString *)description {
179 NSMutableString *description =
180 [NSMutableString stringWithFormat:@"<%@ %p>: Field: %d", [self class], self, number_];
182 case GPBUnknownFieldTypeVarint:
183 [description appendFormat:@" varint: %llu", storage_.intValue];
185 case GPBUnknownFieldTypeFixed32:
186 [description appendFormat:@" fixed32: %u", (uint32_t)storage_.intValue];
188 case GPBUnknownFieldTypeFixed64:
189 [description appendFormat:@" fixed64: %llu", storage_.intValue];
191 case GPBUnknownFieldTypeLengthDelimited:
192 [description appendFormat:@" fixed64: %@", storage_.lengthDelimited];
194 case GPBUnknownFieldTypeGroup:
195 [description appendFormat:@" group: %@", storage_.group];
201 #pragma clang diagnostic pop