void SystemCore::deserializeActiveSystems(Tny* root, uint64_t referenceTime) { if (root->type != TNY_DICT) { std::cerr << "es-system: Unexpected type during deserialization." << std::endl; throw std::runtime_error("Unexepected Tny type"); } while (Tny_hasNext(root)) { root = Tny_next(root); std::string name = root->key; if (root->type != TNY_OBJ) { std::cerr << "es-system: Unexpected type during deserialization." << std::endl; throw std::runtime_error("Unexpected Tny type"); } Tny* comp = root->value.tny; if (comp->type != TNY_DICT) { std::cerr << "es-system: Unexpected type during deserialization." << std::endl; throw std::runtime_error("Unexpected Tny type"); } Tny* val = Tny_get(comp, "interval"); uint64_t interval = val->value.num; Tny_get(comp, "stagger"); uint64_t stagger = val->value.num; // We ignore next exec and calculate it ourselves. //Tny_get(comp, "nextExec"); //uint64_t nextExec = val->value.num; addActiveSystem(name, interval, referenceTime, stagger); } }
int main(void) { Tny *root = NULL; Tny *embedded = NULL; Tny *tmp = NULL; char *message = "Message"; uint32_t ui32 = 0xB16B00B5; uint64_t ui64 = 0xDEADBEEFABAD1DEAlu; char c = 'A'; double flt = 13.37f; char *typesStr[] = {"BINARY", "INT32", "INT64", "CHAR", "NULL", "DOUBLE"}; TnyType types[] = {TNY_BIN, TNY_INT32, TNY_INT64, TNY_CHAR, TNY_NULL, TNY_DOUBLE}; void *values[] = {message, &ui32, &ui64, &c, NULL, &flt}; size_t sizes[] = {strlen(message),0, 0, 0, 0, 0}; char *keys[] = {"Key1", "Key2", "Key3", "Key4", "Key5", "Key6"}; char corruptedObj[] = {0x01, 0x01, 0x00, 0x00, 0x00, 0x04, 0x08, 0x00, 0x00, 0x00, 0x4D, 0x65, 0x73, 0x73, 0x61, 0x67, 0x65}; int counter = 0; int errors = 0; // Checking every datatype in an array. for (int i = 0; i < 6; i++) { root = Tny_add(NULL, TNY_ARRAY, NULL, NULL, 0); root = Tny_add(root, types[i], NULL, values[i], sizes[i]); if(serialize_deserialize(root)) { printf("Test with type %s in an array failed.\n", typesStr[i]); errors++; } TnyElement_free(root); } // Checking every datatype in a dictionary. for (int i = 0; i < 6; i++) { root = Tny_add(NULL, TNY_DICT, NULL, NULL, 0); root = Tny_add(root, types[i], keys[i], values[i], sizes[i]); if(serialize_deserialize(root)) { printf("Test with type %s in a dictionary failed.\n", typesStr[i]); errors++; } TnyElement_free(root); } // Adding every datatype to an array. root = Tny_add(NULL, TNY_ARRAY, NULL, NULL, 0); for (int i = 0; i < 6; i++) { root = Tny_add(root, types[i], NULL, values[i], sizes[i]); } if (serialize_deserialize(root)) { printf("Test with all types in an array failed.\n"); errors++; } TnyElement_free(root); // Adding every datatype to a dictionary. root = Tny_add(NULL, TNY_DICT, NULL, NULL, 0); for (int i = 0; i < 6; i++) { root = Tny_add(root, types[i], keys[i], values[i], sizes[i]); } if (serialize_deserialize(root)) { printf("Test with all types in a dictionary failed.\n"); errors++; } TnyElement_free(root); // Adding a dictionary to an array. root = Tny_add(NULL, TNY_ARRAY, NULL, NULL, 0); for (int i = 0; i < 6; i++) { root = Tny_add(root, types[i], NULL, values[i], sizes[i]); } embedded = Tny_add(NULL, TNY_DICT, NULL, NULL, 0); for (int i = 0; i < 6; i++) { embedded = Tny_add(embedded, types[i], keys[i], values[i], sizes[i]); } Tny_add(root, TNY_OBJ, NULL, embedded, 0); if (serialize_deserialize(root)) { printf("Test with a sub document in an array failed.\n"); errors++; } if (root != NULL && embedded != NULL) { // Fetching a random element from an array tmp = Tny_at(root, 2); if (tmp == NULL || tmp->value.num != *(uint64_t*)values[2]) { printf("Fetching element at position 2 failed!\n"); errors++; } // Fetching a random element from a dictionary tmp = Tny_get(embedded, "Key3"); if (tmp == NULL || tmp->value.num != *(uint64_t*)values[2]) { printf("Fetching element with key 'Key3' failed!\n"); errors++; } // Remove an element. Tny_remove(Tny_at(root, 2)); tmp = Tny_at(root, 2); if (tmp == NULL || tmp->value.chr != *(char*)values[3]) { printf("Deleting element at position 2 failed!\n"); errors++; } // Adding element after position 2 ui32 = 0x12345678; tmp = Tny_at(root, 2); Tny_add(tmp, TNY_INT32, NULL, &ui32, 0); tmp = Tny_at(root, 3); if (tmp == NULL || tmp->value.num != ui32) { printf("Adding element after position 2 failed!\n"); errors++; } } TnyElement_free(root); // Testing the iterator functions. root = Tny_add(NULL, TNY_ARRAY, NULL, NULL, 0); for (uint32_t i = 0; i < 10; i++) { root = Tny_add(root, TNY_INT32, NULL, &i, 0); } counter = 0; root = root->root; while (Tny_hasNext(root)) { root = Tny_next(root); if (root->value.num != counter) { printf("Iterator Test (1) failed!\n"); errors++; break; } counter++; } if (counter != root->root->size) { printf("Iterator Test (2) failed!\n"); errors++; } TnyElement_free(root); // Loading a corrupted document containing a corrupted size field. root = Tny_loads(corruptedObj, sizeof(corruptedObj)); if (root == NULL || root->size != 0) { printf("Loading of a corrupted document failed!\n"); errors++; } TnyElement_free(root); printf("Tny tests completed with %u error(s).\n", errors); return EXIT_SUCCESS; }
Tny* Tny_add(Tny *prev, TnyType type, char *key, void *value, uint64_t size) { Tny *tny = NULL; enum {CHECK_PRECONDITIONS, ALLOCATE, CHAIN, SET_KEY, SET_VALUE, FAILED}; int status = CHECK_PRECONDITIONS; int loop = 1; int isoverwrite = 0; size_t keyLen = 0; while (loop) { switch (status) { case CHECK_PRECONDITIONS: if ((prev != NULL && type != TNY_ARRAY && type != TNY_DICT) || (prev == NULL && (type == TNY_ARRAY || type == TNY_DICT))) { status = ALLOCATE; if (prev != NULL && prev->root->type == TNY_DICT && key == NULL) { /* Dict must have a key! */ status = FAILED; } else if (key != NULL && prev != NULL && prev->root->type == TNY_DICT) { tny = Tny_get(prev, key); if (tny != NULL) { Tny_freeValue(tny); status = SET_VALUE; isoverwrite = 1; } } } else { status = FAILED; } break; case ALLOCATE: tny = malloc(sizeof(Tny)); if (tny != NULL) { memset(tny, 0, sizeof(Tny)); status = CHAIN; } else { status = FAILED; } break; case CHAIN: if (prev != tny) { if (prev != NULL) { tny->prev = prev; tny->next = prev->next; prev->next = tny; if (tny->next != NULL) { tny->next->prev = tny; } tny->root = prev->root; tny->root->size++; tny->docSizePtr = tny->root->docSizePtr; } else { tny->root = tny; tny->docSizePtr = &tny->docSize; } } if (key != NULL && tny->key == NULL && prev->root->type == TNY_DICT) { status = SET_KEY; } else { status = SET_VALUE; } break; case SET_KEY: keyLen = strlen(key) + 1; tny->key = malloc(keyLen); if (tny->key != NULL) { memcpy(tny->key, key, keyLen); Tny_addSize(tny, sizeof(uint32_t) + keyLen); status = SET_VALUE; } else { status = FAILED; } break; case SET_VALUE: tny->type = type; if (type != TNY_ARRAY && type != TNY_DICT) { /* Set size */ tny->size = size; /* Set value */ if (tny->type == TNY_OBJ) { if (value != NULL) { tny->value.tny = Tny_copy(tny->root->docSizePtr, value); if (tny->value.tny == NULL) { status = FAILED; break; } } } else if (tny->type == TNY_BIN) { tny->value.ptr = malloc(size); if (tny->value.ptr != NULL) { memcpy(tny->value.ptr, value, size); } else { status = FAILED; break; } } else if (tny->type == TNY_CHAR) { tny->value.chr = *((char*)value); } else if (tny->type == TNY_INT32) { tny->value.num = *((uint32_t*)value); } else if (tny->type == TNY_INT64) { tny->value.num = *((uint64_t*)value); } else if (tny->type == TNY_DOUBLE) { tny->value.flt = *((double*)value); } } Tny_addSize(tny, Tny_valueSize(tny->type, tny->size)); /* SUCCESS */ loop = 0; break; case FAILED: if (tny != NULL && !isoverwrite) { free(tny->key); free(tny); } tny = NULL; loop = 0; isoverwrite = 0; break; } } return isoverwrite ? prev : tny; }
Tny* Tny_add(Tny *prev, TnyType type, char *key, void *value, uint64_t size) { Tny *tny = NULL; if ((prev != NULL && type != TNY_ARRAY && type != TNY_DICT) || (prev == NULL && (type == TNY_ARRAY || type == TNY_DICT))) { if (prev != NULL && prev->root->type == TNY_DICT && key == NULL) { // Dict must have a key! return NULL; } if (key != NULL) { tny = Tny_get(prev, key); } if (tny == NULL) { tny = malloc(sizeof(Tny)); memset(tny, 0, sizeof(Tny)); // Add to doubly-linked list if (prev != NULL) { tny->prev = prev; tny->next = prev->next; prev->next = tny; if (tny->next != NULL) { tny->next->prev = tny; } tny->root = prev->root; tny->root->size++; } else { tny->root = tny; } } else { Tny_freeContent(tny); } // Set key if present. if (key != NULL) { tny->key = malloc(strlen(key) + 1); memcpy(tny->key, key, strlen(key) + 1); } tny->type = type; if (type != TNY_ARRAY && type != TNY_DICT) { // Set size tny->size = size; // Set value if (tny->type == TNY_OBJ) { tny->value.ptr = ((Tny*)value)->root; } else if (tny->type == TNY_BIN) { tny->value.ptr = malloc(size); memcpy(tny->value.ptr, value, size); } else if (tny->type == TNY_CHAR) { tny->value.chr = *((char*)value); } else if (tny->type == TNY_INT32) { tny->value.num = *((uint32_t*)value); } else if (tny->type == TNY_INT64) { tny->value.num = *((uint64_t*)value); } else if (tny->type == TNY_DOUBLE) { tny->value.flt = *((double*)value); } } } return tny; }