Home | History | Annotate | Download | only in objectivec
      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 "GPBCodedOutputStream_PackagePrivate.h"
     32 
     33 #import <mach/vm_param.h>
     34 
     35 #import "GPBArray.h"
     36 #import "GPBUnknownFieldSet_PackagePrivate.h"
     37 #import "GPBUtilities_PackagePrivate.h"
     38 
     39 // Structure for containing state of a GPBCodedInputStream. Brought out into
     40 // a struct so that we can inline several common functions instead of dealing
     41 // with overhead of ObjC dispatch.
     42 typedef struct GPBOutputBufferState {
     43   uint8_t *bytes;
     44   size_t size;
     45   size_t position;
     46   NSOutputStream *output;
     47 } GPBOutputBufferState;
     48 
     49 @implementation GPBCodedOutputStream {
     50   GPBOutputBufferState state_;
     51   NSMutableData *buffer_;
     52 }
     53 
     54 static const int32_t LITTLE_ENDIAN_32_SIZE = sizeof(uint32_t);
     55 static const int32_t LITTLE_ENDIAN_64_SIZE = sizeof(uint64_t);
     56 
     57 // Internal helper that writes the current buffer to the output. The
     58 // buffer position is reset to its initial value when this returns.
     59 static void GPBRefreshBuffer(GPBOutputBufferState *state) {
     60   if (state->output == nil) {
     61     // We're writing to a single buffer.
     62     [NSException raise:@"OutOfSpace" format:@""];
     63   }
     64   if (state->position != 0) {
     65     NSInteger written =
     66         [state->output write:state->bytes maxLength:state->position];
     67     if (written != (NSInteger)state->position) {
     68       [NSException raise:@"WriteFailed" format:@""];
     69     }
     70     state->position = 0;
     71   }
     72 }
     73 
     74 static void GPBWriteRawByte(GPBOutputBufferState *state, uint8_t value) {
     75   if (state->position == state->size) {
     76     GPBRefreshBuffer(state);
     77   }
     78   state->bytes[state->position++] = value;
     79 }
     80 
     81 static void GPBWriteRawVarint32(GPBOutputBufferState *state, int32_t value) {
     82   while (YES) {
     83     if ((value & ~0x7F) == 0) {
     84       uint8_t val = (uint8_t)value;
     85       GPBWriteRawByte(state, val);
     86       return;
     87     } else {
     88       GPBWriteRawByte(state, (value & 0x7F) | 0x80);
     89       value = GPBLogicalRightShift32(value, 7);
     90     }
     91   }
     92 }
     93 
     94 static void GPBWriteRawVarint64(GPBOutputBufferState *state, int64_t value) {
     95   while (YES) {
     96     if ((value & ~0x7FL) == 0) {
     97       uint8_t val = (uint8_t)value;
     98       GPBWriteRawByte(state, val);
     99       return;
    100     } else {
    101       GPBWriteRawByte(state, ((int32_t)value & 0x7F) | 0x80);
    102       value = GPBLogicalRightShift64(value, 7);
    103     }
    104   }
    105 }
    106 
    107 static void GPBWriteInt32NoTag(GPBOutputBufferState *state, int32_t value) {
    108   if (value >= 0) {
    109     GPBWriteRawVarint32(state, value);
    110   } else {
    111     // Must sign-extend
    112     GPBWriteRawVarint64(state, value);
    113   }
    114 }
    115 
    116 static void GPBWriteUInt32(GPBOutputBufferState *state, int32_t fieldNumber,
    117                            uint32_t value) {
    118   GPBWriteTagWithFormat(state, fieldNumber, GPBWireFormatVarint);
    119   GPBWriteRawVarint32(state, value);
    120 }
    121 
    122 static void GPBWriteTagWithFormat(GPBOutputBufferState *state,
    123                                   uint32_t fieldNumber, GPBWireFormat format) {
    124   GPBWriteRawVarint32(state, GPBWireFormatMakeTag(fieldNumber, format));
    125 }
    126 
    127 static void GPBWriteRawLittleEndian32(GPBOutputBufferState *state,
    128                                       int32_t value) {
    129   GPBWriteRawByte(state, (value)&0xFF);
    130   GPBWriteRawByte(state, (value >> 8) & 0xFF);
    131   GPBWriteRawByte(state, (value >> 16) & 0xFF);
    132   GPBWriteRawByte(state, (value >> 24) & 0xFF);
    133 }
    134 
    135 static void GPBWriteRawLittleEndian64(GPBOutputBufferState *state,
    136                                       int64_t value) {
    137   GPBWriteRawByte(state, (int32_t)(value)&0xFF);
    138   GPBWriteRawByte(state, (int32_t)(value >> 8) & 0xFF);
    139   GPBWriteRawByte(state, (int32_t)(value >> 16) & 0xFF);
    140   GPBWriteRawByte(state, (int32_t)(value >> 24) & 0xFF);
    141   GPBWriteRawByte(state, (int32_t)(value >> 32) & 0xFF);
    142   GPBWriteRawByte(state, (int32_t)(value >> 40) & 0xFF);
    143   GPBWriteRawByte(state, (int32_t)(value >> 48) & 0xFF);
    144   GPBWriteRawByte(state, (int32_t)(value >> 56) & 0xFF);
    145 }
    146 
    147 #if DEBUG && !defined(NS_BLOCK_ASSERTIONS)
    148 + (void)load {
    149   // This test exists to verify that CFStrings with embedded NULLs will work
    150   // for us. If this Assert fails, all code below that depends on
    151   // CFStringGetCStringPtr will NOT work properly on strings that contain
    152   // embedded NULLs, and we do get that in some protobufs.
    153   // Note that this will not be compiled in release.
    154   // We didn't feel that just keeping it in a unit test was sufficient because
    155   // the Protobuf unit tests are only run when somebody is actually working
    156   // on protobufs.
    157   CFStringRef zeroTest = CFSTR("Test\0String");
    158   const char *cString = CFStringGetCStringPtr(zeroTest, kCFStringEncodingUTF8);
    159   NSAssert(cString == NULL, @"Serious Error");
    160 }
    161 #endif  // DEBUG && !defined(NS_BLOCK_ASSERTIONS)
    162 
    163 - (void)dealloc {
    164   [self flush];
    165   [state_.output close];
    166   [state_.output release];
    167   [buffer_ release];
    168 
    169   [super dealloc];
    170 }
    171 
    172 - (instancetype)initWithOutputStream:(NSOutputStream *)output {
    173   NSMutableData *data = [NSMutableData dataWithLength:PAGE_SIZE];
    174   return [self initWithOutputStream:output data:data];
    175 }
    176 
    177 - (instancetype)initWithData:(NSMutableData *)data {
    178   return [self initWithOutputStream:nil data:data];
    179 }
    180 
    181 // This initializer isn't exposed, but it is the designated initializer.
    182 // Setting OutputStream and NSData is to control the buffering behavior/size
    183 // of the work, but that is more obvious via the bufferSize: version.
    184 - (instancetype)initWithOutputStream:(NSOutputStream *)output
    185                                 data:(NSMutableData *)data {
    186   if ((self = [super init])) {
    187     buffer_ = [data retain];
    188     [output open];
    189     state_.bytes = [data mutableBytes];
    190     state_.size = [data length];
    191     state_.output = [output retain];
    192   }
    193   return self;
    194 }
    195 
    196 + (instancetype)streamWithOutputStream:(NSOutputStream *)output {
    197   NSMutableData *data = [NSMutableData dataWithLength:PAGE_SIZE];
    198   return [[[self alloc] initWithOutputStream:output
    199                                         data:data] autorelease];
    200 }
    201 
    202 + (instancetype)streamWithData:(NSMutableData *)data {
    203   return [[[self alloc] initWithData:data] autorelease];
    204 }
    205 
    206 - (void)writeDoubleNoTag:(double)value {
    207   GPBWriteRawLittleEndian64(&state_, GPBConvertDoubleToInt64(value));
    208 }
    209 
    210 - (void)writeDouble:(int32_t)fieldNumber value:(double)value {
    211   GPBWriteTagWithFormat(&state_, fieldNumber, GPBWireFormatFixed64);
    212   GPBWriteRawLittleEndian64(&state_, GPBConvertDoubleToInt64(value));
    213 }
    214 
    215 - (void)writeFloatNoTag:(float)value {
    216   GPBWriteRawLittleEndian32(&state_, GPBConvertFloatToInt32(value));
    217 }
    218 
    219 - (void)writeFloat:(int32_t)fieldNumber value:(float)value {
    220   GPBWriteTagWithFormat(&state_, fieldNumber, GPBWireFormatFixed32);
    221   GPBWriteRawLittleEndian32(&state_, GPBConvertFloatToInt32(value));
    222 }
    223 
    224 - (void)writeUInt64NoTag:(uint64_t)value {
    225   GPBWriteRawVarint64(&state_, value);
    226 }
    227 
    228 - (void)writeUInt64:(int32_t)fieldNumber value:(uint64_t)value {
    229   GPBWriteTagWithFormat(&state_, fieldNumber, GPBWireFormatVarint);
    230   GPBWriteRawVarint64(&state_, value);
    231 }
    232 
    233 - (void)writeInt64NoTag:(int64_t)value {
    234   GPBWriteRawVarint64(&state_, value);
    235 }
    236 
    237 - (void)writeInt64:(int32_t)fieldNumber value:(int64_t)value {
    238   GPBWriteTagWithFormat(&state_, fieldNumber, GPBWireFormatVarint);
    239   GPBWriteRawVarint64(&state_, value);
    240 }
    241 
    242 - (void)writeInt32NoTag:(int32_t)value {
    243   GPBWriteInt32NoTag(&state_, value);
    244 }
    245 
    246 - (void)writeInt32:(int32_t)fieldNumber value:(int32_t)value {
    247   GPBWriteTagWithFormat(&state_, fieldNumber, GPBWireFormatVarint);
    248   GPBWriteInt32NoTag(&state_, value);
    249 }
    250 
    251 - (void)writeFixed64NoTag:(uint64_t)value {
    252   GPBWriteRawLittleEndian64(&state_, value);
    253 }
    254 
    255 - (void)writeFixed64:(int32_t)fieldNumber value:(uint64_t)value {
    256   GPBWriteTagWithFormat(&state_, fieldNumber, GPBWireFormatFixed64);
    257   GPBWriteRawLittleEndian64(&state_, value);
    258 }
    259 
    260 - (void)writeFixed32NoTag:(uint32_t)value {
    261   GPBWriteRawLittleEndian32(&state_, value);
    262 }
    263 
    264 - (void)writeFixed32:(int32_t)fieldNumber value:(uint32_t)value {
    265   GPBWriteTagWithFormat(&state_, fieldNumber, GPBWireFormatFixed32);
    266   GPBWriteRawLittleEndian32(&state_, value);
    267 }
    268 
    269 - (void)writeBoolNoTag:(BOOL)value {
    270   GPBWriteRawByte(&state_, (value ? 1 : 0));
    271 }
    272 
    273 - (void)writeBool:(int32_t)fieldNumber value:(BOOL)value {
    274   GPBWriteTagWithFormat(&state_, fieldNumber, GPBWireFormatVarint);
    275   GPBWriteRawByte(&state_, (value ? 1 : 0));
    276 }
    277 
    278 - (void)writeStringNoTag:(const NSString *)value {
    279   // If you are concerned about embedded NULLs see the test in
    280   // +load above.
    281   const char *quickString =
    282       CFStringGetCStringPtr((CFStringRef)value, kCFStringEncodingUTF8);
    283   size_t length = (quickString != NULL)
    284                       ? strlen(quickString)
    285                       : [value lengthOfBytesUsingEncoding:NSUTF8StringEncoding];
    286   GPBWriteRawVarint32(&state_, (int32_t)length);
    287 
    288   if (length == 0) {
    289     return;
    290   }
    291 
    292   // Fast path: Most strings are short, if the buffer already has space,
    293   // add to it directly.
    294   NSUInteger bufferBytesLeft = state_.size - state_.position;
    295   if (bufferBytesLeft >= length) {
    296     NSUInteger usedBufferLength = 0;
    297     BOOL result;
    298     if (quickString != NULL) {
    299       memcpy(state_.bytes + state_.position, quickString, length);
    300       usedBufferLength = length;
    301       result = YES;
    302     } else {
    303       result = [value getBytes:state_.bytes + state_.position
    304                      maxLength:bufferBytesLeft
    305                     usedLength:&usedBufferLength
    306                       encoding:NSUTF8StringEncoding
    307                        options:0
    308                          range:NSMakeRange(0, [value length])
    309                 remainingRange:NULL];
    310     }
    311     if (result) {
    312       NSAssert2((usedBufferLength == length),
    313                 @"Our UTF8 calc was wrong? %tu vs %zd", usedBufferLength,
    314                 length);
    315       state_.position += usedBufferLength;
    316       return;
    317     }
    318   } else if (quickString != NULL) {
    319     [self writeRawPtr:quickString offset:0 length:length];
    320   } else {
    321     // Slow path: just get it as data and write it out.
    322     NSData *utf8Data = [value dataUsingEncoding:NSUTF8StringEncoding];
    323     NSAssert2(([utf8Data length] == length),
    324               @"Strings UTF8 length was wrong? %tu vs %zd", [utf8Data length],
    325               length);
    326     [self writeRawData:utf8Data];
    327   }
    328 }
    329 
    330 - (void)writeString:(int32_t)fieldNumber value:(NSString *)value {
    331   GPBWriteTagWithFormat(&state_, fieldNumber, GPBWireFormatLengthDelimited);
    332   [self writeStringNoTag:value];
    333 }
    334 
    335 - (void)writeGroupNoTag:(int32_t)fieldNumber value:(GPBMessage *)value {
    336   [value writeToCodedOutputStream:self];
    337   GPBWriteTagWithFormat(&state_, fieldNumber, GPBWireFormatEndGroup);
    338 }
    339 
    340 - (void)writeGroup:(int32_t)fieldNumber value:(GPBMessage *)value {
    341   GPBWriteTagWithFormat(&state_, fieldNumber, GPBWireFormatStartGroup);
    342   [self writeGroupNoTag:fieldNumber value:value];
    343 }
    344 
    345 - (void)writeUnknownGroupNoTag:(int32_t)fieldNumber
    346                          value:(const GPBUnknownFieldSet *)value {
    347   [value writeToCodedOutputStream:self];
    348   GPBWriteTagWithFormat(&state_, fieldNumber, GPBWireFormatEndGroup);
    349 }
    350 
    351 - (void)writeUnknownGroup:(int32_t)fieldNumber
    352                     value:(GPBUnknownFieldSet *)value {
    353   GPBWriteTagWithFormat(&state_, fieldNumber, GPBWireFormatStartGroup);
    354   [self writeUnknownGroupNoTag:fieldNumber value:value];
    355 }
    356 
    357 - (void)writeMessageNoTag:(GPBMessage *)value {
    358   GPBWriteRawVarint32(&state_, (int32_t)[value serializedSize]);
    359   [value writeToCodedOutputStream:self];
    360 }
    361 
    362 - (void)writeMessage:(int32_t)fieldNumber value:(GPBMessage *)value {
    363   GPBWriteTagWithFormat(&state_, fieldNumber, GPBWireFormatLengthDelimited);
    364   [self writeMessageNoTag:value];
    365 }
    366 
    367 - (void)writeBytesNoTag:(NSData *)value {
    368   GPBWriteRawVarint32(&state_, (int32_t)[value length]);
    369   [self writeRawData:value];
    370 }
    371 
    372 - (void)writeBytes:(int32_t)fieldNumber value:(NSData *)value {
    373   GPBWriteTagWithFormat(&state_, fieldNumber, GPBWireFormatLengthDelimited);
    374   [self writeBytesNoTag:value];
    375 }
    376 
    377 - (void)writeUInt32NoTag:(uint32_t)value {
    378   GPBWriteRawVarint32(&state_, value);
    379 }
    380 
    381 - (void)writeUInt32:(int32_t)fieldNumber value:(uint32_t)value {
    382   GPBWriteUInt32(&state_, fieldNumber, value);
    383 }
    384 
    385 - (void)writeEnumNoTag:(int32_t)value {
    386   GPBWriteRawVarint32(&state_, value);
    387 }
    388 
    389 - (void)writeEnum:(int32_t)fieldNumber value:(int32_t)value {
    390   GPBWriteTagWithFormat(&state_, fieldNumber, GPBWireFormatVarint);
    391   GPBWriteRawVarint32(&state_, value);
    392 }
    393 
    394 - (void)writeSFixed32NoTag:(int32_t)value {
    395   GPBWriteRawLittleEndian32(&state_, value);
    396 }
    397 
    398 - (void)writeSFixed32:(int32_t)fieldNumber value:(int32_t)value {
    399   GPBWriteTagWithFormat(&state_, fieldNumber, GPBWireFormatFixed32);
    400   GPBWriteRawLittleEndian32(&state_, value);
    401 }
    402 
    403 - (void)writeSFixed64NoTag:(int64_t)value {
    404   GPBWriteRawLittleEndian64(&state_, value);
    405 }
    406 
    407 - (void)writeSFixed64:(int32_t)fieldNumber value:(int64_t)value {
    408   GPBWriteTagWithFormat(&state_, fieldNumber, GPBWireFormatFixed64);
    409   GPBWriteRawLittleEndian64(&state_, value);
    410 }
    411 
    412 - (void)writeSInt32NoTag:(int32_t)value {
    413   GPBWriteRawVarint32(&state_, GPBEncodeZigZag32(value));
    414 }
    415 
    416 - (void)writeSInt32:(int32_t)fieldNumber value:(int32_t)value {
    417   GPBWriteTagWithFormat(&state_, fieldNumber, GPBWireFormatVarint);
    418   GPBWriteRawVarint32(&state_, GPBEncodeZigZag32(value));
    419 }
    420 
    421 - (void)writeSInt64NoTag:(int64_t)value {
    422   GPBWriteRawVarint64(&state_, GPBEncodeZigZag64(value));
    423 }
    424 
    425 - (void)writeSInt64:(int32_t)fieldNumber value:(int64_t)value {
    426   GPBWriteTagWithFormat(&state_, fieldNumber, GPBWireFormatVarint);
    427   GPBWriteRawVarint64(&state_, GPBEncodeZigZag64(value));
    428 }
    429 
    430 //%PDDM-DEFINE WRITE_PACKABLE_DEFNS(NAME, ARRAY_TYPE, TYPE, ACCESSOR_NAME)
    431 //%- (void)write##NAME##Array:(int32_t)fieldNumber
    432 //%       NAME$S     values:(GPB##ARRAY_TYPE##Array *)values
    433 //%       NAME$S        tag:(uint32_t)tag {
    434 //%  if (tag != 0) {
    435 //%    if (values.count == 0) return;
    436 //%    __block size_t dataSize = 0;
    437 //%    [values enumerate##ACCESSOR_NAME##ValuesWithBlock:^(TYPE value, NSUInteger idx, BOOL *stop) {
    438 //%#pragma unused(idx, stop)
    439 //%      dataSize += GPBCompute##NAME##SizeNoTag(value);
    440 //%    }];
    441 //%    GPBWriteRawVarint32(&state_, tag);
    442 //%    GPBWriteRawVarint32(&state_, (int32_t)dataSize);
    443 //%    [values enumerate##ACCESSOR_NAME##ValuesWithBlock:^(TYPE value, NSUInteger idx, BOOL *stop) {
    444 //%#pragma unused(idx, stop)
    445 //%      [self write##NAME##NoTag:value];
    446 //%    }];
    447 //%  } else {
    448 //%    [values enumerate##ACCESSOR_NAME##ValuesWithBlock:^(TYPE value, NSUInteger idx, BOOL *stop) {
    449 //%#pragma unused(idx, stop)
    450 //%      [self write##NAME:fieldNumber value:value];
    451 //%    }];
    452 //%  }
    453 //%}
    454 //%
    455 //%PDDM-DEFINE WRITE_UNPACKABLE_DEFNS(NAME, TYPE)
    456 //%- (void)write##NAME##Array:(int32_t)fieldNumber values:(NSArray *)values {
    457 //%  for (TYPE *value in values) {
    458 //%    [self write##NAME:fieldNumber value:value];
    459 //%  }
    460 //%}
    461 //%
    462 //%PDDM-EXPAND WRITE_PACKABLE_DEFNS(Double, Double, double, )
    463 // This block of code is generated, do not edit it directly.
    464 
    465 - (void)writeDoubleArray:(int32_t)fieldNumber
    466                   values:(GPBDoubleArray *)values
    467                      tag:(uint32_t)tag {
    468   if (tag != 0) {
    469     if (values.count == 0) return;
    470     __block size_t dataSize = 0;
    471     [values enumerateValuesWithBlock:^(double value, NSUInteger idx, BOOL *stop) {
    472 #pragma unused(idx, stop)
    473       dataSize += GPBComputeDoubleSizeNoTag(value);
    474     }];
    475     GPBWriteRawVarint32(&state_, tag);
    476     GPBWriteRawVarint32(&state_, (int32_t)dataSize);
    477     [values enumerateValuesWithBlock:^(double value, NSUInteger idx, BOOL *stop) {
    478 #pragma unused(idx, stop)
    479       [self writeDoubleNoTag:value];
    480     }];
    481   } else {
    482     [values enumerateValuesWithBlock:^(double value, NSUInteger idx, BOOL *stop) {
    483 #pragma unused(idx, stop)
    484       [self writeDouble:fieldNumber value:value];
    485     }];
    486   }
    487 }
    488 
    489 //%PDDM-EXPAND WRITE_PACKABLE_DEFNS(Float, Float, float, )
    490 // This block of code is generated, do not edit it directly.
    491 
    492 - (void)writeFloatArray:(int32_t)fieldNumber
    493                  values:(GPBFloatArray *)values
    494                     tag:(uint32_t)tag {
    495   if (tag != 0) {
    496     if (values.count == 0) return;
    497     __block size_t dataSize = 0;
    498     [values enumerateValuesWithBlock:^(float value, NSUInteger idx, BOOL *stop) {
    499 #pragma unused(idx, stop)
    500       dataSize += GPBComputeFloatSizeNoTag(value);
    501     }];
    502     GPBWriteRawVarint32(&state_, tag);
    503     GPBWriteRawVarint32(&state_, (int32_t)dataSize);
    504     [values enumerateValuesWithBlock:^(float value, NSUInteger idx, BOOL *stop) {
    505 #pragma unused(idx, stop)
    506       [self writeFloatNoTag:value];
    507     }];
    508   } else {
    509     [values enumerateValuesWithBlock:^(float value, NSUInteger idx, BOOL *stop) {
    510 #pragma unused(idx, stop)
    511       [self writeFloat:fieldNumber value:value];
    512     }];
    513   }
    514 }
    515 
    516 //%PDDM-EXPAND WRITE_PACKABLE_DEFNS(UInt64, UInt64, uint64_t, )
    517 // This block of code is generated, do not edit it directly.
    518 
    519 - (void)writeUInt64Array:(int32_t)fieldNumber
    520                   values:(GPBUInt64Array *)values
    521                      tag:(uint32_t)tag {
    522   if (tag != 0) {
    523     if (values.count == 0) return;
    524     __block size_t dataSize = 0;
    525     [values enumerateValuesWithBlock:^(uint64_t value, NSUInteger idx, BOOL *stop) {
    526 #pragma unused(idx, stop)
    527       dataSize += GPBComputeUInt64SizeNoTag(value);
    528     }];
    529     GPBWriteRawVarint32(&state_, tag);
    530     GPBWriteRawVarint32(&state_, (int32_t)dataSize);
    531     [values enumerateValuesWithBlock:^(uint64_t value, NSUInteger idx, BOOL *stop) {
    532 #pragma unused(idx, stop)
    533       [self writeUInt64NoTag:value];
    534     }];
    535   } else {
    536     [values enumerateValuesWithBlock:^(uint64_t value, NSUInteger idx, BOOL *stop) {
    537 #pragma unused(idx, stop)
    538       [self writeUInt64:fieldNumber value:value];
    539     }];
    540   }
    541 }
    542 
    543 //%PDDM-EXPAND WRITE_PACKABLE_DEFNS(Int64, Int64, int64_t, )
    544 // This block of code is generated, do not edit it directly.
    545 
    546 - (void)writeInt64Array:(int32_t)fieldNumber
    547                  values:(GPBInt64Array *)values
    548                     tag:(uint32_t)tag {
    549   if (tag != 0) {
    550     if (values.count == 0) return;
    551     __block size_t dataSize = 0;
    552     [values enumerateValuesWithBlock:^(int64_t value, NSUInteger idx, BOOL *stop) {
    553 #pragma unused(idx, stop)
    554       dataSize += GPBComputeInt64SizeNoTag(value);
    555     }];
    556     GPBWriteRawVarint32(&state_, tag);
    557     GPBWriteRawVarint32(&state_, (int32_t)dataSize);
    558     [values enumerateValuesWithBlock:^(int64_t value, NSUInteger idx, BOOL *stop) {
    559 #pragma unused(idx, stop)
    560       [self writeInt64NoTag:value];
    561     }];
    562   } else {
    563     [values enumerateValuesWithBlock:^(int64_t value, NSUInteger idx, BOOL *stop) {
    564 #pragma unused(idx, stop)
    565       [self writeInt64:fieldNumber value:value];
    566     }];
    567   }
    568 }
    569 
    570 //%PDDM-EXPAND WRITE_PACKABLE_DEFNS(Int32, Int32, int32_t, )
    571 // This block of code is generated, do not edit it directly.
    572 
    573 - (void)writeInt32Array:(int32_t)fieldNumber
    574                  values:(GPBInt32Array *)values
    575                     tag:(uint32_t)tag {
    576   if (tag != 0) {
    577     if (values.count == 0) return;
    578     __block size_t dataSize = 0;
    579     [values enumerateValuesWithBlock:^(int32_t value, NSUInteger idx, BOOL *stop) {
    580 #pragma unused(idx, stop)
    581       dataSize += GPBComputeInt32SizeNoTag(value);
    582     }];
    583     GPBWriteRawVarint32(&state_, tag);
    584     GPBWriteRawVarint32(&state_, (int32_t)dataSize);
    585     [values enumerateValuesWithBlock:^(int32_t value, NSUInteger idx, BOOL *stop) {
    586 #pragma unused(idx, stop)
    587       [self writeInt32NoTag:value];
    588     }];
    589   } else {
    590     [values enumerateValuesWithBlock:^(int32_t value, NSUInteger idx, BOOL *stop) {
    591 #pragma unused(idx, stop)
    592       [self writeInt32:fieldNumber value:value];
    593     }];
    594   }
    595 }
    596 
    597 //%PDDM-EXPAND WRITE_PACKABLE_DEFNS(UInt32, UInt32, uint32_t, )
    598 // This block of code is generated, do not edit it directly.
    599 
    600 - (void)writeUInt32Array:(int32_t)fieldNumber
    601                   values:(GPBUInt32Array *)values
    602                      tag:(uint32_t)tag {
    603   if (tag != 0) {
    604     if (values.count == 0) return;
    605     __block size_t dataSize = 0;
    606     [values enumerateValuesWithBlock:^(uint32_t value, NSUInteger idx, BOOL *stop) {
    607 #pragma unused(idx, stop)
    608       dataSize += GPBComputeUInt32SizeNoTag(value);
    609     }];
    610     GPBWriteRawVarint32(&state_, tag);
    611     GPBWriteRawVarint32(&state_, (int32_t)dataSize);
    612     [values enumerateValuesWithBlock:^(uint32_t value, NSUInteger idx, BOOL *stop) {
    613 #pragma unused(idx, stop)
    614       [self writeUInt32NoTag:value];
    615     }];
    616   } else {
    617     [values enumerateValuesWithBlock:^(uint32_t value, NSUInteger idx, BOOL *stop) {
    618 #pragma unused(idx, stop)
    619       [self writeUInt32:fieldNumber value:value];
    620     }];
    621   }
    622 }
    623 
    624 //%PDDM-EXPAND WRITE_PACKABLE_DEFNS(Fixed64, UInt64, uint64_t, )
    625 // This block of code is generated, do not edit it directly.
    626 
    627 - (void)writeFixed64Array:(int32_t)fieldNumber
    628                    values:(GPBUInt64Array *)values
    629                       tag:(uint32_t)tag {
    630   if (tag != 0) {
    631     if (values.count == 0) return;
    632     __block size_t dataSize = 0;
    633     [values enumerateValuesWithBlock:^(uint64_t value, NSUInteger idx, BOOL *stop) {
    634 #pragma unused(idx, stop)
    635       dataSize += GPBComputeFixed64SizeNoTag(value);
    636     }];
    637     GPBWriteRawVarint32(&state_, tag);
    638     GPBWriteRawVarint32(&state_, (int32_t)dataSize);
    639     [values enumerateValuesWithBlock:^(uint64_t value, NSUInteger idx, BOOL *stop) {
    640 #pragma unused(idx, stop)
    641       [self writeFixed64NoTag:value];
    642     }];
    643   } else {
    644     [values enumerateValuesWithBlock:^(uint64_t value, NSUInteger idx, BOOL *stop) {
    645 #pragma unused(idx, stop)
    646       [self writeFixed64:fieldNumber value:value];
    647     }];
    648   }
    649 }
    650 
    651 //%PDDM-EXPAND WRITE_PACKABLE_DEFNS(Fixed32, UInt32, uint32_t, )
    652 // This block of code is generated, do not edit it directly.
    653 
    654 - (void)writeFixed32Array:(int32_t)fieldNumber
    655                    values:(GPBUInt32Array *)values
    656                       tag:(uint32_t)tag {
    657   if (tag != 0) {
    658     if (values.count == 0) return;
    659     __block size_t dataSize = 0;
    660     [values enumerateValuesWithBlock:^(uint32_t value, NSUInteger idx, BOOL *stop) {
    661 #pragma unused(idx, stop)
    662       dataSize += GPBComputeFixed32SizeNoTag(value);
    663     }];
    664     GPBWriteRawVarint32(&state_, tag);
    665     GPBWriteRawVarint32(&state_, (int32_t)dataSize);
    666     [values enumerateValuesWithBlock:^(uint32_t value, NSUInteger idx, BOOL *stop) {
    667 #pragma unused(idx, stop)
    668       [self writeFixed32NoTag:value];
    669     }];
    670   } else {
    671     [values enumerateValuesWithBlock:^(uint32_t value, NSUInteger idx, BOOL *stop) {
    672 #pragma unused(idx, stop)
    673       [self writeFixed32:fieldNumber value:value];
    674     }];
    675   }
    676 }
    677 
    678 //%PDDM-EXPAND WRITE_PACKABLE_DEFNS(SInt32, Int32, int32_t, )
    679 // This block of code is generated, do not edit it directly.
    680 
    681 - (void)writeSInt32Array:(int32_t)fieldNumber
    682                   values:(GPBInt32Array *)values
    683                      tag:(uint32_t)tag {
    684   if (tag != 0) {
    685     if (values.count == 0) return;
    686     __block size_t dataSize = 0;
    687     [values enumerateValuesWithBlock:^(int32_t value, NSUInteger idx, BOOL *stop) {
    688 #pragma unused(idx, stop)
    689       dataSize += GPBComputeSInt32SizeNoTag(value);
    690     }];
    691     GPBWriteRawVarint32(&state_, tag);
    692     GPBWriteRawVarint32(&state_, (int32_t)dataSize);
    693     [values enumerateValuesWithBlock:^(int32_t value, NSUInteger idx, BOOL *stop) {
    694 #pragma unused(idx, stop)
    695       [self writeSInt32NoTag:value];
    696     }];
    697   } else {
    698     [values enumerateValuesWithBlock:^(int32_t value, NSUInteger idx, BOOL *stop) {
    699 #pragma unused(idx, stop)
    700       [self writeSInt32:fieldNumber value:value];
    701     }];
    702   }
    703 }
    704 
    705 //%PDDM-EXPAND WRITE_PACKABLE_DEFNS(SInt64, Int64, int64_t, )
    706 // This block of code is generated, do not edit it directly.
    707 
    708 - (void)writeSInt64Array:(int32_t)fieldNumber
    709                   values:(GPBInt64Array *)values
    710                      tag:(uint32_t)tag {
    711   if (tag != 0) {
    712     if (values.count == 0) return;
    713     __block size_t dataSize = 0;
    714     [values enumerateValuesWithBlock:^(int64_t value, NSUInteger idx, BOOL *stop) {
    715 #pragma unused(idx, stop)
    716       dataSize += GPBComputeSInt64SizeNoTag(value);
    717     }];
    718     GPBWriteRawVarint32(&state_, tag);
    719     GPBWriteRawVarint32(&state_, (int32_t)dataSize);
    720     [values enumerateValuesWithBlock:^(int64_t value, NSUInteger idx, BOOL *stop) {
    721 #pragma unused(idx, stop)
    722       [self writeSInt64NoTag:value];
    723     }];
    724   } else {
    725     [values enumerateValuesWithBlock:^(int64_t value, NSUInteger idx, BOOL *stop) {
    726 #pragma unused(idx, stop)
    727       [self writeSInt64:fieldNumber value:value];
    728     }];
    729   }
    730 }
    731 
    732 //%PDDM-EXPAND WRITE_PACKABLE_DEFNS(SFixed64, Int64, int64_t, )
    733 // This block of code is generated, do not edit it directly.
    734 
    735 - (void)writeSFixed64Array:(int32_t)fieldNumber
    736                     values:(GPBInt64Array *)values
    737                        tag:(uint32_t)tag {
    738   if (tag != 0) {
    739     if (values.count == 0) return;
    740     __block size_t dataSize = 0;
    741     [values enumerateValuesWithBlock:^(int64_t value, NSUInteger idx, BOOL *stop) {
    742 #pragma unused(idx, stop)
    743       dataSize += GPBComputeSFixed64SizeNoTag(value);
    744     }];
    745     GPBWriteRawVarint32(&state_, tag);
    746     GPBWriteRawVarint32(&state_, (int32_t)dataSize);
    747     [values enumerateValuesWithBlock:^(int64_t value, NSUInteger idx, BOOL *stop) {
    748 #pragma unused(idx, stop)
    749       [self writeSFixed64NoTag:value];
    750     }];
    751   } else {
    752     [values enumerateValuesWithBlock:^(int64_t value, NSUInteger idx, BOOL *stop) {
    753 #pragma unused(idx, stop)
    754       [self writeSFixed64:fieldNumber value:value];
    755     }];
    756   }
    757 }
    758 
    759 //%PDDM-EXPAND WRITE_PACKABLE_DEFNS(SFixed32, Int32, int32_t, )
    760 // This block of code is generated, do not edit it directly.
    761 
    762 - (void)writeSFixed32Array:(int32_t)fieldNumber
    763                     values:(GPBInt32Array *)values
    764                        tag:(uint32_t)tag {
    765   if (tag != 0) {
    766     if (values.count == 0) return;
    767     __block size_t dataSize = 0;
    768     [values enumerateValuesWithBlock:^(int32_t value, NSUInteger idx, BOOL *stop) {
    769 #pragma unused(idx, stop)
    770       dataSize += GPBComputeSFixed32SizeNoTag(value);
    771     }];
    772     GPBWriteRawVarint32(&state_, tag);
    773     GPBWriteRawVarint32(&state_, (int32_t)dataSize);
    774     [values enumerateValuesWithBlock:^(int32_t value, NSUInteger idx, BOOL *stop) {
    775 #pragma unused(idx, stop)
    776       [self writeSFixed32NoTag:value];
    777     }];
    778   } else {
    779     [values enumerateValuesWithBlock:^(int32_t value, NSUInteger idx, BOOL *stop) {
    780 #pragma unused(idx, stop)
    781       [self writeSFixed32:fieldNumber value:value];
    782     }];
    783   }
    784 }
    785 
    786 //%PDDM-EXPAND WRITE_PACKABLE_DEFNS(Bool, Bool, BOOL, )
    787 // This block of code is generated, do not edit it directly.
    788 
    789 - (void)writeBoolArray:(int32_t)fieldNumber
    790                 values:(GPBBoolArray *)values
    791                    tag:(uint32_t)tag {
    792   if (tag != 0) {
    793     if (values.count == 0) return;
    794     __block size_t dataSize = 0;
    795     [values enumerateValuesWithBlock:^(BOOL value, NSUInteger idx, BOOL *stop) {
    796 #pragma unused(idx, stop)
    797       dataSize += GPBComputeBoolSizeNoTag(value);
    798     }];
    799     GPBWriteRawVarint32(&state_, tag);
    800     GPBWriteRawVarint32(&state_, (int32_t)dataSize);
    801     [values enumerateValuesWithBlock:^(BOOL value, NSUInteger idx, BOOL *stop) {
    802 #pragma unused(idx, stop)
    803       [self writeBoolNoTag:value];
    804     }];
    805   } else {
    806     [values enumerateValuesWithBlock:^(BOOL value, NSUInteger idx, BOOL *stop) {
    807 #pragma unused(idx, stop)
    808       [self writeBool:fieldNumber value:value];
    809     }];
    810   }
    811 }
    812 
    813 //%PDDM-EXPAND WRITE_PACKABLE_DEFNS(Enum, Enum, int32_t, Raw)
    814 // This block of code is generated, do not edit it directly.
    815 
    816 - (void)writeEnumArray:(int32_t)fieldNumber
    817                 values:(GPBEnumArray *)values
    818                    tag:(uint32_t)tag {
    819   if (tag != 0) {
    820     if (values.count == 0) return;
    821     __block size_t dataSize = 0;
    822     [values enumerateRawValuesWithBlock:^(int32_t value, NSUInteger idx, BOOL *stop) {
    823 #pragma unused(idx, stop)
    824       dataSize += GPBComputeEnumSizeNoTag(value);
    825     }];
    826     GPBWriteRawVarint32(&state_, tag);
    827     GPBWriteRawVarint32(&state_, (int32_t)dataSize);
    828     [values enumerateRawValuesWithBlock:^(int32_t value, NSUInteger idx, BOOL *stop) {
    829 #pragma unused(idx, stop)
    830       [self writeEnumNoTag:value];
    831     }];
    832   } else {
    833     [values enumerateRawValuesWithBlock:^(int32_t value, NSUInteger idx, BOOL *stop) {
    834 #pragma unused(idx, stop)
    835       [self writeEnum:fieldNumber value:value];
    836     }];
    837   }
    838 }
    839 
    840 //%PDDM-EXPAND WRITE_UNPACKABLE_DEFNS(String, NSString)
    841 // This block of code is generated, do not edit it directly.
    842 
    843 - (void)writeStringArray:(int32_t)fieldNumber values:(NSArray *)values {
    844   for (NSString *value in values) {
    845     [self writeString:fieldNumber value:value];
    846   }
    847 }
    848 
    849 //%PDDM-EXPAND WRITE_UNPACKABLE_DEFNS(Message, GPBMessage)
    850 // This block of code is generated, do not edit it directly.
    851 
    852 - (void)writeMessageArray:(int32_t)fieldNumber values:(NSArray *)values {
    853   for (GPBMessage *value in values) {
    854     [self writeMessage:fieldNumber value:value];
    855   }
    856 }
    857 
    858 //%PDDM-EXPAND WRITE_UNPACKABLE_DEFNS(Bytes, NSData)
    859 // This block of code is generated, do not edit it directly.
    860 
    861 - (void)writeBytesArray:(int32_t)fieldNumber values:(NSArray *)values {
    862   for (NSData *value in values) {
    863     [self writeBytes:fieldNumber value:value];
    864   }
    865 }
    866 
    867 //%PDDM-EXPAND WRITE_UNPACKABLE_DEFNS(Group, GPBMessage)
    868 // This block of code is generated, do not edit it directly.
    869 
    870 - (void)writeGroupArray:(int32_t)fieldNumber values:(NSArray *)values {
    871   for (GPBMessage *value in values) {
    872     [self writeGroup:fieldNumber value:value];
    873   }
    874 }
    875 
    876 //%PDDM-EXPAND WRITE_UNPACKABLE_DEFNS(UnknownGroup, GPBUnknownFieldSet)
    877 // This block of code is generated, do not edit it directly.
    878 
    879 - (void)writeUnknownGroupArray:(int32_t)fieldNumber values:(NSArray *)values {
    880   for (GPBUnknownFieldSet *value in values) {
    881     [self writeUnknownGroup:fieldNumber value:value];
    882   }
    883 }
    884 
    885 //%PDDM-EXPAND-END (19 expansions)
    886 
    887 - (void)writeMessageSetExtension:(int32_t)fieldNumber
    888                            value:(GPBMessage *)value {
    889   GPBWriteTagWithFormat(&state_, GPBWireFormatMessageSetItem,
    890                         GPBWireFormatStartGroup);
    891   GPBWriteUInt32(&state_, GPBWireFormatMessageSetTypeId, fieldNumber);
    892   [self writeMessage:GPBWireFormatMessageSetMessage value:value];
    893   GPBWriteTagWithFormat(&state_, GPBWireFormatMessageSetItem,
    894                         GPBWireFormatEndGroup);
    895 }
    896 
    897 - (void)writeRawMessageSetExtension:(int32_t)fieldNumber value:(NSData *)value {
    898   GPBWriteTagWithFormat(&state_, GPBWireFormatMessageSetItem,
    899                         GPBWireFormatStartGroup);
    900   GPBWriteUInt32(&state_, GPBWireFormatMessageSetTypeId, fieldNumber);
    901   [self writeBytes:GPBWireFormatMessageSetMessage value:value];
    902   GPBWriteTagWithFormat(&state_, GPBWireFormatMessageSetItem,
    903                         GPBWireFormatEndGroup);
    904 }
    905 
    906 - (void)flush {
    907   if (state_.output != nil) {
    908     GPBRefreshBuffer(&state_);
    909   }
    910 }
    911 
    912 - (void)writeRawByte:(uint8_t)value {
    913   GPBWriteRawByte(&state_, value);
    914 }
    915 
    916 - (void)writeRawData:(const NSData *)data {
    917   [self writeRawPtr:[data bytes] offset:0 length:[data length]];
    918 }
    919 
    920 - (void)writeRawPtr:(const void *)value
    921              offset:(size_t)offset
    922              length:(size_t)length {
    923   if (value == nil || length == 0) {
    924     return;
    925   }
    926 
    927   NSUInteger bufferLength = state_.size;
    928   NSUInteger bufferBytesLeft = bufferLength - state_.position;
    929   if (bufferBytesLeft >= length) {
    930     // We have room in the current buffer.
    931     memcpy(state_.bytes + state_.position, ((uint8_t *)value) + offset, length);
    932     state_.position += length;
    933   } else {
    934     // Write extends past current buffer.  Fill the rest of this buffer and
    935     // flush.
    936     size_t bytesWritten = bufferBytesLeft;
    937     memcpy(state_.bytes + state_.position, ((uint8_t *)value) + offset,
    938            bytesWritten);
    939     offset += bytesWritten;
    940     length -= bytesWritten;
    941     state_.position = bufferLength;
    942     GPBRefreshBuffer(&state_);
    943     bufferLength = state_.size;
    944 
    945     // Now deal with the rest.
    946     // Since we have an output stream, this is our buffer
    947     // and buffer offset == 0
    948     if (length <= bufferLength) {
    949       // Fits in new buffer.
    950       memcpy(state_.bytes, ((uint8_t *)value) + offset, length);
    951       state_.position = length;
    952     } else {
    953       // Write is very big.  Let's do it all at once.
    954       [state_.output write:((uint8_t *)value) + offset maxLength:length];
    955     }
    956   }
    957 }
    958 
    959 - (void)writeTag:(uint32_t)fieldNumber format:(GPBWireFormat)format {
    960   GPBWriteTagWithFormat(&state_, fieldNumber, format);
    961 }
    962 
    963 - (void)writeRawVarint32:(int32_t)value {
    964   GPBWriteRawVarint32(&state_, value);
    965 }
    966 
    967 - (void)writeRawVarintSizeTAs32:(size_t)value {
    968   // Note the truncation.
    969   GPBWriteRawVarint32(&state_, (int32_t)value);
    970 }
    971 
    972 - (void)writeRawVarint64:(int64_t)value {
    973   GPBWriteRawVarint64(&state_, value);
    974 }
    975 
    976 - (void)writeRawLittleEndian32:(int32_t)value {
    977   GPBWriteRawLittleEndian32(&state_, value);
    978 }
    979 
    980 - (void)writeRawLittleEndian64:(int64_t)value {
    981   GPBWriteRawLittleEndian64(&state_, value);
    982 }
    983 
    984 @end
    985 
    986 size_t GPBComputeDoubleSizeNoTag(Float64 value) {
    987 #pragma unused(value)
    988   return LITTLE_ENDIAN_64_SIZE;
    989 }
    990 
    991 size_t GPBComputeFloatSizeNoTag(Float32 value) {
    992 #pragma unused(value)
    993   return LITTLE_ENDIAN_32_SIZE;
    994 }
    995 
    996 size_t GPBComputeUInt64SizeNoTag(uint64_t value) {
    997   return GPBComputeRawVarint64Size(value);
    998 }
    999 
   1000 size_t GPBComputeInt64SizeNoTag(int64_t value) {
   1001   return GPBComputeRawVarint64Size(value);
   1002 }
   1003 
   1004 size_t GPBComputeInt32SizeNoTag(int32_t value) {
   1005   if (value >= 0) {
   1006     return GPBComputeRawVarint32Size(value);
   1007   } else {
   1008     // Must sign-extend.
   1009     return 10;
   1010   }
   1011 }
   1012 
   1013 size_t GPBComputeSizeTSizeAsInt32NoTag(size_t value) {
   1014   return GPBComputeInt32SizeNoTag((int32_t)value);
   1015 }
   1016 
   1017 size_t GPBComputeFixed64SizeNoTag(uint64_t value) {
   1018 #pragma unused(value)
   1019   return LITTLE_ENDIAN_64_SIZE;
   1020 }
   1021 
   1022 size_t GPBComputeFixed32SizeNoTag(uint32_t value) {
   1023 #pragma unused(value)
   1024   return LITTLE_ENDIAN_32_SIZE;
   1025 }
   1026 
   1027 size_t GPBComputeBoolSizeNoTag(BOOL value) {
   1028 #pragma unused(value)
   1029   return 1;
   1030 }
   1031 
   1032 size_t GPBComputeStringSizeNoTag(NSString *value) {
   1033   // If you are concerned about embedded NULLs see the test in
   1034   // +load above.
   1035   const char *quickString =
   1036       CFStringGetCStringPtr((CFStringRef)value, kCFStringEncodingUTF8);
   1037   NSUInteger length =
   1038       (quickString != NULL)
   1039           ? strlen(quickString)
   1040           : [value lengthOfBytesUsingEncoding:NSUTF8StringEncoding];
   1041   return GPBComputeRawVarint32SizeForInteger(length) + length;
   1042 }
   1043 
   1044 size_t GPBComputeGroupSizeNoTag(GPBMessage *value) {
   1045   return [value serializedSize];
   1046 }
   1047 
   1048 size_t GPBComputeUnknownGroupSizeNoTag(GPBUnknownFieldSet *value) {
   1049   return value.serializedSize;
   1050 }
   1051 
   1052 size_t GPBComputeMessageSizeNoTag(GPBMessage *value) {
   1053   size_t size = [value serializedSize];
   1054   return GPBComputeRawVarint32SizeForInteger(size) + size;
   1055 }
   1056 
   1057 size_t GPBComputeBytesSizeNoTag(NSData *value) {
   1058   NSUInteger valueLength = [value length];
   1059   return GPBComputeRawVarint32SizeForInteger(valueLength) + valueLength;
   1060 }
   1061 
   1062 size_t GPBComputeUInt32SizeNoTag(int32_t value) {
   1063   return GPBComputeRawVarint32Size(value);
   1064 }
   1065 
   1066 size_t GPBComputeEnumSizeNoTag(int32_t value) {
   1067   return GPBComputeRawVarint32Size(value);
   1068 }
   1069 
   1070 size_t GPBComputeSFixed32SizeNoTag(int32_t value) {
   1071 #pragma unused(value)
   1072   return LITTLE_ENDIAN_32_SIZE;
   1073 }
   1074 
   1075 size_t GPBComputeSFixed64SizeNoTag(int64_t value) {
   1076 #pragma unused(value)
   1077   return LITTLE_ENDIAN_64_SIZE;
   1078 }
   1079 
   1080 size_t GPBComputeSInt32SizeNoTag(int32_t value) {
   1081   return GPBComputeRawVarint32Size(GPBEncodeZigZag32(value));
   1082 }
   1083 
   1084 size_t GPBComputeSInt64SizeNoTag(int64_t value) {
   1085   return GPBComputeRawVarint64Size(GPBEncodeZigZag64(value));
   1086 }
   1087 
   1088 size_t GPBComputeDoubleSize(int32_t fieldNumber, double value) {
   1089   return GPBComputeTagSize(fieldNumber) + GPBComputeDoubleSizeNoTag(value);
   1090 }
   1091 
   1092 size_t GPBComputeFloatSize(int32_t fieldNumber, float value) {
   1093   return GPBComputeTagSize(fieldNumber) + GPBComputeFloatSizeNoTag(value);
   1094 }
   1095 
   1096 size_t GPBComputeUInt64Size(int32_t fieldNumber, uint64_t value) {
   1097   return GPBComputeTagSize(fieldNumber) + GPBComputeUInt64SizeNoTag(value);
   1098 }
   1099 
   1100 size_t GPBComputeInt64Size(int32_t fieldNumber, int64_t value) {
   1101   return GPBComputeTagSize(fieldNumber) + GPBComputeInt64SizeNoTag(value);
   1102 }
   1103 
   1104 size_t GPBComputeInt32Size(int32_t fieldNumber, int32_t value) {
   1105   return GPBComputeTagSize(fieldNumber) + GPBComputeInt32SizeNoTag(value);
   1106 }
   1107 
   1108 size_t GPBComputeFixed64Size(int32_t fieldNumber, uint64_t value) {
   1109   return GPBComputeTagSize(fieldNumber) + GPBComputeFixed64SizeNoTag(value);
   1110 }
   1111 
   1112 size_t GPBComputeFixed32Size(int32_t fieldNumber, uint32_t value) {
   1113   return GPBComputeTagSize(fieldNumber) + GPBComputeFixed32SizeNoTag(value);
   1114 }
   1115 
   1116 size_t GPBComputeBoolSize(int32_t fieldNumber, BOOL value) {
   1117   return GPBComputeTagSize(fieldNumber) + GPBComputeBoolSizeNoTag(value);
   1118 }
   1119 
   1120 size_t GPBComputeStringSize(int32_t fieldNumber, NSString *value) {
   1121   return GPBComputeTagSize(fieldNumber) + GPBComputeStringSizeNoTag(value);
   1122 }
   1123 
   1124 size_t GPBComputeGroupSize(int32_t fieldNumber, GPBMessage *value) {
   1125   return GPBComputeTagSize(fieldNumber) * 2 + GPBComputeGroupSizeNoTag(value);
   1126 }
   1127 
   1128 size_t GPBComputeUnknownGroupSize(int32_t fieldNumber,
   1129                                   GPBUnknownFieldSet *value) {
   1130   return GPBComputeTagSize(fieldNumber) * 2 +
   1131          GPBComputeUnknownGroupSizeNoTag(value);
   1132 }
   1133 
   1134 size_t GPBComputeMessageSize(int32_t fieldNumber, GPBMessage *value) {
   1135   return GPBComputeTagSize(fieldNumber) + GPBComputeMessageSizeNoTag(value);
   1136 }
   1137 
   1138 size_t GPBComputeBytesSize(int32_t fieldNumber, NSData *value) {
   1139   return GPBComputeTagSize(fieldNumber) + GPBComputeBytesSizeNoTag(value);
   1140 }
   1141 
   1142 size_t GPBComputeUInt32Size(int32_t fieldNumber, uint32_t value) {
   1143   return GPBComputeTagSize(fieldNumber) + GPBComputeUInt32SizeNoTag(value);
   1144 }
   1145 
   1146 size_t GPBComputeEnumSize(int32_t fieldNumber, int32_t value) {
   1147   return GPBComputeTagSize(fieldNumber) + GPBComputeEnumSizeNoTag(value);
   1148 }
   1149 
   1150 size_t GPBComputeSFixed32Size(int32_t fieldNumber, int32_t value) {
   1151   return GPBComputeTagSize(fieldNumber) + GPBComputeSFixed32SizeNoTag(value);
   1152 }
   1153 
   1154 size_t GPBComputeSFixed64Size(int32_t fieldNumber, int64_t value) {
   1155   return GPBComputeTagSize(fieldNumber) + GPBComputeSFixed64SizeNoTag(value);
   1156 }
   1157 
   1158 size_t GPBComputeSInt32Size(int32_t fieldNumber, int32_t value) {
   1159   return GPBComputeTagSize(fieldNumber) + GPBComputeSInt32SizeNoTag(value);
   1160 }
   1161 
   1162 size_t GPBComputeSInt64Size(int32_t fieldNumber, int64_t value) {
   1163   return GPBComputeTagSize(fieldNumber) +
   1164          GPBComputeRawVarint64Size(GPBEncodeZigZag64(value));
   1165 }
   1166 
   1167 size_t GPBComputeMessageSetExtensionSize(int32_t fieldNumber,
   1168                                          GPBMessage *value) {
   1169   return GPBComputeTagSize(GPBWireFormatMessageSetItem) * 2 +
   1170          GPBComputeUInt32Size(GPBWireFormatMessageSetTypeId, fieldNumber) +
   1171          GPBComputeMessageSize(GPBWireFormatMessageSetMessage, value);
   1172 }
   1173 
   1174 size_t GPBComputeRawMessageSetExtensionSize(int32_t fieldNumber,
   1175                                             NSData *value) {
   1176   return GPBComputeTagSize(GPBWireFormatMessageSetItem) * 2 +
   1177          GPBComputeUInt32Size(GPBWireFormatMessageSetTypeId, fieldNumber) +
   1178          GPBComputeBytesSize(GPBWireFormatMessageSetMessage, value);
   1179 }
   1180 
   1181 size_t GPBComputeTagSize(int32_t fieldNumber) {
   1182   return GPBComputeRawVarint32Size(
   1183       GPBWireFormatMakeTag(fieldNumber, GPBWireFormatVarint));
   1184 }
   1185 
   1186 size_t GPBComputeWireFormatTagSize(int field_number, GPBDataType dataType) {
   1187   size_t result = GPBComputeTagSize(field_number);
   1188   if (dataType == GPBDataTypeGroup) {
   1189     // Groups have both a start and an end tag.
   1190     return result * 2;
   1191   } else {
   1192     return result;
   1193   }
   1194 }
   1195 
   1196 size_t GPBComputeRawVarint32Size(int32_t value) {
   1197   // value is treated as unsigned, so it won't be sign-extended if negative.
   1198   if ((value & (0xffffffff << 7)) == 0) return 1;
   1199   if ((value & (0xffffffff << 14)) == 0) return 2;
   1200   if ((value & (0xffffffff << 21)) == 0) return 3;
   1201   if ((value & (0xffffffff << 28)) == 0) return 4;
   1202   return 5;
   1203 }
   1204 
   1205 size_t GPBComputeRawVarint32SizeForInteger(NSInteger value) {
   1206   // Note the truncation.
   1207   return GPBComputeRawVarint32Size((int32_t)value);
   1208 }
   1209 
   1210 size_t GPBComputeRawVarint64Size(int64_t value) {
   1211   if ((value & (0xffffffffffffffffL << 7)) == 0) return 1;
   1212   if ((value & (0xffffffffffffffffL << 14)) == 0) return 2;
   1213   if ((value & (0xffffffffffffffffL << 21)) == 0) return 3;
   1214   if ((value & (0xffffffffffffffffL << 28)) == 0) return 4;
   1215   if ((value & (0xffffffffffffffffL << 35)) == 0) return 5;
   1216   if ((value & (0xffffffffffffffffL << 42)) == 0) return 6;
   1217   if ((value & (0xffffffffffffffffL << 49)) == 0) return 7;
   1218   if ((value & (0xffffffffffffffffL << 56)) == 0) return 8;
   1219   if ((value & (0xffffffffffffffffL << 63)) == 0) return 9;
   1220   return 10;
   1221 }
   1222