GPBCodedOutputStream.m 40 KB

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