static wi_string_t * _wi_dictionary_description(wi_runtime_instance_t *instance) { wi_dictionary_t *dictionary = instance; _wi_dictionary_bucket_t *bucket; wi_mutable_string_t *string; wi_string_t *key_description, *value_description; wi_uinteger_t i; string = wi_mutable_string_with_format(WI_STR("<%@ %p>{count = %lu, mutable = %u, values = (\n"), wi_runtime_class_name(dictionary), dictionary, dictionary->key_count, wi_runtime_options(dictionary) & WI_RUNTIME_OPTION_MUTABLE ? 1 : 0); for(i = 0; i < dictionary->buckets_count; i++) { for(bucket = dictionary->buckets[i]; bucket; bucket = bucket->next) { if(dictionary->key_callbacks.description) key_description = (*dictionary->key_callbacks.description)(bucket->key); else key_description = wi_string_with_format(WI_STR("%p"), bucket->key); if(dictionary->value_callbacks.description) value_description = (*dictionary->value_callbacks.description)(bucket->data); else value_description = wi_string_with_format(WI_STR("%p"), bucket->data); wi_mutable_string_append_format(string, WI_STR(" %@: %@\n"), key_description, value_description); } } wi_mutable_string_append_string(string, WI_STR(")}")); wi_runtime_make_immutable(string); return string; }
wi_data_t * wi_file_read_to_end_of_file(wi_file_t *file) { wi_mutable_data_t *data; char buffer[WI_FILE_BUFFER_SIZE]; wi_integer_t bytes; _WI_FILE_ASSERT_OPEN(file); data = wi_data_init_with_capacity(wi_mutable_data_alloc(), WI_FILE_BUFFER_SIZE); while(true) { bytes = wi_file_read_bytes(file, buffer, sizeof(buffer)); if(bytes <= 0) break; wi_mutable_data_append_bytes(data, buffer, bytes); } if(bytes < 0) { wi_release(data); data = NULL; } wi_runtime_make_immutable(data); return wi_autorelease(data); }
wi_string_t * wi_file_read_to_string(wi_file_t *file, wi_string_t *separator) { wi_mutable_string_t *totalstring = NULL; wi_string_t *string; wi_uinteger_t index, length; _WI_FILE_ASSERT_OPEN(file); while((string = wi_file_read(file, WI_FILE_BUFFER_SIZE))) { if(!totalstring) totalstring = wi_string_init(wi_mutable_string_alloc()); index = wi_string_index_of_string(string, separator, 0); if(index == WI_NOT_FOUND) { wi_mutable_string_append_string(totalstring, string); } else { length = wi_string_length(string); wi_mutable_string_append_string(totalstring, wi_string_substring_to_index(string, index)); wi_file_seek(file, wi_file_offset(file) - length + index + 1); break; } } wi_runtime_make_immutable(string); return wi_autorelease(totalstring); }
static wi_string_t * _wi_set_description(wi_runtime_instance_t *instance) { wi_set_t *set = instance; _wi_set_bucket_t *bucket; wi_mutable_string_t *string; wi_string_t *description; wi_uinteger_t i; string = wi_mutable_string_with_format(WI_STR("<%@ %p>{count = %lu, mutable = %u, values = (\n"), wi_runtime_class_name(set), set, set->data_count, wi_runtime_options(set) & WI_RUNTIME_OPTION_MUTABLE ? 1 : 0); for(i = 0; i < set->buckets_count; i++) { for(bucket = set->buckets[i]; bucket; bucket = bucket->next) { if(set->callbacks.description) description = (*set->callbacks.description)(bucket->data); else description = wi_string_with_format(WI_STR("%p"), bucket->data); wi_mutable_string_append_format(string, WI_STR(" %@\n"), description); } } wi_mutable_string_append_string(string, WI_STR(")}")); wi_runtime_make_immutable(string); return string; }
static wi_string_t * _wi_p7_message_description(wi_runtime_instance_t *instance) { wi_p7_message_t *p7_message = instance; wi_enumerator_t *enumerator; wi_dictionary_t *fields; wi_mutable_string_t *string; wi_string_t *field_name, *field_value; string = wi_mutable_string_with_format(WI_STR("<%@ %p>{name = %@, buffer = %@, fields = (\n"), wi_runtime_class_name(p7_message), p7_message, p7_message->name, wi_data_with_bytes_no_copy(p7_message->binary_buffer, p7_message->binary_size, false)); fields = wi_p7_message_fields(p7_message); enumerator = wi_dictionary_key_enumerator(fields); while((field_name = wi_enumerator_next_data(enumerator))) { field_value = wi_dictionary_data_for_key(fields, field_name); wi_mutable_string_append_format(string, WI_STR(" %@ = %@\n"), field_name, field_value); } wi_mutable_string_append_string(string, WI_STR(")}")); wi_runtime_make_immutable(string); return string; }
wi_data_t * wi_file_read(wi_file_t *file, wi_uinteger_t length) { wi_mutable_data_t *data; char buffer[WI_FILE_BUFFER_SIZE]; wi_integer_t bytes = -1; _WI_FILE_ASSERT_OPEN(file); data = wi_data_init_with_capacity(wi_mutable_data_alloc(), length); while(length > 0) { bytes = wi_file_read_bytes(file, buffer, WI_MIN(sizeof(buffer), length)); if(bytes <= 0) break; wi_mutable_data_append_bytes(data, buffer, bytes); length -= bytes; } if(bytes < 0) { wi_release(data); data = NULL; } wi_runtime_make_immutable(data); return wi_autorelease(data); }
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; }
wi_data_t * wi_data_by_appending_bytes(wi_data_t *data, const void *bytes, wi_uinteger_t length) { wi_mutable_data_t *newdata; newdata = wi_copy(data); wi_mutable_data_append_bytes(newdata, bytes, length); wi_runtime_make_immutable(data); return wi_autorelease(newdata); }
wi_data_t * wi_data_by_appending_data(wi_data_t *data, wi_data_t *append_data) { wi_mutable_data_t *newdata; newdata = wi_mutable_copy(data); wi_mutable_data_append_bytes(newdata, append_data->bytes, append_data->length); wi_runtime_make_immutable(data); return wi_autorelease(newdata); }
wi_string_t * wi_time_interval_rfc3339_string(wi_time_interval_t interval) { wi_mutable_string_t *string; string = wi_mutable_copy(wi_time_interval_string_with_format(interval, WI_STR("%Y-%m-%dT%H:%M:%S%z"))); wi_mutable_string_insert_string_at_index(string, WI_STR(":"), 22); wi_runtime_make_immutable(string); return wi_autorelease(string); }
wi_string_t * wi_terminal_string_by_adjusting_to_fit_width(wi_terminal_t *terminal, wi_string_t *string) { wi_mutable_string_t *newstring; newstring = wi_mutable_copy(string); wi_terminal_adjust_string_to_fit_width(terminal, newstring); wi_runtime_make_immutable(newstring); return newstring; }
wi_string_t * wi_file_read_to_end_of_file(wi_file_t *file) { wi_mutable_string_t *string; char buffer[WI_FILE_BUFFER_SIZE]; wi_integer_t bytes; string = wi_string_init(wi_mutable_string_alloc()); while((bytes = wi_file_read_buffer(file, buffer, sizeof(buffer)))) wi_mutable_string_append_bytes(string, buffer, bytes); wi_runtime_make_immutable(string); return wi_autorelease(string); }
wi_array_t * wi_dictionary_keys_sorted_by_value(wi_dictionary_t *dictionary, wi_compare_func_t *compare) { wi_mutable_array_t *array, *buckets; _wi_dictionary_bucket_t *bucket; wi_array_callbacks_t callbacks; void **data; wi_uinteger_t i; if(dictionary->key_count == 0) return wi_autorelease(wi_array_init(wi_array_alloc())); callbacks.retain = NULL; callbacks.release = NULL; callbacks.is_equal = NULL; callbacks.description = NULL; buckets = wi_array_init_with_capacity_and_callbacks(wi_mutable_array_alloc(), dictionary->key_count, callbacks); for(i = 0; i < dictionary->buckets_count; i++) { for(bucket = dictionary->buckets[i]; bucket; bucket = bucket->next) wi_mutable_array_add_data(buckets, bucket); } data = wi_malloc(sizeof(void *) * dictionary->key_count); wi_array_get_data(buckets, data); #ifdef _WI_DICTIONARY_USE_QSORT_R qsort_r(data, dictionary->key_count, sizeof(void *), compare, _wi_dictionary_compare_buckets); #else wi_lock_lock(_wi_dictionary_sort_lock); _wi_dictionary_sort_function = compare; qsort(data, dictionary->key_count, sizeof(void *), _wi_dictionary_compare_buckets); wi_lock_unlock(_wi_dictionary_sort_lock); #endif callbacks.retain = dictionary->key_callbacks.retain; callbacks.release = dictionary->key_callbacks.release; callbacks.is_equal = dictionary->key_callbacks.is_equal; callbacks.description = dictionary->key_callbacks.description; array = wi_array_init_with_capacity_and_callbacks(wi_mutable_array_alloc(), dictionary->key_count, callbacks); for(i = 0; i < dictionary->key_count; i++) wi_mutable_array_add_data(array, ((_wi_dictionary_bucket_t *) data[i])->key); wi_free(data); wi_release(buckets); wi_runtime_make_immutable(array); return wi_autorelease(array); }
wi_string_t * wi_socket_read_string(wi_socket_t *socket, wi_time_interval_t timeout) { wi_mutable_string_t *string; char buffer[WI_SOCKET_BUFFER_SIZE]; int bytes = -1; string = wi_autorelease(wi_string_init_with_capacity(wi_mutable_string_alloc(), WI_SOCKET_BUFFER_SIZE)); bytes = _wi_socket_read_buffer(socket, timeout, buffer, WI_SOCKET_BUFFER_SIZE); if(bytes <= 0) return NULL; wi_mutable_string_append_bytes(string, buffer, bytes); wi_runtime_make_immutable(string); return string; }
static wi_string_t * _wi_number_description(wi_runtime_instance_t *instance) { wi_number_t *number = instance; wi_mutable_string_t *string; string = wi_mutable_string_with_format(WI_STR("<%@ %p>{value = "), wi_runtime_class_name(number), number); if(_wi_number_is_float(number)) wi_mutable_string_append_format(string, WI_STR("%f"), wi_number_double(number)); else wi_mutable_string_append_format(string, WI_STR("%lld"), wi_number_int64(number)); wi_mutable_string_append_string(string, WI_STR("}")); wi_runtime_make_immutable(string); return string; }
static wi_string_t * _wi_data_description(wi_runtime_instance_t *instance) { wi_data_t *data = instance; wi_mutable_string_t *string; const unsigned char *bytes; wi_uinteger_t i; string = wi_mutable_string(); bytes = data->bytes; for(i = 0; i < data->length; i++) { if(i > 0 && i % 4 == 0) wi_mutable_string_append_string(string, WI_STR(" ")); wi_mutable_string_append_format(string, WI_STR("%02X"), bytes[i]); } wi_runtime_make_immutable(string); return string; }
wi_array_t * wi_set_all_data(wi_set_t *set) { wi_array_t *array; _wi_set_bucket_t *bucket; wi_array_callbacks_t callbacks; wi_uinteger_t i; callbacks.retain = set->callbacks.retain; callbacks.release = set->callbacks.release; callbacks.is_equal = set->callbacks.is_equal; callbacks.description = set->callbacks.description; array = wi_array_init_with_capacity_and_callbacks(wi_mutable_array_alloc(), set->data_count, callbacks); for(i = 0; i < set->buckets_count; i++) { for(bucket = set->buckets[i]; bucket; bucket = bucket->next) wi_mutable_array_add_data(array, bucket->data); } wi_runtime_make_immutable(array); return wi_autorelease(array); }
wi_array_t * wi_dictionary_all_values(wi_dictionary_t *dictionary) { wi_array_t *array; _wi_dictionary_bucket_t *bucket; wi_array_callbacks_t callbacks; wi_uinteger_t i; callbacks.retain = dictionary->value_callbacks.retain; callbacks.release = dictionary->value_callbacks.release; callbacks.is_equal = dictionary->value_callbacks.is_equal; callbacks.description = dictionary->value_callbacks.description; array = wi_array_init_with_capacity_and_callbacks(wi_mutable_array_alloc(), dictionary->key_count, callbacks); for(i = 0; i < dictionary->buckets_count; i++) { for(bucket = dictionary->buckets[i]; bucket; bucket = bucket->next) wi_mutable_array_add_data(array, bucket->data); } wi_runtime_make_immutable(array); return wi_autorelease(array); }
wi_string_t * wi_file_read(wi_file_t *file, wi_uinteger_t length) { wi_mutable_string_t *string; char buffer[WI_FILE_BUFFER_SIZE]; wi_integer_t bytes = -1; _WI_FILE_ASSERT_OPEN(file); string = wi_string_init_with_capacity(wi_mutable_string_alloc(), length); while(length > sizeof(buffer)) { bytes = wi_file_read_buffer(file, buffer, sizeof(buffer)); if(bytes <= 0) goto end; wi_mutable_string_append_bytes(string, buffer, bytes); length -= bytes; } if(length > 0) { bytes = wi_file_read_buffer(file, buffer, sizeof(buffer)); if(bytes <= 0) goto end; wi_mutable_string_append_bytes(string, buffer, bytes); } end: if(bytes <= 0) { wi_release(string); string = NULL; } wi_runtime_make_immutable(string); return wi_autorelease(string); }
wi_array_t * wi_backtrace(void) { #ifdef HAVE_BACKTRACE wi_mutable_array_t *array; void *callstack[128]; char **symbols; int i, frames; frames = backtrace(callstack, sizeof(callstack)); symbols = backtrace_symbols(callstack, frames); array = wi_array_init_with_capacity(wi_mutable_array_alloc(), frames); for(i = 0; i < frames; i++) wi_mutable_array_add_data(array, wi_string_with_utf8_string(symbols[i])); free(symbols); wi_runtime_make_immutable(array); return wi_autorelease(array); #else return NULL; #endif }
wi_dictionary_t * wi_sqlite3_fetch_statement_results(wi_sqlite3_database_t *database, wi_sqlite3_statement_t *statement) { wi_mutable_dictionary_t *results; wi_runtime_instance_t *instance; int i, count, length, result; wi_recursive_lock_lock(database->lock); result = sqlite3_step(statement->statement); switch(result) { case SQLITE_DONE: results = wi_dictionary(); sqlite3_finalize(statement->statement); statement->statement = NULL; break; case SQLITE_ROW: results = wi_mutable_dictionary(); count = sqlite3_column_count(statement->statement); for(i = 0; i < count; i++) { switch(sqlite3_column_type(statement->statement, i)) { case SQLITE_INTEGER: instance = wi_number_with_int64(sqlite3_column_int64(statement->statement, i)); break; case SQLITE_FLOAT: instance = wi_number_with_double(sqlite3_column_double(statement->statement, i)); break; case SQLITE_TEXT: instance = wi_string_with_cstring((const char *) sqlite3_column_text(statement->statement, i)); break; case SQLITE_BLOB: length = sqlite3_column_bytes(statement->statement, i); instance = wi_data_with_bytes(sqlite3_column_blob(statement->statement, i), length); break; case SQLITE_NULL: instance = wi_null(); break; default: instance = NULL; break; } if(instance) wi_mutable_dictionary_set_data_for_key(results, instance, wi_string_with_cstring(sqlite3_column_name(statement->statement, i))); } wi_runtime_make_immutable(results); break; default: wi_error_set_sqlite3_error_with_description(database->database, wi_description(statement)); sqlite3_finalize(statement->statement); statement->statement = NULL; results = NULL; break; } wi_recursive_lock_unlock(database->lock); return results; }