GPBUtilities.m 60 KB

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