Tny* _Tny_loads(char *data, size_t length, size_t *pos, size_t *docSizePtr) { Tny *tny = NULL; Tny *newObj = NULL; TnyType type = TNY_NULL; uint32_t size = 0; uint32_t i32 = 0; uint64_t i64 = 0; double flt = 0.0f; char *key = NULL; uint64_t counter = 0; uint64_t elements = 0; while ((*pos) < length && (counter == 0 || counter < elements)) { type = data[(*pos)++]; if (tny == NULL) { if (type == TNY_ARRAY || type == TNY_DICT) { HASNEXTDATA(sizeof(uint32_t)); Tny_swapBytes32(&size, (const char*)(data + (*pos))); *pos += sizeof(uint32_t); elements = size; tny = Tny_add(NULL, type, NULL, NULL, size); if (tny != NULL) { if (docSizePtr != NULL) { tny->docSizePtr = docSizePtr; *tny->docSizePtr += tny->docSize; } } else { break; } if (elements == 0) { break; } else { continue; } } else { break; } } if (tny->root->type == TNY_DICT) { HASNEXTDATA(sizeof(uint32_t)); Tny_swapBytes32(&size, (const char*)(data + (*pos))); *pos += sizeof(uint32_t); HASNEXTDATA(size); if (data[(*pos) + size - 1] == '\0') { key = data + (*pos); *pos += size; } else { break; } } else { key = NULL; } if (type == TNY_NULL) { tny = Tny_add(tny, type, key, NULL, 0); } else if (type == TNY_OBJ) { newObj = _Tny_loads(data, length, pos, tny->root->docSizePtr); if (newObj != NULL) { tny = Tny_add(tny, type, key, NULL, 0); if (tny != NULL) { tny->value.tny = newObj->root; } else { break; } } else { break; } } else if (type == TNY_BIN) { HASNEXTDATA(sizeof(uint32_t)); Tny_swapBytes32(&size, (const char*)(data + (*pos))); *pos += sizeof(uint32_t); HASNEXTDATA(size); tny = Tny_add(tny, type, key, (data + *pos), size); *pos += size; } else if (type == TNY_CHAR) { HASNEXTDATA(1); tny = Tny_add(tny, type, key, (data + *pos), 0); (*pos)++; } else if (type == TNY_INT32) { HASNEXTDATA(sizeof(uint32_t)); Tny_swapBytes32(&i32, (const char*)(data + (*pos))); *pos += sizeof(uint32_t); tny = Tny_add(tny, type, key, &i32, 0); } else if (type == TNY_INT64) { HASNEXTDATA(sizeof(uint64_t)); Tny_swapBytes64(&i64, (data + (*pos))); *pos += sizeof(uint64_t); tny = Tny_add(tny, type, key, &i64, 0); } else if (type == TNY_DOUBLE) { HASNEXTDATA(sizeof(double)); Tny_swapBytes64((uint64_t*)&flt, (data + (*pos))); *pos += sizeof(double); tny = Tny_add(tny, type, key, &flt, 0); } counter++; } if (tny != NULL) { tny = tny->root; } return tny; }
Tny* Tny_loads(void *data, size_t length) { size_t pos = 0; return _Tny_loads(data, length, &pos, NULL); }
Tny* _Tny_loads(char *data, size_t length, size_t *pos) { Tny *tny = NULL; TnyType type = TNY_NULL; uint32_t size = 0; uint32_t i32 = 0; uint64_t i64 = 0; double flt = 0.0f; char *key = NULL; uint64_t counter = 0; uint64_t elements = 0; while ((*pos) < length) { type = data[(*pos)++]; if (tny == NULL) { if (type == TNY_ARRAY || type == TNY_DICT) { HASNEXTDATA(sizeof(uint32_t)); Tny_swapBytes32(&size, (uint32_t*)(data + (*pos))); *pos += sizeof(uint32_t); elements = size; tny = Tny_add(NULL, type, NULL, NULL, size); continue; } else { break; } } if (tny->root->type == TNY_DICT) { HASNEXTDATA(sizeof(uint32_t)); Tny_swapBytes32(&size, (uint32_t*)(data + (*pos))); *pos += sizeof(uint32_t); HASNEXTDATA(size); if (data[(*pos) + size - 1] == '\0') { key = data + (*pos); *pos += size; } else { break; } } else { key = NULL; } if (type == TNY_NULL) { tny = Tny_add(tny, type, key, NULL, 0); } else if (type == TNY_OBJ) { tny = Tny_add(tny, type, key, _Tny_loads(data, length, pos), 0); } else if (type == TNY_BIN) { HASNEXTDATA(sizeof(uint32_t)); Tny_swapBytes32(&size, (uint32_t*)(data + (*pos))); *pos += sizeof(uint32_t); HASNEXTDATA(size); tny = Tny_add(tny, type, key, (data + *pos), size); *pos += size; } else if (type == TNY_CHAR) { HASNEXTDATA(1); tny = Tny_add(tny, type, key, (data + *pos), 0); (*pos)++; } else if (type == TNY_INT32) { HASNEXTDATA(sizeof(uint32_t)); Tny_swapBytes32(&i32, (uint32_t*)(data + (*pos))); *pos += sizeof(uint32_t); tny = Tny_add(tny, type, key, &i32, 0); } else if (type == TNY_INT64) { HASNEXTDATA(sizeof(uint64_t)); Tny_swapBytes64(&i64, (uint64_t*)(data + (*pos))); *pos += sizeof(uint64_t); tny = Tny_add(tny, type, key, &i64, 0); } else if (type == TNY_DOUBLE) { HASNEXTDATA(sizeof(double)); Tny_swapBytes64((uint64_t*)&flt, (uint64_t*)(data + (*pos))); *pos += sizeof(double); tny = Tny_add(tny, type, key, &flt, 0); } counter++; if (counter >= elements) { break; } } if (Tny_calcSize(tny->root) == 0) { Tny_free(tny); tny = NULL; } else { tny = tny->root; } return tny; }