iron_armpack.c 16 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769
  1. #include "iron_armpack.h"
  2. #include <stdlib.h>
  3. #include <stdbool.h>
  4. #include <string.h>
  5. #include "iron_gc.h"
  6. static const int PTR_SIZE = 8;
  7. static uint32_t di; // Decoded index
  8. static uint32_t ei; // Encoded index
  9. static uint32_t bottom; // Decoded bottom
  10. static uint8_t *decoded;
  11. static uint8_t *encoded;
  12. static uint32_t capacity;
  13. static uint32_t array_count;
  14. static uint32_t string_length;
  15. static void read_store();
  16. static inline uint64_t pad(int di, int n) {
  17. return (n - (di % n)) % n;
  18. }
  19. static void store_u8(uint8_t u8) {
  20. *(uint8_t *)(decoded + di) = u8;
  21. di += 1;
  22. }
  23. static void store_i16(int16_t i16) {
  24. di += pad(di, 2);
  25. *(int16_t *)(decoded + di) = i16;
  26. di += 2;
  27. }
  28. static void store_u32(uint32_t u32) {
  29. di += pad(di, 4);
  30. *(uint32_t *)(decoded + di) = u32;
  31. di += 4;
  32. }
  33. static void store_i32(int32_t i32) {
  34. di += pad(di, 4);
  35. *(int32_t *)(decoded + di) = i32;
  36. di += 4;
  37. }
  38. static void store_f32(float f32) {
  39. di += pad(di, 4);
  40. *(float *)(decoded + di) = f32;
  41. di += 4;
  42. }
  43. static void store_ptr(uint32_t ptr) {
  44. di += pad(di, PTR_SIZE);
  45. *(uint64_t *)(decoded + di) = (uint64_t)decoded + (uint64_t)ptr;
  46. di += PTR_SIZE;
  47. }
  48. static void store_ptr_abs(void *ptr) {
  49. di += pad(di, PTR_SIZE);
  50. *(uint64_t *)(decoded + di) = (uint64_t)ptr;
  51. di += PTR_SIZE;
  52. }
  53. static void store_string_bytes(char *str) {
  54. for (int i = 0; i < string_length; ++i) {
  55. store_u8(str[i]);
  56. }
  57. store_u8('\0');
  58. }
  59. static void store_string(char *str) {
  60. // Put string at the bottom and store a pointer to it
  61. store_ptr(bottom);
  62. uint32_t _di = di;
  63. di = bottom;
  64. store_string_bytes(str);
  65. bottom = pad(di, PTR_SIZE) + di;
  66. di = _di;
  67. }
  68. static uint8_t read_u8() {
  69. uint8_t u8 = *(uint8_t *)(encoded + ei);
  70. ei += 1;
  71. return u8;
  72. }
  73. static int16_t read_i16() {
  74. int16_t i16 = *(int16_t *)(encoded + ei);
  75. ei += 2;
  76. return i16;
  77. }
  78. static int32_t read_i32() {
  79. int32_t i32 = *(int32_t *)(encoded + ei);
  80. ei += 4;
  81. return i32;
  82. }
  83. static uint32_t read_u32() {
  84. uint32_t u32 = *(uint32_t *)(encoded + ei);
  85. ei += 4;
  86. return u32;
  87. }
  88. static float read_f32() {
  89. float f32 = *(float *)(encoded + ei);
  90. ei += 4;
  91. return f32;
  92. }
  93. static char *read_string() {
  94. string_length = read_u32();
  95. char *str = (char *)(encoded + ei);
  96. ei += string_length;
  97. return str;
  98. }
  99. static uint32_t traverse(int di, bool count_arrays) {
  100. uint8_t flag = read_u8();
  101. switch (flag) {
  102. case 0xc0: // NULL
  103. return pad(di, PTR_SIZE) + PTR_SIZE;
  104. case 0xc2: // false
  105. return 1;
  106. case 0xc3: // true
  107. return 1;
  108. case 0xca: // f32
  109. ei += 4;
  110. return pad(di, 4) + 4;
  111. case 0xd2: // i32
  112. ei += 4;
  113. return pad(di, 4) + 4;
  114. case 0xdf: { // map
  115. uint32_t len = 0;
  116. int count = read_i32();
  117. for (int i = 0; i < count; ++i) {
  118. read_u8(); // 0xdb string
  119. read_string(); // key
  120. len += traverse(di + len, count_arrays); // value
  121. }
  122. len += pad(di + len, PTR_SIZE) + PTR_SIZE; // void *_
  123. return len;
  124. }
  125. case 0xdd: { // array
  126. uint32_t len = 0;
  127. uint32_t count = read_u32();
  128. uint8_t flag2 = count > 0 ? read_u8() : 0x0;
  129. switch (flag2) {
  130. case 0x0: // Empty array
  131. break;
  132. case 0xca: // Typed f32
  133. ei += 4 * count;
  134. len += 4 * count;
  135. break;
  136. case 0xd2: // Typed i32
  137. ei += 4 * count;
  138. len += 4 * count;
  139. break;
  140. case 0xd1: // Typed i16
  141. ei += 2 * count;
  142. len += 2 * count;
  143. break;
  144. case 0xc4: // Typed u8
  145. ei += count;
  146. len += count;
  147. break;
  148. case 0xc2: // Bool array
  149. ei -= 1;
  150. ei += count;
  151. len += count;
  152. break;
  153. case 0xc3: // Bool array
  154. ei -= 1;
  155. ei += count;
  156. len += count;
  157. break;
  158. default: // Dynamic (type (array / map / string) - value)
  159. ei -= 1; // Undo flag2 read
  160. for (uint32_t j = 0; j < count; ++j) {
  161. len += traverse(0, count_arrays);
  162. }
  163. }
  164. len += 32; // buffer ptr, length, capacity + align?
  165. if (!count_arrays) {
  166. len = 0;
  167. }
  168. // ptr (to array_t)
  169. len += pad(di, PTR_SIZE) + PTR_SIZE;
  170. return len;
  171. }
  172. case 0xdb: { // string
  173. uint32_t len = read_u32(); // string_length
  174. ei += len;
  175. len += 1; // '\0'
  176. if (!count_arrays) {
  177. len = 0;
  178. }
  179. len += pad(di, PTR_SIZE) + PTR_SIZE;
  180. return len;
  181. }
  182. default:
  183. return 0;
  184. }
  185. }
  186. static uint32_t get_struct_length() {
  187. uint32_t _ei = ei;
  188. uint32_t len = traverse(0, false);
  189. ei = _ei;
  190. return len;
  191. }
  192. static void read_store_map(uint32_t count) {
  193. ei -= 5; // u8 map, i32 count
  194. uint32_t size = get_struct_length();
  195. size += pad(size, PTR_SIZE);
  196. bottom += size * array_count;
  197. array_count = 0;
  198. ei += 5;
  199. for (uint32_t i = 0; i < count; ++i) {
  200. read_u8(); // 0xdb string
  201. read_string(); // key
  202. read_store(); // value
  203. }
  204. di += pad(di, PTR_SIZE);
  205. di += PTR_SIZE; // void *_ for runtime storage
  206. }
  207. static bool is_typed_array(uint8_t flag) {
  208. return flag == 0xca || flag == 0xd2 || flag == 0xd1 || flag == 0xc4 || flag == 0xc2 || flag == 0xc3;
  209. }
  210. static uint8_t flag_to_byte_size(uint8_t flag) {
  211. if (flag == 0xca) return 4; // f32
  212. if (flag == 0xd2) return 4; // i32
  213. if (flag == 0xd1) return 2; // i16
  214. if (flag == 0xc4) return 1; // u8
  215. if (flag == 0xc2) return 1; // u8 (true)
  216. if (flag == 0xc3) return 1; // u8 (false)
  217. return 0;
  218. }
  219. static void store_typed_array(uint8_t flag, uint32_t count) {
  220. uint32_t size = flag_to_byte_size(flag) * count;
  221. memcpy(decoded + di, encoded + ei, size);
  222. if (size > 4096) {
  223. gc_cut(decoded, di, size);
  224. }
  225. ei += size;
  226. di += size;
  227. }
  228. static void read_store_array(uint32_t count) { // Store in any/i32/../_array_t format
  229. // Store pointer to array_t struct
  230. // Put array contents at the bottom
  231. // - pointer to array_t buffer
  232. // - element count
  233. // - capacity (same as count)
  234. // - buffer
  235. store_ptr(bottom);
  236. uint32_t _di = di;
  237. di = bottom;
  238. if (count > 0) {
  239. store_ptr(di + PTR_SIZE + 4 + 4); // Pointer to buffer contents
  240. }
  241. else {
  242. store_ptr_abs(NULL);
  243. }
  244. store_u32(count); // Element count
  245. store_u32(0); // Capacity = 0 -> do not free on first realloc
  246. bottom = di;
  247. if (count == 0) {
  248. di = _di;
  249. return;
  250. }
  251. uint8_t flag = read_u8();
  252. if (is_typed_array(flag)) {
  253. if (flag == 0xc2 || flag == 0xc3) {
  254. ei--; // Bool array
  255. }
  256. store_typed_array(flag, count);
  257. bottom = pad(di, PTR_SIZE) + di;
  258. }
  259. // Dynamic (type (array / map / string) - value)
  260. else {
  261. ei -= 1; // Undo flag read
  262. // Strings
  263. if (flag == 0xdb) {
  264. // String pointers
  265. uint32_t _ei = ei;
  266. uint32_t strings_length = 0;
  267. for (uint32_t i = 0; i < count; ++i) {
  268. store_ptr(bottom + count * PTR_SIZE + strings_length);
  269. if (i < count - 1) {
  270. ei += 1; // String flag
  271. uint32_t length = read_u32(); // String length
  272. ei += length;
  273. strings_length += length;
  274. strings_length += 1; // '\0'
  275. }
  276. }
  277. ei = _ei;
  278. // String bytes
  279. for (uint32_t i = 0; i < count; ++i) {
  280. ei += 1; // String flag
  281. store_string_bytes(read_string());
  282. }
  283. bottom = pad(di, PTR_SIZE) + di;
  284. }
  285. // Arrays
  286. else if (flag == 0xdd) {
  287. // Array pointers
  288. uint32_t _ei = ei;
  289. uint32_t arrays_length = 0;
  290. for (uint32_t i = 0; i < count; ++i) {
  291. store_ptr(bottom + count * PTR_SIZE + arrays_length);
  292. if (i < count - 1) {
  293. ei += 1; // Array flag
  294. uint32_t length = read_u32(); // Array length
  295. ei += length;
  296. length += pad(length, PTR_SIZE);
  297. arrays_length += length;
  298. arrays_length += 8 + 8 + 4 + 4;
  299. }
  300. }
  301. ei = _ei;
  302. // Array contents
  303. bottom = pad(di, PTR_SIZE) + di;
  304. array_count = count;
  305. for (uint32_t i = 0; i < count; ++i) {
  306. uint8_t flag = read_u8();
  307. read_store_array(read_i32());
  308. }
  309. }
  310. // Structs
  311. else {
  312. uint32_t size = get_struct_length();
  313. size += pad(size, PTR_SIZE);
  314. // Struct pointers
  315. for (uint32_t i = 0; i < count; ++i) {
  316. store_ptr(bottom + count * PTR_SIZE + i * size);
  317. }
  318. // Struct contents
  319. bottom = pad(di, PTR_SIZE) + di;
  320. array_count = count;
  321. for (uint32_t i = 0; i < count; ++i) {
  322. di = pad(di, PTR_SIZE) + di;
  323. uint8_t flag = read_u8();
  324. read_store_map(read_i32());
  325. }
  326. }
  327. }
  328. di = _di;
  329. }
  330. static void read_store() {
  331. uint8_t flag = read_u8();
  332. switch (flag) {
  333. case 0xc0:
  334. store_ptr_abs(NULL);
  335. break;
  336. case 0xc2:
  337. store_u8(false);
  338. break;
  339. case 0xc3:
  340. store_u8(true);
  341. break;
  342. case 0xca:
  343. store_f32(read_f32());
  344. break;
  345. case 0xd2:
  346. store_i32(read_i32());
  347. break;
  348. case 0xdf: {
  349. array_count = 1;
  350. read_store_map(read_i32());
  351. break;
  352. }
  353. case 0xdd:
  354. read_store_array(read_i32());
  355. break;
  356. case 0xdb:
  357. store_string(read_string());
  358. break;
  359. }
  360. }
  361. static void reset() {
  362. di = 0;
  363. ei = 0;
  364. bottom = 0;
  365. }
  366. void *armpack_decode(buffer_t *b) {
  367. reset();
  368. encoded = b->buffer;
  369. capacity = traverse(0, true);
  370. reset();
  371. decoded = gc_alloc(capacity);
  372. read_store();
  373. return decoded;
  374. }
  375. void armpack_encode_start(void *_encoded) {
  376. encoded = _encoded;
  377. ei = 0;
  378. }
  379. int armpack_encode_end() {
  380. return ei;
  381. }
  382. static void armpack_write_u8(uint8_t i) {
  383. *(uint8_t *)(encoded + ei) = i;
  384. ei += 1;
  385. }
  386. static void armpack_write_i16(int16_t i) {
  387. *(int16_t *)(encoded + ei) = i;
  388. ei += 2;
  389. }
  390. static void armpack_write_u32(uint32_t i) {
  391. *(uint32_t *)(encoded + ei) = i;
  392. ei += 4;
  393. }
  394. static void armpack_write_i32(int32_t i) {
  395. *(int32_t *)(encoded + ei) = i;
  396. ei += 4;
  397. }
  398. static void armpack_write_f32(float i) {
  399. *(float *)(encoded + ei) = i;
  400. ei += 4;
  401. }
  402. void armpack_encode_map(uint32_t count) {
  403. armpack_write_u8(0xdf);
  404. armpack_write_i32(count);
  405. }
  406. void armpack_encode_array(uint32_t count) { // array of arrays / array of maps
  407. armpack_write_u8(0xdd);
  408. armpack_write_u32(count);
  409. }
  410. void armpack_encode_array_f32(f32_array_t *f32a) {
  411. if (f32a == NULL) {
  412. armpack_write_u8(0xc0); // NULL
  413. return;
  414. }
  415. armpack_write_u8(0xdd);
  416. armpack_write_u32(f32a->length);
  417. if (f32a->length > 0) {
  418. armpack_write_u8(0xca);
  419. for (uint32_t i = 0; i < f32a->length; ++i) {
  420. armpack_write_f32(f32a->buffer[i]);
  421. }
  422. }
  423. }
  424. void armpack_encode_array_i32(i32_array_t *i32a) {
  425. if (i32a == NULL) {
  426. armpack_write_u8(0xc0); // NULL
  427. return;
  428. }
  429. armpack_write_u8(0xdd);
  430. armpack_write_u32(i32a->length);
  431. if (i32a->length > 0) {
  432. armpack_write_u8(0xd2);
  433. for (uint32_t i = 0; i < i32a->length; ++i) {
  434. armpack_write_i32(i32a->buffer[i]);
  435. }
  436. }
  437. }
  438. void armpack_encode_array_i16(i16_array_t *i16a) {
  439. if (i16a == NULL) {
  440. armpack_write_u8(0xc0); // NULL
  441. return;
  442. }
  443. armpack_write_u8(0xdd);
  444. armpack_write_u32(i16a->length);
  445. if (i16a->length > 0) {
  446. armpack_write_u8(0xd1);
  447. for (uint32_t i = 0; i < i16a->length; ++i) {
  448. armpack_write_i16(i16a->buffer[i]);
  449. }
  450. }
  451. }
  452. void armpack_encode_array_u8(u8_array_t *u8a) {
  453. if (u8a == NULL) {
  454. armpack_write_u8(0xc0); // NULL
  455. return;
  456. }
  457. armpack_write_u8(0xdd);
  458. armpack_write_u32(u8a->length);
  459. if (u8a->length > 0) {
  460. armpack_write_u8(0xc4);
  461. for (uint32_t i = 0; i < u8a->length; ++i) {
  462. armpack_write_u8(u8a->buffer[i]);
  463. }
  464. }
  465. }
  466. void armpack_encode_array_string(char_ptr_array_t *strings) {
  467. if (strings == NULL) {
  468. armpack_write_u8(0xc0); // NULL
  469. return;
  470. }
  471. armpack_write_u8(0xdd);
  472. armpack_write_u32(strings->length);
  473. for (uint32_t i = 0; i < strings->length; ++i) {
  474. armpack_encode_string(strings->buffer[i]);
  475. }
  476. }
  477. void armpack_encode_string(char *str) {
  478. if (str == NULL) {
  479. armpack_write_u8(0xc0); // NULL
  480. return;
  481. }
  482. armpack_write_u8(0xdb);
  483. size_t len = strlen(str);
  484. armpack_write_u32(len);
  485. for (uint32_t i = 0; i < len; ++i) {
  486. armpack_write_u8(str[i]);
  487. }
  488. }
  489. void armpack_encode_i32(int32_t i) {
  490. armpack_write_u8(0xd2);
  491. armpack_write_i32(i);
  492. }
  493. void armpack_encode_f32(float f) {
  494. armpack_write_u8(0xca);
  495. armpack_write_f32(f);
  496. }
  497. void armpack_encode_bool(bool b) {
  498. armpack_write_u8(b ? 0xc3 : 0xc2);
  499. }
  500. void armpack_encode_null() {
  501. armpack_write_u8(0xc0);
  502. }
  503. uint32_t armpack_size_map() {
  504. return 1 + 4; // u8 tag + u32 count
  505. }
  506. uint32_t armpack_size_array() {
  507. return 1 + 4; // u8 tag + u32 count
  508. }
  509. uint32_t armpack_size_array_f32(f32_array_t *f32a) {
  510. return 1 + 4 + 1 + f32a->length * 4; // u8 tag + u32 count + u8 flag + f32* contents
  511. }
  512. uint32_t armpack_size_array_u8(u8_array_t *u8a) {
  513. return 1 + 4 + 1 + u8a->length; // u8 tag + u32 count + u8 flag + u8* contents
  514. }
  515. uint32_t armpack_size_string(char *str) {
  516. return 1 + 4 + strlen(str); // u8 tag + u32 length + contents
  517. }
  518. uint32_t armpack_size_i32() {
  519. return 1 + 4; // u8 tag + i32
  520. }
  521. uint32_t armpack_size_f32() {
  522. return 1 + 4; // u8 tag + f32
  523. }
  524. uint32_t armpack_size_bool() {
  525. return 1; // u8 tag
  526. }
  527. static char *read_string_alloc() {
  528. char *s = read_string();
  529. char *allocated = gc_alloc(string_length + 1);
  530. memcpy(allocated, s, string_length);
  531. allocated[string_length] = '\0';
  532. return allocated;
  533. }
  534. typedef union ptr_storage {
  535. void *p;
  536. struct {
  537. float f;
  538. int type; // 0 - float, 1 - int
  539. };
  540. int i;
  541. } ptr_storage_t;
  542. any_map_t *_armpack_decode_to_map() {
  543. any_map_t *result = any_map_create();
  544. uint32_t count = read_u32();
  545. for (uint32_t i = 0; i < count; i++) {
  546. read_u8(); // 0xdb string
  547. char *key = read_string_alloc();
  548. uint8_t flag = read_u8();
  549. switch (flag) {
  550. case 0xc0: { // NULL
  551. any_map_set(result, key, NULL);
  552. break;
  553. }
  554. case 0xc2: { // false
  555. ptr_storage_t s;
  556. s.i = 0;
  557. s.type = 1;
  558. any_map_set(result, key, s.p);
  559. break;
  560. }
  561. case 0xc3: { // true
  562. ptr_storage_t s;
  563. s.i = 1;
  564. s.type = 1;
  565. any_map_set(result, key, s.p);
  566. break;
  567. }
  568. case 0xca: { // f32
  569. ptr_storage_t s;
  570. s.f = read_f32();
  571. s.type = 0;
  572. any_map_set(result, key, s.p);
  573. break;
  574. }
  575. case 0xd2: { // i32
  576. ptr_storage_t s;
  577. s.i = read_i32();
  578. s.type = 1;
  579. any_map_set(result, key, s.p);
  580. break;
  581. }
  582. case 0xdb: { // string
  583. any_map_set(result, key, read_string_alloc());
  584. break;
  585. }
  586. case 0xdf: { // map
  587. any_map_t *nested_map = _armpack_decode_to_map();
  588. any_map_set(result, key, nested_map);
  589. break;
  590. }
  591. case 0xdd: { // array
  592. uint32_t array_count = read_u32();
  593. uint8_t element_flag = read_u8();
  594. if (element_flag == 0xca) { // f32
  595. f32_array_t *array = f32_array_create(array_count);
  596. for (uint32_t j = 0; j < array_count; j++) {
  597. array->buffer[j] = read_f32();
  598. }
  599. any_map_set(result, key, array);
  600. }
  601. else if (element_flag == 0xd2) { // i32
  602. i32_array_t *array = i32_array_create(array_count);
  603. for (uint32_t j = 0; j < array_count; j++) {
  604. array->buffer[j] = read_i32();
  605. }
  606. any_map_set(result, key, array);
  607. }
  608. else if (element_flag == 0xd1) { // i16
  609. i16_array_t *array = i16_array_create(array_count);
  610. for (uint32_t j = 0; j < array_count; j++) {
  611. array->buffer[j] = read_i16();
  612. }
  613. any_map_set(result, key, array);
  614. }
  615. else if (element_flag == 0xc4) { // u8
  616. u8_array_t *array = u8_array_create(array_count);
  617. for (uint32_t j = 0; j < array_count; j++) {
  618. array->buffer[j] = read_u8();
  619. }
  620. any_map_set(result, key, array);
  621. }
  622. else if (element_flag == 0xdb) { // string
  623. ei--;
  624. char_ptr_array_t *array = char_ptr_array_create(array_count);
  625. for (uint32_t j = 0; j < array_count; j++) {
  626. read_u8(); // flag
  627. array->buffer[j] = read_string_alloc();
  628. }
  629. any_map_set(result, key, array);
  630. }
  631. else if (element_flag == 0xdf) { // map
  632. ei--;
  633. any_array_t *array = any_array_create(array_count);
  634. for (uint32_t j = 0; j < array_count; j++) {
  635. read_u8(); // flag
  636. array->buffer[j] = _armpack_decode_to_map();
  637. }
  638. any_map_set(result, key, array);
  639. }
  640. else if (element_flag == 0xc6) { // buffer_t (deprecated)
  641. ei--;
  642. any_array_t *array = any_array_create(array_count);
  643. for (uint32_t j = 0; j < array_count; j++) {
  644. read_u8(); // flag
  645. uint32_t buffer_size = read_u32();
  646. buffer_t *buffer = buffer_create(buffer_size);
  647. for (uint32_t k = 0; k < buffer_size; k++) {
  648. buffer->buffer[k] = read_u8();
  649. }
  650. array->buffer[j] = buffer;
  651. }
  652. any_map_set(result, key, array);
  653. }
  654. break;
  655. }
  656. case 0xc6: { // buffer_t (deprecated)
  657. uint32_t buffer_size = read_u32();
  658. buffer_t *buffer = buffer_create(buffer_size);
  659. for (uint32_t j = 0; j < buffer_size; j++) {
  660. buffer->buffer[j] = read_u8();
  661. }
  662. any_map_set(result, key, buffer);
  663. }
  664. }
  665. }
  666. return result;
  667. }
  668. any_map_t *armpack_decode_to_map(buffer_t *b) {
  669. encoded = b->buffer;
  670. ei = 0;
  671. read_u8(); // Must be 0xdf for a map
  672. return _armpack_decode_to_map();
  673. }
  674. float armpack_map_get_f32(any_map_t *map, char *key) {
  675. ptr_storage_t ps;
  676. ps.p = any_map_get(map, key);
  677. if (ps.p == NULL) {
  678. return 0.0;
  679. }
  680. return ps.type == 0 ? ps.f : (float)ps.i;
  681. }
  682. int armpack_map_get_i32(any_map_t *map, char *key) {
  683. ptr_storage_t ps;
  684. ps.p = any_map_get(map, key);
  685. if (ps.p == NULL) {
  686. return 0;
  687. }
  688. return ps.type == 1 ? ps.i : (int)ps.f;
  689. }