f_print
f_signal
f_socket
+f_status_string
f_thread
f_time
build_language c
build_libraries -lc
-build_libraries-individual -lfll_error -lfll_print -lfll_program -lfl_conversion -lfl_fss -lfl_print -lf_color -lf_compare -lf_console -lf_conversion -lf_file -lf_fss -lf_memory -lf_network -lf_path -lf_pipe -lf_print -lf_signal -lf_socket -lf_string -lf_time -lf_type_array -lf_utf
+build_libraries-individual -lfll_error -lfll_print -lfll_program -lfl_conversion -lfl_fss -lfl_print -lf_color -lf_compare -lf_console -lf_conversion -lf_file -lf_fss -lf_memory -lf_network -lf_path -lf_pipe -lf_print -lf_signal -lf_socket -lf_status_string -lf_string -lf_time -lf_type_array -lf_utf
build_libraries-individual_thread -lf_thread
build_libraries-level -lfll_2 -lfll_1 -lfll_0
build_libraries-monolithic -lfll
* - maintain: The max size in bytes to maintain a particular buffer.
*
* kt_tacocat_packet_*_d:
+ * - headers: The number of header Objects in the abstruse to create for sending a packet (type, name, part, size, status, and total).
* - minimum: The minimum packet size, "header:\npayload:\n" = 17.
* - peek: The size to peek into the packet to get the initial information.
* - prebuffer: A size used to include during allocation to add additional space for the packet header and therefore help reduce the potential number of allocations.
#define kt_tacocat_max_buffer_d 0x10000000 // 0x10^0x5 * 0x100 (Which is 256 Megabytes (0x10^0x5 where the base unit is 16 rather than 10 or 2 (maybe call this xytes? Megaxytes?)).
#define kt_tacocat_max_maintain_d 0x100000 // 0x10^5 (Which is 1 Megabyte in base 16 (1 Megaxyte (MX)).
- #define kt_tacocat_packet_minimum_d 17
- #define kt_tacocat_packet_peek_d 64
+ #define kt_tacocat_packet_headers_d 0x6
+ #define kt_tacocat_packet_minimum_d 0x11
+ #define kt_tacocat_packet_peek_d 0x40
#define kt_tacocat_packet_prebuffer_d 0x200
- #define kt_tacocat_packet_read_d 0x2000
+ #define kt_tacocat_packet_read_d 0x8000
#define kt_tacocat_signal_check_d 0x4e20
#define kt_tacocat_signal_check_failsafe_d 0x4e20
}
#endif // _di_kt_tacocat_print_error_on_buffer_too_large_
+#ifndef _di_kt_tacocat_print_error_on_file_too_large_
+ f_status_t kt_tacocat_print_error_on_file_too_large(fl_print_t * const print, f_string_static_t file, f_string_static_t on, const f_string_static_t network, const f_number_unsigned_t size_expect, const f_number_unsigned_t size_got) {
+
+ if (!print) return F_status_set_error(F_output_not);
+ if (print->verbosity < f_console_verbosity_error_e) return F_output_not;
+
+ f_file_stream_lock(print->to);
+
+ fl_print_format("%[%QFile '%] ", print->to, print->set->error, print->prefix, print->set->error);
+ fl_print_format(f_string_format_Q_single_s.string, print->to, print->set->notable, on, print->set->notable);
+ fl_print_format(" %[' for '%]", print->to, print->set->error, print->set->error, f_string_eol_s);
+ fl_print_format(f_string_format_Q_single_s.string, print->to, print->set->notable, on, print->set->notable);
+ fl_print_format(" %[ for '%]", print->to, print->set->error, print->set->error, f_string_eol_s);
+ fl_print_format(f_string_format_Q_single_s.string, print->to, print->set->notable, network, print->set->notable);
+ fl_print_format("%[', the maximum size is%] ", print->to, print->set->error, print->set->error);
+ fl_print_format("%[%ul%]", print->to, print->set->notable, size_expect, print->set->notable);
+ fl_print_format("%[, and the provided size is%] ", print->to, print->set->error, print->set->error);
+ fl_print_format("%[%ul%]", print->to, print->set->notable, size_got, print->set->notable);
+ fl_print_format(f_string_format_sentence_end_s.string, print->to, print->set->error, print->set->error, f_string_eol_s);
+
+ f_file_stream_unlock(print->to);
+
+ return F_okay;
+ }
+#endif // _di_kt_tacocat_print_error_on_file_too_large_
+
#ifndef _di_kt_tacocat_print_error_on_busy_
f_status_t kt_tacocat_print_error_on_busy(fl_print_t * const print, f_string_static_t on, const f_string_static_t network) {
}
#endif // _di_kt_tacocat_print_error_on_busy_
-#ifndef _di_kt_tacocat_print_error_on_file_
- f_status_t kt_tacocat_print_error_on_file(fl_print_t * const print, const f_string_t function, f_string_static_t on, const f_string_static_t network, const f_status_t status, const f_string_static_t name, const f_string_static_t operation) {
+#ifndef _di_kt_tacocat_print_error_on_file_receive_
+ f_status_t kt_tacocat_print_error_on_file_receive(fl_print_t * const print, const f_string_t function, f_string_static_t on, const f_string_static_t network, const f_status_t status, const f_string_static_t name, const f_string_static_t operation) {
+
+ if (!print || !print->custom) return F_status_set_error(F_output_not);
+ if (print->verbosity < f_console_verbosity_error_e) return F_output_not;
+
+ f_file_stream_lock(print->to);
+
+ fl_print_format("%[%QNetwork on%] ", print->to, print->set->error, print->prefix, print->set->error);
+ fl_print_format(f_string_format_Q_single_s.string, print->to, print->set->notable, on, print->set->notable);
+ fl_print_format(" %[for '%]", print->to, print->set->error, print->set->error, f_string_eol_s);
+ fl_print_format(f_string_format_Q_single_s.string, print->to, print->set->notable, network, print->set->notable);
+ fl_print_format("%[' failed to receive data or write to file '%]", print->to, print->set->error, print->set->error, f_string_eol_s);
+ fl_print_format(f_string_format_Q_single_s.string, print->to, print->set->notable, name, print->set->notable);
+ fl_print_format("%['.%]%r", print->to, print->set->error, print->set->error, f_string_eol_s);
+
+ f_file_stream_unlock(print->to);
+
+ fll_error_file_print(print, F_status_set_fine(((kt_tacocat_main_t *) print->custom)->setting.state.status), function, F_true, name, operation, fll_error_file_type_file_e);
+ }
+#endif // _di_kt_tacocat_print_error_on_file_receive_
+
+#ifndef _di_kt_tacocat_print_error_on_file_send_
+ f_status_t kt_tacocat_print_error_on_file_send(fl_print_t * const print, const f_string_t function, f_string_static_t on, const f_string_static_t network, const f_status_t status, const f_string_static_t name, const f_string_static_t operation) {
if (!print || !print->custom) return F_status_set_error(F_output_not);
if (print->verbosity < f_console_verbosity_error_e) return F_output_not;
fl_print_format(f_string_format_Q_single_s.string, print->to, print->set->notable, on, print->set->notable);
fl_print_format(" %[for '%]", print->to, print->set->error, print->set->error, f_string_eol_s);
fl_print_format(f_string_format_Q_single_s.string, print->to, print->set->notable, network, print->set->notable);
- fl_print_format("%[' failed to write to file '%]", print->to, print->set->error, print->set->error, f_string_eol_s);
+ fl_print_format("%[' failed to send data or read from file '%]", print->to, print->set->error, print->set->error, f_string_eol_s);
fl_print_format(f_string_format_Q_single_s.string, print->to, print->set->notable, name, print->set->notable);
fl_print_format("%['.%]%r", print->to, print->set->error, print->set->error, f_string_eol_s);
fll_error_file_print(print, F_status_set_fine(((kt_tacocat_main_t *) print->custom)->setting.state.status), function, F_true, name, operation, fll_error_file_type_file_e);
}
-#endif // _di_kt_tacocat_print_error_on_file_
+#endif // _di_kt_tacocat_print_error_on_file_send_
#ifndef _di_kt_tacocat_print_error_on_packet_too_small_
f_status_t kt_tacocat_print_error_on_packet_too_small(fl_print_t * const print, f_string_static_t on, const f_string_static_t network, const f_number_unsigned_t size_expect, const f_number_unsigned_t size_got) {
#endif // _di_kt_tacocat_print_error_on_buffer_too_large_
/**
+ * Print network-related error message for when file is too large to send.
+ *
+ * @param print
+ * The output structure to print to.
+ *
+ * This does not alter print.custom.setting.state.status.
+ * @param file
+ * The name of the file.
+ * @param on
+ * The network connection direction, which should either be "receive" or "send".
+ * @param network
+ * The name of the network in which the error is related.
+ * @param size_max
+ * The maximum buffer size.
+ * @param size_got
+ * The provided buffer size.
+ *
+ * @return
+ * F_okay on success.
+ * F_output_not on success, but no printing is performed.
+ *
+ * F_output_not (with error bit) if setting is NULL.
+ *
+ * @see fll_error_file_print()
+ */
+#ifndef _di_kt_tacocat_print_error_on_file_too_large_
+ extern f_status_t kt_tacocat_print_error_on_file_too_large(fl_print_t * const print, f_string_static_t file, f_string_static_t on, const f_string_static_t network, const f_number_unsigned_t size_expect, const f_number_unsigned_t size_got);
+#endif // _di_kt_tacocat_print_error_on_file_too_large_
+
+/**
* Print network-related error message for when the connection is busy.
*
* @param print
#ifndef _di_kt_tacocat_print_error_on_busy_
extern f_status_t kt_tacocat_print_error_on_busy(fl_print_t * const print, f_string_static_t on, const f_string_static_t network);
#endif // _di_kt_tacocat_print_error_on_busy_
+
+/**
+ * Print network-related error message regarding receiving the network data or writing the network data to a file.
+ *
+ * @param print
+ * The output structure to print to.
+ *
+ * This does not alter print.custom.setting.state.status.
+ * @param function
+ * The name of the function where the error happened.
+ * Set to 0 to disable.
+ * @param on
+ * The network connection direction, which should either be "receive" or "send".
+ * @param network
+ * The name of the network in which the error is related.
+ * @param status
+ * The status code representing the error.
+ * @param name
+ * The name of the file or directory.
+ * @param operation
+ * The file operation that fails, such as 'open' or 'write'.
+ *
+ * @return
+ * F_okay on success.
+ * F_output_not on success, but no printing is performed.
+ *
+ * F_output_not (with error bit) if setting is NULL.
+ *
+ * @see fll_error_file_print()
+ */
+#ifndef _di_kt_tacocat_print_error_on_file_receive_
+ extern f_status_t kt_tacocat_print_error_on_file_receive(fl_print_t * const print, const f_string_t function, f_string_static_t on, const f_string_static_t network, const f_status_t status, const f_string_static_t name, const f_string_static_t operation);
+#endif // _di_kt_tacocat_print_error_on_file_receive_
+
/**
- * Print network-related error message regarding the writing the network data to a file.
+ * Print network-related error message regarding sending to the network data or reading the file.
*
* @param print
* The output structure to print to.
*
* @see fll_error_file_print()
*/
-#ifndef _di_kt_tacocat_print_error_on_file_
- extern f_status_t kt_tacocat_print_error_on_file(fl_print_t * const print, const f_string_t function, f_string_static_t on, const f_string_static_t network, const f_status_t status, const f_string_static_t name, const f_string_static_t operation);
-#endif // _di_kt_tacocat_print_error_on_file_
+#ifndef _di_kt_tacocat_print_error_on_file_send_
+ extern f_status_t kt_tacocat_print_error_on_file_send(fl_print_t * const print, const f_string_t function, f_string_static_t on, const f_string_static_t network, const f_status_t status, const f_string_static_t name, const f_string_static_t operation);
+#endif // _di_kt_tacocat_print_error_on_file_send_
/**
* Print network-related error message for when the connection is busy.
set->status = f_file_open(set->name, F_file_mode_all_rw_d, &set->file);
if (F_status_is_error(set->status)) {
- kt_tacocat_print_error_on_file(&main->program.error, macro_kt_tacocat_f(f_file_open), kt_tacocat_receive_s, set->network, set->status, set->name, f_file_operation_open_s);
+ kt_tacocat_print_error_on_file_receive(&main->program.error, macro_kt_tacocat_f(f_file_open), kt_tacocat_receive_s, set->network, set->status, set->name, f_file_operation_open_s);
return;
}
// Keep going on error, but in the future more advanced error handling/recovery is needed to make this more robust.
if (F_status_is_error(set->status)) {
- kt_tacocat_print_error_on_file(&main->program.error, macro_kt_tacocat_f(f_file_write), kt_tacocat_receive_s, set->network, set->status, set->name, f_file_operation_write_s);
+ kt_tacocat_print_error_on_file_receive(&main->program.error, macro_kt_tacocat_f(f_file_write), kt_tacocat_receive_s, set->network, set->status, set->name, f_file_operation_write_s);
}
// Reset buffer used and increment counter.
// @todo this needs a max retries for sending without error, possibly resetting depending on the part (flag).
if (!set->flag) {
+ set->abstruses.used = 0;
+ set->buffer.used = 0;
+ set->header.used = 0;
+ set->headers.used = 0;
set->size_done = 0;
+ // Initialize the default file payload.
+ set->status = f_memory_array_increase_by(kt_tacocat_packet_headers_d, sizeof(f_string_map_t), (void **) &set->headers.array, &set->headers.used, &set->headers.size);
+ macro_kt_send_process_handle_error_exit_1(main, f_memory_array_increase_by, set->network, set->status, set->flag);
+
+ set->status = f_memory_array_increase_by(kt_tacocat_packet_prebuffer_d, sizeof(f_char_t), (void **) &set->header.string, &set->header.used, &set->header.size);
+ macro_kt_send_process_handle_error_exit_1(main, f_memory_array_increase_by, set->network, set->status, set->flag);
+
+ set->status = f_memory_array_increase_by(kt_tacocat_packet_headers_d, sizeof(f_abstruse_map_t), (void **) &set->abstruses.array, &set->abstruses.used, &set->abstruses.size);
+ macro_kt_send_process_handle_error_exit_1(main, f_memory_array_increase_by, set->network, set->status, set->flag);
+
+ // Make sure the buffer is large enough for the file block reads (including a space for a terminating NULL).
+ set->status = f_memory_array_increase_by(set->file.size_read + f_fss_payload_object_payload_s.used + f_fss_payload_object_end_s.used + 2, sizeof(f_char_t), (void **) &set->buffer.string, &set->buffer.used, &set->buffer.size);
+ macro_kt_send_process_handle_error_exit_1(main, f_memory_array_increase_by, set->network, set->status, set->flag);
+
+ // Index 0 is the status.
+ set->abstruses.array[0].key = f_fss_payload_object_status_s;
+ set->abstruses.array[0].value.type = f_abstruse_dynamic_e;
+ set->abstruses.array[0].value.is.a_dynamic = f_status_okay_s;
+
+ // Index 1 is the type.
+ set->abstruses.array[1].key = f_fss_payload_object_type_s;
+ set->abstruses.array[1].value.type = f_abstruse_dynamic_e;
+ set->abstruses.array[1].value.is.a_dynamic = f_file_type_name_file_s;
+
+ // Index 2 is the length.
+ set->abstruses.array[2].key = f_fss_payload_object_length_s;
+ set->abstruses.array[2].value.type = f_abstruse_unsigned_e;
+ set->abstruses.array[2].value.is.a_unsigned = 0;
+
+ // Index 3 is the part.
+ set->abstruses.array[3].key = f_fss_payload_object_part_s;
+ set->abstruses.array[3].value.type = f_abstruse_unsigned_e;
+ set->abstruses.array[3].value.is.a_unsigned = 0;
+
+ // Index 4 is the total (size of file).
+ set->abstruses.array[4].key = f_fss_payload_object_total_s;
+ set->abstruses.array[4].value.type = f_abstruse_unsigned_e;
+ set->abstruses.array[4].value.is.a_unsigned = 0;
+
+ // Index 5 is the name.
+ set->abstruses.array[5].key = f_fss_payload_object_name_s;
+ set->abstruses.array[5].value.type = f_abstruse_dynamic_e;
+ set->abstruses.array[5].value.is.a_dynamic = set->name;
+
set->status = f_file_open(set->name, F_file_mode_all_r_d, &set->file);
if (F_status_is_error(set->status)) {
- kt_tacocat_print_error_on_file(&main->program.error, macro_kt_tacocat_f(f_file_open), kt_tacocat_send_s, set->network, set->status, set->name, f_file_operation_open_s);
+ kt_tacocat_print_error_on_file_receive(&main->program.error, macro_kt_tacocat_f(f_file_open), kt_tacocat_send_s, set->network, set->status, set->name, f_file_operation_open_s);
return F_done_not;
}
set->status = f_file_size_by_id(set->file, &total);
if (F_status_is_error(set->status)) {
- kt_tacocat_print_error_on_file(&main->program.error, macro_kt_tacocat_f(f_file_size_by_id), kt_tacocat_send_s, set->network, set->status, set->name, f_file_operation_open_s);
+ kt_tacocat_print_error_on_file_receive(&main->program.error, macro_kt_tacocat_f(f_file_size_by_id), kt_tacocat_send_s, set->network, set->status, set->name, f_file_operation_open_s);
return F_done_not;
}
- set->size_total = (size_t) total; // @todo there is a size_total, but there is a total packet size and a total payload size. Find a way to distinguish both.
+ if ((f_number_unsigned_t) total > F_number_t_size_unsigned_d) {
+ set->status = F_status_set_error(F_too_large);
+
+ kt_tacocat_print_error_on_file_too_large(&main->program.error, set->name, kt_tacocat_send_s, set->network, F_number_t_size_unsigned_d, set->abstruses.array[4].value.is.a_unsigned);
+
+ return F_done_not;
+ }
+
+ set->abstruses.array[4].value.is.a_unsigned = (f_number_unsigned_t) total;
set->flag = kt_tacocat_socket_flag_send_file_e;
}
if (set->flag == kt_tacocat_socket_flag_send_file_e) {
set->buffer.used = 0;
- // Make sure the buffer is large enough for the file block reads (including a space for a terminating NULL).
- set->status = f_memory_array_increase_by(set->file.size_read + f_fss_payload_object_payload_s.used + f_fss_payload_object_end_s.used + 1, sizeof(f_char_t), (void **) &set->buffer.string, &set->buffer.used, &set->buffer.size);
- macro_kt_send_process_handle_error_exit_1(main, f_memory_array_increase_by, set->network, set->status, set->flag);
-
set->status = f_string_dynamic_append(f_fss_payload_object_payload_s, &set->buffer);
macro_kt_send_process_handle_error_exit_1(main, f_file_read_block, set->network, set->status, set->flag);
set->status = f_string_dynamic_append(f_fss_payload_object_end_s, &set->buffer);
macro_kt_send_process_handle_error_exit_1(main, f_file_read_block, set->network, set->status, set->flag);
+ // Each block is sent one at a time.
set->status = f_file_read_block(set->file, &set->buffer);
macro_kt_send_process_handle_error_exit_1(main, f_file_read_block, set->network, set->status, set->flag);
if (set->flag == kt_tacocat_socket_flag_send_build_e) {
set->header.used = 0;
- if (set->buffer.used) {
- set->status = f_memory_array_increase_by(kt_tacocat_packet_prebuffer_d, sizeof(f_char_t), (void **) &set->header.string, &set->header.used, &set->header.size);
- macro_kt_send_process_handle_error_exit_1(main, f_memory_array_increase_by, set->network, set->status, set->flag);
-
+ if (set->header.used) {
f_state_t state_local = main->setting.state;
state_local.data = &set->write_state;
// 1) type file (or string, and if file, then name is filesize and size is filesize, otherwise name is unused and size is string length.)
// 1) name "example.csv"
// 2) size 1234
- // 3) status F_okay
+ // 3) status F_okay (f_status_okay_s)
// @todo
// 1) Build abstruse headers map of data.
*
* F_packet_too_large (with error bit) on total packet size is too large.
* F_payload_too_large (with error bit) on total payload size is too large.
+ * F_too_large (with error bit) on file too large.
* @param set
* The socket set to process.
* Must not be NULL.
*
+ * @todo Processing and logic around the return status needs to reviewed and updated.
+ *
* @see f_socket_read_stream()
*/
#ifndef _di_kt_tacocat_send_process_
#include <fll/level_0/print.h>
#include <fll/level_0/signal.h>
#include <fll/level_0/socket.h>
+#include <fll/level_0/status_string.h>
#include <fll/level_0/time.h>
#include <fll/level_0/thread.h>