static inline _treenode_t * _co_tree_insert_r(_treenode_t *root, _treenode_t *current, const char *orig_key, const size_t orig_klen, const char *key, const size_t klen, co_obj_t *value) { if (current == NULL) { current = (_treenode_t *) h_calloc(1, sizeof(_treenode_t)); if(root == NULL) { root = current; } else { hattach(current, root); } current->splitchar = *key; } if (*key < current->splitchar) { current->low = _co_tree_insert_r(root, current->low, orig_key, orig_klen, key, klen, value); } else if (*key == current->splitchar) { if (klen > 1) { // not done yet, keep going but one less current->equal = _co_tree_insert_r(root, current->equal, orig_key, orig_klen, key+1, klen - 1, value); } else { if(current->value != NULL) { co_obj_free(current->value); } if(current->key != NULL) { co_obj_free(current->key); } current->value = value; current->key = co_str8_create(orig_key, orig_klen, 0); hattach(current->key, current); hattach(current->value, current); current->key->_ref++; current->value->_ref++; } } else { current->high = _co_tree_insert_r(root, current->high, orig_key, orig_klen, key, klen, value); } return current; }
int co_call(co_obj_t *connection, co_obj_t **response, const char *method, const size_t mlen, co_obj_t *request) { CHECK(method != NULL && mlen > 0 && mlen < UINT8_MAX, "Invalid method name."); CHECK(connection != NULL && IS_SOCK(connection), "Invalid connection."); co_obj_t *params = NULL, *rlist = NULL, *rtree = NULL; int retval = 0; size_t reqlen = 0, resplen = 0; char req[REQUEST_MAX]; char resp[RESPONSE_MAX]; if(request != NULL) { CHECK(IS_LIST(request), "Not a valid request."); params = request; } else { params = co_list16_create(); } co_obj_t *m = co_str8_create(method, mlen, 0); reqlen = co_request_alloc(req, sizeof(req), m, params); CHECK(((co_socket_t*)connection)->send((co_obj_t*)((co_socket_t*)connection)->fd, req, reqlen) != -1, "Send error!"); if((resplen = ((co_socket_t*)connection)->receive(connection, (co_obj_t*)((co_socket_t*)connection)->fd, resp, sizeof(resp))) > 0) { CHECK(co_list_import(&rlist, resp, resplen) > 0, "Failed to parse response."); rtree = co_list_element(rlist, 3); if(!IS_NIL(rtree)) { retval = 1; } else { rtree = co_list_element(rlist, 2); retval = 0; } if(rtree != NULL && IS_TREE(rtree)) { *response = rtree; hattach(*response, _pool); } else SENTINEL("Invalid response."); } else SENTINEL("Failed to receive data."); co_obj_free(m); if(params != request) co_obj_free(params); return retval; error: co_obj_free(m); if(params != request) co_obj_free(params); return retval; }
void co_free(co_obj_t *object) { hattach(object, NULL); co_obj_free(object); return; }
int co_shutdown(void) { CHECK_MEM(_sockets); CHECK(IS_LIST(_sockets), "API not properly initialized."); co_list_parse(_sockets, _co_shutdown_sockets_i, NULL); co_obj_free(_pool); return 1; error: return 0; }
co_obj_t * co_connect(const char *uri, const size_t ulen) { CHECK_MEM(_sockets); CHECK(uri != NULL && ulen > 0, "Invalid URI."); co_obj_t *socket = NEW(co_socket, unix_socket); hattach(socket, _pool); CHECK((((co_socket_t*)socket)->connect(socket, uri)), "Failed to connect to commotiond at %s\n", uri); co_list_append(_sockets, socket); return socket; error: co_obj_free(socket); return NULL; }
~TreeTest() { co_obj_free(Tree16); co_obj_free(Tree32); }
size_t co_tree_import(co_obj_t **tree, const char *input, const size_t ilen) { size_t length = 0, olen = 0, read = 0, klen = 0; char *kstr = NULL; int i = 0; co_obj_t *obj = NULL; const char *cursor = input; switch((uint8_t)input[0]) { case _tree16: length = *((uint16_t *)(input + 1)); *tree = co_tree16_create(); cursor += sizeof(uint16_t) + 1; read = sizeof(uint16_t) + 1; break; case _tree32: length = (uint32_t)(*(uint32_t*)(input + 1)); *tree = co_tree32_create(); cursor += sizeof(uint32_t) + 1; read = sizeof(uint32_t) + 1; break; default: SENTINEL("Not a tree."); break; } while(i < length && read <= ilen) { DEBUG("Importing tuple:"); if((uint8_t)cursor[0] == _str8) { DEBUG("Reading key..."); cursor += 1; read += 1; klen = (uint8_t)cursor[0]; kstr = (char *)&cursor[1]; cursor += klen + 1; read += klen + 1; DEBUG("Reading value..."); switch((uint8_t)cursor[0]) { case _list16: case _list32: olen = co_list_import(&obj, cursor, ilen - read); break; case _tree16: case _tree32: olen = co_tree_import(&obj, cursor, ilen - read); break; default: olen = co_obj_import(&obj, cursor, ilen - read, 0); break; } CHECK(olen > 0, "Failed to import object."); cursor +=olen; read += olen; DEBUG("Inserting value into tree with key."); CHECK(co_tree_insert(*tree, kstr, klen, obj), "Failed to insert object."); i++; } } return read; error: if(obj != NULL) co_obj_free(obj); return -1; }
void co_free(co_obj_t *object) { co_obj_free(object); return; }