1*6777b538SAndroid Build Coastguard Worker// Protocol Buffers - Google's data interchange format 2*6777b538SAndroid Build Coastguard Worker// Copyright 2008 Google Inc. All rights reserved. 3*6777b538SAndroid Build Coastguard Worker// https://developers.google.com/protocol-buffers/ 4*6777b538SAndroid Build Coastguard Worker// 5*6777b538SAndroid Build Coastguard Worker// Redistribution and use in source and binary forms, with or without 6*6777b538SAndroid Build Coastguard Worker// modification, are permitted provided that the following conditions are 7*6777b538SAndroid Build Coastguard Worker// met: 8*6777b538SAndroid Build Coastguard Worker// 9*6777b538SAndroid Build Coastguard Worker// * Redistributions of source code must retain the above copyright 10*6777b538SAndroid Build Coastguard Worker// notice, this list of conditions and the following disclaimer. 11*6777b538SAndroid Build Coastguard Worker// * Redistributions in binary form must reproduce the above 12*6777b538SAndroid Build Coastguard Worker// copyright notice, this list of conditions and the following disclaimer 13*6777b538SAndroid Build Coastguard Worker// in the documentation and/or other materials provided with the 14*6777b538SAndroid Build Coastguard Worker// distribution. 15*6777b538SAndroid Build Coastguard Worker// * Neither the name of Google Inc. nor the names of its 16*6777b538SAndroid Build Coastguard Worker// contributors may be used to endorse or promote products derived from 17*6777b538SAndroid Build Coastguard Worker// this software without specific prior written permission. 18*6777b538SAndroid Build Coastguard Worker// 19*6777b538SAndroid Build Coastguard Worker// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 20*6777b538SAndroid Build Coastguard Worker// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 21*6777b538SAndroid Build Coastguard Worker// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR 22*6777b538SAndroid Build Coastguard Worker// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT 23*6777b538SAndroid Build Coastguard Worker// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, 24*6777b538SAndroid Build Coastguard Worker// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT 25*6777b538SAndroid Build Coastguard Worker// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 26*6777b538SAndroid Build Coastguard Worker// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 27*6777b538SAndroid Build Coastguard Worker// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 28*6777b538SAndroid Build Coastguard Worker// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 29*6777b538SAndroid Build Coastguard Worker// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 30*6777b538SAndroid Build Coastguard Worker 31*6777b538SAndroid Build Coastguard Worker#import "GPBExtensionInternals.h" 32*6777b538SAndroid Build Coastguard Worker 33*6777b538SAndroid Build Coastguard Worker#import <objc/runtime.h> 34*6777b538SAndroid Build Coastguard Worker 35*6777b538SAndroid Build Coastguard Worker#import "GPBCodedInputStream_PackagePrivate.h" 36*6777b538SAndroid Build Coastguard Worker#import "GPBCodedOutputStream_PackagePrivate.h" 37*6777b538SAndroid Build Coastguard Worker#import "GPBDescriptor_PackagePrivate.h" 38*6777b538SAndroid Build Coastguard Worker#import "GPBMessage_PackagePrivate.h" 39*6777b538SAndroid Build Coastguard Worker#import "GPBUtilities_PackagePrivate.h" 40*6777b538SAndroid Build Coastguard Worker 41*6777b538SAndroid Build Coastguard Workerstatic id NewSingleValueFromInputStream(GPBExtensionDescriptor *extension, 42*6777b538SAndroid Build Coastguard Worker GPBCodedInputStream *input, 43*6777b538SAndroid Build Coastguard Worker GPBExtensionRegistry *extensionRegistry, 44*6777b538SAndroid Build Coastguard Worker GPBMessage *existingValue) 45*6777b538SAndroid Build Coastguard Worker __attribute__((ns_returns_retained)); 46*6777b538SAndroid Build Coastguard Worker 47*6777b538SAndroid Build Coastguard WorkerGPB_INLINE size_t DataTypeSize(GPBDataType dataType) { 48*6777b538SAndroid Build Coastguard Worker#pragma clang diagnostic push 49*6777b538SAndroid Build Coastguard Worker#pragma clang diagnostic ignored "-Wswitch-enum" 50*6777b538SAndroid Build Coastguard Worker switch (dataType) { 51*6777b538SAndroid Build Coastguard Worker case GPBDataTypeBool: 52*6777b538SAndroid Build Coastguard Worker return 1; 53*6777b538SAndroid Build Coastguard Worker case GPBDataTypeFixed32: 54*6777b538SAndroid Build Coastguard Worker case GPBDataTypeSFixed32: 55*6777b538SAndroid Build Coastguard Worker case GPBDataTypeFloat: 56*6777b538SAndroid Build Coastguard Worker return 4; 57*6777b538SAndroid Build Coastguard Worker case GPBDataTypeFixed64: 58*6777b538SAndroid Build Coastguard Worker case GPBDataTypeSFixed64: 59*6777b538SAndroid Build Coastguard Worker case GPBDataTypeDouble: 60*6777b538SAndroid Build Coastguard Worker return 8; 61*6777b538SAndroid Build Coastguard Worker default: 62*6777b538SAndroid Build Coastguard Worker return 0; 63*6777b538SAndroid Build Coastguard Worker } 64*6777b538SAndroid Build Coastguard Worker#pragma clang diagnostic pop 65*6777b538SAndroid Build Coastguard Worker} 66*6777b538SAndroid Build Coastguard Worker 67*6777b538SAndroid Build Coastguard Workerstatic size_t ComputePBSerializedSizeNoTagOfObject(GPBDataType dataType, id object) { 68*6777b538SAndroid Build Coastguard Worker#define FIELD_CASE(TYPE, ACCESSOR) \ 69*6777b538SAndroid Build Coastguard Worker case GPBDataType##TYPE: \ 70*6777b538SAndroid Build Coastguard Worker return GPBCompute##TYPE##SizeNoTag([(NSNumber *)object ACCESSOR]); 71*6777b538SAndroid Build Coastguard Worker#define FIELD_CASE2(TYPE) \ 72*6777b538SAndroid Build Coastguard Worker case GPBDataType##TYPE: \ 73*6777b538SAndroid Build Coastguard Worker return GPBCompute##TYPE##SizeNoTag(object); 74*6777b538SAndroid Build Coastguard Worker switch (dataType) { 75*6777b538SAndroid Build Coastguard Worker FIELD_CASE(Bool, boolValue) 76*6777b538SAndroid Build Coastguard Worker FIELD_CASE(Float, floatValue) 77*6777b538SAndroid Build Coastguard Worker FIELD_CASE(Double, doubleValue) 78*6777b538SAndroid Build Coastguard Worker FIELD_CASE(Int32, intValue) 79*6777b538SAndroid Build Coastguard Worker FIELD_CASE(SFixed32, intValue) 80*6777b538SAndroid Build Coastguard Worker FIELD_CASE(SInt32, intValue) 81*6777b538SAndroid Build Coastguard Worker FIELD_CASE(Enum, intValue) 82*6777b538SAndroid Build Coastguard Worker FIELD_CASE(Int64, longLongValue) 83*6777b538SAndroid Build Coastguard Worker FIELD_CASE(SInt64, longLongValue) 84*6777b538SAndroid Build Coastguard Worker FIELD_CASE(SFixed64, longLongValue) 85*6777b538SAndroid Build Coastguard Worker FIELD_CASE(UInt32, unsignedIntValue) 86*6777b538SAndroid Build Coastguard Worker FIELD_CASE(Fixed32, unsignedIntValue) 87*6777b538SAndroid Build Coastguard Worker FIELD_CASE(UInt64, unsignedLongLongValue) 88*6777b538SAndroid Build Coastguard Worker FIELD_CASE(Fixed64, unsignedLongLongValue) 89*6777b538SAndroid Build Coastguard Worker FIELD_CASE2(Bytes) 90*6777b538SAndroid Build Coastguard Worker FIELD_CASE2(String) 91*6777b538SAndroid Build Coastguard Worker FIELD_CASE2(Message) 92*6777b538SAndroid Build Coastguard Worker FIELD_CASE2(Group) 93*6777b538SAndroid Build Coastguard Worker } 94*6777b538SAndroid Build Coastguard Worker#undef FIELD_CASE 95*6777b538SAndroid Build Coastguard Worker#undef FIELD_CASE2 96*6777b538SAndroid Build Coastguard Worker} 97*6777b538SAndroid Build Coastguard Worker 98*6777b538SAndroid Build Coastguard Workerstatic size_t ComputeSerializedSizeIncludingTagOfObject( 99*6777b538SAndroid Build Coastguard Worker GPBExtensionDescription *description, id object) { 100*6777b538SAndroid Build Coastguard Worker#define FIELD_CASE(TYPE, ACCESSOR) \ 101*6777b538SAndroid Build Coastguard Worker case GPBDataType##TYPE: \ 102*6777b538SAndroid Build Coastguard Worker return GPBCompute##TYPE##Size(description->fieldNumber, \ 103*6777b538SAndroid Build Coastguard Worker [(NSNumber *)object ACCESSOR]); 104*6777b538SAndroid Build Coastguard Worker#define FIELD_CASE2(TYPE) \ 105*6777b538SAndroid Build Coastguard Worker case GPBDataType##TYPE: \ 106*6777b538SAndroid Build Coastguard Worker return GPBCompute##TYPE##Size(description->fieldNumber, object); 107*6777b538SAndroid Build Coastguard Worker switch (description->dataType) { 108*6777b538SAndroid Build Coastguard Worker FIELD_CASE(Bool, boolValue) 109*6777b538SAndroid Build Coastguard Worker FIELD_CASE(Float, floatValue) 110*6777b538SAndroid Build Coastguard Worker FIELD_CASE(Double, doubleValue) 111*6777b538SAndroid Build Coastguard Worker FIELD_CASE(Int32, intValue) 112*6777b538SAndroid Build Coastguard Worker FIELD_CASE(SFixed32, intValue) 113*6777b538SAndroid Build Coastguard Worker FIELD_CASE(SInt32, intValue) 114*6777b538SAndroid Build Coastguard Worker FIELD_CASE(Enum, intValue) 115*6777b538SAndroid Build Coastguard Worker FIELD_CASE(Int64, longLongValue) 116*6777b538SAndroid Build Coastguard Worker FIELD_CASE(SInt64, longLongValue) 117*6777b538SAndroid Build Coastguard Worker FIELD_CASE(SFixed64, longLongValue) 118*6777b538SAndroid Build Coastguard Worker FIELD_CASE(UInt32, unsignedIntValue) 119*6777b538SAndroid Build Coastguard Worker FIELD_CASE(Fixed32, unsignedIntValue) 120*6777b538SAndroid Build Coastguard Worker FIELD_CASE(UInt64, unsignedLongLongValue) 121*6777b538SAndroid Build Coastguard Worker FIELD_CASE(Fixed64, unsignedLongLongValue) 122*6777b538SAndroid Build Coastguard Worker FIELD_CASE2(Bytes) 123*6777b538SAndroid Build Coastguard Worker FIELD_CASE2(String) 124*6777b538SAndroid Build Coastguard Worker FIELD_CASE2(Group) 125*6777b538SAndroid Build Coastguard Worker case GPBDataTypeMessage: 126*6777b538SAndroid Build Coastguard Worker if (GPBExtensionIsWireFormat(description)) { 127*6777b538SAndroid Build Coastguard Worker return GPBComputeMessageSetExtensionSize(description->fieldNumber, 128*6777b538SAndroid Build Coastguard Worker object); 129*6777b538SAndroid Build Coastguard Worker } else { 130*6777b538SAndroid Build Coastguard Worker return GPBComputeMessageSize(description->fieldNumber, object); 131*6777b538SAndroid Build Coastguard Worker } 132*6777b538SAndroid Build Coastguard Worker } 133*6777b538SAndroid Build Coastguard Worker#undef FIELD_CASE 134*6777b538SAndroid Build Coastguard Worker#undef FIELD_CASE2 135*6777b538SAndroid Build Coastguard Worker} 136*6777b538SAndroid Build Coastguard Worker 137*6777b538SAndroid Build Coastguard Workerstatic size_t ComputeSerializedSizeIncludingTagOfArray( 138*6777b538SAndroid Build Coastguard Worker GPBExtensionDescription *description, NSArray *values) { 139*6777b538SAndroid Build Coastguard Worker if (GPBExtensionIsPacked(description)) { 140*6777b538SAndroid Build Coastguard Worker size_t size = 0; 141*6777b538SAndroid Build Coastguard Worker size_t typeSize = DataTypeSize(description->dataType); 142*6777b538SAndroid Build Coastguard Worker if (typeSize != 0) { 143*6777b538SAndroid Build Coastguard Worker size = values.count * typeSize; 144*6777b538SAndroid Build Coastguard Worker } else { 145*6777b538SAndroid Build Coastguard Worker for (id value in values) { 146*6777b538SAndroid Build Coastguard Worker size += 147*6777b538SAndroid Build Coastguard Worker ComputePBSerializedSizeNoTagOfObject(description->dataType, value); 148*6777b538SAndroid Build Coastguard Worker } 149*6777b538SAndroid Build Coastguard Worker } 150*6777b538SAndroid Build Coastguard Worker return size + GPBComputeTagSize(description->fieldNumber) + 151*6777b538SAndroid Build Coastguard Worker GPBComputeRawVarint32SizeForInteger(size); 152*6777b538SAndroid Build Coastguard Worker } else { 153*6777b538SAndroid Build Coastguard Worker size_t size = 0; 154*6777b538SAndroid Build Coastguard Worker for (id value in values) { 155*6777b538SAndroid Build Coastguard Worker size += ComputeSerializedSizeIncludingTagOfObject(description, value); 156*6777b538SAndroid Build Coastguard Worker } 157*6777b538SAndroid Build Coastguard Worker return size; 158*6777b538SAndroid Build Coastguard Worker } 159*6777b538SAndroid Build Coastguard Worker} 160*6777b538SAndroid Build Coastguard Worker 161*6777b538SAndroid Build Coastguard Workerstatic void WriteObjectIncludingTagToCodedOutputStream( 162*6777b538SAndroid Build Coastguard Worker id object, GPBExtensionDescription *description, 163*6777b538SAndroid Build Coastguard Worker GPBCodedOutputStream *output) { 164*6777b538SAndroid Build Coastguard Worker#define FIELD_CASE(TYPE, ACCESSOR) \ 165*6777b538SAndroid Build Coastguard Worker case GPBDataType##TYPE: \ 166*6777b538SAndroid Build Coastguard Worker [output write##TYPE:description->fieldNumber \ 167*6777b538SAndroid Build Coastguard Worker value:[(NSNumber *)object ACCESSOR]]; \ 168*6777b538SAndroid Build Coastguard Worker return; 169*6777b538SAndroid Build Coastguard Worker#define FIELD_CASE2(TYPE) \ 170*6777b538SAndroid Build Coastguard Worker case GPBDataType##TYPE: \ 171*6777b538SAndroid Build Coastguard Worker [output write##TYPE:description->fieldNumber value:object]; \ 172*6777b538SAndroid Build Coastguard Worker return; 173*6777b538SAndroid Build Coastguard Worker switch (description->dataType) { 174*6777b538SAndroid Build Coastguard Worker FIELD_CASE(Bool, boolValue) 175*6777b538SAndroid Build Coastguard Worker FIELD_CASE(Float, floatValue) 176*6777b538SAndroid Build Coastguard Worker FIELD_CASE(Double, doubleValue) 177*6777b538SAndroid Build Coastguard Worker FIELD_CASE(Int32, intValue) 178*6777b538SAndroid Build Coastguard Worker FIELD_CASE(SFixed32, intValue) 179*6777b538SAndroid Build Coastguard Worker FIELD_CASE(SInt32, intValue) 180*6777b538SAndroid Build Coastguard Worker FIELD_CASE(Enum, intValue) 181*6777b538SAndroid Build Coastguard Worker FIELD_CASE(Int64, longLongValue) 182*6777b538SAndroid Build Coastguard Worker FIELD_CASE(SInt64, longLongValue) 183*6777b538SAndroid Build Coastguard Worker FIELD_CASE(SFixed64, longLongValue) 184*6777b538SAndroid Build Coastguard Worker FIELD_CASE(UInt32, unsignedIntValue) 185*6777b538SAndroid Build Coastguard Worker FIELD_CASE(Fixed32, unsignedIntValue) 186*6777b538SAndroid Build Coastguard Worker FIELD_CASE(UInt64, unsignedLongLongValue) 187*6777b538SAndroid Build Coastguard Worker FIELD_CASE(Fixed64, unsignedLongLongValue) 188*6777b538SAndroid Build Coastguard Worker FIELD_CASE2(Bytes) 189*6777b538SAndroid Build Coastguard Worker FIELD_CASE2(String) 190*6777b538SAndroid Build Coastguard Worker FIELD_CASE2(Group) 191*6777b538SAndroid Build Coastguard Worker case GPBDataTypeMessage: 192*6777b538SAndroid Build Coastguard Worker if (GPBExtensionIsWireFormat(description)) { 193*6777b538SAndroid Build Coastguard Worker [output writeMessageSetExtension:description->fieldNumber value:object]; 194*6777b538SAndroid Build Coastguard Worker } else { 195*6777b538SAndroid Build Coastguard Worker [output writeMessage:description->fieldNumber value:object]; 196*6777b538SAndroid Build Coastguard Worker } 197*6777b538SAndroid Build Coastguard Worker return; 198*6777b538SAndroid Build Coastguard Worker } 199*6777b538SAndroid Build Coastguard Worker#undef FIELD_CASE 200*6777b538SAndroid Build Coastguard Worker#undef FIELD_CASE2 201*6777b538SAndroid Build Coastguard Worker} 202*6777b538SAndroid Build Coastguard Worker 203*6777b538SAndroid Build Coastguard Workerstatic void WriteObjectNoTagToCodedOutputStream( 204*6777b538SAndroid Build Coastguard Worker id object, GPBExtensionDescription *description, 205*6777b538SAndroid Build Coastguard Worker GPBCodedOutputStream *output) { 206*6777b538SAndroid Build Coastguard Worker#define FIELD_CASE(TYPE, ACCESSOR) \ 207*6777b538SAndroid Build Coastguard Worker case GPBDataType##TYPE: \ 208*6777b538SAndroid Build Coastguard Worker [output write##TYPE##NoTag:[(NSNumber *)object ACCESSOR]]; \ 209*6777b538SAndroid Build Coastguard Worker return; 210*6777b538SAndroid Build Coastguard Worker#define FIELD_CASE2(TYPE) \ 211*6777b538SAndroid Build Coastguard Worker case GPBDataType##TYPE: \ 212*6777b538SAndroid Build Coastguard Worker [output write##TYPE##NoTag:object]; \ 213*6777b538SAndroid Build Coastguard Worker return; 214*6777b538SAndroid Build Coastguard Worker switch (description->dataType) { 215*6777b538SAndroid Build Coastguard Worker FIELD_CASE(Bool, boolValue) 216*6777b538SAndroid Build Coastguard Worker FIELD_CASE(Float, floatValue) 217*6777b538SAndroid Build Coastguard Worker FIELD_CASE(Double, doubleValue) 218*6777b538SAndroid Build Coastguard Worker FIELD_CASE(Int32, intValue) 219*6777b538SAndroid Build Coastguard Worker FIELD_CASE(SFixed32, intValue) 220*6777b538SAndroid Build Coastguard Worker FIELD_CASE(SInt32, intValue) 221*6777b538SAndroid Build Coastguard Worker FIELD_CASE(Enum, intValue) 222*6777b538SAndroid Build Coastguard Worker FIELD_CASE(Int64, longLongValue) 223*6777b538SAndroid Build Coastguard Worker FIELD_CASE(SInt64, longLongValue) 224*6777b538SAndroid Build Coastguard Worker FIELD_CASE(SFixed64, longLongValue) 225*6777b538SAndroid Build Coastguard Worker FIELD_CASE(UInt32, unsignedIntValue) 226*6777b538SAndroid Build Coastguard Worker FIELD_CASE(Fixed32, unsignedIntValue) 227*6777b538SAndroid Build Coastguard Worker FIELD_CASE(UInt64, unsignedLongLongValue) 228*6777b538SAndroid Build Coastguard Worker FIELD_CASE(Fixed64, unsignedLongLongValue) 229*6777b538SAndroid Build Coastguard Worker FIELD_CASE2(Bytes) 230*6777b538SAndroid Build Coastguard Worker FIELD_CASE2(String) 231*6777b538SAndroid Build Coastguard Worker FIELD_CASE2(Message) 232*6777b538SAndroid Build Coastguard Worker case GPBDataTypeGroup: 233*6777b538SAndroid Build Coastguard Worker [output writeGroupNoTag:description->fieldNumber value:object]; 234*6777b538SAndroid Build Coastguard Worker return; 235*6777b538SAndroid Build Coastguard Worker } 236*6777b538SAndroid Build Coastguard Worker#undef FIELD_CASE 237*6777b538SAndroid Build Coastguard Worker#undef FIELD_CASE2 238*6777b538SAndroid Build Coastguard Worker} 239*6777b538SAndroid Build Coastguard Worker 240*6777b538SAndroid Build Coastguard Workerstatic void WriteArrayIncludingTagsToCodedOutputStream( 241*6777b538SAndroid Build Coastguard Worker NSArray *values, GPBExtensionDescription *description, 242*6777b538SAndroid Build Coastguard Worker GPBCodedOutputStream *output) { 243*6777b538SAndroid Build Coastguard Worker if (GPBExtensionIsPacked(description)) { 244*6777b538SAndroid Build Coastguard Worker [output writeTag:description->fieldNumber 245*6777b538SAndroid Build Coastguard Worker format:GPBWireFormatLengthDelimited]; 246*6777b538SAndroid Build Coastguard Worker size_t dataSize = 0; 247*6777b538SAndroid Build Coastguard Worker size_t typeSize = DataTypeSize(description->dataType); 248*6777b538SAndroid Build Coastguard Worker if (typeSize != 0) { 249*6777b538SAndroid Build Coastguard Worker dataSize = values.count * typeSize; 250*6777b538SAndroid Build Coastguard Worker } else { 251*6777b538SAndroid Build Coastguard Worker for (id value in values) { 252*6777b538SAndroid Build Coastguard Worker dataSize += 253*6777b538SAndroid Build Coastguard Worker ComputePBSerializedSizeNoTagOfObject(description->dataType, value); 254*6777b538SAndroid Build Coastguard Worker } 255*6777b538SAndroid Build Coastguard Worker } 256*6777b538SAndroid Build Coastguard Worker [output writeRawVarintSizeTAs32:dataSize]; 257*6777b538SAndroid Build Coastguard Worker for (id value in values) { 258*6777b538SAndroid Build Coastguard Worker WriteObjectNoTagToCodedOutputStream(value, description, output); 259*6777b538SAndroid Build Coastguard Worker } 260*6777b538SAndroid Build Coastguard Worker } else { 261*6777b538SAndroid Build Coastguard Worker for (id value in values) { 262*6777b538SAndroid Build Coastguard Worker WriteObjectIncludingTagToCodedOutputStream(value, description, output); 263*6777b538SAndroid Build Coastguard Worker } 264*6777b538SAndroid Build Coastguard Worker } 265*6777b538SAndroid Build Coastguard Worker} 266*6777b538SAndroid Build Coastguard Worker 267*6777b538SAndroid Build Coastguard Worker// Direct access is use for speed, to avoid even internally declaring things 268*6777b538SAndroid Build Coastguard Worker// read/write, etc. The warning is enabled in the project to ensure code calling 269*6777b538SAndroid Build Coastguard Worker// protos can turn on -Wdirect-ivar-access without issues. 270*6777b538SAndroid Build Coastguard Worker#pragma clang diagnostic push 271*6777b538SAndroid Build Coastguard Worker#pragma clang diagnostic ignored "-Wdirect-ivar-access" 272*6777b538SAndroid Build Coastguard Worker 273*6777b538SAndroid Build Coastguard Workervoid GPBExtensionMergeFromInputStream(GPBExtensionDescriptor *extension, 274*6777b538SAndroid Build Coastguard Worker BOOL isPackedOnStream, 275*6777b538SAndroid Build Coastguard Worker GPBCodedInputStream *input, 276*6777b538SAndroid Build Coastguard Worker GPBExtensionRegistry *extensionRegistry, 277*6777b538SAndroid Build Coastguard Worker GPBMessage *message) { 278*6777b538SAndroid Build Coastguard Worker GPBExtensionDescription *description = extension->description_; 279*6777b538SAndroid Build Coastguard Worker GPBCodedInputStreamState *state = &input->state_; 280*6777b538SAndroid Build Coastguard Worker if (isPackedOnStream) { 281*6777b538SAndroid Build Coastguard Worker NSCAssert(GPBExtensionIsRepeated(description), 282*6777b538SAndroid Build Coastguard Worker @"How was it packed if it isn't repeated?"); 283*6777b538SAndroid Build Coastguard Worker int32_t length = GPBCodedInputStreamReadInt32(state); 284*6777b538SAndroid Build Coastguard Worker size_t limit = GPBCodedInputStreamPushLimit(state, length); 285*6777b538SAndroid Build Coastguard Worker while (GPBCodedInputStreamBytesUntilLimit(state) > 0) { 286*6777b538SAndroid Build Coastguard Worker id value = NewSingleValueFromInputStream(extension, 287*6777b538SAndroid Build Coastguard Worker input, 288*6777b538SAndroid Build Coastguard Worker extensionRegistry, 289*6777b538SAndroid Build Coastguard Worker nil); 290*6777b538SAndroid Build Coastguard Worker [message addExtension:extension value:value]; 291*6777b538SAndroid Build Coastguard Worker [value release]; 292*6777b538SAndroid Build Coastguard Worker } 293*6777b538SAndroid Build Coastguard Worker GPBCodedInputStreamPopLimit(state, limit); 294*6777b538SAndroid Build Coastguard Worker } else { 295*6777b538SAndroid Build Coastguard Worker id existingValue = nil; 296*6777b538SAndroid Build Coastguard Worker BOOL isRepeated = GPBExtensionIsRepeated(description); 297*6777b538SAndroid Build Coastguard Worker if (!isRepeated && GPBDataTypeIsMessage(description->dataType)) { 298*6777b538SAndroid Build Coastguard Worker existingValue = [message getExistingExtension:extension]; 299*6777b538SAndroid Build Coastguard Worker } 300*6777b538SAndroid Build Coastguard Worker id value = NewSingleValueFromInputStream(extension, 301*6777b538SAndroid Build Coastguard Worker input, 302*6777b538SAndroid Build Coastguard Worker extensionRegistry, 303*6777b538SAndroid Build Coastguard Worker existingValue); 304*6777b538SAndroid Build Coastguard Worker if (isRepeated) { 305*6777b538SAndroid Build Coastguard Worker [message addExtension:extension value:value]; 306*6777b538SAndroid Build Coastguard Worker } else { 307*6777b538SAndroid Build Coastguard Worker [message setExtension:extension value:value]; 308*6777b538SAndroid Build Coastguard Worker } 309*6777b538SAndroid Build Coastguard Worker [value release]; 310*6777b538SAndroid Build Coastguard Worker } 311*6777b538SAndroid Build Coastguard Worker} 312*6777b538SAndroid Build Coastguard Worker 313*6777b538SAndroid Build Coastguard Workervoid GPBWriteExtensionValueToOutputStream(GPBExtensionDescriptor *extension, 314*6777b538SAndroid Build Coastguard Worker id value, 315*6777b538SAndroid Build Coastguard Worker GPBCodedOutputStream *output) { 316*6777b538SAndroid Build Coastguard Worker GPBExtensionDescription *description = extension->description_; 317*6777b538SAndroid Build Coastguard Worker if (GPBExtensionIsRepeated(description)) { 318*6777b538SAndroid Build Coastguard Worker WriteArrayIncludingTagsToCodedOutputStream(value, description, output); 319*6777b538SAndroid Build Coastguard Worker } else { 320*6777b538SAndroid Build Coastguard Worker WriteObjectIncludingTagToCodedOutputStream(value, description, output); 321*6777b538SAndroid Build Coastguard Worker } 322*6777b538SAndroid Build Coastguard Worker} 323*6777b538SAndroid Build Coastguard Worker 324*6777b538SAndroid Build Coastguard Workersize_t GPBComputeExtensionSerializedSizeIncludingTag( 325*6777b538SAndroid Build Coastguard Worker GPBExtensionDescriptor *extension, id value) { 326*6777b538SAndroid Build Coastguard Worker GPBExtensionDescription *description = extension->description_; 327*6777b538SAndroid Build Coastguard Worker if (GPBExtensionIsRepeated(description)) { 328*6777b538SAndroid Build Coastguard Worker return ComputeSerializedSizeIncludingTagOfArray(description, value); 329*6777b538SAndroid Build Coastguard Worker } else { 330*6777b538SAndroid Build Coastguard Worker return ComputeSerializedSizeIncludingTagOfObject(description, value); 331*6777b538SAndroid Build Coastguard Worker } 332*6777b538SAndroid Build Coastguard Worker} 333*6777b538SAndroid Build Coastguard Worker 334*6777b538SAndroid Build Coastguard Worker// Note that this returns a retained value intentionally. 335*6777b538SAndroid Build Coastguard Workerstatic id NewSingleValueFromInputStream(GPBExtensionDescriptor *extension, 336*6777b538SAndroid Build Coastguard Worker GPBCodedInputStream *input, 337*6777b538SAndroid Build Coastguard Worker GPBExtensionRegistry *extensionRegistry, 338*6777b538SAndroid Build Coastguard Worker GPBMessage *existingValue) { 339*6777b538SAndroid Build Coastguard Worker GPBExtensionDescription *description = extension->description_; 340*6777b538SAndroid Build Coastguard Worker GPBCodedInputStreamState *state = &input->state_; 341*6777b538SAndroid Build Coastguard Worker switch (description->dataType) { 342*6777b538SAndroid Build Coastguard Worker case GPBDataTypeBool: return [[NSNumber alloc] initWithBool:GPBCodedInputStreamReadBool(state)]; 343*6777b538SAndroid Build Coastguard Worker case GPBDataTypeFixed32: return [[NSNumber alloc] initWithUnsignedInt:GPBCodedInputStreamReadFixed32(state)]; 344*6777b538SAndroid Build Coastguard Worker case GPBDataTypeSFixed32: return [[NSNumber alloc] initWithInt:GPBCodedInputStreamReadSFixed32(state)]; 345*6777b538SAndroid Build Coastguard Worker case GPBDataTypeFloat: return [[NSNumber alloc] initWithFloat:GPBCodedInputStreamReadFloat(state)]; 346*6777b538SAndroid Build Coastguard Worker case GPBDataTypeFixed64: return [[NSNumber alloc] initWithUnsignedLongLong:GPBCodedInputStreamReadFixed64(state)]; 347*6777b538SAndroid Build Coastguard Worker case GPBDataTypeSFixed64: return [[NSNumber alloc] initWithLongLong:GPBCodedInputStreamReadSFixed64(state)]; 348*6777b538SAndroid Build Coastguard Worker case GPBDataTypeDouble: return [[NSNumber alloc] initWithDouble:GPBCodedInputStreamReadDouble(state)]; 349*6777b538SAndroid Build Coastguard Worker case GPBDataTypeInt32: return [[NSNumber alloc] initWithInt:GPBCodedInputStreamReadInt32(state)]; 350*6777b538SAndroid Build Coastguard Worker case GPBDataTypeInt64: return [[NSNumber alloc] initWithLongLong:GPBCodedInputStreamReadInt64(state)]; 351*6777b538SAndroid Build Coastguard Worker case GPBDataTypeSInt32: return [[NSNumber alloc] initWithInt:GPBCodedInputStreamReadSInt32(state)]; 352*6777b538SAndroid Build Coastguard Worker case GPBDataTypeSInt64: return [[NSNumber alloc] initWithLongLong:GPBCodedInputStreamReadSInt64(state)]; 353*6777b538SAndroid Build Coastguard Worker case GPBDataTypeUInt32: return [[NSNumber alloc] initWithUnsignedInt:GPBCodedInputStreamReadUInt32(state)]; 354*6777b538SAndroid Build Coastguard Worker case GPBDataTypeUInt64: return [[NSNumber alloc] initWithUnsignedLongLong:GPBCodedInputStreamReadUInt64(state)]; 355*6777b538SAndroid Build Coastguard Worker case GPBDataTypeBytes: return GPBCodedInputStreamReadRetainedBytes(state); 356*6777b538SAndroid Build Coastguard Worker case GPBDataTypeString: return GPBCodedInputStreamReadRetainedString(state); 357*6777b538SAndroid Build Coastguard Worker case GPBDataTypeEnum: return [[NSNumber alloc] initWithInt:GPBCodedInputStreamReadEnum(state)]; 358*6777b538SAndroid Build Coastguard Worker case GPBDataTypeGroup: 359*6777b538SAndroid Build Coastguard Worker case GPBDataTypeMessage: { 360*6777b538SAndroid Build Coastguard Worker GPBMessage *message; 361*6777b538SAndroid Build Coastguard Worker if (existingValue) { 362*6777b538SAndroid Build Coastguard Worker message = [existingValue retain]; 363*6777b538SAndroid Build Coastguard Worker } else { 364*6777b538SAndroid Build Coastguard Worker GPBDescriptor *descriptor = [extension.msgClass descriptor]; 365*6777b538SAndroid Build Coastguard Worker message = [[descriptor.messageClass alloc] init]; 366*6777b538SAndroid Build Coastguard Worker } 367*6777b538SAndroid Build Coastguard Worker 368*6777b538SAndroid Build Coastguard Worker if (description->dataType == GPBDataTypeGroup) { 369*6777b538SAndroid Build Coastguard Worker [input readGroup:description->fieldNumber 370*6777b538SAndroid Build Coastguard Worker message:message 371*6777b538SAndroid Build Coastguard Worker extensionRegistry:extensionRegistry]; 372*6777b538SAndroid Build Coastguard Worker } else { 373*6777b538SAndroid Build Coastguard Worker // description->dataType == GPBDataTypeMessage 374*6777b538SAndroid Build Coastguard Worker if (GPBExtensionIsWireFormat(description)) { 375*6777b538SAndroid Build Coastguard Worker // For MessageSet fields the message length will have already been 376*6777b538SAndroid Build Coastguard Worker // read. 377*6777b538SAndroid Build Coastguard Worker [message mergeFromCodedInputStream:input 378*6777b538SAndroid Build Coastguard Worker extensionRegistry:extensionRegistry]; 379*6777b538SAndroid Build Coastguard Worker } else { 380*6777b538SAndroid Build Coastguard Worker [input readMessage:message extensionRegistry:extensionRegistry]; 381*6777b538SAndroid Build Coastguard Worker } 382*6777b538SAndroid Build Coastguard Worker } 383*6777b538SAndroid Build Coastguard Worker 384*6777b538SAndroid Build Coastguard Worker return message; 385*6777b538SAndroid Build Coastguard Worker } 386*6777b538SAndroid Build Coastguard Worker } 387*6777b538SAndroid Build Coastguard Worker 388*6777b538SAndroid Build Coastguard Worker return nil; 389*6777b538SAndroid Build Coastguard Worker} 390*6777b538SAndroid Build Coastguard Worker 391*6777b538SAndroid Build Coastguard Worker#pragma clang diagnostic pop 392