/Telegraph/PSKeyValueDecoder.m

https://gitlab.com/iranjith4/Telegram · Objective C · 599 lines · 481 code · 118 blank · 0 comment · 77 complexity · d7d9a6dce13cd72f2cadbfbfc61cb719 MD5 · raw file

  1. #import "PSKeyValueDecoder.h"
  2. #import <objc/runtime.h>
  3. @interface PSKeyValueDecoder ()
  4. {
  5. NSData *_data;
  6. @public
  7. uint8_t const *_currentPtr;
  8. uint8_t const *_begin;
  9. uint8_t const *_end;
  10. PSKeyValueDecoder *_tempCoder;
  11. }
  12. @end
  13. static uint32_t readLength(uint8_t const **currentPtr)
  14. {
  15. uint32_t result = 0;
  16. result |= (*(*currentPtr)) & 127;
  17. if ((*(*currentPtr)) & 128)
  18. {
  19. (*currentPtr)++;
  20. result |= ((*(*currentPtr)) & 127) << (7 * 1);
  21. if ((*(*currentPtr)) & 128)
  22. {
  23. (*currentPtr)++;
  24. result |= ((*(*currentPtr)) & 127) << (7 * 2);
  25. if ((*(*currentPtr)) & 128)
  26. {
  27. (*currentPtr)++;
  28. result |= ((*(*currentPtr)) & 127) << (7 * 3);
  29. if ((*(*currentPtr)) & 128)
  30. {
  31. (*currentPtr)++;
  32. result |= ((*(*currentPtr)) & 127) << (7 * 4);
  33. }
  34. }
  35. }
  36. }
  37. (*currentPtr)++;
  38. return result;
  39. }
  40. static NSString *readString(uint8_t const **currentPtr)
  41. {
  42. uint32_t stringLength = readLength(currentPtr);
  43. NSString *string = [[NSString alloc] initWithBytes:*currentPtr length:stringLength encoding:NSUTF8StringEncoding];
  44. (*currentPtr) += stringLength;
  45. return string;
  46. }
  47. static void skipString(uint8_t const **currentPtr)
  48. {
  49. uint32_t stringLength = readLength(currentPtr);
  50. (*currentPtr) += stringLength;
  51. }
  52. static int32_t readInt32(uint8_t const **currentPtr)
  53. {
  54. int32_t number = *((int32_t *)(*currentPtr));
  55. (*currentPtr) += 4;
  56. return number;
  57. }
  58. static void skipInt32(uint8_t const **currentPtr)
  59. {
  60. (*currentPtr) += 4;
  61. }
  62. static int64_t readInt64(uint8_t const **currentPtr)
  63. {
  64. int64_t number;
  65. memcpy(&number, *currentPtr, 8);
  66. (*currentPtr) += 8;
  67. return number;
  68. }
  69. static void skipInt64(uint8_t const **currentPtr)
  70. {
  71. (*currentPtr) += 8;
  72. }
  73. static id<PSCoding> readObject(uint8_t const **currentPtr, PSKeyValueDecoder *tempCoder)
  74. {
  75. uint32_t objectLength = *((uint32_t *)(*currentPtr));
  76. (*currentPtr) += 4;
  77. uint8_t const *objectEnd = (*currentPtr) + objectLength;
  78. const char *className = (const char *)(*currentPtr);
  79. NSUInteger classNameLength = strlen(className) + 1;
  80. (*currentPtr) += classNameLength;
  81. id<PSCoding> object = nil;
  82. Class<PSCoding> objectClass = objc_getClass(className);
  83. if (objectClass != nil)
  84. {
  85. tempCoder->_begin = *currentPtr;
  86. tempCoder->_end = objectEnd;
  87. tempCoder->_currentPtr = tempCoder->_begin;
  88. object = [(id<PSCoding>)[(id)objectClass alloc] initWithKeyValueCoder:tempCoder];
  89. }
  90. *currentPtr = objectEnd;
  91. return object;
  92. }
  93. static void skipObject(uint8_t const **currentPtr)
  94. {
  95. uint32_t objectLength = *((uint32_t *)currentPtr);
  96. (*currentPtr) += 4 + objectLength;
  97. }
  98. static NSArray *readArray(uint8_t const **currentPtr, PSKeyValueDecoder *tempCoder)
  99. {
  100. uint32_t objectLength = *((uint32_t *)(*currentPtr));
  101. (*currentPtr) += 4;
  102. uint8_t const *objectEnd = (*currentPtr) + objectLength;
  103. uint32_t count = readLength(currentPtr);
  104. NSMutableArray *array = [[NSMutableArray alloc] initWithCapacity:count];
  105. for (uint32_t i = 0; i < count; i++)
  106. {
  107. id<PSCoding> object = readObject(currentPtr, tempCoder);
  108. if (object != nil)
  109. [array addObject:object];
  110. }
  111. *currentPtr = objectEnd;
  112. return array;
  113. }
  114. static void skipArray(uint8_t const **currentPtr)
  115. {
  116. uint32_t objectLength = *((uint32_t *)currentPtr);
  117. (*currentPtr) += 4 + objectLength;
  118. }
  119. static NSData *readData(uint8_t const **currentPtr)
  120. {
  121. uint32_t length = readLength(currentPtr);
  122. NSData *data = [[NSData alloc] initWithBytes:*currentPtr length:length];
  123. *currentPtr += length;
  124. return data;
  125. }
  126. static void readBytes(uint8_t const **currentPtr, uint8_t *value, NSUInteger maxLength)
  127. {
  128. uint32_t length = readLength(currentPtr);
  129. memcpy(value, *currentPtr, MIN((uint32_t)maxLength, length));
  130. *currentPtr += length;
  131. }
  132. static void skipData(uint8_t const **currentPtr)
  133. {
  134. uint32_t length = readLength(currentPtr);
  135. (*currentPtr) += length;
  136. }
  137. static void skipField(uint8_t const **currentPtr)
  138. {
  139. uint8_t fieldType = *(*currentPtr);
  140. (*currentPtr)++;
  141. switch (fieldType)
  142. {
  143. case PSKeyValueCoderFieldTypeString:
  144. {
  145. skipString(currentPtr);
  146. break;
  147. }
  148. case PSKeyValueCoderFieldTypeInt32:
  149. {
  150. skipInt32(currentPtr);
  151. break;
  152. }
  153. case PSKeyValueCoderFieldTypeInt64:
  154. {
  155. skipInt64(currentPtr);
  156. break;
  157. }
  158. case PSKeyValueCoderFieldTypeCustomClass:
  159. {
  160. skipObject(currentPtr);
  161. break;
  162. }
  163. case PSKeyValueCoderFieldTypeArray:
  164. {
  165. skipArray(currentPtr);
  166. break;
  167. }
  168. case PSKeyValueCoderFieldTypeData:
  169. {
  170. skipData(currentPtr);
  171. break;
  172. }
  173. default:
  174. break;
  175. }
  176. }
  177. @implementation PSKeyValueDecoder
  178. - (instancetype)init
  179. {
  180. self = [super init];
  181. if (self != nil)
  182. {
  183. }
  184. return self;
  185. }
  186. - (instancetype)initWithData:(NSData *)data
  187. {
  188. self = [super init];
  189. if (self != nil)
  190. {
  191. _data = data;
  192. _begin = (uint8_t const *)[_data bytes];
  193. _end = _begin + [_data length];
  194. _currentPtr = _begin;
  195. }
  196. return self;
  197. }
  198. - (void)resetData:(NSData *)data
  199. {
  200. _data = data;
  201. _begin = (uint8_t const *)[_data bytes];
  202. _end = _begin + [_data length];
  203. _currentPtr = _begin;
  204. }
  205. - (void)resetBytes:(uint8_t const *)bytes length:(NSUInteger)length
  206. {
  207. _data = nil;
  208. _begin = bytes;
  209. _end = _begin + length;
  210. _currentPtr = _begin;
  211. }
  212. - (void)rewind {
  213. _begin = (uint8_t const *)[_data bytes];
  214. _end = _begin + [_data length];
  215. _currentPtr = _begin;
  216. }
  217. static bool skipToValueForRawKey(PSKeyValueDecoder *self, uint8_t const *key, NSUInteger keyLength)
  218. {
  219. uint8_t const *middlePtr = self->_currentPtr;
  220. for (int i = 0; i < 2; i++)
  221. {
  222. uint8_t const *scanEnd = self->_end;
  223. if (i == 1)
  224. {
  225. self->_currentPtr = self->_begin;
  226. scanEnd = middlePtr;
  227. }
  228. while (self->_currentPtr < scanEnd)
  229. {
  230. uint32_t compareKeyLength = readLength(&self->_currentPtr);
  231. if (compareKeyLength != keyLength || memcmp(key, self->_currentPtr, keyLength))
  232. {
  233. self->_currentPtr += compareKeyLength;
  234. skipField(&self->_currentPtr);
  235. continue;
  236. }
  237. self->_currentPtr += compareKeyLength;
  238. return true;
  239. }
  240. }
  241. return false;
  242. }
  243. static NSString *decodeStringForRawKey(PSKeyValueDecoder *self, uint8_t const *key, NSUInteger keyLength)
  244. {
  245. if (skipToValueForRawKey(self, key, keyLength))
  246. {
  247. uint8_t fieldType = *self->_currentPtr;
  248. self->_currentPtr++;
  249. if (fieldType == PSKeyValueCoderFieldTypeString)
  250. return readString(&self->_currentPtr);
  251. else if (fieldType == PSKeyValueCoderFieldTypeInt32)
  252. return [[NSString alloc] initWithFormat:@"%" PRId32 "", readInt32(&self->_currentPtr)];
  253. else if (fieldType == PSKeyValueCoderFieldTypeInt64)
  254. return [[NSString alloc] initWithFormat:@"%" PRId64 "", readInt64(&self->_currentPtr)];
  255. else
  256. {
  257. skipField(&self->_currentPtr);
  258. return nil;
  259. }
  260. }
  261. return nil;
  262. }
  263. - (NSString *)decodeStringForKey:(NSString *)key
  264. {
  265. NSData *keyData = [key dataUsingEncoding:NSUTF8StringEncoding];
  266. return decodeStringForRawKey(self, (uint8_t const *)[keyData bytes], [keyData length]);
  267. }
  268. - (NSString *)decodeStringForCKey:(const char *)key
  269. {
  270. return decodeStringForRawKey(self, (uint8_t const *)key, (NSUInteger)strlen(key));
  271. }
  272. static int32_t decodeInt32ForRawKey(PSKeyValueDecoder *self, uint8_t const *key, NSUInteger keyLength)
  273. {
  274. if (skipToValueForRawKey(self, key, keyLength))
  275. {
  276. uint8_t fieldType = *self->_currentPtr;
  277. self->_currentPtr++;
  278. if (fieldType == PSKeyValueCoderFieldTypeString)
  279. return (int32_t)[readString(&self->_currentPtr) intValue];
  280. else if (fieldType == PSKeyValueCoderFieldTypeInt32)
  281. return readInt32(&self->_currentPtr);
  282. else if (fieldType == PSKeyValueCoderFieldTypeInt64)
  283. return (int32_t)readInt64(&self->_currentPtr);
  284. else
  285. {
  286. skipField(&self->_currentPtr);
  287. return 0;
  288. }
  289. }
  290. return 0;
  291. }
  292. - (int32_t)decodeInt32ForKey:(NSString *)key
  293. {
  294. NSData *keyData = [key dataUsingEncoding:NSUTF8StringEncoding];
  295. return decodeInt32ForRawKey(self, (uint8_t const *)[keyData bytes], [keyData length]);
  296. }
  297. - (int32_t)decodeInt32ForCKey:(const char *)key
  298. {
  299. return decodeInt32ForRawKey(self, (uint8_t const *)key, strlen(key));
  300. }
  301. static int64_t decodeInt64ForRawKey(PSKeyValueDecoder *self, uint8_t const *key, NSUInteger keyLength)
  302. {
  303. if (skipToValueForRawKey(self, key, keyLength))
  304. {
  305. uint8_t fieldType = *self->_currentPtr;
  306. self->_currentPtr++;
  307. if (fieldType == PSKeyValueCoderFieldTypeString)
  308. return (int64_t)[readString(&self->_currentPtr) longLongValue];
  309. else if (fieldType == PSKeyValueCoderFieldTypeInt32)
  310. return readInt32(&self->_currentPtr);
  311. else if (fieldType == PSKeyValueCoderFieldTypeInt64)
  312. return readInt64(&self->_currentPtr);
  313. else
  314. {
  315. skipField(&self->_currentPtr);
  316. return 0;
  317. }
  318. }
  319. return 0;
  320. }
  321. - (int64_t)decodeInt64ForKey:(NSString *)key
  322. {
  323. NSData *keyData = [key dataUsingEncoding:NSUTF8StringEncoding];
  324. return decodeInt64ForRawKey(self, (uint8_t const *)[keyData bytes], [keyData length]);
  325. }
  326. - (int64_t)decodeInt64ForCKey:(const char *)key
  327. {
  328. return decodeInt64ForRawKey(self, (uint8_t const *)key, strlen(key));
  329. }
  330. static id<PSCoding> decodeObjectForRawKey(PSKeyValueDecoder *self, uint8_t const *key, NSUInteger keyLength)
  331. {
  332. if (skipToValueForRawKey(self, key, keyLength))
  333. {
  334. uint8_t fieldType = *self->_currentPtr;
  335. self->_currentPtr++;
  336. if (fieldType == PSKeyValueCoderFieldTypeCustomClass)
  337. {
  338. if (self->_tempCoder == nil)
  339. self->_tempCoder = [[PSKeyValueDecoder alloc] init];
  340. return readObject(&self->_currentPtr, self->_tempCoder);
  341. }
  342. else
  343. {
  344. skipField(&self->_currentPtr);
  345. return nil;
  346. }
  347. }
  348. return nil;
  349. }
  350. - (id<PSCoding>)decodeObjectForKey:(NSString *)key
  351. {
  352. NSData *keyData = [key dataUsingEncoding:NSUTF8StringEncoding];
  353. return decodeObjectForRawKey(self, (uint8_t const *)[keyData bytes], [keyData length]);
  354. }
  355. - (id<PSCoding>)decodeObjectForCKey:(const char *)key
  356. {
  357. return decodeObjectForRawKey(self, (uint8_t const *)key, strlen(key));
  358. }
  359. static NSArray *decodeArrayForRawKey(PSKeyValueDecoder *self, uint8_t const *key, NSUInteger keyLength)
  360. {
  361. if (skipToValueForRawKey(self, key, keyLength))
  362. {
  363. uint8_t fieldType = *self->_currentPtr;
  364. self->_currentPtr++;
  365. if (fieldType == PSKeyValueCoderFieldTypeArray)
  366. {
  367. if (self->_tempCoder == nil)
  368. self->_tempCoder = [[PSKeyValueDecoder alloc] init];
  369. return readArray(&self->_currentPtr, self->_tempCoder);
  370. }
  371. else
  372. {
  373. skipField(&self->_currentPtr);
  374. return nil;
  375. }
  376. }
  377. return nil;
  378. }
  379. - (NSArray *)decodeArrayForKey:(NSString *)key
  380. {
  381. NSData *keyData = [key dataUsingEncoding:NSUTF8StringEncoding];
  382. return decodeArrayForRawKey(self, (uint8_t const *)[keyData bytes], [keyData length]);
  383. }
  384. - (NSArray *)decodeArrayForCKey:(const char *)key
  385. {
  386. return decodeArrayForRawKey(self, (uint8_t const *)key, strlen(key));
  387. }
  388. static NSData *decodeDataForRawKey(PSKeyValueDecoder *self, uint8_t const *key, NSUInteger keyLength)
  389. {
  390. if (skipToValueForRawKey(self, key, keyLength))
  391. {
  392. uint8_t fieldType = *self->_currentPtr;
  393. self->_currentPtr++;
  394. if (fieldType == PSKeyValueCoderFieldTypeData)
  395. {
  396. return readData(&self->_currentPtr);
  397. }
  398. else
  399. {
  400. skipField(&self->_currentPtr);
  401. return nil;
  402. }
  403. }
  404. return nil;
  405. }
  406. static void decodeBytesForRawKey(PSKeyValueDecoder *self, uint8_t const *key, NSUInteger keyLength, uint8_t *value, NSUInteger maxLength)
  407. {
  408. if (skipToValueForRawKey(self, key, keyLength))
  409. {
  410. uint8_t fieldType = *self->_currentPtr;
  411. self->_currentPtr++;
  412. if (fieldType == PSKeyValueCoderFieldTypeData)
  413. {
  414. readBytes(&self->_currentPtr, value, maxLength);
  415. }
  416. else
  417. {
  418. skipField(&self->_currentPtr);
  419. }
  420. }
  421. }
  422. - (NSData *)decodeDataCorCKey:(const char *)key
  423. {
  424. return decodeDataForRawKey(self, (uint8_t const *)key, strlen(key));
  425. }
  426. - (void)decodeBytesForCKey:(const char *)key value:(uint8_t *)value length:(NSUInteger)length
  427. {
  428. decodeBytesForRawKey(self, (uint8_t const *)key, strlen(key), value, length);
  429. }
  430. - (NSDictionary *)decodeObjectsByKeys
  431. {
  432. NSMutableDictionary *dict = [[NSMutableDictionary alloc] init];
  433. if (self->_tempCoder == nil)
  434. self->_tempCoder = [[PSKeyValueDecoder alloc] init];
  435. self->_currentPtr = self->_begin;
  436. while (self->_currentPtr < self->_end)
  437. {
  438. uint32_t keyLength = readLength(&self->_currentPtr);
  439. NSString *key = [[NSString alloc] initWithBytes:self->_currentPtr length:keyLength encoding:NSUTF8StringEncoding];
  440. self->_currentPtr += keyLength;
  441. uint8_t fieldType = *self->_currentPtr;
  442. self->_currentPtr++;
  443. if (fieldType == PSKeyValueCoderFieldTypeCustomClass)
  444. {
  445. id<PSCoding> value = readObject(&self->_currentPtr, self->_tempCoder);
  446. if (value == nil)
  447. continue;
  448. dict[key] = value;
  449. }
  450. else
  451. break;
  452. }
  453. self->_currentPtr = self->_begin;
  454. return dict;
  455. }
  456. - (NSArray *)decodeInt32ArrayForCKey:(const char *)key {
  457. if (skipToValueForRawKey(self, (void *)key, strlen(key))) {
  458. uint8_t fieldType = *self->_currentPtr;
  459. self->_currentPtr++;
  460. if (fieldType == PSKeyValueCoderFieldTypeInt32Array) {
  461. int32_t count = 0;
  462. memcpy(&count, self->_currentPtr, 4);
  463. self->_currentPtr += 4;
  464. NSMutableArray *array = [[NSMutableArray alloc] init];
  465. for (int32_t i = 0; i < count; i++) {
  466. int32_t number = 0;
  467. memcpy(&number, self->_currentPtr, 4);
  468. self->_currentPtr += 4;
  469. [array addObject:@(number)];
  470. }
  471. return array;
  472. } else {
  473. self->_currentPtr--;
  474. skipField(&self->_currentPtr);
  475. return nil;
  476. }
  477. } else {
  478. return nil;
  479. }
  480. }
  481. @end