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