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