1// Protocol Buffers - Google's data interchange format 2// Copyright 2008 Google Inc. All rights reserved. 3// https://developers.google.com/protocol-buffers/ 4// 5// Redistribution and use in source and binary forms, with or without 6// modification, are permitted provided that the following conditions are 7// met: 8// 9// * Redistributions of source code must retain the above copyright 10// notice, this list of conditions and the following disclaimer. 11// * Redistributions in binary form must reproduce the above 12// copyright notice, this list of conditions and the following disclaimer 13// in the documentation and/or other materials provided with the 14// distribution. 15// * Neither the name of Google Inc. nor the names of its 16// contributors may be used to endorse or promote products derived from 17// this software without specific prior written permission. 18// 19// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 20// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 21// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR 22// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT 23// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, 24// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT 25// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 26// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 27// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 28// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 29// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 30 31#import "GPBUnknownField_PackagePrivate.h" 32 33#import "GPBArray.h" 34#import "GPBCodedOutputStream_PackagePrivate.h" 35 36@implementation GPBUnknownField { 37 @protected 38 int32_t number_; 39 GPBUInt64Array *mutableVarintList_; 40 GPBUInt32Array *mutableFixed32List_; 41 GPBUInt64Array *mutableFixed64List_; 42 NSMutableArray<NSData*> *mutableLengthDelimitedList_; 43 NSMutableArray<GPBUnknownFieldSet*> *mutableGroupList_; 44} 45 46@synthesize number = number_; 47@synthesize varintList = mutableVarintList_; 48@synthesize fixed32List = mutableFixed32List_; 49@synthesize fixed64List = mutableFixed64List_; 50@synthesize lengthDelimitedList = mutableLengthDelimitedList_; 51@synthesize groupList = mutableGroupList_; 52 53- (instancetype)initWithNumber:(int32_t)number { 54 if ((self = [super init])) { 55 number_ = number; 56 } 57 return self; 58} 59 60- (void)dealloc { 61 [mutableVarintList_ release]; 62 [mutableFixed32List_ release]; 63 [mutableFixed64List_ release]; 64 [mutableLengthDelimitedList_ release]; 65 [mutableGroupList_ release]; 66 67 [super dealloc]; 68} 69 70// Direct access is use for speed, to avoid even internally declaring things 71// read/write, etc. The warning is enabled in the project to ensure code calling 72// protos can turn on -Wdirect-ivar-access without issues. 73#pragma clang diagnostic push 74#pragma clang diagnostic ignored "-Wdirect-ivar-access" 75 76- (id)copyWithZone:(NSZone *)zone { 77 GPBUnknownField *result = 78 [[GPBUnknownField allocWithZone:zone] initWithNumber:number_]; 79 result->mutableFixed32List_ = [mutableFixed32List_ copyWithZone:zone]; 80 result->mutableFixed64List_ = [mutableFixed64List_ copyWithZone:zone]; 81 result->mutableLengthDelimitedList_ = 82 [mutableLengthDelimitedList_ copyWithZone:zone]; 83 result->mutableVarintList_ = [mutableVarintList_ copyWithZone:zone]; 84 if (mutableGroupList_.count) { 85 result->mutableGroupList_ = [[NSMutableArray allocWithZone:zone] 86 initWithCapacity:mutableGroupList_.count]; 87 for (GPBUnknownFieldSet *group in mutableGroupList_) { 88 GPBUnknownFieldSet *copied = [group copyWithZone:zone]; 89 [result->mutableGroupList_ addObject:copied]; 90 [copied release]; 91 } 92 } 93 return result; 94} 95 96- (BOOL)isEqual:(id)object { 97 if (self == object) return YES; 98 if (![object isKindOfClass:[GPBUnknownField class]]) return NO; 99 GPBUnknownField *field = (GPBUnknownField *)object; 100 BOOL equalVarint = 101 (mutableVarintList_.count == 0 && field->mutableVarintList_.count == 0) || 102 [mutableVarintList_ isEqual:field->mutableVarintList_]; 103 if (!equalVarint) return NO; 104 BOOL equalFixed32 = (mutableFixed32List_.count == 0 && 105 field->mutableFixed32List_.count == 0) || 106 [mutableFixed32List_ isEqual:field->mutableFixed32List_]; 107 if (!equalFixed32) return NO; 108 BOOL equalFixed64 = (mutableFixed64List_.count == 0 && 109 field->mutableFixed64List_.count == 0) || 110 [mutableFixed64List_ isEqual:field->mutableFixed64List_]; 111 if (!equalFixed64) return NO; 112 BOOL equalLDList = 113 (mutableLengthDelimitedList_.count == 0 && 114 field->mutableLengthDelimitedList_.count == 0) || 115 [mutableLengthDelimitedList_ isEqual:field->mutableLengthDelimitedList_]; 116 if (!equalLDList) return NO; 117 BOOL equalGroupList = 118 (mutableGroupList_.count == 0 && field->mutableGroupList_.count == 0) || 119 [mutableGroupList_ isEqual:field->mutableGroupList_]; 120 if (!equalGroupList) return NO; 121 return YES; 122} 123 124- (NSUInteger)hash { 125 // Just mix the hashes of the possible sub arrays. 126 const int prime = 31; 127 NSUInteger result = prime + [mutableVarintList_ hash]; 128 result = prime * result + [mutableFixed32List_ hash]; 129 result = prime * result + [mutableFixed64List_ hash]; 130 result = prime * result + [mutableLengthDelimitedList_ hash]; 131 result = prime * result + [mutableGroupList_ hash]; 132 return result; 133} 134 135- (void)writeToOutput:(GPBCodedOutputStream *)output { 136 NSUInteger count = mutableVarintList_.count; 137 if (count > 0) { 138 [output writeUInt64Array:number_ values:mutableVarintList_ tag:0]; 139 } 140 count = mutableFixed32List_.count; 141 if (count > 0) { 142 [output writeFixed32Array:number_ values:mutableFixed32List_ tag:0]; 143 } 144 count = mutableFixed64List_.count; 145 if (count > 0) { 146 [output writeFixed64Array:number_ values:mutableFixed64List_ tag:0]; 147 } 148 count = mutableLengthDelimitedList_.count; 149 if (count > 0) { 150 [output writeBytesArray:number_ values:mutableLengthDelimitedList_]; 151 } 152 count = mutableGroupList_.count; 153 if (count > 0) { 154 [output writeUnknownGroupArray:number_ values:mutableGroupList_]; 155 } 156} 157 158- (size_t)serializedSize { 159 __block size_t result = 0; 160 int32_t number = number_; 161 [mutableVarintList_ 162 enumerateValuesWithBlock:^(uint64_t value, NSUInteger idx, BOOL *stop) { 163#pragma unused(idx, stop) 164 result += GPBComputeUInt64Size(number, value); 165 }]; 166 167 [mutableFixed32List_ 168 enumerateValuesWithBlock:^(uint32_t value, NSUInteger idx, BOOL *stop) { 169#pragma unused(idx, stop) 170 result += GPBComputeFixed32Size(number, value); 171 }]; 172 173 [mutableFixed64List_ 174 enumerateValuesWithBlock:^(uint64_t value, NSUInteger idx, BOOL *stop) { 175#pragma unused(idx, stop) 176 result += GPBComputeFixed64Size(number, value); 177 }]; 178 179 for (NSData *data in mutableLengthDelimitedList_) { 180 result += GPBComputeBytesSize(number, data); 181 } 182 183 for (GPBUnknownFieldSet *set in mutableGroupList_) { 184 result += GPBComputeUnknownGroupSize(number, set); 185 } 186 187 return result; 188} 189 190- (void)writeAsMessageSetExtensionToOutput:(GPBCodedOutputStream *)output { 191 for (NSData *data in mutableLengthDelimitedList_) { 192 [output writeRawMessageSetExtension:number_ value:data]; 193 } 194} 195 196- (size_t)serializedSizeAsMessageSetExtension { 197 size_t result = 0; 198 for (NSData *data in mutableLengthDelimitedList_) { 199 result += GPBComputeRawMessageSetExtensionSize(number_, data); 200 } 201 return result; 202} 203 204- (NSString *)description { 205 NSMutableString *description = [NSMutableString 206 stringWithFormat:@"<%@ %p>: Field: %d {\n", [self class], self, number_]; 207 [mutableVarintList_ 208 enumerateValuesWithBlock:^(uint64_t value, NSUInteger idx, BOOL *stop) { 209#pragma unused(idx, stop) 210 [description appendFormat:@"\t%llu\n", value]; 211 }]; 212 213 [mutableFixed32List_ 214 enumerateValuesWithBlock:^(uint32_t value, NSUInteger idx, BOOL *stop) { 215#pragma unused(idx, stop) 216 [description appendFormat:@"\t%u\n", value]; 217 }]; 218 219 [mutableFixed64List_ 220 enumerateValuesWithBlock:^(uint64_t value, NSUInteger idx, BOOL *stop) { 221#pragma unused(idx, stop) 222 [description appendFormat:@"\t%llu\n", value]; 223 }]; 224 225 for (NSData *data in mutableLengthDelimitedList_) { 226 [description appendFormat:@"\t%@\n", data]; 227 } 228 229 for (GPBUnknownFieldSet *set in mutableGroupList_) { 230 [description appendFormat:@"\t%@\n", set]; 231 } 232 [description appendString:@"}"]; 233 return description; 234} 235 236- (void)mergeFromField:(GPBUnknownField *)other { 237 GPBUInt64Array *otherVarintList = other.varintList; 238 if (otherVarintList.count > 0) { 239 if (mutableVarintList_ == nil) { 240 mutableVarintList_ = [otherVarintList copy]; 241 } else { 242 [mutableVarintList_ addValuesFromArray:otherVarintList]; 243 } 244 } 245 246 GPBUInt32Array *otherFixed32List = other.fixed32List; 247 if (otherFixed32List.count > 0) { 248 if (mutableFixed32List_ == nil) { 249 mutableFixed32List_ = [otherFixed32List copy]; 250 } else { 251 [mutableFixed32List_ addValuesFromArray:otherFixed32List]; 252 } 253 } 254 255 GPBUInt64Array *otherFixed64List = other.fixed64List; 256 if (otherFixed64List.count > 0) { 257 if (mutableFixed64List_ == nil) { 258 mutableFixed64List_ = [otherFixed64List copy]; 259 } else { 260 [mutableFixed64List_ addValuesFromArray:otherFixed64List]; 261 } 262 } 263 264 NSArray *otherLengthDelimitedList = other.lengthDelimitedList; 265 if (otherLengthDelimitedList.count > 0) { 266 if (mutableLengthDelimitedList_ == nil) { 267 mutableLengthDelimitedList_ = [otherLengthDelimitedList mutableCopy]; 268 } else { 269 [mutableLengthDelimitedList_ 270 addObjectsFromArray:otherLengthDelimitedList]; 271 } 272 } 273 274 NSArray *otherGroupList = other.groupList; 275 if (otherGroupList.count > 0) { 276 if (mutableGroupList_ == nil) { 277 mutableGroupList_ = 278 [[NSMutableArray alloc] initWithCapacity:otherGroupList.count]; 279 } 280 // Make our own mutable copies. 281 for (GPBUnknownFieldSet *group in otherGroupList) { 282 GPBUnknownFieldSet *copied = [group copy]; 283 [mutableGroupList_ addObject:copied]; 284 [copied release]; 285 } 286 } 287} 288 289- (void)addVarint:(uint64_t)value { 290 if (mutableVarintList_ == nil) { 291 mutableVarintList_ = [[GPBUInt64Array alloc] initWithValues:&value count:1]; 292 } else { 293 [mutableVarintList_ addValue:value]; 294 } 295} 296 297- (void)addFixed32:(uint32_t)value { 298 if (mutableFixed32List_ == nil) { 299 mutableFixed32List_ = 300 [[GPBUInt32Array alloc] initWithValues:&value count:1]; 301 } else { 302 [mutableFixed32List_ addValue:value]; 303 } 304} 305 306- (void)addFixed64:(uint64_t)value { 307 if (mutableFixed64List_ == nil) { 308 mutableFixed64List_ = 309 [[GPBUInt64Array alloc] initWithValues:&value count:1]; 310 } else { 311 [mutableFixed64List_ addValue:value]; 312 } 313} 314 315- (void)addLengthDelimited:(NSData *)value { 316 if (mutableLengthDelimitedList_ == nil) { 317 mutableLengthDelimitedList_ = 318 [[NSMutableArray alloc] initWithObjects:&value count:1]; 319 } else { 320 [mutableLengthDelimitedList_ addObject:value]; 321 } 322} 323 324- (void)addGroup:(GPBUnknownFieldSet *)value { 325 if (mutableGroupList_ == nil) { 326 mutableGroupList_ = [[NSMutableArray alloc] initWithObjects:&value count:1]; 327 } else { 328 [mutableGroupList_ addObject:value]; 329 } 330} 331 332#pragma clang diagnostic pop 333 334@end 335