GPBUtilities.m 62 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952953954955956957958959960961962963964965966967968969970971972973974975976977978979980981982983984985986987988989990991992993994995996997998999100010011002100310041005100610071008100910101011101210131014101510161017101810191020102110221023102410251026102710281029103010311032103310341035103610371038103910401041104210431044104510461047104810491050105110521053105410551056105710581059106010611062106310641065106610671068106910701071107210731074107510761077107810791080108110821083108410851086108710881089109010911092109310941095109610971098109911001101110211031104110511061107110811091110111111121113111411151116111711181119112011211122112311241125112611271128112911301131113211331134113511361137113811391140114111421143114411451146114711481149115011511152115311541155115611571158115911601161116211631164116511661167116811691170117111721173117411751176117711781179118011811182118311841185118611871188118911901191119211931194119511961197119811991200120112021203120412051206120712081209121012111212121312141215121612171218121912201221122212231224122512261227122812291230123112321233123412351236123712381239124012411242124312441245124612471248124912501251125212531254125512561257125812591260126112621263126412651266126712681269127012711272127312741275127612771278127912801281128212831284128512861287128812891290129112921293129412951296129712981299130013011302130313041305130613071308130913101311131213131314131513161317131813191320132113221323132413251326132713281329133013311332133313341335133613371338133913401341134213431344134513461347134813491350135113521353135413551356135713581359136013611362136313641365136613671368136913701371137213731374137513761377137813791380138113821383138413851386138713881389139013911392139313941395139613971398139914001401140214031404140514061407140814091410141114121413141414151416141714181419142014211422142314241425142614271428142914301431143214331434143514361437143814391440144114421443144414451446144714481449145014511452145314541455145614571458145914601461146214631464146514661467146814691470147114721473147414751476147714781479148014811482148314841485148614871488148914901491149214931494149514961497149814991500150115021503150415051506150715081509151015111512151315141515151615171518151915201521152215231524152515261527152815291530153115321533153415351536153715381539154015411542154315441545154615471548154915501551155215531554155515561557155815591560156115621563156415651566156715681569157015711572157315741575157615771578157915801581158215831584158515861587158815891590159115921593159415951596159715981599160016011602160316041605160616071608160916101611161216131614161516161617161816191620162116221623162416251626162716281629163016311632163316341635163616371638163916401641164216431644164516461647164816491650165116521653165416551656165716581659166016611662166316641665166616671668166916701671167216731674167516761677167816791680168116821683168416851686
  1. // Protocol Buffers - Google's data interchange format
  2. // Copyright 2008 Google Inc. All rights reserved.
  3. // https://developers.google.com/protocol-buffers/
  4. //
  5. // Redistribution and use in source and binary forms, with or without
  6. // modification, are permitted provided that the following conditions are
  7. // met:
  8. //
  9. // * Redistributions of source code must retain the above copyright
  10. // notice, this list of conditions and the following disclaimer.
  11. // * Redistributions in binary form must reproduce the above
  12. // copyright notice, this list of conditions and the following disclaimer
  13. // in the documentation and/or other materials provided with the
  14. // distribution.
  15. // * Neither the name of Google Inc. nor the names of its
  16. // contributors may be used to endorse or promote products derived from
  17. // this software without specific prior written permission.
  18. //
  19. // THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
  20. // "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
  21. // LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
  22. // A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
  23. // OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
  24. // SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
  25. // LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
  26. // DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
  27. // THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
  28. // (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
  29. // OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
  30. #import "GPBUtilities_PackagePrivate.h"
  31. #import <objc/runtime.h>
  32. #import "GPBArray_PackagePrivate.h"
  33. #import "GPBDescriptor_PackagePrivate.h"
  34. #import "GPBDictionary_PackagePrivate.h"
  35. #import "GPBExtensionField.h"
  36. #import "GPBField.h"
  37. #import "GPBMessage_PackagePrivate.h"
  38. #import "GPBUnknownFieldSet.h"
  39. static void AppendTextFormatForMessage(GPBMessage *message,
  40. NSMutableString *toStr,
  41. NSString *lineIndent);
  42. NSData *GPBEmptyNSData(void) {
  43. static dispatch_once_t onceToken;
  44. static NSData *defaultNSData = nil;
  45. dispatch_once(&onceToken, ^{
  46. defaultNSData = [[NSData alloc] init];
  47. });
  48. return defaultNSData;
  49. }
  50. BOOL GPBMessageHasFieldNumberSet(GPBMessage *self, uint32_t fieldNumber) {
  51. GPBDescriptor *descriptor = [self descriptor];
  52. GPBFieldDescriptor *field = [descriptor fieldWithNumber:fieldNumber];
  53. return GPBMessageHasFieldSet(self, field);
  54. }
  55. BOOL GPBMessageHasFieldSet(GPBMessage *self, GPBFieldDescriptor *field) {
  56. if (self == nil || field == nil) return NO;
  57. // Repeated/Map don't use the bit, they check the count.
  58. if (GPBFieldIsMapOrArray(field)) {
  59. // Array/map type doesn't matter, since GPB*Array/NSArray and
  60. // GPB*Dictionary/NSDictionary all support -count;
  61. NSArray *arrayOrMap = GPBGetObjectIvarWithFieldNoAutocreate(self, field);
  62. return (arrayOrMap.count > 0);
  63. } else {
  64. return GPBGetHasIvarField(self, field);
  65. }
  66. }
  67. void GPBClearMessageField(GPBMessage *self, GPBFieldDescriptor *field) {
  68. // If not set, nothing to do.
  69. if (!GPBGetHasIvarField(self, field)) {
  70. return;
  71. }
  72. if (GPBFieldStoresObject(field)) {
  73. // Object types are handled slightly differently, they need to be released.
  74. uint8_t *storage = (uint8_t *)self->messageStorage_;
  75. id *typePtr = (id *)&storage[field->description_->offset];
  76. [*typePtr release];
  77. *typePtr = nil;
  78. } else {
  79. // POD types just need to clear the has bit as the Get* method will
  80. // fetch the default when needed.
  81. }
  82. GPBSetHasIvarField(self, field, NO);
  83. }
  84. BOOL GPBGetHasIvar(GPBMessage *self, int32_t idx, uint32_t fieldNumber) {
  85. NSCAssert(self->messageStorage_ != NULL,
  86. @"%@: All messages should have storage (from init)",
  87. [self class]);
  88. if (idx < 0) {
  89. NSCAssert(fieldNumber != 0, @"Invalid field number.");
  90. BOOL hasIvar = (self->messageStorage_->_has_storage_[-idx] == fieldNumber);
  91. return hasIvar;
  92. } else {
  93. NSCAssert(idx != GPBNoHasBit, @"Invalid has bit.");
  94. uint32_t byteIndex = idx / 32;
  95. uint32_t bitMask = (1 << (idx % 32));
  96. BOOL hasIvar =
  97. (self->messageStorage_->_has_storage_[byteIndex] & bitMask) ? YES : NO;
  98. return hasIvar;
  99. }
  100. }
  101. uint32_t GPBGetHasOneof(GPBMessage *self, int32_t idx) {
  102. NSCAssert(idx < 0, @"%@: invalid index (%d) for oneof.",
  103. [self class], idx);
  104. uint32_t result = self->messageStorage_->_has_storage_[-idx];
  105. return result;
  106. }
  107. void GPBSetHasIvar(GPBMessage *self, int32_t idx, uint32_t fieldNumber,
  108. BOOL value) {
  109. if (idx < 0) {
  110. NSCAssert(fieldNumber != 0, @"Invalid field number.");
  111. uint32_t *has_storage = self->messageStorage_->_has_storage_;
  112. has_storage[-idx] = (value ? fieldNumber : 0);
  113. } else {
  114. NSCAssert(idx != GPBNoHasBit, @"Invalid has bit.");
  115. uint32_t *has_storage = self->messageStorage_->_has_storage_;
  116. uint32_t byte = idx / 32;
  117. uint32_t bitMask = (1 << (idx % 32));
  118. if (value) {
  119. has_storage[byte] |= bitMask;
  120. } else {
  121. has_storage[byte] &= ~bitMask;
  122. }
  123. }
  124. }
  125. void GPBMaybeClearOneof(GPBMessage *self, GPBOneofDescriptor *oneof,
  126. uint32_t fieldNumberNotToClear) {
  127. int32_t hasIndex = oneof->oneofDescription_->index;
  128. uint32_t fieldNumberSet = GPBGetHasOneof(self, hasIndex);
  129. if ((fieldNumberSet == fieldNumberNotToClear) || (fieldNumberSet == 0)) {
  130. // Do nothing/nothing set in the oneof.
  131. return;
  132. }
  133. // Like GPBClearMessageField(), free the memory if an objecttype is set,
  134. // pod types don't need to do anything.
  135. GPBFieldDescriptor *fieldSet = [oneof fieldWithNumber:fieldNumberSet];
  136. NSCAssert(fieldSet,
  137. @"%@: oneof set to something (%u) not in the oneof?",
  138. [self class], fieldNumberSet);
  139. if (fieldSet && GPBFieldStoresObject(fieldSet)) {
  140. uint8_t *storage = (uint8_t *)self->messageStorage_;
  141. id *typePtr = (id *)&storage[fieldSet->description_->offset];
  142. [*typePtr release];
  143. *typePtr = nil;
  144. }
  145. // Set to nothing stored in the oneof.
  146. // (field number doesn't matter since setting to nothing).
  147. GPBSetHasIvar(self, hasIndex, 1, NO);
  148. }
  149. #pragma mark - IVar accessors
  150. //%PDDM-DEFINE IVAR_POD_ACCESSORS_DEFN(NAME, TYPE)
  151. //%TYPE GPBGet##NAME##IvarWithField(GPBMessage *self,
  152. //% TYPE$S NAME$S GPBFieldDescriptor *field) {
  153. //% if (GPBGetHasIvarField(self, field)) {
  154. //% uint8_t *storage = (uint8_t *)self->messageStorage_;
  155. //% TYPE *typePtr = (TYPE *)&storage[field->description_->offset];
  156. //% return *typePtr;
  157. //% } else {
  158. //% return field.defaultValue.value##NAME;
  159. //% }
  160. //%}
  161. //%
  162. //%// Only exists for public api, no core code should use this.
  163. //%void GPBSet##NAME##IvarWithField(GPBMessage *self,
  164. //% NAME$S GPBFieldDescriptor *field,
  165. //% NAME$S TYPE value) {
  166. //% if (self == nil || field == nil) return;
  167. //% GPBFileSyntax syntax = [self descriptor].file.syntax;
  168. //% GPBSet##NAME##IvarWithFieldInternal(self, field, value, syntax);
  169. //%}
  170. //%
  171. //%void GPBSet##NAME##IvarWithFieldInternal(GPBMessage *self,
  172. //% NAME$S GPBFieldDescriptor *field,
  173. //% NAME$S TYPE value,
  174. //% NAME$S GPBFileSyntax syntax) {
  175. //% GPBOneofDescriptor *oneof = field->containingOneof_;
  176. //% if (oneof) {
  177. //% GPBMaybeClearOneof(self, oneof, GPBFieldNumber(field));
  178. //% }
  179. //% NSCAssert(self->messageStorage_ != NULL,
  180. //% @"%@: All messages should have storage (from init)",
  181. //% [self class]);
  182. //%#if defined(__clang_analyzer__)
  183. //% if (self->messageStorage_ == NULL) return;
  184. //%#endif
  185. //% uint8_t *storage = (uint8_t *)self->messageStorage_;
  186. //% TYPE *typePtr = (TYPE *)&storage[field->description_->offset];
  187. //% *typePtr = value;
  188. //% // proto2: any value counts as having been set; proto3, it
  189. //% // has to be a non zero value.
  190. //% BOOL hasValue =
  191. //% (syntax == GPBFileSyntaxProto2) || (value != (TYPE)0);
  192. //% GPBSetHasIvarField(self, field, hasValue);
  193. //% GPBBecomeVisibleToAutocreator(self);
  194. //%}
  195. //%
  196. //%PDDM-DEFINE IVAR_ALIAS_DEFN(NAME, ALIAS_NAME, TYPE, ALIAS_TYPE)
  197. //%// Only exists for public api, no core code should use this.
  198. //%TYPE GPBGet##NAME##IvarWithField(GPBMessage *self,
  199. //% TYPE$S NAME$S GPBFieldDescriptor *field) {
  200. //% return (TYPE)GPBGet##ALIAS_NAME##IvarWithField(self, field);
  201. //%}
  202. //%
  203. //%// Only exists for public api, no core code should use this.
  204. //%void GPBSet##NAME##IvarWithField(GPBMessage *self,
  205. //% NAME$S GPBFieldDescriptor *field,
  206. //% NAME$S TYPE value) {
  207. //% GPBSet##ALIAS_NAME##IvarWithField(self, field, (ALIAS_TYPE)value);
  208. //%}
  209. //%
  210. // Object types are handled slightly differently, they need to be released
  211. // and retained.
  212. void GPBSetAutocreatedRetainedObjectIvarWithField(
  213. GPBMessage *self, GPBFieldDescriptor *field,
  214. id __attribute__((ns_consumed)) value) {
  215. uint8_t *storage = (uint8_t *)self->messageStorage_;
  216. id *typePtr = (id *)&storage[field->description_->offset];
  217. NSCAssert(*typePtr == NULL, @"Can't set autocreated object more than once.");
  218. *typePtr = value;
  219. }
  220. void GPBClearAutocreatedMessageIvarWithField(GPBMessage *self,
  221. GPBFieldDescriptor *field) {
  222. if (GPBGetHasIvarField(self, field)) {
  223. return;
  224. }
  225. uint8_t *storage = (uint8_t *)self->messageStorage_;
  226. id *typePtr = (id *)&storage[field->description_->offset];
  227. GPBMessage *oldValue = *typePtr;
  228. *typePtr = NULL;
  229. GPBClearMessageAutocreator(oldValue);
  230. [oldValue release];
  231. }
  232. // This exists only for briging some aliased types, nothing else should use it.
  233. GPB_INLINE void GPBSetObjectIvarWithField(GPBMessage *self,
  234. GPBFieldDescriptor *field, id value) {
  235. if (self == nil || field == nil) return;
  236. GPBFileSyntax syntax = [self descriptor].file.syntax;
  237. GPBSetRetainedObjectIvarWithFieldInternal(self, field, [value retain],
  238. syntax);
  239. }
  240. void GPBSetObjectIvarWithFieldInternal(GPBMessage *self,
  241. GPBFieldDescriptor *field, id value,
  242. GPBFileSyntax syntax) {
  243. GPBSetRetainedObjectIvarWithFieldInternal(self, field, [value retain],
  244. syntax);
  245. }
  246. void GPBSetRetainedObjectIvarWithFieldInternal(GPBMessage *self,
  247. GPBFieldDescriptor *field,
  248. id value, GPBFileSyntax syntax) {
  249. NSCAssert(self->messageStorage_ != NULL,
  250. @"%@: All messages should have storage (from init)",
  251. [self class]);
  252. #if defined(__clang_analyzer__)
  253. if (self->messageStorage_ == NULL) return;
  254. #endif
  255. GPBType fieldType = GPBGetFieldType(field);
  256. BOOL isMapOrArray = GPBFieldIsMapOrArray(field);
  257. BOOL fieldIsMessage = GPBTypeIsMessage(fieldType);
  258. #ifdef DEBUG
  259. if (value == nil && !isMapOrArray && !fieldIsMessage &&
  260. field.hasDefaultValue) {
  261. // Setting a message to nil is an obvious way to "clear" the value
  262. // as there is no way to set a non-empty default value for messages.
  263. //
  264. // For Strings and Bytes that have default values set it is not clear what
  265. // should be done when their value is set to nil. Is the intention just to
  266. // clear the set value and reset to default, or is the intention to set the
  267. // value to the empty string/data? Arguments can be made for both cases.
  268. // 'nil' has been abused as a replacement for an empty string/data in ObjC.
  269. // We decided to be consistent with all "object" types and clear the has
  270. // field, and fall back on the default value. The warning below will only
  271. // appear in debug, but the could should be changed so the intention is
  272. // clear.
  273. NSString *hasSel = NSStringFromSelector(field->hasSel_);
  274. NSString *propName = field.name;
  275. NSString *className = self.descriptor.name;
  276. NSLog(@"warning: '%@.%@ = nil;' is not clearly defined for fields with "
  277. @"default values. Please use '%@.%@ = %@' if you want to set it to "
  278. @"empty, or call '%@.%@ = NO' to reset it to it's default value of "
  279. @"'%@'. Defaulting to resetting default value.",
  280. className, propName, className, propName,
  281. (fieldType == GPBTypeString) ? @"@\"\"" : @"GPBEmptyNSData()",
  282. className, hasSel, field.defaultValue.valueString);
  283. // Note: valueString, depending on the type, it could easily be
  284. // valueData/valueMessage.
  285. }
  286. #endif // DEBUG
  287. if (!isMapOrArray) {
  288. // Non repeated/map can be in an oneof, clear any existing value from the
  289. // oneof.
  290. GPBOneofDescriptor *oneof = field->containingOneof_;
  291. if (oneof) {
  292. GPBMaybeClearOneof(self, oneof, GPBFieldNumber(field));
  293. }
  294. // Clear "has" if they are being set to nil.
  295. BOOL setHasValue = (value != nil);
  296. // Under proto3, Data & String fields get cleared by resetting them to their
  297. // default (empty) values, so if they are set to something of length zero,
  298. // they are being cleared.
  299. if ((syntax == GPBFileSyntaxProto3) && !fieldIsMessage &&
  300. ([value length] == 0)) {
  301. setHasValue = NO;
  302. value = nil;
  303. }
  304. GPBSetHasIvarField(self, field, setHasValue);
  305. }
  306. uint8_t *storage = (uint8_t *)self->messageStorage_;
  307. id *typePtr = (id *)&storage[field->description_->offset];
  308. id oldValue = *typePtr;
  309. *typePtr = value;
  310. if (oldValue) {
  311. if (isMapOrArray) {
  312. if (field.fieldType == GPBFieldTypeRepeated) {
  313. // If the old array was autocreated by us, then clear it.
  314. if (GPBTypeIsObject(fieldType)) {
  315. GPBAutocreatedArray *autoArray = oldValue;
  316. if (autoArray->_autocreator == self) {
  317. autoArray->_autocreator = nil;
  318. }
  319. } else {
  320. // Type doesn't matter, it is a GPB*Array.
  321. GPBInt32Array *gpbArray = oldValue;
  322. if (gpbArray->_autocreator == self) {
  323. gpbArray->_autocreator = nil;
  324. }
  325. }
  326. } else { // GPBFieldTypeMap
  327. // If the old map was autocreated by us, then clear it.
  328. if ((field.mapKeyType == GPBTypeString) &&
  329. GPBTypeIsObject(fieldType)) {
  330. GPBAutocreatedDictionary *autoDict = oldValue;
  331. if (autoDict->_autocreator == self) {
  332. autoDict->_autocreator = nil;
  333. }
  334. } else {
  335. // Type doesn't matter, it is a GPB*Dictionary.
  336. GPBInt32Int32Dictionary *gpbDict = oldValue;
  337. if (gpbDict->_autocreator == self) {
  338. gpbDict->_autocreator = nil;
  339. }
  340. }
  341. }
  342. } else if (fieldIsMessage) {
  343. // If the old message value was autocreated by us, then clear it.
  344. GPBMessage *oldMessageValue = oldValue;
  345. if (GPBWasMessageAutocreatedBy(oldMessageValue, self)) {
  346. GPBClearMessageAutocreator(oldMessageValue);
  347. }
  348. }
  349. [oldValue release];
  350. }
  351. GPBBecomeVisibleToAutocreator(self);
  352. }
  353. id GPBGetObjectIvarWithFieldNoAutocreate(GPBMessage *self,
  354. GPBFieldDescriptor *field) {
  355. if (self->messageStorage_ == nil) {
  356. return nil;
  357. }
  358. uint8_t *storage = (uint8_t *)self->messageStorage_;
  359. id *typePtr = (id *)&storage[field->description_->offset];
  360. return *typePtr;
  361. }
  362. id GPBGetObjectIvarWithField(GPBMessage *self, GPBFieldDescriptor *field) {
  363. NSCAssert(!GPBFieldIsMapOrArray(field), @"Shouldn't get here");
  364. if (GPBGetHasIvarField(self, field)) {
  365. uint8_t *storage = (uint8_t *)self->messageStorage_;
  366. id *typePtr = (id *)&storage[field->description_->offset];
  367. return *typePtr;
  368. }
  369. // Not set...
  370. // Non messages (string/data), get their default.
  371. if (!GPBFieldTypeIsMessage(field)) {
  372. return field.defaultValue.valueMessage;
  373. }
  374. OSSpinLockLock(&self->readOnlyMutex_);
  375. GPBMessage *result = GPBGetObjectIvarWithFieldNoAutocreate(self, field);
  376. if (!result) {
  377. // For non repeated messages, create the object, set it and return it.
  378. // This object will not initially be visible via GPBGetHasIvar, so
  379. // we save its creator so it can become visible if it's mutated later.
  380. result = GPBCreateMessageWithAutocreator(field.msgClass, self, field);
  381. GPBSetAutocreatedRetainedObjectIvarWithField(self, field, result);
  382. }
  383. OSSpinLockUnlock(&self->readOnlyMutex_);
  384. return result;
  385. }
  386. // Only exists for public api, no core code should use this.
  387. int32_t GPBGetEnumIvarWithField(GPBMessage *self, GPBFieldDescriptor *field) {
  388. GPBFileSyntax syntax = [self descriptor].file.syntax;
  389. return GPBGetEnumIvarWithFieldInternal(self, field, syntax);
  390. }
  391. int32_t GPBGetEnumIvarWithFieldInternal(GPBMessage *self,
  392. GPBFieldDescriptor *field,
  393. GPBFileSyntax syntax) {
  394. int32_t result = GPBGetInt32IvarWithField(self, field);
  395. // If this is presevering unknown enums, make sure the value is
  396. // valid before returning it.
  397. if (GPBHasPreservingUnknownEnumSemantics(syntax) &&
  398. ![field isValidEnumValue:result]) {
  399. result = kGPBUnrecognizedEnumeratorValue;
  400. }
  401. return result;
  402. }
  403. // Only exists for public api, no core code should use this.
  404. void GPBSetEnumIvarWithField(GPBMessage *self, GPBFieldDescriptor *field,
  405. int32_t value) {
  406. GPBFileSyntax syntax = [self descriptor].file.syntax;
  407. GPBSetInt32IvarWithFieldInternal(self, field, value, syntax);
  408. }
  409. void GPBSetEnumIvarWithFieldInternal(GPBMessage *self,
  410. GPBFieldDescriptor *field, int32_t value,
  411. GPBFileSyntax syntax) {
  412. // Don't allow in unknown values. Proto3 can use the Raw method.
  413. if (![field isValidEnumValue:value]) {
  414. [NSException raise:NSInvalidArgumentException
  415. format:@"%@.%@: Attempt to set an unknown enum value (%d)",
  416. [self class], field.name, value];
  417. }
  418. GPBSetInt32IvarWithFieldInternal(self, field, value, syntax);
  419. }
  420. //%PDDM-EXPAND IVAR_POD_ACCESSORS_DEFN(Bool, BOOL)
  421. // This block of code is generated, do not edit it directly.
  422. BOOL GPBGetBoolIvarWithField(GPBMessage *self,
  423. GPBFieldDescriptor *field) {
  424. if (GPBGetHasIvarField(self, field)) {
  425. uint8_t *storage = (uint8_t *)self->messageStorage_;
  426. BOOL *typePtr = (BOOL *)&storage[field->description_->offset];
  427. return *typePtr;
  428. } else {
  429. return field.defaultValue.valueBool;
  430. }
  431. }
  432. // Only exists for public api, no core code should use this.
  433. void GPBSetBoolIvarWithField(GPBMessage *self,
  434. GPBFieldDescriptor *field,
  435. BOOL value) {
  436. if (self == nil || field == nil) return;
  437. GPBFileSyntax syntax = [self descriptor].file.syntax;
  438. GPBSetBoolIvarWithFieldInternal(self, field, value, syntax);
  439. }
  440. void GPBSetBoolIvarWithFieldInternal(GPBMessage *self,
  441. GPBFieldDescriptor *field,
  442. BOOL value,
  443. GPBFileSyntax syntax) {
  444. GPBOneofDescriptor *oneof = field->containingOneof_;
  445. if (oneof) {
  446. GPBMaybeClearOneof(self, oneof, GPBFieldNumber(field));
  447. }
  448. NSCAssert(self->messageStorage_ != NULL,
  449. @"%@: All messages should have storage (from init)",
  450. [self class]);
  451. #if defined(__clang_analyzer__)
  452. if (self->messageStorage_ == NULL) return;
  453. #endif
  454. uint8_t *storage = (uint8_t *)self->messageStorage_;
  455. BOOL *typePtr = (BOOL *)&storage[field->description_->offset];
  456. *typePtr = value;
  457. // proto2: any value counts as having been set; proto3, it
  458. // has to be a non zero value.
  459. BOOL hasValue =
  460. (syntax == GPBFileSyntaxProto2) || (value != (BOOL)0);
  461. GPBSetHasIvarField(self, field, hasValue);
  462. GPBBecomeVisibleToAutocreator(self);
  463. }
  464. //%PDDM-EXPAND IVAR_POD_ACCESSORS_DEFN(Int32, int32_t)
  465. // This block of code is generated, do not edit it directly.
  466. int32_t GPBGetInt32IvarWithField(GPBMessage *self,
  467. GPBFieldDescriptor *field) {
  468. if (GPBGetHasIvarField(self, field)) {
  469. uint8_t *storage = (uint8_t *)self->messageStorage_;
  470. int32_t *typePtr = (int32_t *)&storage[field->description_->offset];
  471. return *typePtr;
  472. } else {
  473. return field.defaultValue.valueInt32;
  474. }
  475. }
  476. // Only exists for public api, no core code should use this.
  477. void GPBSetInt32IvarWithField(GPBMessage *self,
  478. GPBFieldDescriptor *field,
  479. int32_t value) {
  480. if (self == nil || field == nil) return;
  481. GPBFileSyntax syntax = [self descriptor].file.syntax;
  482. GPBSetInt32IvarWithFieldInternal(self, field, value, syntax);
  483. }
  484. void GPBSetInt32IvarWithFieldInternal(GPBMessage *self,
  485. GPBFieldDescriptor *field,
  486. int32_t value,
  487. GPBFileSyntax syntax) {
  488. GPBOneofDescriptor *oneof = field->containingOneof_;
  489. if (oneof) {
  490. GPBMaybeClearOneof(self, oneof, GPBFieldNumber(field));
  491. }
  492. NSCAssert(self->messageStorage_ != NULL,
  493. @"%@: All messages should have storage (from init)",
  494. [self class]);
  495. #if defined(__clang_analyzer__)
  496. if (self->messageStorage_ == NULL) return;
  497. #endif
  498. uint8_t *storage = (uint8_t *)self->messageStorage_;
  499. int32_t *typePtr = (int32_t *)&storage[field->description_->offset];
  500. *typePtr = value;
  501. // proto2: any value counts as having been set; proto3, it
  502. // has to be a non zero value.
  503. BOOL hasValue =
  504. (syntax == GPBFileSyntaxProto2) || (value != (int32_t)0);
  505. GPBSetHasIvarField(self, field, hasValue);
  506. GPBBecomeVisibleToAutocreator(self);
  507. }
  508. //%PDDM-EXPAND IVAR_POD_ACCESSORS_DEFN(UInt32, uint32_t)
  509. // This block of code is generated, do not edit it directly.
  510. uint32_t GPBGetUInt32IvarWithField(GPBMessage *self,
  511. GPBFieldDescriptor *field) {
  512. if (GPBGetHasIvarField(self, field)) {
  513. uint8_t *storage = (uint8_t *)self->messageStorage_;
  514. uint32_t *typePtr = (uint32_t *)&storage[field->description_->offset];
  515. return *typePtr;
  516. } else {
  517. return field.defaultValue.valueUInt32;
  518. }
  519. }
  520. // Only exists for public api, no core code should use this.
  521. void GPBSetUInt32IvarWithField(GPBMessage *self,
  522. GPBFieldDescriptor *field,
  523. uint32_t value) {
  524. if (self == nil || field == nil) return;
  525. GPBFileSyntax syntax = [self descriptor].file.syntax;
  526. GPBSetUInt32IvarWithFieldInternal(self, field, value, syntax);
  527. }
  528. void GPBSetUInt32IvarWithFieldInternal(GPBMessage *self,
  529. GPBFieldDescriptor *field,
  530. uint32_t value,
  531. GPBFileSyntax syntax) {
  532. GPBOneofDescriptor *oneof = field->containingOneof_;
  533. if (oneof) {
  534. GPBMaybeClearOneof(self, oneof, GPBFieldNumber(field));
  535. }
  536. NSCAssert(self->messageStorage_ != NULL,
  537. @"%@: All messages should have storage (from init)",
  538. [self class]);
  539. #if defined(__clang_analyzer__)
  540. if (self->messageStorage_ == NULL) return;
  541. #endif
  542. uint8_t *storage = (uint8_t *)self->messageStorage_;
  543. uint32_t *typePtr = (uint32_t *)&storage[field->description_->offset];
  544. *typePtr = value;
  545. // proto2: any value counts as having been set; proto3, it
  546. // has to be a non zero value.
  547. BOOL hasValue =
  548. (syntax == GPBFileSyntaxProto2) || (value != (uint32_t)0);
  549. GPBSetHasIvarField(self, field, hasValue);
  550. GPBBecomeVisibleToAutocreator(self);
  551. }
  552. //%PDDM-EXPAND IVAR_POD_ACCESSORS_DEFN(Int64, int64_t)
  553. // This block of code is generated, do not edit it directly.
  554. int64_t GPBGetInt64IvarWithField(GPBMessage *self,
  555. GPBFieldDescriptor *field) {
  556. if (GPBGetHasIvarField(self, field)) {
  557. uint8_t *storage = (uint8_t *)self->messageStorage_;
  558. int64_t *typePtr = (int64_t *)&storage[field->description_->offset];
  559. return *typePtr;
  560. } else {
  561. return field.defaultValue.valueInt64;
  562. }
  563. }
  564. // Only exists for public api, no core code should use this.
  565. void GPBSetInt64IvarWithField(GPBMessage *self,
  566. GPBFieldDescriptor *field,
  567. int64_t value) {
  568. if (self == nil || field == nil) return;
  569. GPBFileSyntax syntax = [self descriptor].file.syntax;
  570. GPBSetInt64IvarWithFieldInternal(self, field, value, syntax);
  571. }
  572. void GPBSetInt64IvarWithFieldInternal(GPBMessage *self,
  573. GPBFieldDescriptor *field,
  574. int64_t value,
  575. GPBFileSyntax syntax) {
  576. GPBOneofDescriptor *oneof = field->containingOneof_;
  577. if (oneof) {
  578. GPBMaybeClearOneof(self, oneof, GPBFieldNumber(field));
  579. }
  580. NSCAssert(self->messageStorage_ != NULL,
  581. @"%@: All messages should have storage (from init)",
  582. [self class]);
  583. #if defined(__clang_analyzer__)
  584. if (self->messageStorage_ == NULL) return;
  585. #endif
  586. uint8_t *storage = (uint8_t *)self->messageStorage_;
  587. int64_t *typePtr = (int64_t *)&storage[field->description_->offset];
  588. *typePtr = value;
  589. // proto2: any value counts as having been set; proto3, it
  590. // has to be a non zero value.
  591. BOOL hasValue =
  592. (syntax == GPBFileSyntaxProto2) || (value != (int64_t)0);
  593. GPBSetHasIvarField(self, field, hasValue);
  594. GPBBecomeVisibleToAutocreator(self);
  595. }
  596. //%PDDM-EXPAND IVAR_POD_ACCESSORS_DEFN(UInt64, uint64_t)
  597. // This block of code is generated, do not edit it directly.
  598. uint64_t GPBGetUInt64IvarWithField(GPBMessage *self,
  599. GPBFieldDescriptor *field) {
  600. if (GPBGetHasIvarField(self, field)) {
  601. uint8_t *storage = (uint8_t *)self->messageStorage_;
  602. uint64_t *typePtr = (uint64_t *)&storage[field->description_->offset];
  603. return *typePtr;
  604. } else {
  605. return field.defaultValue.valueUInt64;
  606. }
  607. }
  608. // Only exists for public api, no core code should use this.
  609. void GPBSetUInt64IvarWithField(GPBMessage *self,
  610. GPBFieldDescriptor *field,
  611. uint64_t value) {
  612. if (self == nil || field == nil) return;
  613. GPBFileSyntax syntax = [self descriptor].file.syntax;
  614. GPBSetUInt64IvarWithFieldInternal(self, field, value, syntax);
  615. }
  616. void GPBSetUInt64IvarWithFieldInternal(GPBMessage *self,
  617. GPBFieldDescriptor *field,
  618. uint64_t value,
  619. GPBFileSyntax syntax) {
  620. GPBOneofDescriptor *oneof = field->containingOneof_;
  621. if (oneof) {
  622. GPBMaybeClearOneof(self, oneof, GPBFieldNumber(field));
  623. }
  624. NSCAssert(self->messageStorage_ != NULL,
  625. @"%@: All messages should have storage (from init)",
  626. [self class]);
  627. #if defined(__clang_analyzer__)
  628. if (self->messageStorage_ == NULL) return;
  629. #endif
  630. uint8_t *storage = (uint8_t *)self->messageStorage_;
  631. uint64_t *typePtr = (uint64_t *)&storage[field->description_->offset];
  632. *typePtr = value;
  633. // proto2: any value counts as having been set; proto3, it
  634. // has to be a non zero value.
  635. BOOL hasValue =
  636. (syntax == GPBFileSyntaxProto2) || (value != (uint64_t)0);
  637. GPBSetHasIvarField(self, field, hasValue);
  638. GPBBecomeVisibleToAutocreator(self);
  639. }
  640. //%PDDM-EXPAND IVAR_POD_ACCESSORS_DEFN(Float, float)
  641. // This block of code is generated, do not edit it directly.
  642. float GPBGetFloatIvarWithField(GPBMessage *self,
  643. GPBFieldDescriptor *field) {
  644. if (GPBGetHasIvarField(self, field)) {
  645. uint8_t *storage = (uint8_t *)self->messageStorage_;
  646. float *typePtr = (float *)&storage[field->description_->offset];
  647. return *typePtr;
  648. } else {
  649. return field.defaultValue.valueFloat;
  650. }
  651. }
  652. // Only exists for public api, no core code should use this.
  653. void GPBSetFloatIvarWithField(GPBMessage *self,
  654. GPBFieldDescriptor *field,
  655. float value) {
  656. if (self == nil || field == nil) return;
  657. GPBFileSyntax syntax = [self descriptor].file.syntax;
  658. GPBSetFloatIvarWithFieldInternal(self, field, value, syntax);
  659. }
  660. void GPBSetFloatIvarWithFieldInternal(GPBMessage *self,
  661. GPBFieldDescriptor *field,
  662. float value,
  663. GPBFileSyntax syntax) {
  664. GPBOneofDescriptor *oneof = field->containingOneof_;
  665. if (oneof) {
  666. GPBMaybeClearOneof(self, oneof, GPBFieldNumber(field));
  667. }
  668. NSCAssert(self->messageStorage_ != NULL,
  669. @"%@: All messages should have storage (from init)",
  670. [self class]);
  671. #if defined(__clang_analyzer__)
  672. if (self->messageStorage_ == NULL) return;
  673. #endif
  674. uint8_t *storage = (uint8_t *)self->messageStorage_;
  675. float *typePtr = (float *)&storage[field->description_->offset];
  676. *typePtr = value;
  677. // proto2: any value counts as having been set; proto3, it
  678. // has to be a non zero value.
  679. BOOL hasValue =
  680. (syntax == GPBFileSyntaxProto2) || (value != (float)0);
  681. GPBSetHasIvarField(self, field, hasValue);
  682. GPBBecomeVisibleToAutocreator(self);
  683. }
  684. //%PDDM-EXPAND IVAR_POD_ACCESSORS_DEFN(Double, double)
  685. // This block of code is generated, do not edit it directly.
  686. double GPBGetDoubleIvarWithField(GPBMessage *self,
  687. GPBFieldDescriptor *field) {
  688. if (GPBGetHasIvarField(self, field)) {
  689. uint8_t *storage = (uint8_t *)self->messageStorage_;
  690. double *typePtr = (double *)&storage[field->description_->offset];
  691. return *typePtr;
  692. } else {
  693. return field.defaultValue.valueDouble;
  694. }
  695. }
  696. // Only exists for public api, no core code should use this.
  697. void GPBSetDoubleIvarWithField(GPBMessage *self,
  698. GPBFieldDescriptor *field,
  699. double value) {
  700. if (self == nil || field == nil) return;
  701. GPBFileSyntax syntax = [self descriptor].file.syntax;
  702. GPBSetDoubleIvarWithFieldInternal(self, field, value, syntax);
  703. }
  704. void GPBSetDoubleIvarWithFieldInternal(GPBMessage *self,
  705. GPBFieldDescriptor *field,
  706. double value,
  707. GPBFileSyntax syntax) {
  708. GPBOneofDescriptor *oneof = field->containingOneof_;
  709. if (oneof) {
  710. GPBMaybeClearOneof(self, oneof, GPBFieldNumber(field));
  711. }
  712. NSCAssert(self->messageStorage_ != NULL,
  713. @"%@: All messages should have storage (from init)",
  714. [self class]);
  715. #if defined(__clang_analyzer__)
  716. if (self->messageStorage_ == NULL) return;
  717. #endif
  718. uint8_t *storage = (uint8_t *)self->messageStorage_;
  719. double *typePtr = (double *)&storage[field->description_->offset];
  720. *typePtr = value;
  721. // proto2: any value counts as having been set; proto3, it
  722. // has to be a non zero value.
  723. BOOL hasValue =
  724. (syntax == GPBFileSyntaxProto2) || (value != (double)0);
  725. GPBSetHasIvarField(self, field, hasValue);
  726. GPBBecomeVisibleToAutocreator(self);
  727. }
  728. //%PDDM-EXPAND-END (7 expansions)
  729. // Aliases are function calls that are virtually the same.
  730. //%PDDM-EXPAND IVAR_ALIAS_DEFN(SInt32, Int32, int32_t, int32_t)
  731. // This block of code is generated, do not edit it directly.
  732. // Only exists for public api, no core code should use this.
  733. int32_t GPBGetSInt32IvarWithField(GPBMessage *self,
  734. GPBFieldDescriptor *field) {
  735. return (int32_t)GPBGetInt32IvarWithField(self, field);
  736. }
  737. // Only exists for public api, no core code should use this.
  738. void GPBSetSInt32IvarWithField(GPBMessage *self,
  739. GPBFieldDescriptor *field,
  740. int32_t value) {
  741. GPBSetInt32IvarWithField(self, field, (int32_t)value);
  742. }
  743. //%PDDM-EXPAND IVAR_ALIAS_DEFN(SFixed32, Int32, int32_t, int32_t)
  744. // This block of code is generated, do not edit it directly.
  745. // Only exists for public api, no core code should use this.
  746. int32_t GPBGetSFixed32IvarWithField(GPBMessage *self,
  747. GPBFieldDescriptor *field) {
  748. return (int32_t)GPBGetInt32IvarWithField(self, field);
  749. }
  750. // Only exists for public api, no core code should use this.
  751. void GPBSetSFixed32IvarWithField(GPBMessage *self,
  752. GPBFieldDescriptor *field,
  753. int32_t value) {
  754. GPBSetInt32IvarWithField(self, field, (int32_t)value);
  755. }
  756. //%PDDM-EXPAND IVAR_ALIAS_DEFN(Fixed32, UInt32, uint32_t, uint32_t)
  757. // This block of code is generated, do not edit it directly.
  758. // Only exists for public api, no core code should use this.
  759. uint32_t GPBGetFixed32IvarWithField(GPBMessage *self,
  760. GPBFieldDescriptor *field) {
  761. return (uint32_t)GPBGetUInt32IvarWithField(self, field);
  762. }
  763. // Only exists for public api, no core code should use this.
  764. void GPBSetFixed32IvarWithField(GPBMessage *self,
  765. GPBFieldDescriptor *field,
  766. uint32_t value) {
  767. GPBSetUInt32IvarWithField(self, field, (uint32_t)value);
  768. }
  769. //%PDDM-EXPAND IVAR_ALIAS_DEFN(SInt64, Int64, int64_t, int64_t)
  770. // This block of code is generated, do not edit it directly.
  771. // Only exists for public api, no core code should use this.
  772. int64_t GPBGetSInt64IvarWithField(GPBMessage *self,
  773. GPBFieldDescriptor *field) {
  774. return (int64_t)GPBGetInt64IvarWithField(self, field);
  775. }
  776. // Only exists for public api, no core code should use this.
  777. void GPBSetSInt64IvarWithField(GPBMessage *self,
  778. GPBFieldDescriptor *field,
  779. int64_t value) {
  780. GPBSetInt64IvarWithField(self, field, (int64_t)value);
  781. }
  782. //%PDDM-EXPAND IVAR_ALIAS_DEFN(SFixed64, Int64, int64_t, int64_t)
  783. // This block of code is generated, do not edit it directly.
  784. // Only exists for public api, no core code should use this.
  785. int64_t GPBGetSFixed64IvarWithField(GPBMessage *self,
  786. GPBFieldDescriptor *field) {
  787. return (int64_t)GPBGetInt64IvarWithField(self, field);
  788. }
  789. // Only exists for public api, no core code should use this.
  790. void GPBSetSFixed64IvarWithField(GPBMessage *self,
  791. GPBFieldDescriptor *field,
  792. int64_t value) {
  793. GPBSetInt64IvarWithField(self, field, (int64_t)value);
  794. }
  795. //%PDDM-EXPAND IVAR_ALIAS_DEFN(Fixed64, UInt64, uint64_t, uint64_t)
  796. // This block of code is generated, do not edit it directly.
  797. // Only exists for public api, no core code should use this.
  798. uint64_t GPBGetFixed64IvarWithField(GPBMessage *self,
  799. GPBFieldDescriptor *field) {
  800. return (uint64_t)GPBGetUInt64IvarWithField(self, field);
  801. }
  802. // Only exists for public api, no core code should use this.
  803. void GPBSetFixed64IvarWithField(GPBMessage *self,
  804. GPBFieldDescriptor *field,
  805. uint64_t value) {
  806. GPBSetUInt64IvarWithField(self, field, (uint64_t)value);
  807. }
  808. //%PDDM-EXPAND IVAR_ALIAS_DEFN(String, Object, NSString*, id)
  809. // This block of code is generated, do not edit it directly.
  810. // Only exists for public api, no core code should use this.
  811. NSString* GPBGetStringIvarWithField(GPBMessage *self,
  812. GPBFieldDescriptor *field) {
  813. return (NSString*)GPBGetObjectIvarWithField(self, field);
  814. }
  815. // Only exists for public api, no core code should use this.
  816. void GPBSetStringIvarWithField(GPBMessage *self,
  817. GPBFieldDescriptor *field,
  818. NSString* value) {
  819. GPBSetObjectIvarWithField(self, field, (id)value);
  820. }
  821. //%PDDM-EXPAND IVAR_ALIAS_DEFN(Data, Object, NSData*, id)
  822. // This block of code is generated, do not edit it directly.
  823. // Only exists for public api, no core code should use this.
  824. NSData* GPBGetDataIvarWithField(GPBMessage *self,
  825. GPBFieldDescriptor *field) {
  826. return (NSData*)GPBGetObjectIvarWithField(self, field);
  827. }
  828. // Only exists for public api, no core code should use this.
  829. void GPBSetDataIvarWithField(GPBMessage *self,
  830. GPBFieldDescriptor *field,
  831. NSData* value) {
  832. GPBSetObjectIvarWithField(self, field, (id)value);
  833. }
  834. //%PDDM-EXPAND IVAR_ALIAS_DEFN(Message, Object, GPBMessage*, id)
  835. // This block of code is generated, do not edit it directly.
  836. // Only exists for public api, no core code should use this.
  837. GPBMessage* GPBGetMessageIvarWithField(GPBMessage *self,
  838. GPBFieldDescriptor *field) {
  839. return (GPBMessage*)GPBGetObjectIvarWithField(self, field);
  840. }
  841. // Only exists for public api, no core code should use this.
  842. void GPBSetMessageIvarWithField(GPBMessage *self,
  843. GPBFieldDescriptor *field,
  844. GPBMessage* value) {
  845. GPBSetObjectIvarWithField(self, field, (id)value);
  846. }
  847. //%PDDM-EXPAND IVAR_ALIAS_DEFN(Group, Object, GPBMessage*, id)
  848. // This block of code is generated, do not edit it directly.
  849. // Only exists for public api, no core code should use this.
  850. GPBMessage* GPBGetGroupIvarWithField(GPBMessage *self,
  851. GPBFieldDescriptor *field) {
  852. return (GPBMessage*)GPBGetObjectIvarWithField(self, field);
  853. }
  854. // Only exists for public api, no core code should use this.
  855. void GPBSetGroupIvarWithField(GPBMessage *self,
  856. GPBFieldDescriptor *field,
  857. GPBMessage* value) {
  858. GPBSetObjectIvarWithField(self, field, (id)value);
  859. }
  860. //%PDDM-EXPAND-END (10 expansions)
  861. #pragma mark - Misc Dynamic Runtime Utils
  862. void GPBApplyFunctionsToMessageFields(GPBApplyFunctions *functions,
  863. GPBMessage *msg, void *context) {
  864. GPBDescriptor *descriptor = [[msg class] descriptor];
  865. for (GPBFieldDescriptor *field in descriptor->fields_) {
  866. BOOL wasGood;
  867. if (GPBFieldIsMapOrArray(field)) {
  868. wasGood = (*functions)[GPBApplyFunctionObject](field, context);
  869. } else {
  870. wasGood = GPBApplyFunctionsBasedOnField(field, functions, context);
  871. }
  872. if (!wasGood) {
  873. break;
  874. }
  875. }
  876. }
  877. BOOL GPBApplyFunctionsBasedOnField(GPBFieldDescriptor *field,
  878. GPBApplyFunctions *functions,
  879. void *context) {
  880. static const GPBApplyFunctionOrder typeMap[GPBTypeCount] = {
  881. GPBApplyFunctionBool,
  882. GPBApplyFunctionUInt32,
  883. GPBApplyFunctionInt32,
  884. GPBApplyFunctionFloat,
  885. GPBApplyFunctionUInt64,
  886. GPBApplyFunctionInt64,
  887. GPBApplyFunctionDouble,
  888. GPBApplyFunctionInt32,
  889. GPBApplyFunctionInt64,
  890. GPBApplyFunctionInt32,
  891. GPBApplyFunctionInt64,
  892. GPBApplyFunctionUInt32,
  893. GPBApplyFunctionUInt64,
  894. GPBApplyFunctionObject,
  895. GPBApplyFunctionObject,
  896. GPBApplyFunctionObject,
  897. GPBApplyFunctionObject,
  898. GPBApplyFunctionInt32
  899. };
  900. return (*functions)[typeMap[GPBGetFieldType(field)]](field, context);
  901. }
  902. void GPBApplyStrictFunctionsToMessageFields(GPBApplyStrictFunctions *functions,
  903. GPBMessage *msg, void *context) {
  904. GPBDescriptor *descriptor = [[msg class] descriptor];
  905. for (GPBFieldDescriptor *fieldDescriptor in descriptor->fields_) {
  906. GPBApplyFunction function = (*functions)[GPBGetFieldType(fieldDescriptor)];
  907. BOOL wasGood = function(fieldDescriptor, context);
  908. if (!wasGood) {
  909. break;
  910. }
  911. }
  912. }
  913. const char *GPBMessageEncodingForSelector(SEL selector, BOOL instanceSel) {
  914. Protocol *protocol =
  915. objc_getProtocol(GPBStringifySymbol(GPBMessageSignatureProtocol));
  916. struct objc_method_description description =
  917. protocol_getMethodDescription(protocol, selector, NO, instanceSel);
  918. return description.types;
  919. }
  920. #pragma mark - Text Format Support
  921. static void AppendStringEscaped(NSString *toPrint, NSMutableString *destStr) {
  922. [destStr appendString:@"\""];
  923. NSUInteger len = [toPrint length];
  924. for (NSUInteger i = 0; i < len; ++i) {
  925. unichar aChar = [toPrint characterAtIndex:i];
  926. switch (aChar) {
  927. case '\n': [destStr appendString:@"\\n"]; break;
  928. case '\r': [destStr appendString:@"\\r"]; break;
  929. case '\t': [destStr appendString:@"\\t"]; break;
  930. case '\"': [destStr appendString:@"\\\""]; break;
  931. case '\'': [destStr appendString:@"\\\'"]; break;
  932. case '\\': [destStr appendString:@"\\\\"]; break;
  933. default:
  934. [destStr appendFormat:@"%C", aChar];
  935. break;
  936. }
  937. }
  938. [destStr appendString:@"\""];
  939. }
  940. static void AppendBufferAsString(NSData *buffer, NSMutableString *destStr) {
  941. const char *src = (const char *)[buffer bytes];
  942. size_t srcLen = [buffer length];
  943. [destStr appendString:@"\""];
  944. for (const char *srcEnd = src + srcLen; src < srcEnd; src++) {
  945. switch (*src) {
  946. case '\n': [destStr appendString:@"\\n"]; break;
  947. case '\r': [destStr appendString:@"\\r"]; break;
  948. case '\t': [destStr appendString:@"\\t"]; break;
  949. case '\"': [destStr appendString:@"\\\""]; break;
  950. case '\'': [destStr appendString:@"\\\'"]; break;
  951. case '\\': [destStr appendString:@"\\\\"]; break;
  952. default:
  953. if (isprint(*src)) {
  954. [destStr appendFormat:@"%c", *src];
  955. } else {
  956. // NOTE: doing hex means you have to worry about the letter after
  957. // the hex being another hex char and forcing that to be escaped, so
  958. // use octal to keep it simple.
  959. [destStr appendFormat:@"\\%03o", (uint8_t)(*src)];
  960. }
  961. break;
  962. }
  963. }
  964. [destStr appendString:@"\""];
  965. }
  966. static void AppendTextFormatForMapMessageField(
  967. id map, GPBFieldDescriptor *field, NSMutableString *toStr,
  968. NSString *lineIndent, NSString *fieldName, NSString *lineEnding) {
  969. GPBType keyType = field.mapKeyType;
  970. GPBType valueType = GPBGetFieldType(field);
  971. BOOL isMessageValue = GPBTypeIsMessage(valueType);
  972. NSString *msgStartFirst =
  973. [NSString stringWithFormat:@"%@%@ {%@\n", lineIndent, fieldName, lineEnding];
  974. NSString *msgStart =
  975. [NSString stringWithFormat:@"%@%@ {\n", lineIndent, fieldName];
  976. NSString *msgEnd = [NSString stringWithFormat:@"%@}\n", lineIndent];
  977. NSString *keyLine = [NSString stringWithFormat:@"%@ key: ", lineIndent];
  978. NSString *valueLine = [NSString stringWithFormat:@"%@ value%s ", lineIndent,
  979. (isMessageValue ? "" : ":")];
  980. __block BOOL isFirst = YES;
  981. if ((keyType == GPBTypeString) && GPBTypeIsObject(valueType)) {
  982. // map is an NSDictionary.
  983. NSDictionary *dict = map;
  984. [dict enumerateKeysAndObjectsUsingBlock:^(NSString *key, id value, BOOL *stop) {
  985. #pragma unused(stop)
  986. [toStr appendString:(isFirst ? msgStartFirst : msgStart)];
  987. isFirst = NO;
  988. [toStr appendString:keyLine];
  989. AppendStringEscaped(key, toStr);
  990. [toStr appendString:@"\n"];
  991. [toStr appendString:valueLine];
  992. switch (valueType) {
  993. case GPBTypeString:
  994. AppendStringEscaped(value, toStr);
  995. break;
  996. case GPBTypeData:
  997. AppendBufferAsString(value, toStr);
  998. break;
  999. case GPBTypeMessage:
  1000. [toStr appendString:@"{\n"];
  1001. NSString *subIndent = [lineIndent stringByAppendingString:@" "];
  1002. AppendTextFormatForMessage(value, toStr, subIndent);
  1003. [toStr appendFormat:@"%@ }", lineIndent];
  1004. break;
  1005. default:
  1006. NSCAssert(NO, @"Can't happen");
  1007. break;
  1008. }
  1009. [toStr appendString:@"\n"];
  1010. [toStr appendString:msgEnd];
  1011. }];
  1012. } else {
  1013. // map is one of the GPB*Dictionary classes, type doesn't matter.
  1014. GPBInt32Int32Dictionary *dict = map;
  1015. [dict enumerateForTextFormat:^(id keyObj, id valueObj) {
  1016. [toStr appendString:(isFirst ? msgStartFirst : msgStart)];
  1017. isFirst = NO;
  1018. // Key always is a NSString.
  1019. if (keyType == GPBTypeString) {
  1020. [toStr appendString:keyLine];
  1021. AppendStringEscaped(keyObj, toStr);
  1022. [toStr appendString:@"\n"];
  1023. } else {
  1024. [toStr appendFormat:@"%@%@\n", keyLine, keyObj];
  1025. }
  1026. [toStr appendString:valueLine];
  1027. switch (valueType) {
  1028. case GPBTypeString:
  1029. AppendStringEscaped(valueObj, toStr);
  1030. break;
  1031. case GPBTypeData:
  1032. AppendBufferAsString(valueObj, toStr);
  1033. break;
  1034. case GPBTypeMessage:
  1035. [toStr appendString:@"{\n"];
  1036. NSString *subIndent = [lineIndent stringByAppendingString:@" "];
  1037. AppendTextFormatForMessage(valueObj, toStr, subIndent);
  1038. [toStr appendFormat:@"%@ }", lineIndent];
  1039. break;
  1040. case GPBTypeEnum: {
  1041. int32_t enumValue = [valueObj intValue];
  1042. NSString *valueStr = nil;
  1043. GPBEnumDescriptor *descriptor = field.enumDescriptor;
  1044. if (descriptor) {
  1045. valueStr = [descriptor textFormatNameForValue:enumValue];
  1046. }
  1047. if (valueStr) {
  1048. [toStr appendString:valueStr];
  1049. } else {
  1050. [toStr appendFormat:@"%d", enumValue];
  1051. }
  1052. break;
  1053. }
  1054. default:
  1055. NSCAssert(valueType != GPBTypeGroup, @"Can't happen");
  1056. // Everything else is a NSString.
  1057. [toStr appendString:valueObj];
  1058. break;
  1059. }
  1060. [toStr appendString:@"\n"];
  1061. [toStr appendString:msgEnd];
  1062. }];
  1063. }
  1064. }
  1065. static void AppendTextFormatForMessageField(GPBMessage *message,
  1066. GPBFieldDescriptor *field,
  1067. NSMutableString *toStr,
  1068. NSString *lineIndent) {
  1069. id arrayOrMap;
  1070. NSUInteger count;
  1071. GPBFieldType fieldType = field.fieldType;
  1072. switch (fieldType) {
  1073. case GPBFieldTypeSingle:
  1074. arrayOrMap = nil;
  1075. count = (GPBGetHasIvarField(message, field) ? 1 : 0);
  1076. break;
  1077. case GPBFieldTypeRepeated:
  1078. // Will be NSArray or GPB*Array, type doesn't matter, they both
  1079. // implement count.
  1080. arrayOrMap = GPBGetObjectIvarWithFieldNoAutocreate(message, field);
  1081. count = [(NSArray *)arrayOrMap count];
  1082. break;
  1083. case GPBFieldTypeMap: {
  1084. // Will be GPB*Dictionary or NSMutableDictionary, type doesn't matter,
  1085. // they both implement count.
  1086. arrayOrMap = GPBGetObjectIvarWithFieldNoAutocreate(message, field);
  1087. count = [(NSDictionary *)arrayOrMap count];
  1088. break;
  1089. }
  1090. }
  1091. if (count == 0) {
  1092. // Nothing to print, out of here.
  1093. return;
  1094. }
  1095. NSString *lineEnding = @"";
  1096. // If the name can't be reversed or support for extra info was turned off,
  1097. // this can return nil.
  1098. NSString *fieldName = [field textFormatName];
  1099. if ([fieldName length] == 0) {
  1100. fieldName = [NSString stringWithFormat:@"%u", GPBFieldNumber(field)];
  1101. // If there is only one entry, put the objc name as a comment, other wise
  1102. // add it before the the repeated values.
  1103. if (count > 1) {
  1104. [toStr appendFormat:@"%@# %@\n", lineIndent, field.name];
  1105. } else {
  1106. lineEnding = [NSString stringWithFormat:@" # %@", field.name];
  1107. }
  1108. }
  1109. if (fieldType == GPBFieldTypeMap) {
  1110. AppendTextFormatForMapMessageField(arrayOrMap, field, toStr, lineIndent,
  1111. fieldName, lineEnding);
  1112. return;
  1113. }
  1114. id array = arrayOrMap;
  1115. const BOOL isRepeated = (array != nil);
  1116. GPBType fieldDataType = GPBGetFieldType(field);
  1117. BOOL isMessageField = GPBTypeIsMessage(fieldDataType);
  1118. for (NSUInteger j = 0; j < count; ++j) {
  1119. // Start the line.
  1120. [toStr appendFormat:@"%@%@%s ", lineIndent, fieldName,
  1121. (isMessageField ? "" : ":")];
  1122. // The value.
  1123. switch (fieldDataType) {
  1124. #define FIELD_CASE(GPBTYPE, CTYPE, ARRAY_TYPE, ...) \
  1125. case GPBType##GPBTYPE: { \
  1126. CTYPE v = (isRepeated ? [(GPB##ARRAY_TYPE##Array *)array valueAtIndex:j] \
  1127. : GPBGet##GPBTYPE##IvarWithField(message, field)); \
  1128. [toStr appendFormat:__VA_ARGS__, v]; \
  1129. break; \
  1130. }
  1131. FIELD_CASE(Int32, int32_t, Int32, @"%d")
  1132. FIELD_CASE(SInt32, int32_t, Int32, @"%d")
  1133. FIELD_CASE(SFixed32, int32_t, Int32, @"%d")
  1134. FIELD_CASE(UInt32, uint32_t, UInt32, @"%u")
  1135. FIELD_CASE(Fixed32, uint32_t, UInt32, @"%u")
  1136. FIELD_CASE(Int64, int64_t, Int64, @"%lld")
  1137. FIELD_CASE(SInt64, int64_t, Int64, @"%lld")
  1138. FIELD_CASE(SFixed64, int64_t, Int64, @"%lld")
  1139. FIELD_CASE(UInt64, uint64_t, UInt64, @"%llu")
  1140. FIELD_CASE(Fixed64, uint64_t, UInt64, @"%llu")
  1141. FIELD_CASE(Float, float, Float, @"%.*g", FLT_DIG)
  1142. FIELD_CASE(Double, double, Double, @"%.*lg", DBL_DIG)
  1143. #undef FIELD_CASE
  1144. case GPBTypeEnum: {
  1145. int32_t v = (isRepeated ? [(GPBEnumArray *)array rawValueAtIndex:j]
  1146. : GPBGetInt32IvarWithField(message, field));
  1147. NSString *valueStr = nil;
  1148. GPBEnumDescriptor *descriptor = field.enumDescriptor;
  1149. if (descriptor) {
  1150. valueStr = [descriptor textFormatNameForValue:v];
  1151. }
  1152. if (valueStr) {
  1153. [toStr appendString:valueStr];
  1154. } else {
  1155. [toStr appendFormat:@"%d", v];
  1156. }
  1157. break;
  1158. }
  1159. case GPBTypeBool: {
  1160. BOOL v = (isRepeated ? [(GPBBoolArray *)array valueAtIndex:j]
  1161. : GPBGetBoolIvarWithField(message, field));
  1162. [toStr appendString:(v ? @"true" : @"false")];
  1163. break;
  1164. }
  1165. case GPBTypeString: {
  1166. NSString *v = (isRepeated ? [(NSArray *)array objectAtIndex:j]
  1167. : GPBGetStringIvarWithField(message, field));
  1168. AppendStringEscaped(v, toStr);
  1169. break;
  1170. }
  1171. case GPBTypeData: {
  1172. NSData *v = (isRepeated ? [(NSArray *)array objectAtIndex:j]
  1173. : GPBGetDataIvarWithField(message, field));
  1174. AppendBufferAsString(v, toStr);
  1175. break;
  1176. }
  1177. case GPBTypeGroup:
  1178. case GPBTypeMessage: {
  1179. GPBMessage *v =
  1180. (isRepeated ? [(NSArray *)array objectAtIndex:j]
  1181. : GPBGetObjectIvarWithField(message, field));
  1182. [toStr appendFormat:@"{%@\n", lineEnding];
  1183. NSString *subIndent = [lineIndent stringByAppendingString:@" "];
  1184. AppendTextFormatForMessage(v, toStr, subIndent);
  1185. [toStr appendFormat:@"%@}", lineIndent];
  1186. lineEnding = @"";
  1187. break;
  1188. }
  1189. } // switch(fieldDataType)
  1190. // End the line.
  1191. [toStr appendFormat:@"%@\n", lineEnding];
  1192. } // for(count)
  1193. }
  1194. static void AppendTextFormatForMessageExtensionRange(GPBMessage *message,
  1195. NSArray *activeExtensions,
  1196. GPBExtensionRange range,
  1197. NSMutableString *toStr,
  1198. NSString *lineIndent) {
  1199. uint32_t start = range.start;
  1200. uint32_t end = range.end;
  1201. for (GPBExtensionField *extension in activeExtensions) {
  1202. uint32_t fieldNumber = extension.fieldNumber;
  1203. if (fieldNumber < start) {
  1204. // Not there yet.
  1205. continue;
  1206. }
  1207. if (fieldNumber > end) {
  1208. // Done.
  1209. break;
  1210. }
  1211. id rawExtValue = [message getExtension:extension];
  1212. GPBExtensionDescriptor *extDescriptor = [extension descriptor];
  1213. BOOL isRepeated = extDescriptor.isRepeated;
  1214. NSUInteger numValues = 1;
  1215. NSString *lineEnding = @"";
  1216. if (isRepeated) {
  1217. numValues = [(NSArray *)rawExtValue count];
  1218. }
  1219. NSString *singletonName = extension.descriptor.singletonName;
  1220. if (numValues == 1) {
  1221. lineEnding = [NSString stringWithFormat:@" # [%@]", singletonName];
  1222. } else {
  1223. [toStr appendFormat:@"%@# [%@]\n", lineIndent, singletonName];
  1224. }
  1225. GPBType extType = extDescriptor.type;
  1226. for (NSUInteger j = 0; j < numValues; ++j) {
  1227. id curValue = (isRepeated ? [rawExtValue objectAtIndex:j] : rawExtValue);
  1228. // Start the line.
  1229. [toStr appendFormat:@"%@%u%s ", lineIndent, fieldNumber,
  1230. (GPBTypeIsMessage(extType) ? "" : ":")];
  1231. // The value.
  1232. switch (extType) {
  1233. #define FIELD_CASE(GPBTYPE, CTYPE, NUMSELECTOR, ...) \
  1234. case GPBType##GPBTYPE: { \
  1235. CTYPE v = [(NSNumber *)curValue NUMSELECTOR]; \
  1236. [toStr appendFormat:__VA_ARGS__, v]; \
  1237. break; \
  1238. }
  1239. FIELD_CASE(Int32, int32_t, intValue, @"%d")
  1240. FIELD_CASE(SInt32, int32_t, intValue, @"%d")
  1241. FIELD_CASE(SFixed32, int32_t, unsignedIntValue, @"%d")
  1242. FIELD_CASE(UInt32, uint32_t, unsignedIntValue, @"%u")
  1243. FIELD_CASE(Fixed32, uint32_t, unsignedIntValue, @"%u")
  1244. FIELD_CASE(Int64, int64_t, longLongValue, @"%lld")
  1245. FIELD_CASE(SInt64, int64_t, longLongValue, @"%lld")
  1246. FIELD_CASE(SFixed64, int64_t, longLongValue, @"%lld")
  1247. FIELD_CASE(UInt64, uint64_t, unsignedLongLongValue, @"%llu")
  1248. FIELD_CASE(Fixed64, uint64_t, unsignedLongLongValue, @"%llu")
  1249. FIELD_CASE(Float, float, floatValue, @"%.*g", FLT_DIG)
  1250. FIELD_CASE(Double, double, doubleValue, @"%.*lg", DBL_DIG)
  1251. // TODO: Add a comment with the enum name from enum descriptors
  1252. // (might not be real value, so leave it as a comment, ObjC compiler
  1253. // name mangles differently). Doesn't look like we actually generate
  1254. // an enum descriptor reference like we do for normal fields, so this
  1255. // will take a compiler change.
  1256. FIELD_CASE(Enum, int32_t, intValue, @"%d")
  1257. #undef FIELD_CASE
  1258. case GPBTypeBool:
  1259. [toStr appendString:([(NSNumber *)curValue boolValue] ? @"true"
  1260. : @"false")];
  1261. break;
  1262. case GPBTypeString:
  1263. AppendStringEscaped(curValue, toStr);
  1264. break;
  1265. case GPBTypeData:
  1266. AppendBufferAsString((NSData *)curValue, toStr);
  1267. break;
  1268. case GPBTypeGroup:
  1269. case GPBTypeMessage: {
  1270. [toStr appendFormat:@"{%@\n", lineEnding];
  1271. NSString *subIndent = [lineIndent stringByAppendingString:@" "];
  1272. AppendTextFormatForMessage(curValue, toStr, subIndent);
  1273. [toStr appendFormat:@"%@}", lineIndent];
  1274. lineEnding = @"";
  1275. break;
  1276. }
  1277. } // switch(extType)
  1278. } // for(numValues)
  1279. // End the line.
  1280. [toStr appendFormat:@"%@\n", lineEnding];
  1281. } // for..in(activeExtensions)
  1282. }
  1283. static void AppendTextFormatForMessage(GPBMessage *message,
  1284. NSMutableString *toStr,
  1285. NSString *lineIndent) {
  1286. GPBDescriptor *descriptor = [message descriptor];
  1287. NSArray *fieldsArray = descriptor->fields_;
  1288. NSUInteger fieldCount = fieldsArray.count;
  1289. const GPBExtensionRange *extensionRanges = descriptor.extensionRanges;
  1290. NSUInteger extensionRangesCount = descriptor.extensionRangesCount;
  1291. NSArray *activeExtensions = [message sortedExtensionsInUse];
  1292. for (NSUInteger i = 0, j = 0; i < fieldCount || j < extensionRangesCount;) {
  1293. if (i == fieldCount) {
  1294. AppendTextFormatForMessageExtensionRange(
  1295. message, activeExtensions, extensionRanges[j++], toStr, lineIndent);
  1296. } else if (j == extensionRangesCount ||
  1297. GPBFieldNumber(fieldsArray[i]) < extensionRanges[j].start) {
  1298. AppendTextFormatForMessageField(message, fieldsArray[i++], toStr,
  1299. lineIndent);
  1300. } else {
  1301. AppendTextFormatForMessageExtensionRange(
  1302. message, activeExtensions, extensionRanges[j++], toStr, lineIndent);
  1303. }
  1304. }
  1305. NSString *unknownFieldsStr =
  1306. GPBTextFormatForUnknownFieldSet(message.unknownFields, lineIndent);
  1307. if ([unknownFieldsStr length] > 0) {
  1308. [toStr appendFormat:@"%@# --- Unknown fields ---\n", lineIndent];
  1309. [toStr appendString:unknownFieldsStr];
  1310. }
  1311. }
  1312. NSString *GPBTextFormatForMessage(GPBMessage *message, NSString *lineIndent) {
  1313. if (message == nil) return nil;
  1314. if (lineIndent == nil) lineIndent = @"";
  1315. NSMutableString *buildString = [NSMutableString string];
  1316. AppendTextFormatForMessage(message, buildString, lineIndent);
  1317. return buildString;
  1318. }
  1319. NSString *GPBTextFormatForUnknownFieldSet(GPBUnknownFieldSet *unknownSet,
  1320. NSString *lineIndent) {
  1321. if (unknownSet == nil) return nil;
  1322. if (lineIndent == nil) lineIndent = @"";
  1323. NSMutableString *result = [NSMutableString string];
  1324. for (GPBField *field in [unknownSet sortedFields]) {
  1325. int32_t fieldNumber = [field number];
  1326. #define PRINT_LOOP(PROPNAME, CTYPE, FORMAT) \
  1327. [field.PROPNAME \
  1328. enumerateValuesWithBlock:^(CTYPE value, NSUInteger idx, BOOL * stop) { \
  1329. _Pragma("unused(idx, stop)"); \
  1330. [result \
  1331. appendFormat:@"%@%d: " #FORMAT "\n", lineIndent, fieldNumber, value]; \
  1332. }];
  1333. PRINT_LOOP(varintList, uint64_t, %llu);
  1334. PRINT_LOOP(fixed32List, uint32_t, 0x%X);
  1335. PRINT_LOOP(fixed64List, uint64_t, 0x%llX);
  1336. #undef PRINT_LOOP
  1337. // NOTE: C++ version of TextFormat tries to parse this as a message
  1338. // and print that if it succeeds.
  1339. for (NSData *data in field.lengthDelimitedList) {
  1340. [result appendFormat:@"%@%d: ", lineIndent, fieldNumber];
  1341. AppendBufferAsString(data, result);
  1342. [result appendString:@"\n"];
  1343. }
  1344. for (GPBUnknownFieldSet *subUnknownSet in field.groupList) {
  1345. [result appendFormat:@"%@%d: {\n", lineIndent, fieldNumber];
  1346. NSString *subIndent = [lineIndent stringByAppendingString:@" "];
  1347. NSString *subUnknwonSetStr =
  1348. GPBTextFormatForUnknownFieldSet(subUnknownSet, subIndent);
  1349. [result appendString:subUnknwonSetStr];
  1350. [result appendFormat:@"%@}\n", lineIndent];
  1351. }
  1352. }
  1353. return result;
  1354. }
  1355. // Helpers to decode a varint. Not using GPBCodedInputStream version because
  1356. // that needs a state object, and we don't want to create an input stream out
  1357. // of the data.
  1358. static inline int8_t ReadRawByteFromData(const uint8_t **data) {
  1359. int8_t result = *((int8_t *)(*data));
  1360. ++(*data);
  1361. return result;
  1362. }
  1363. static inline int32_t ReadRawVarint32FromData(const uint8_t **data) {
  1364. int8_t tmp = ReadRawByteFromData(data);
  1365. if (tmp >= 0) {
  1366. return tmp;
  1367. }
  1368. int32_t result = tmp & 0x7f;
  1369. if ((tmp = ReadRawByteFromData(data)) >= 0) {
  1370. result |= tmp << 7;
  1371. } else {
  1372. result |= (tmp & 0x7f) << 7;
  1373. if ((tmp = ReadRawByteFromData(data)) >= 0) {
  1374. result |= tmp << 14;
  1375. } else {
  1376. result |= (tmp & 0x7f) << 14;
  1377. if ((tmp = ReadRawByteFromData(data)) >= 0) {
  1378. result |= tmp << 21;
  1379. } else {
  1380. result |= (tmp & 0x7f) << 21;
  1381. result |= (tmp = ReadRawByteFromData(data)) << 28;
  1382. if (tmp < 0) {
  1383. // Discard upper 32 bits.
  1384. for (int i = 0; i < 5; i++) {
  1385. if (ReadRawByteFromData(data) >= 0) {
  1386. return result;
  1387. }
  1388. }
  1389. [NSException raise:NSParseErrorException
  1390. format:@"Unable to read varint32"];
  1391. }
  1392. }
  1393. }
  1394. }
  1395. return result;
  1396. }
  1397. NSString *GPBDecodeTextFormatName(const uint8_t *decodeData, int32_t key,
  1398. NSString *inputStr) {
  1399. // decodData form:
  1400. // varint32: num entries
  1401. // for each entry:
  1402. // varint32: key
  1403. // bytes*: decode data
  1404. //
  1405. // decode data one of two forms:
  1406. // 1: a \0 followed by the string followed by an \0
  1407. // 2: bytecodes to transform an input into the right thing, ending with \0
  1408. //
  1409. // the bytes codes are of the form:
  1410. // 0xabbccccc
  1411. // 0x0 (all zeros), end.
  1412. // a - if set, add an underscore
  1413. // bb - 00 ccccc bytes as is
  1414. // bb - 10 ccccc upper first, as is on rest, ccccc byte total
  1415. // bb - 01 ccccc lower first, as is on rest, ccccc byte total
  1416. // bb - 11 ccccc all upper, ccccc byte total
  1417. if (!decodeData || !inputStr) {
  1418. return nil;
  1419. }
  1420. // Find key
  1421. const uint8_t *scan = decodeData;
  1422. int32_t numEntries = ReadRawVarint32FromData(&scan);
  1423. BOOL foundKey = NO;
  1424. while (!foundKey && (numEntries > 0)) {
  1425. --numEntries;
  1426. int32_t dataKey = ReadRawVarint32FromData(&scan);
  1427. if (dataKey == key) {
  1428. foundKey = YES;
  1429. } else {
  1430. // If it is a inlined string, it will start with \0; if it is bytecode it
  1431. // will start with a code. So advance one (skipping the inline string
  1432. // marker), and then loop until reaching the end marker (\0).
  1433. ++scan;
  1434. while (*scan != 0) ++scan;
  1435. // Now move past the end marker.
  1436. ++scan;
  1437. }
  1438. }
  1439. if (!foundKey) {
  1440. return nil;
  1441. }
  1442. // Decode
  1443. if (*scan == 0) {
  1444. // Inline string. Move over the marker, and NSString can take it as
  1445. // UTF8.
  1446. ++scan;
  1447. NSString *result = [NSString stringWithUTF8String:(const char *)scan];
  1448. return result;
  1449. }
  1450. NSMutableString *result =
  1451. [NSMutableString stringWithCapacity:[inputStr length]];
  1452. const uint8_t kAddUnderscore = 0b10000000;
  1453. const uint8_t kOpMask = 0b01100000;
  1454. // const uint8_t kOpAsIs = 0b00000000;
  1455. const uint8_t kOpFirstUpper = 0b01000000;
  1456. const uint8_t kOpFirstLower = 0b00100000;
  1457. const uint8_t kOpAllUpper = 0b01100000;
  1458. const uint8_t kSegmentLenMask = 0b00011111;
  1459. NSInteger i = 0;
  1460. for (; *scan != 0; ++scan) {
  1461. if (*scan & kAddUnderscore) {
  1462. [result appendString:@"_"];
  1463. }
  1464. int segmentLen = *scan & kSegmentLenMask;
  1465. uint8_t decodeOp = *scan & kOpMask;
  1466. // Do op specific handling of the first character.
  1467. if (decodeOp == kOpFirstUpper) {
  1468. unichar c = [inputStr characterAtIndex:i];
  1469. [result appendFormat:@"%c", toupper((char)c)];
  1470. ++i;
  1471. --segmentLen;
  1472. } else if (decodeOp == kOpFirstLower) {
  1473. unichar c = [inputStr characterAtIndex:i];
  1474. [result appendFormat:@"%c", tolower((char)c)];
  1475. ++i;
  1476. --segmentLen;
  1477. }
  1478. // else op == kOpAsIs || op == kOpAllUpper
  1479. // Now pull over the rest of the length for this segment.
  1480. for (int x = 0; x < segmentLen; ++x) {
  1481. unichar c = [inputStr characterAtIndex:(i + x)];
  1482. if (decodeOp == kOpAllUpper) {
  1483. [result appendFormat:@"%c", toupper((char)c)];
  1484. } else {
  1485. [result appendFormat:@"%C", c];
  1486. }
  1487. }
  1488. i += segmentLen;
  1489. }
  1490. return result;
  1491. }
  1492. #pragma mark - GPBMessageSignatureProtocol
  1493. // A series of selectors that are used solely to get @encoding values
  1494. // for them by the dynamic protobuf runtime code. An object using the protocol
  1495. // needs to be declared for the protocol to be valid at runtime.
  1496. @interface GPBMessageSignatureProtocol : NSObject<GPBMessageSignatureProtocol>
  1497. @end
  1498. @implementation GPBMessageSignatureProtocol
  1499. @end