wi_array_t * wd_user_subscribed_virtual_paths_for_path(wd_user_t *user, wi_string_t *path) { wi_mutable_array_t *array; wi_string_t *virtualpath; array = wi_mutable_array(); wi_recursive_lock_lock(user->user_lock); if(wi_is_equal(wi_string_last_path_component(path), WI_STR(WD_FILES_META_PATH))) { path = wi_string_by_deleting_last_path_component(path); virtualpath = wi_dictionary_data_for_key(user->subscribed_virtualpaths, path); if(virtualpath) wi_mutable_array_add_data(array, virtualpath); if(!wi_is_equal(path, WI_STR("/"))) { path = wi_string_by_deleting_last_path_component(path); virtualpath = wi_dictionary_data_for_key(user->subscribed_virtualpaths, path); if(virtualpath) wi_mutable_array_add_data(array, virtualpath); } } else { virtualpath = wi_dictionary_data_for_key(user->subscribed_virtualpaths, path); if(virtualpath) wi_mutable_array_add_data(array, virtualpath); } wi_recursive_lock_unlock(user->user_lock); return array; }
wi_array_t * wi_p7_message_list_for_name(wi_p7_message_t *p7_message, wi_string_t *field_name) { wi_p7_spec_field_t *field; wi_p7_spec_type_t *listtype; wi_array_t *list; wi_runtime_instance_t *instance; unsigned char *binary; wi_p7_type_t listtype_id; uint32_t field_size, list_size, string_size; field = wi_p7_spec_field_with_name(p7_message->spec, field_name); if(!field) { wi_error_set_libwired_error_with_format(WI_ERROR_P7_UNKNOWNFIELD, WI_STR("No id found for field \"%@\""), field_name); if(wi_p7_message_debug) wi_log_debug(WI_STR("wi_p7_message_list_for_name: %m")); return NULL; } listtype = wi_p7_spec_field_listtype(field); listtype_id = wi_p7_spec_type_id(listtype); if(listtype_id != WI_P7_STRING) { wi_error_set_libwired_error_with_format(WI_ERROR_P7_UNKNOWNFIELD, WI_STR("Unhandled type %@ in list"), wi_p7_spec_type_name(listtype)); if(wi_p7_message_debug) wi_log_debug(WI_STR("wi_p7_message_list_for_name: %m")); return NULL; } list = wi_mutable_array(); if(!_wi_p7_message_get_binary_buffer_for_reading_for_name(p7_message, field_name, &binary, &field_size)) return NULL; list_size = 0; while(list_size < field_size) { if(listtype_id == WI_P7_STRING) { string_size = wi_read_swap_big_to_host_int32(binary, list_size); list_size += 4; instance = wi_string_with_bytes(binary + list_size, string_size - 1); list_size += string_size; } wi_mutable_array_add_data(list, instance); } wi_runtime_make_immutable(list); return list; }
static wi_boolean_t _wi_plist_read_node_to_instance(xmlNodePtr content_node, wi_runtime_instance_t *collection) { xmlNodePtr node; wi_string_t *key = NULL; wi_runtime_instance_t *instance = NULL; wi_boolean_t dictionary; dictionary = (wi_runtime_id(collection) == wi_dictionary_runtime_id()); for(node = content_node->children; node != NULL; node = node->next) { if(node->type == XML_ELEMENT_NODE) { if(strcmp((const char *) node->name, "key") == 0) key = wi_xml_node_content(node); else if(strcmp((const char *) node->name, "string") == 0) instance = wi_xml_node_content(node); else if(strcmp((const char *) node->name, "integer") == 0) instance = wi_number_with_integer(wi_string_integer(wi_xml_node_content(node))); else if(strcmp((const char *) node->name, "real") == 0) instance = wi_number_with_double(wi_string_double(wi_xml_node_content(node))); else if(strcmp((const char *) node->name, "true") == 0) instance = wi_number_with_bool(true); else if(strcmp((const char *) node->name, "false") == 0) instance = wi_number_with_bool(false); else if(strcmp((const char *) node->name, "date") == 0) instance = wi_date_with_rfc3339_string(wi_xml_node_content(node)); else if(strcmp((const char *) node->name, "data") == 0) instance = wi_data_with_base64(wi_xml_node_content(node)); else if(strcmp((const char *) node->name, "dict") == 0) { instance = wi_mutable_dictionary(); if(!_wi_plist_read_node_to_instance(node, instance)) return false; } else if(strcmp((const char *) node->name, "array") == 0) { instance = wi_mutable_array(); if(!_wi_plist_read_node_to_instance(node, instance)) return false; } else { wi_error_set_libwired_error_with_format(WI_ERROR_PLIST_READFAILED, WI_STR("Unhandled node \"%s\""), node->name); return false; } } if(instance) { if(dictionary) wi_mutable_dictionary_set_data_for_key(collection, instance, key); else wi_mutable_array_add_data(collection, instance); instance = NULL; key = NULL; } } return true; }
void wi_test_directory_enumerator(void) { wi_directory_enumerator_t *enumerator; wi_mutable_array_t *contents; wi_string_t *path, *subpath; wi_boolean_t result; wi_directory_enumerator_status_t status; path = wi_filesystem_temporary_path_with_template(WI_STR("/tmp/libwired-test-directory-enumerator.XXXXXXX")); path = wi_string_by_resolving_symbolic_links_in_path(path); result = wi_filesystem_create_directory_at_path(path); WI_TEST_ASSERT_TRUE(result, ""); enumerator = wi_filesystem_directory_enumerator_at_path(path); WI_TEST_ASSERT_NOT_NULL(enumerator, ""); contents = wi_mutable_array(); while((status = wi_directory_enumerator_get_next_path(enumerator, &subpath)) == WI_DIRECTORY_ENUMERATOR_PATH) wi_mutable_array_add_data(contents, subpath); WI_TEST_ASSERT_EQUALS(status, WI_DIRECTORY_ENUMERATOR_EOF, ""); WI_TEST_ASSERT_EQUALS(wi_array_count(contents), 0U, ""); result = wi_filesystem_change_current_directory_to_path(path); WI_TEST_ASSERT_TRUE(result, ""); result = wi_filesystem_create_directory_at_path(WI_STR("foo")); WI_TEST_ASSERT_TRUE(result, ""); result = wi_filesystem_create_directory_at_path(WI_STR("foo/bar")); WI_TEST_ASSERT_TRUE(result, ""); result = wi_filesystem_create_directory_at_path(WI_STR("foo/bar/baz")); WI_TEST_ASSERT_TRUE(result, ""); enumerator = wi_filesystem_directory_enumerator_at_path(path); WI_TEST_ASSERT_NOT_NULL(enumerator, ""); while((status = wi_directory_enumerator_get_next_path(enumerator, &subpath)) == WI_DIRECTORY_ENUMERATOR_PATH) wi_mutable_array_add_data(contents, subpath); WI_TEST_ASSERT_EQUALS(status, WI_DIRECTORY_ENUMERATOR_EOF, ""); WI_TEST_ASSERT_EQUALS(wi_array_count(contents), 3U, ""); WI_TEST_ASSERT_EQUAL_INSTANCES(wi_array_data_at_index(contents, 0), wi_string_by_appending_path_component(path, WI_STR("foo")), ""); WI_TEST_ASSERT_EQUAL_INSTANCES(wi_array_data_at_index(contents, 1), wi_string_by_appending_path_component(path, WI_STR("foo/bar")), ""); WI_TEST_ASSERT_EQUAL_INSTANCES(wi_array_data_at_index(contents, 2), wi_string_by_appending_path_component(path, WI_STR("foo/bar/baz")), ""); wi_filesystem_delete_path(path); }
static wi_runtime_instance_t * _wi_plist_instance_for_node(xmlNodePtr node) { wi_string_t *name; name = wi_xml_node_name(node); if(wi_is_equal(name, WI_STR("dict"))) return wi_mutable_dictionary(); else if(wi_is_equal(name, WI_STR("array"))) return wi_mutable_array(); wi_error_set_libwired_error_with_format(WI_ERROR_PLIST_READFAILED, WI_STR("Content \"%@\" is not \"dict\" or \"array\""), name); return NULL; }
wi_array_t * wd_users_users_with_login(wi_string_t *name) { wi_enumerator_t *enumerator; wi_mutable_array_t *users; wd_user_t *user; users = wi_mutable_array(); wi_dictionary_rdlock(wd_users); enumerator = wi_dictionary_data_enumerator(wd_users); while((user = wi_enumerator_next_data(enumerator))) { if(wi_is_equal(wd_user_login(user), name)) wi_mutable_array_add_data(users, user); } wi_dictionary_unlock(wd_users); return users; }
static void wd_transfers_queue_thread(wi_runtime_instance_t *argument) { wi_pool_t *pool; wi_enumerator_t *enumerator; wi_mutable_dictionary_t *key_queues; wi_mutable_array_t *key_queue, *keys; wi_string_t *key; wd_transfer_t *transfer; wd_account_t *account; wi_uinteger_t user_downloads, user_uploads, user_transfers; wi_uinteger_t new_position, position, queue, i, count, longest_queue; pool = wi_pool_init(wi_pool_alloc()); key_queues = wi_dictionary_init(wi_mutable_dictionary_alloc()); while(true) { wi_mutable_dictionary_remove_all_data(key_queues); wi_condition_lock_lock_when_condition(wd_transfers_queue_lock, 1, 0.0); wi_array_rdlock(wd_transfers); longest_queue = 0; enumerator = wi_array_data_enumerator(wd_transfers); while((transfer = wi_enumerator_next_data(enumerator))) { wi_condition_lock_lock(transfer->queue_lock); if(transfer->state == WD_TRANSFER_QUEUED && transfer->queue != 0) { key_queue = wi_dictionary_data_for_key(key_queues, transfer->key); if(!key_queue) { key_queue = wi_mutable_array(); wi_mutable_dictionary_set_data_for_key(key_queues, key_queue, transfer->key); } wi_mutable_array_add_data(key_queue, transfer); if(wi_array_count(key_queue) > longest_queue) longest_queue = wi_array_count(key_queue); } wi_condition_lock_unlock(transfer->queue_lock); } keys = wi_autorelease(wi_mutable_copy(wi_dictionary_keys_sorted_by_value(key_queues, wd_transfers_queue_compare))); position = 1; count = wi_array_count(keys); while(longest_queue > 0) { for(i = 0; i < count; i++) { key = WI_ARRAY(keys, i); key_queue = wi_dictionary_data_for_key(key_queues, key); if(wi_array_count(key_queue) > 0) { transfer = WI_ARRAY(key_queue, 0); account = wd_user_account(transfer->user); wi_lock_lock(wd_transfers_status_lock); if(transfer->type == WD_TRANSFER_DOWNLOAD) { wi_dictionary_rdlock(wd_transfers_user_downloads); user_downloads = wd_account_transfer_download_limit(account); user_transfers = (wi_integer_t) wi_dictionary_data_for_key(wd_transfers_user_downloads, transfer->key); queue = ((wd_transfers_total_downloads > 0 && wd_transfers_active_downloads >= wd_transfers_total_downloads) || (user_downloads > 0 && user_transfers >= user_downloads)); wi_dictionary_unlock(wd_transfers_user_downloads); } else { wi_dictionary_rdlock(wd_transfers_user_uploads); user_uploads = wd_account_transfer_upload_limit(account); user_transfers = (wi_integer_t) wi_dictionary_data_for_key(wd_transfers_user_uploads, transfer->key); queue = ((wd_transfers_total_uploads > 0 && wd_transfers_active_uploads >= wd_transfers_total_uploads) || (user_uploads > 0 && user_transfers >= user_uploads)); wi_dictionary_unlock(wd_transfers_user_uploads); } wi_lock_unlock(wd_transfers_status_lock); if(queue) new_position = position++; else new_position = 0; if(new_position != (wi_uinteger_t) transfer->queue) { if(new_position == 0) wd_transfers_add_or_remove_transfer(transfer, true); wi_condition_lock_lock(transfer->queue_lock); transfer->queue = new_position; wi_condition_lock_unlock_with_condition(transfer->queue_lock, 1); } wi_mutable_array_remove_data_at_index(key_queue, 0); } } longest_queue--; } wi_array_unlock(wd_transfers); wi_condition_lock_unlock_with_condition(wd_transfers_queue_lock, 0); wi_pool_drain(pool); } wi_release(key_queues); wi_release(pool); }
wi_boolean_t wi_config_read_file(wi_config_t *config) { wi_enumerator_t *enumerator; wi_runtime_instance_t *instance; wi_file_t *file; wi_mutable_array_t *array; wi_mutable_dictionary_t *previous_values; wi_string_t *string, *name, *value; wi_config_type_t type; file = wi_file_for_reading(config->path); if(!file) { wi_log_err(WI_STR("Could not open %@: %m"), config->path); return false; } wi_log_info(WI_STR("Reading %@"), config->path); config->line = 0; wi_lock_lock(config->lock); previous_values = config->values; config->values = wi_dictionary_init(wi_mutable_dictionary_alloc()); if(config->defaults) { enumerator = wi_dictionary_key_enumerator(config->defaults); while((name = wi_enumerator_next_data(enumerator))) { // instance = wi_mutable_copy(wi_dictionary_data_for_key(config->defaults, name)); instance = wi_dictionary_data_for_key(config->defaults, name); if(wi_runtime_id(instance) == wi_array_runtime_id()) instance = wi_autorelease(wi_mutable_copy(instance)); wi_mutable_dictionary_set_data_for_key(config->values, instance, name); // wi_release(instance); } } while((string = wi_file_read_line(file))) { config->line++; if(wi_string_length(string) > 0 && !wi_string_has_prefix(string, WI_STR("#"))) { if(_wi_config_parse_string(config, string, &name, &value)) { instance = _wi_config_instance_for_setting(config, name, value, &type); if(instance) { wi_log_debug(WI_STR(" %@ = %@"), name, value); if(type == WI_CONFIG_STRINGLIST) { array = wi_dictionary_data_for_key(config->values, name); if(!array) { array = wi_mutable_array(); wi_mutable_dictionary_set_data_for_key(config->values, array, name); } wi_mutable_array_add_data(array, instance); } else { wi_mutable_dictionary_set_data_for_key(config->values, instance, name); } } else { _wi_config_log_error(config, name); } } else { wi_error_set_libwired_error(WI_ERROR_SETTINGS_SYNTAXERROR); _wi_config_log_error(config, string); } } } enumerator = wi_dictionary_key_enumerator(config->values); while((name = wi_enumerator_next_data(enumerator))) { instance = wi_dictionary_data_for_key(config->values, name); if(!previous_values || !wi_is_equal(instance, wi_dictionary_data_for_key(previous_values, name))) wi_mutable_set_add_data(config->changes, name); } wi_release(previous_values); wi_lock_unlock(config->lock); return true; }
static wi_boolean_t _wi_plist_write_instance_to_node(wi_runtime_instance_t *instance, xmlNodePtr node) { wi_enumerator_t *enumerator; wi_mutable_array_t *keys; wi_runtime_instance_t *value; xmlNodePtr child_node; void *key; wi_runtime_id_t id; wi_number_type_t type; wi_uinteger_t i, count; id = wi_runtime_id(instance); if(id == wi_string_runtime_id()) { wi_xml_node_new_child(node, WI_STR("string"), instance); } else if(id == wi_number_runtime_id()) { type = wi_number_type(instance); if(type == WI_NUMBER_BOOL) { if(wi_number_bool(instance)) wi_xml_node_new_child(node, WI_STR("true"), NULL); else wi_xml_node_new_child(node, WI_STR("false"), NULL); } else { if(type == WI_NUMBER_FLOAT || type == WI_NUMBER_DOUBLE) wi_xml_node_new_child(node, WI_STR("real"), wi_number_string(instance)); else wi_xml_node_new_child(node, WI_STR("integer"), wi_number_string(instance)); } } else if(id == wi_data_runtime_id()) { wi_xml_node_new_child(node, WI_STR("data"), wi_data_base64(instance)); } else if(id == wi_date_runtime_id()) { wi_xml_node_new_child(node, WI_STR("date"), wi_date_string_with_format(instance, WI_STR("%Y-%m-%dT%H:%M:%SZ"))); } else if(id == wi_dictionary_runtime_id()) { child_node = wi_xml_node_new_child(node, WI_STR("dict"), NULL); keys = wi_mutable_array(); enumerator = wi_dictionary_key_enumerator(instance); while((key = wi_enumerator_next_data(enumerator))) wi_mutable_array_add_data_sorted(keys, key, wi_string_compare); count = wi_array_count(keys); for(i = 0; i < count; i++) { key = WI_ARRAY(keys, i); value = wi_dictionary_data_for_key(instance, key); wi_xml_node_new_child(child_node, WI_STR("key"), key); if(!_wi_plist_write_instance_to_node(value, child_node)) return false; } } else if(id == wi_array_runtime_id()) { child_node = wi_xml_node_new_child(node, WI_STR("array"), NULL); xmlAddChild(node, child_node); enumerator = wi_array_data_enumerator(instance); while((value = wi_enumerator_next_data(enumerator))) { if(!_wi_plist_write_instance_to_node(value, child_node)) return false; } } else { wi_error_set_libwired_error_with_format(WI_ERROR_PLIST_WRITEFAILED, WI_STR("Unhandled class %@"), wi_runtime_class_name(instance)); return false; } return true; }