From: Kevin Day Date: Tue, 16 Jan 2024 23:59:37 +0000 (-0600) Subject: Progress: Continue adding FSS Payload processing code. X-Git-Url: https://git.kevux.org/?a=commitdiff_plain;h=5333431dcc8ac48e53fa8c476d28bb43da8155f6;p=fll Progress: Continue adding FSS Payload processing code. I did a lot of cleaning up and reorganization. This adds a several flags that I intended to use but the current state of these is highly subject to change. There are still a lot of incomplete changes, especially regarding existing code and the newly added flags. --- diff --git a/build/level_1/settings b/build/level_1/settings index 926b599..9395ecc 100644 --- a/build/level_1/settings +++ b/build/level_1/settings @@ -38,7 +38,7 @@ build_sources_library control_group.c build_sources_library conversion.c private-conversion.c conversion/common.c build_sources_library directory.c private-directory.c build_sources_library environment.c -build_sources_library private-fss.c fss/basic.c fss/basic_list.c fss/embedded_list.c fss/extended.c fss/extended_list.c fss/payload.c +build_sources_library private-fss.c fss/basic.c fss/basic_list.c fss/embedded_list.c fss/extended.c fss/extended_list.c fss/payload.c fss/private-payload.c build_sources_library iki.c build_sources_library path.c build_sources_library print.c private-print.c print/common.c diff --git a/build/monolithic/settings b/build/monolithic/settings index fb943cf..60a04cc 100644 --- a/build/monolithic/settings +++ b/build/monolithic/settings @@ -86,7 +86,7 @@ build_sources_library level_1/control_group.c build_sources_library level_1/conversion.c level_1/private-conversion.c level_1/conversion/common.c build_sources_library level_1/directory.c level_1/private-directory.c build_sources_library level_1/environment.c -build_sources_library level_1/private-fss.c level_1/fss/basic.c level_1/fss/basic_list.c level_1/fss/embedded_list.c level_1/fss/extended.c level_1/fss/extended_list.c level_1/fss/payload.c +build_sources_library level_1/private-fss.c level_1/fss/basic.c level_1/fss/basic_list.c level_1/fss/embedded_list.c level_1/fss/extended.c level_1/fss/extended_list.c level_1/fss/payload.c level_1/fss/private-payload.c build_sources_library level_1/iki.c build_sources_library level_1/path.c build_sources_library level_1/print.c level_1/private-print.c level_1/print/common.c diff --git a/level_0/f_fss/c/fss/payload.h b/level_0/f_fss/c/fss/payload.h index 4deb92a..906e08b 100644 --- a/level_0/f_fss/c/fss/payload.h +++ b/level_0/f_fss/c/fss/payload.h @@ -19,24 +19,58 @@ extern "C" { /** * Flags used by the FSS-000E (Payload) header map functions. * - * Values of f_fss_payload_header_map_*_e: - * - none: No map flag set. - * - base_2: Convert number to string using base 2. - * - base_8: Convert number to string using base 8. - * - base_10: Convert number to string using base 10. - * - base_12: Convert number to string using base 12. - * - base_16: Convert number to string using base 16. + * When both *_split_range_e and *_split_ranges_e are set, then both the individual ranges and the range sets are split into separate Content (separate columns). + * + * Values of f_fss_payload_header_map_flag_*_e: + * - none: No flag set. + * - join_digits: Types of digits are combined into a single Content (single column). + * - join_dynamics: Types of dynamics are combined into a single Content (single column). + * - join_map: Types of map are combined into a single Content (single column), example: "key1 value1" "key2 value2" as opposed to "key1" "value1" "key2" "value2". + * - join_maps: Types of maps are combined into a single Content (single column), example: "key1 value1 key2 value2" as opposed to "key1 value1" "key2 value2" or "key1" "value1" "key2" "value2". + * - join_range: Types of range are combined into a single Content (single column). + * - join_ranges: Types of ranges are combined into a single Content (single column) (this effectively forces join_range to always be treated as set). + * - join_strings: Types of strings are combined into a single Content (single column). + * - join_triple: Types of triple are combined into a single Content (single column), example: "a b c" "d e f" as opposed to "a" "b" "c" "d" "e" "f". + * - join_triples: Types of triples are combined into a single Content (single column), example: "a b c d e f" as opposed to "a b c" "d e f" or "a" "b" "c" "d" "e" "f". + * - null: When the key has no header Content (header value.used is 0), still add the Object (header key) (When this is not set then the Object (header key) is not added). + * - null_dynamic: Types of dynamic and dynamics have empty strings (such as "") added for NULL values (used is 0). + * - null_map_key: Types of map and maps has empty strings (such as "") added for NULL values (used is 0) for the map key. + * - null_map_value: Types of map and maps has empty strings (such as "") added for NULL values (used is 0) for the map value. + * - null_maps: Types of dynamic and dynamics have empty strings (such as "") added for when null_map_key and null_map_value are not set and both map key and map value have NULL values (used is 0). + * - null_string: Types of string and strings have empty strings (such as "") for NULL values. + * - null_triple_a: Types of triple and triples has empty strings (such as "") added for NULL values (used is 0) for the "a" property. + * - null_triple_b: Types of triple and triples has empty strings (such as "") added for NULL values (used is 0) for the "b" property. + * - null_triple_c: Types of triple and triples has empty strings (such as "") added for NULL values (used is 0) for the "c" property. + * - quote_double: Use double quotes (U+0022) when quoting strings. + * - quote_grave: Use grave (U+0060) when quoting strings. + * - quote_single: Use single quotes (U+0027) when quoting strings. + * - last: This does nothing and is provided to be used as a starting point for anything extending this (there should be a max total of 64 bits allowed). */ -#ifndef _di_f_fss_payload_header_map_e_ +#ifndef _di_f_fss_payload_header_map_flag_e_ enum { - f_fss_payload_header_map_none_e = 0x0, - f_fss_payload_header_map_base_2_e = 0x1, - f_fss_payload_header_map_base_8_e = 0x2, - f_fss_payload_header_map_base_10_e = 0x4, - f_fss_payload_header_map_base_12_e = 0x8, - f_fss_payload_header_map_base_16_e = 0x10, + f_fss_payload_header_map_flag_none_e = 0x0, + f_fss_payload_header_map_flag_join_digits_e = 0x1, + f_fss_payload_header_map_flag_join_dynamics_e = 0x2, + f_fss_payload_header_map_flag_join_range_e = 0x4, + f_fss_payload_header_map_flag_join_ranges_e = 0x8, + f_fss_payload_header_map_flag_join_strings_e = 0x10, + f_fss_payload_header_map_flag_join_triple_e = 0x20, + f_fss_payload_header_map_flag_join_triples_e = 0x40, + f_fss_payload_header_map_flag_null_e = 0x80, + f_fss_payload_header_map_flag_null_dynamic_e = 0x100, + f_fss_payload_header_map_flag_null_map_key_e = 0x200, + f_fss_payload_header_map_flag_null_map_value_e = 0x400, + f_fss_payload_header_map_flag_null_maps_e = 0x800, + f_fss_payload_header_map_flag_null_triple_a_e = 0x1000, + f_fss_payload_header_map_flag_null_triple_b_e = 0x2000, + f_fss_payload_header_map_flag_null_triple_c_e = 0x4000, + f_fss_payload_header_map_flag_null_string_e = 0x8000, + f_fss_payload_header_map_flag_quote_double_e = 0x10000, + f_fss_payload_header_map_flag_quote_grave_e = 0x20000, + f_fss_payload_header_map_flag_quote_single_e = 0x40000, + f_fss_payload_header_map_flag_last_e = 0x80000, }; // enum -#endif // _di_f_fss_payload_header_map_e_ +#endif // _di_f_fss_payload_header_flag_map_e_ /** * FSS-000E (Payload) strings. diff --git a/level_1/fl_fss/c/fss/payload.c b/level_1/fl_fss/c/fss/payload.c index 2ec5c69..b397e81 100644 --- a/level_1/fl_fss/c/fss/payload.c +++ b/level_1/fl_fss/c/fss/payload.c @@ -1,158 +1,11 @@ #include "payload.h" #include "../private-fss.h" +#include "private-payload.h" #ifdef __cplusplus extern "C" { #endif -#ifndef _di_fl_fss_payload_header_write_ - /** - * Inline helper function to reduce amount of code typed. - * - * Process the signed number, converting it to a string and appending that string onto data->cache. - * The resulting data->cache is then appended onto the destination value on success. - * If the number is not appended to data->cache, then nothing is appended to the destination value. - * - * @param data - * The f_fss_payload_header_write_state_t pointer. - * This resets data->cache.used as needed. - * @param state - * The state passed directly from the f_fss_payload_header_write() parameters. - * @param internal - * The internal state, f_fss_payload_header_write_internal_t, created inside of f_fss_payload_header_write(). - * @param number - * The signed number. - * - * @return - * F_true if the caller should break or exit due to an error or something similar. - * F_false, otherwise. - */ - static inline uint8_t private_inline_f_payload_header_write_number_signed(f_fss_payload_header_write_state_t * const data, f_state_t * const state, f_fss_payload_header_write_internal_t * const internal, const f_number_signed_t number) { - - data->cache->used = 0; - - state->status = f_conversion_number_signed_to_string(number, data->conversion, data->cache); - if (F_status_is_error(state->status)) return F_true; - - if (data->cache->used) { - internal->range.start = 0; - internal->range.stop = data->cache->used - 1; - - private_fl_fss_basic_write(F_false, *data->cache, 0, &internal->range, &internal->destinations->array[internal->destinations->used].value, state, (void * const) internal); - if (F_status_is_error(state->status)) return F_true; - - // Strip NULLs that may have been introduced via private_fl_fss_basic_write(). - if (data->cache->used) { - f_number_unsigned_t i = data->cache->used; - f_number_unsigned_t j = 0; - f_number_unsigned_t total = 0; - - while (--i) { - - if (!data->cache->string[i]) { - total = 1; - - for (j = i - 1; j && !data->cache->string[j]; ++total, --j) { - // Do nothing. - } // for - - if (!j) { - if (!data->cache->string[j]) { - ++total; - } - else { - ++j; - } - } - - memmove(data->cache->string + j, data->cache->string + i + 1, total); - - data->cache->used -= total; - i = j; - - if (!i) break; - } - } // while - } - } - - return F_false; - } - - /** - * Inline helper function to reduce amount of code typed. - * - * Process the unsigned number, converting it to a string and appending that string onto data->cache. - * The resulting data->cache is then appended onto the destination value on success. - * If the number is not appended to data->cache, then nothing is appended to the destination value. - * - * @param data - * The f_fss_payload_header_write_state_t pointer. - * This resets data->cache.used as needed. - * @param state - * The state passed directly from the f_fss_payload_header_write() parameters. - * @param internal - * The internal state, f_fss_payload_header_write_internal_t, created inside of f_fss_payload_header_write(). - * @param number - * The unsigned number. - * - * @return - * F_true if the caller should break or exit due to an error or something similar. - * F_false, otherwise. - */ - static inline uint8_t private_inline_f_payload_header_write_number_unsigned(f_fss_payload_header_write_state_t * const data, f_state_t * const state, f_fss_payload_header_write_internal_t * const internal, const f_number_unsigned_t number) { - - data->cache->used = 0; - - state->status = f_conversion_number_unsigned_to_string(number, data->conversion, data->cache); - if (F_status_is_error(state->status)) return F_true; - - if (data->cache->used) { - internal->range.start = 0; - internal->range.stop = data->cache->used - 1; - - private_fl_fss_basic_write(F_false, *data->cache, 0, &internal->range, &internal->destinations->array[internal->destinations->used].value, state, (void * const) internal); - if (F_status_is_error(state->status)) return F_true; - - // Strip NULLs that may have been introduced via private_fl_fss_basic_write(). - if (data->cache->used) { - f_number_unsigned_t i = data->cache->used; - f_number_unsigned_t j = 0; - f_number_unsigned_t total = 0; - - while (--i) { - - if (!data->cache->string[i]) { - total = 1; - - for (j = i - 1; j && !data->cache->string[j]; ++total, --j) { - // Do nothing. - } // for - - if (!j) { - if (!data->cache->string[j]) { - ++total; - } - else { - ++j; - } - } - - memmove(data->cache->string + j, data->cache->string + i + 1, total); - - data->cache->used -= total; - i = j; - - if (!i) break; - } - } // while - } - } - - return F_false; - } -#endif // _di_fl_fss_payload_header_write_ - #ifndef _di_fl_fss_payload_header_map_ void fl_fss_payload_header_map(const f_abstruse_maps_t headers, f_string_maps_t * const destinations, f_state_t * const state) { #ifndef _di_level_1_parameter_checking_ @@ -169,8 +22,8 @@ extern "C" { } #endif // _di_level_1_parameter_checking_ - f_fss_payload_header_write_state_t * const data = (f_fss_payload_header_write_state_t *) state->data; - f_fss_payload_header_write_internal_t internal = macro_f_fss_payload_header_write_internal_t_initialize_2(destinations, destinations->used); + f_fss_payload_header_state_t * const data = (f_fss_payload_header_state_t *) state->data; + f_fss_payload_header_internal_t internal = macro_f_fss_payload_header_internal_t_initialize_2(destinations, destinations->used); if (!data->cache) { state->status = F_status_set_error(F_parameter); @@ -192,6 +45,13 @@ extern "C" { internal.j = 0; internal.k = 0; internal.l = 0; + internal.quote = f_fss_payload_header_map_flag_quote_double_e + ? f_string_ascii_quote_double_s.string[0] + : f_fss_payload_header_map_flag_quote_single_e + ? f_string_ascii_quote_single_s.string[0] + : f_fss_payload_header_map_flag_quote_grave_e + ? f_string_ascii_grave_s.string[0] + : 0; state->status = f_memory_array_increase_by(headers.used, sizeof(f_string_map_t), (void **) &destinations->array, &destinations->used, &destinations->size); @@ -215,20 +75,26 @@ extern "C" { internal.range.start = 0; internal.range.stop = headers.array[internal.i].key.used - 1; - private_fl_fss_basic_write(F_true, headers.array[internal.i].key, 0, &internal.range, &destinations->array[destinations->used].name, state, (void * const) &internal); + private_fl_fss_basic_write(F_true, headers.array[internal.i].key, internal.quote, &internal.range, &destinations->array[destinations->used].name, state, (void * const) &internal); + + if (F_status_is_error_not(state->status)) { + state->status = f_string_dynamic_strip_null(&destinations->array[destinations->used].name); + } if (F_status_is_error_not(state->status)) { - // @todo need flag to specify whether or not to append NULL for single-valued and one for multi-valued number conversion results in invalid or does not exist. - // @todo the same for single-valued strings and multi-valued strings (like maps). - // @todo need a flag to designate whether to use single, double quotes, or auto. switch (headers.array[internal.i].value.type) { case f_abstruse_none_e: case f_abstruse_void_e: case f_abstruse_voids_e: + // Voids and none are unknown or non-existent and so they cannot be converted. break; case f_abstruse_signed_e: - private_inline_f_payload_header_write_number_signed(data, state, &internal, headers.array[internal.i].value.is.a_signed); + data->cache->used = 0; + + if (private_fl_payload_header_map_number_signed(data, state, &internal, headers.array[internal.i].value.is.a_signed) == F_false) { + private_fl_payload_header_map_cache(data, state, &internal); + } if (F_status_is_error_not(state->status)) { ++destinations->used; @@ -237,7 +103,11 @@ extern "C" { break; case f_abstruse_unsigned_e: - private_inline_f_payload_header_write_number_unsigned(data, state, &internal, headers.array[internal.i].value.is.a_unsigned); + data->cache->used = 0; + + if (private_fl_payload_header_map_number_unsigned(data, state, &internal, headers.array[internal.i].value.is.a_unsigned) == F_false) { + private_fl_payload_header_map_cache(data, state, &internal); + } if (F_status_is_error_not(state->status)) { ++destinations->used; @@ -246,52 +116,52 @@ extern "C" { break; case f_abstruse_int8s_e: - macro_f_fss_payload_header_write_process_signed_numbers_d(data, state, internal, headers.array[internal.i].value.is.a_i8s, destinations->array[destinations->used].value); + macro_f_fss_payload_header_write_process_numbers_signed_d(data, state, internal, headers.array[internal.i].value.is.a_i8s, destinations->array[destinations->used].value); break; case f_abstruse_int16s_e: - macro_f_fss_payload_header_write_process_signed_numbers_d(data, state, internal, headers.array[internal.i].value.is.a_i16s, destinations->array[destinations->used].value); + macro_f_fss_payload_header_write_process_numbers_signed_d(data, state, internal, headers.array[internal.i].value.is.a_i16s, destinations->array[destinations->used].value); break; case f_abstruse_int32s_e: - macro_f_fss_payload_header_write_process_signed_numbers_d(data, state, internal, headers.array[internal.i].value.is.a_i32s, destinations->array[destinations->used].value); + macro_f_fss_payload_header_write_process_numbers_signed_d(data, state, internal, headers.array[internal.i].value.is.a_i32s, destinations->array[destinations->used].value); break; case f_abstruse_int64s_e: - macro_f_fss_payload_header_write_process_signed_numbers_d(data, state, internal, headers.array[internal.i].value.is.a_i64s, destinations->array[destinations->used].value); + macro_f_fss_payload_header_write_process_numbers_signed_d(data, state, internal, headers.array[internal.i].value.is.a_i64s, destinations->array[destinations->used].value); break; case f_abstruse_signeds_e: - macro_f_fss_payload_header_write_process_signed_numbers_d(data, state, internal, headers.array[internal.i].value.is.a_signeds, destinations->array[destinations->used].value); + macro_f_fss_payload_header_write_process_numbers_signed_d(data, state, internal, headers.array[internal.i].value.is.a_signeds, destinations->array[destinations->used].value); break; case f_abstruse_uint8s_e: - macro_f_fss_payload_header_write_process_unsigned_numbers_d(data, state, internal, headers.array[internal.i].value.is.a_u8s, destinations->array[destinations->used].value); + macro_f_fss_payload_header_write_process_numbers_unsigned_d(data, state, internal, headers.array[internal.i].value.is.a_u8s, destinations->array[destinations->used].value); break; case f_abstruse_uint16s_e: - macro_f_fss_payload_header_write_process_unsigned_numbers_d(data, state, internal, headers.array[internal.i].value.is.a_u16s, destinations->array[destinations->used].value); + macro_f_fss_payload_header_write_process_numbers_unsigned_d(data, state, internal, headers.array[internal.i].value.is.a_u16s, destinations->array[destinations->used].value); break; case f_abstruse_uint32s_e: - macro_f_fss_payload_header_write_process_unsigned_numbers_d(data, state, internal, headers.array[internal.i].value.is.a_u32s, destinations->array[destinations->used].value); + macro_f_fss_payload_header_write_process_numbers_unsigned_d(data, state, internal, headers.array[internal.i].value.is.a_u32s, destinations->array[destinations->used].value); break; case f_abstruse_uint64s_e: - macro_f_fss_payload_header_write_process_unsigned_numbers_d(data, state, internal, headers.array[internal.i].value.is.a_u64s, destinations->array[destinations->used].value); + macro_f_fss_payload_header_write_process_numbers_unsigned_d(data, state, internal, headers.array[internal.i].value.is.a_u64s, destinations->array[destinations->used].value); break; case f_abstruse_unsigneds_e: - macro_f_fss_payload_header_write_process_unsigned_numbers_d(data, state, internal, headers.array[internal.i].value.is.a_unsigneds, destinations->array[destinations->used].value); + macro_f_fss_payload_header_write_process_numbers_unsigned_d(data, state, internal, headers.array[internal.i].value.is.a_unsigneds, destinations->array[destinations->used].value); break; @@ -299,155 +169,55 @@ extern "C" { string_static.string = headers.array[internal.i].value.is.a_string; string_static.used = string_static.string ? strnlen(string_static.string, F_string_t_size_d) : 0; - if (string_static.used) { - internal.range.start = 0; - internal.range.stop = string_static.used - 1; - - private_fl_fss_basic_write(F_false, string_static, 0, &internal.range, &destinations->array[destinations->used].value, state, (void * const) &internal); + if (string_static.used || (data->flag & f_fss_payload_header_map_flag_null_string_e)) { + private_fl_payload_header_map_dynamic(data, state, &internal, &string_static, destinations); } - - if (F_status_is_error_not(state->status)) { + else if (data->flag & f_fss_payload_header_map_flag_null_e) { ++destinations->used; } break; case f_abstruse_strings_e: - // @todo flag to break strings into multiple rows. - data->cache->used = 0; - if (headers.array[internal.i].value.is.a_strings) { - internal.k = 0; - - for (internal.j = 0; headers.array[internal.i].value.is.a_strings[internal.j]; ++internal.j) { - - if (state->interrupt) { - state->interrupt((void * const) state, (void * const) &internal); - if (F_status_set_fine(state->status) == F_interrupt) return; - } - - string_static.string = headers.array[internal.i].value.is.a_strings[internal.j]; - string_static.used = string_static.string ? strnlen(string_static.string, F_string_t_size_d) : 0; - - internal.k += string_static.used ? string_static.used : f_string_ascii_quote_double_s.used * 2; - internal.k += f_fss_extended_next_s.used; - } // for - - state->status = f_memory_array_increase_by(internal.k, sizeof(f_char_t), (void **) &data->cache->string, &data->cache->used, &data->cache->size); + private_fl_payload_header_map_strings(data, state, &internal, headers.array[internal.i].value.is.a_strings, destinations); + } + else if (data->flag & f_fss_payload_header_map_flag_null_string_e) { + state->status = f_memory_array_increase_by(2, sizeof(f_char_t), (void **) &destinations->array[destinations->used].value.string, &destinations->array[destinations->used].value.used, &destinations->array[destinations->used].value.size); if (F_status_is_error(state->status)) break; - for (internal.j = 0; headers.array[internal.i].value.is.a_strings[internal.j]; ++internal.j) { - - if (state->interrupt) { - state->interrupt((void * const) state, (void * const) &internal); - if (F_status_set_fine(state->status) == F_interrupt) return; - } - - string_static.string = headers.array[internal.i].value.is.a_strings[internal.j]; - string_static.used = string_static.string ? strnlen(string_static.string, F_string_t_size_d) : 0; - - if (string_static.used) { - internal.range.start = 0; - internal.range.stop = string_static.used - 1; - - private_fl_fss_basic_write(F_false, string_static, 0, &internal.range, data->cache, state, (void * const) &internal); - if (F_status_is_error(state->status)) break; - - data->cache->string[data->cache->used++] = f_fss_extended_open_s.string[0]; - } - } // for - - if (F_status_is_error_not(state->status)) { - - // The f_fss_extended_next_s is always added at the end of the loop to avoid an additional condition check in the loop. - data->cache->used -= f_fss_extended_next_s.used; + private_fl_payload_header_map_null_add(internal, &destinations->array[destinations->used].value); + if (F_status_is_error(state->status)) break; - state->status = f_string_dynamic_append(*data->cache, &destinations->array[destinations->used].value); - } + ++destinations->used; } - - if (F_status_is_error_not(state->status)) { + else if (data->flag & f_fss_payload_header_map_flag_null_e) { ++destinations->used; } break; case f_abstruse_dynamic_e: - data->cache->used = 0; - - if (headers.array[internal.i].value.is.a_dynamic.used) { - internal.j = headers.array[internal.i].value.is.a_dynamic.used; - } - else { - internal.j = f_string_ascii_quote_double_s.used * 2; + if (headers.array[internal.i].value.is.a_dynamic.used || (data->flag & f_fss_payload_header_map_flag_null_dynamic_e)) { + private_fl_payload_header_map_dynamic(data, state, &internal, &headers.array[internal.i].value.is.a_dynamic, destinations); } - - state->status = f_memory_array_increase_by(internal.j, sizeof(f_char_t), (void **) &data->cache->string, &data->cache->used, &data->cache->size); - if (F_status_is_error(state->status)) break; - - macro_f_fss_payload_header_write_process_dynamic_d(data, state, internal, headers.array[internal.i].value.is.a_dynamic); - - if (F_status_is_error_not(state->status)) { - - // The f_fss_extended_next_s is always added at the end of the macro. - data->cache->used -= f_fss_extended_next_s.used; - - state->status = f_string_dynamic_append(*data->cache, &destinations->array[destinations->used].value); - } - - if (F_status_is_error_not(state->status)) { + else if (data->flag & f_fss_payload_header_map_flag_null_e) { ++destinations->used; } break; case f_abstruse_dynamics_e: - // @todo flag to break dynamics into multiple rows. - data->cache->used = 0; - if (headers.array[internal.i].value.is.a_dynamics.used) { - internal.k = 0; - - for (internal.j = 0; internal.j < headers.array[internal.i].value.is.a_dynamics.used; ++internal.j) { - - if (state->interrupt) { - state->interrupt((void * const) state, (void * const) &internal); - if (F_status_set_fine(state->status) == F_interrupt) return; - } - - internal.k += headers.array[internal.i].value.is.a_dynamics.array[internal.j].used ? headers.array[internal.i].value.is.a_dynamics.array[internal.j].used : f_string_ascii_quote_double_s.used * 2; - internal.k += f_fss_extended_next_s.used; - } // for - - state->status = f_memory_array_increase_by(internal.k, sizeof(f_char_t), (void **) &data->cache->string, &data->cache->used, &data->cache->size); - if (F_status_is_error(state->status)) break; - - for (internal.j = 0; internal.j < headers.array[internal.i].value.is.a_dynamics.used; ++internal.j) { - - if (state->interrupt) { - state->interrupt((void * const) state, (void * const) &internal); - if (F_status_set_fine(state->status) == F_interrupt) return; - } - - macro_f_fss_payload_header_write_process_dynamic_d(data, state, internal, headers.array[internal.i].value.is.a_dynamics.array[internal.j]); - if (F_status_is_error(state->status)) break; - } // for - - if (F_status_is_error_not(state->status)) { - - // The f_fss_extended_next_s is always added at the end of the loop to avoid an additional condition check in the loop. - data->cache->used -= f_fss_extended_next_s.used; - - state->status = f_string_dynamic_append(*data->cache, &destinations->array[destinations->used].value); - } + private_fl_payload_header_map_dynamics(data, state, &internal, &headers.array[internal.i].value.is.a_dynamics, destinations); } - - if (F_status_is_error_not(state->status)) { + else if (data->flag & f_fss_payload_header_map_flag_null_e) { ++destinations->used; } break; +// @todo resume here. case f_abstruse_map_e: data->cache->used = 0; internal.k = f_fss_extended_next_s.used; @@ -466,6 +236,7 @@ extern "C" { state->status = f_memory_array_increase_by(internal.k, sizeof(f_char_t), (void **) &data->cache->string, &data->cache->used, &data->cache->size); if (F_status_is_error(state->status)) break; + // @todo this should be different, in regards to the f_fss_payload_header_map_flag_null_dynamic_e bit. macro_f_fss_payload_header_write_process_dynamic_d(data, state, internal, headers.array[internal.i].value.is.a_map.name); if (F_status_is_error(state->status)) break; @@ -636,9 +407,7 @@ extern "C" { } // for } - if (F_status_is_error_not(state->status)) { - state->status = F_okay; - } + state->status = F_okay; } #endif // _di_fl_fss_payload_header_map_ diff --git a/level_1/fl_fss/c/fss/payload.h b/level_1/fl_fss/c/fss/payload.h index 14a32d1..4b43e6d 100644 --- a/level_1/fl_fss/c/fss/payload.h +++ b/level_1/fl_fss/c/fss/payload.h @@ -35,8 +35,6 @@ extern "C" { #endif -// @todo fl_fss_payload_header_read() to build an array of f_abstruse for the headers? - /** * Write standard header of the FSS-000E (Payload). * @@ -55,22 +53,23 @@ extern "C" { * @param destinations * A map of strings representing the header names and values after being safely converted into the valid payload header format. * This built header names and values are appended onto this. + * * Must not be NULL. * @param state * A state for providing flags and handling interrupts during long running operations. * The state.handle() is optionally allowed. * There is no "callbacks" structure. - * The data is required and set to f_fss_payload_header_write_state_t. + * The data is required and set to f_fss_payload_header_state_t. * The data.cache must not be NULL. * * The optional state->handle() is called on error and the handler may alter the status to not have an error bit step to prevent returning except for when there is an invalid parameter passed to this function. - * The second parameter is a f_fss_payload_header_write_internal_t. + * The second parameter is a f_fss_payload_header_internal_t. * The second parameter to state->handle() is NULL on invalid paramter passed to this function. * * When state.interrupt() returns, only F_interrupt and F_interrupt_not are processed. * Error bit designates an error but must be passed along with F_interrupt. * All other statuses are ignored. - * The second parameter is a f_fss_payload_header_write_internal_t. + * The second parameter is a f_fss_payload_header_internal_t. * * Must not be NULL. * @@ -88,9 +87,15 @@ extern "C" { * * Errors (with error bit) from: f_memory_array_increase(). * Errors (with error bit) from: f_memory_array_increase_by(). + * Errors (with error bit) from: f_string_dynamic_append_nulless(). + * Errors (with error bit) from: f_string_dynamic_strip_null(). + * Errors (with error bit) from: f_string_dynamic_strip_null_range(). * * @see f_memory_array_increase() * @see f_memory_array_increase_by() + * @see f_string_dynamic_append_nulless() + * @see f_string_dynamic_strip_null() + * @see f_string_dynamic_strip_null_range() */ #ifndef _di_fl_fss_payload_header_map_ extern void fl_fss_payload_header_map(const f_abstruse_maps_t headers, f_string_maps_t * const destinations, f_state_t * const state); diff --git a/level_1/fl_fss/c/fss/payload/define.h b/level_1/fl_fss/c/fss/payload/define.h index 0cd2cf9..c91d70f 100644 --- a/level_1/fl_fss/c/fss/payload/define.h +++ b/level_1/fl_fss/c/fss/payload/define.h @@ -15,34 +15,40 @@ extern "C" { #endif /** - * Defines for f_fss_payload_header_write(). + * Defines for fl_fss_payload_header_map(). * * macro_f_fss_payload_header_write_handle_error_d: * Handle error return status, calling handle and reset destinations.used. * * Parameters: - * - destinations: The destinations passed directly from the f_fss_payload_header_write() parameters. - * - state: The state passed directly from the f_fss_payload_header_write() parameters. - * - internal: The internal state, f_fss_payload_header_write_internal_t, created inside of f_fss_payload_header_write(). + * - destinations: The destinations passed directly from the fl_fss_payload_header_map() parameters. + * - state: The state passed directly from the fl_fss_payload_header_map() parameters. + * - internal: The internal state, f_fss_payload_header_internal_t, created inside of fl_fss_payload_header_map(). * - * macro_f_fss_payload_header_write_process_signed_numbers_d: - * Process the numbers array, converting it to a string. - * The data->cache is reset and used (via private_inline_f_payload_header_write_number_signed()). + * macro_f_fss_payload_header_write_process_numbers_d: + * Process the numbers array (either signed or unsigned), converting it to a string. + * The data->cache is reset and used (via private_fl_payload_header_map_number_signed()). * The destinations->used is incremented on non-error. - * This requires private_inline_f_payload_header_write_number_signed() from payload.c. + * This requires private_fl_payload_header_map_number_signed() from payload.c. * * Parameters: - * - data: The f_fss_payload_header_write_state_t pointer. - * - state: The state passed directly from the f_fss_payload_header_write() parameters. - * - internal: The internal state, f_fss_payload_header_write_internal_t, created inside of f_fss_payload_header_write(). + * - data: The f_fss_payload_header_state_t pointer. + * - state: The state passed directly from the fl_fss_payload_header_map() parameters. + * - internal: The internal state, f_fss_payload_header_internal_t, created inside of fl_fss_payload_header_map(). * - numbers: The is.a representing the array of signed numbers. * - destination: The destination string to append to. + * - function: The private signed/unsigned function to call. + * - cast: The signed/unsigned structure to cast to. * - * macro_f_fss_payload_header_write_process_unsigned_numbers_d: - * The same as the macro_f_fss_payload_header_write_process_signed_numbers_d() macro documentation above except for unsigned rather than signed. + * macro_f_fss_payload_header_write_process_numbers_signed_d: + * This wraps macro_f_fss_payload_header_write_process_numbers_d, passing the signed function and cast. + * + * macro_f_fss_payload_header_write_process_numbers_unsigned_d: + * This wraps macro_f_fss_payload_header_write_process_numbers_d, passing the unsigned function and cast. * * macro_f_fss_payload_header_write_process_dynamic_d: - * @todo document this. + * This macro writes the given dynamic string into the cache. + * If the dynamic string is empty, then an empty quotes are written to the cache. */ #ifndef _di_f_fss_payload_header_write_d_ #define macro_f_fss_payload_header_write_handle_error_d(destinations, state, internal) \ @@ -63,7 +69,9 @@ extern "C" { } \ } - #define macro_f_fss_payload_header_write_process_signed_numbers_d(data, state, internal, numbers, destination) \ + #define macro_f_fss_payload_header_write_process_numbers_d(data, state, internal, numbers, destination, function, cast) \ + data->cache->used = 0; \ + \ for (internal.j = 0; internal.j < numbers.used; ++internal.j) { \ \ if (state->interrupt) { \ @@ -71,50 +79,55 @@ extern "C" { if (F_status_set_fine(state->status) == F_interrupt) break; \ } \ \ - if (private_inline_f_payload_header_write_number_signed(data, state, &internal, (f_number_signed_t) numbers.array[internal.j])) break; \ - \ - if (data->cache->used && internal.j + 1 < numbers.used) { \ - state->status = f_string_dynamic_append(f_fss_extended_open_s, &destination); \ - if (F_status_is_error(state->status)) break; \ + if (!(data->flag & f_fss_payload_header_map_flag_join_digits_e)) { \ + data->cache->used = 0; \ } \ - if (F_status_is_error_not(state->status)) { \ - ++destinations->used; \ - } \ - } // for - - #define macro_f_fss_payload_header_write_process_unsigned_numbers_d(data, state, internal, numbers, destination) \ - for (internal.j = 0; internal.j < numbers.used; ++internal.j) { \ \ - if (state->interrupt) { \ - state->interrupt((void * const) state, (void * const) &internal); \ - if (F_status_set_fine(state->status) == F_interrupt) break; \ + if (function(data, state, &internal, (cast) numbers.array[internal.j])) { \ + data->cache->used = 0; \ + \ + break; \ } \ \ - if (private_inline_f_payload_header_write_number_unsigned(data, state, &internal, (f_number_unsigned_t) numbers.array[internal.j])) break; \ - \ - if (data->cache->used && internal.j + 1 < numbers.used) { \ - state->status = f_string_dynamic_append(f_fss_extended_open_s, &destination); \ - if (F_status_is_error(state->status)) break; \ + if (!(data->flag & f_fss_payload_header_map_flag_join_digits_e)) { \ + if (data->cache->used && internal.j + 1 < numbers.used) { \ + state->status = f_string_dynamic_append(f_fss_extended_open_s, &destination); \ + if (F_status_is_error(state->status)) break; \ + } \ + \ + ++destinations->used; \ } \ + } /* for */ \ + \ + if (data->cache->used && (data->flag & f_fss_payload_header_map_flag_join_digits_e)) { \ + private_fl_payload_header_map_cache(data, state, &internal); \ + \ if (F_status_is_error_not(state->status)) { \ ++destinations->used; \ } \ - } // for + } + + #define macro_f_fss_payload_header_write_process_numbers_signed_d(data, state, internal, numbers, destination) \ + macro_f_fss_payload_header_write_process_numbers_d(data, state, internal, numbers, destination, private_fl_payload_header_map_number_signed, f_number_signed_t) + + #define macro_f_fss_payload_header_write_process_numbers_unsigned_d(data, state, internal, numbers, destination) \ + macro_f_fss_payload_header_write_process_numbers_d(data, state, internal, numbers, destination, private_fl_payload_header_map_number_unsigned, f_number_unsigned_t) #define macro_f_fss_payload_header_write_process_dynamic_d(data, state, internal, dynamic) \ - if (dynamic.used) { \ - internal.range.start = 0; \ - internal.range.stop = dynamic.used - 1; \ + if (dynamic.used || (data->flag & f_fss_payload_header_map_flag_null_dynamic_e)) { \ + if (dynamic.used) { \ + internal.range.start = 0; \ + internal.range.stop = dynamic.used - 1; \ + \ + private_fl_fss_basic_write(F_false, dynamic, internal.quote, &internal.range, data->cache, state, (void * const) &internal); \ + } \ + else { \ + private_fl_payload_header_map_null_add(internal, data->cache); \ + } \ \ - private_fl_fss_basic_write(F_false, dynamic, 0, &internal.range, data->cache, state, (void * const) &internal); \ - } \ - else { \ - data->cache->string[data->cache->used++] = f_string_ascii_quote_double_s.string[0]; \ - data->cache->string[data->cache->used++] = f_string_ascii_quote_double_s.string[0]; \ - } \ - \ - if (F_status_is_error_not(state->status)) { \ - data->cache->string[data->cache->used++] = f_fss_extended_next_s.string[0]; \ + if (F_status_is_error_not(state->status)) { \ + data->cache->string[data->cache->used++] = f_fss_extended_next_s.string[0]; \ + } \ } #endif // _di_f_fss_payload_header_write_d_ diff --git a/level_1/fl_fss/c/fss/payload/type.h b/level_1/fl_fss/c/fss/payload/type.h index 4970985..609a2ca 100644 --- a/level_1/fl_fss/c/fss/payload/type.h +++ b/level_1/fl_fss/c/fss/payload/type.h @@ -15,21 +15,25 @@ extern "C" { #endif /** - * An internal structure for the fss_payload_header_write() passed to callbacks. + * An internal structure for the FSS Payload header functions passed to callbacks. + * + * This is intended to be used by functions such as fl_fss_payload_header_map(). * * Properties: + * - quote: The quote being used in all cases. * - step: The current step. * - i: A counter used for the "headers" outer arrays. * - j: A counter used for the inner loop or for pre-allocation counting. * - k: A number used for converting values but also made available for use as a counter if need be. - * - l: @todo - * - range: @todo + * - l: A counter used for more complex use cases such as with multi-maps. + * - range: Used for passing a given string range to the FSS write functions. * - conversion: The conversion data. * - destinations: The destinations map being appended to. * - original: The original destination used length. */ -#ifndef _di_f_fss_payload_header_write_internal_t_ +#ifndef _di_f_fss_payload_header_internal_t_ typedef struct { + uint8_t quote; uint16_t step; f_number_unsigned_t i; f_number_unsigned_t j; @@ -40,9 +44,10 @@ extern "C" { f_string_maps_t * const destinations; const f_number_unsigned_t original; - } f_fss_payload_header_write_internal_t; + } f_fss_payload_header_internal_t; - #define f_fss_payload_header_write_internal_t_initialize { \ + #define f_fss_payload_header_internal_t_initialize { \ + 0, \ 0, \ 0, \ 0, \ @@ -54,7 +59,8 @@ extern "C" { 0, \ } - #define macro_f_fss_payload_header_write_internal_t_initialize_1(step, i, j, k, l, range, conversion, destinations, original) { \ + #define macro_f_fss_payload_header_internal_t_initialize_1(quote, step, i, j, k, l, range, conversion, destinations, original) { \ + quote, \ step, \ i, \ j, \ @@ -66,7 +72,8 @@ extern "C" { original, \ } - #define macro_f_fss_payload_header_write_internal_t_initialize_2(destinations, original) { \ + #define macro_f_fss_payload_header_internal_t_initialize_2(destinations, original) { \ + 0, \ 0, \ 0, \ 0, \ @@ -77,37 +84,50 @@ extern "C" { destinations, \ original, \ } -#endif // _di_f_fss_payload_header_write_internal_t_ +#endif // _di_f_fss_payload_header_internal_t_ /** - * A state structure for passing data to fss_payload_header_write(). + * A state structure for passing data to FSS Payload header functions. + * + * This is intended to be used by functions such as fl_fss_payload_header_map(). * * Properties: + * - flag: A set of flags for the function to use. * - conversion: The conversion data. * - cache: A string cache to use reduce re-allocations on the destination strings (generally required to not be NULL). */ -#ifndef _di_f_fss_payload_header_write_state_t_ +#ifndef _di_f_fss_payload_header_state_t_ typedef struct { + uint64_t flag; f_conversion_data_t conversion; f_string_dynamic_t *cache; - } f_fss_payload_header_write_state_t; + } f_fss_payload_header_state_t; - #define f_fss_payload_header_write_state_t_initialize { \ + #define f_fss_payload_header_state_t_initialize { \ + 0, \ f_conversion_data_base_10_c, \ 0, \ } - #define macro_f_fss_payload_header_write_state_t_initialize_1(conversion, cache) { \ + #define macro_f_fss_payload_header_state_t_initialize_1(flag, conversion, cache) { \ + 0, \ conversion, \ cache, \ } - #define macro_f_fss_payload_header_write_state_t_initialize_2(cache) { \ + #define macro_f_fss_payload_header_state_t_initialize_2(flag, cache) { \ + flag, \ + f_conversion_data_base_10_c, \ + cache, \ + } + + #define macro_f_fss_payload_header_state_t_initialize_3(cache) { \ + 0, \ f_conversion_data_base_10_c, \ cache, \ } -#endif // _di_f_fss_payload_header_write_state_t_ +#endif // _di_f_fss_payload_header_state_t_ #ifdef __cplusplus } // extern "C" diff --git a/level_1/fl_fss/c/fss/private-payload.c b/level_1/fl_fss/c/fss/private-payload.c new file mode 100644 index 0000000..a1be9ee --- /dev/null +++ b/level_1/fl_fss/c/fss/private-payload.c @@ -0,0 +1,242 @@ +#include "payload.h" +#include "../private-fss.h" +#include "private-payload.h" + +#ifdef __cplusplus +extern "C" { +#endif + +#if !defined(_di_fl_fss_payload_header_map_) + uint8_t private_fl_payload_header_map_cache(f_fss_payload_header_state_t * const data, f_state_t * const state, f_fss_payload_header_internal_t * const internal) { + + if (!data->cache->used) return F_false; + + internal->range.start = 0; + internal->range.stop = data->cache->used - 1; + + private_fl_fss_basic_write(F_false, *data->cache, internal->quote, &internal->range, &internal->destinations->array[internal->destinations->used].value, state, (void * const) internal); + if (F_status_is_error(state->status)) return F_true; + + state->status = f_string_dynamic_strip_null(&internal->destinations->array[internal->destinations->used].value); + if (F_status_is_error(state->status)) return F_true; + + return F_false; + } +#endif // !defined(_di_fl_fss_payload_header_map_) + +#if !defined(_di_fl_fss_payload_header_map_) + uint8_t private_fl_payload_header_map_dynamic(f_fss_payload_header_state_t * const data, f_state_t * const state, f_fss_payload_header_internal_t * const internal, f_string_static_t * const buffer, f_string_maps_t * const destinations) { + + if (buffer->used) { + internal->range.start = 0; + internal->range.stop = buffer->used - 1; + + private_fl_fss_basic_write(F_false, *buffer, 0, &internal->range, &destinations->array[destinations->used].value, state, (void * const) internal); + if (F_status_is_error(state->status)) return F_true; + + state->status = f_string_dynamic_strip_null(&destinations->array[destinations->used].value); + } + else { + state->status = f_memory_array_increase_by(2, sizeof(f_char_t), (void **) &destinations->array[destinations->used].value.string, &destinations->array[destinations->used].value.used, &destinations->array[destinations->used].value.size); + if (F_status_is_error(state->status)) return F_true; + + private_fl_payload_header_map_null_add(*internal, &destinations->array[destinations->used].value); + } + + if (F_status_is_error(state->status)) return F_true; + + ++destinations->used; + + return F_false; + } +#endif // !defined(_di_fl_fss_payload_header_map_) + +#if !defined(_di_fl_fss_payload_header_map_) + uint8_t private_fl_payload_header_map_dynamics(f_fss_payload_header_state_t * const data, f_state_t * const state, f_fss_payload_header_internal_t * const internal, f_string_statics_t * const buffers, f_string_maps_t * const destinations) { + + // @todo this needs to implement f_fss_payload_header_map_flag_join_dynamics_e. + + data->cache->used = 0; + internal->k = 0; + + for (internal->j = 0; internal->j < buffers->used; ++internal->j) { + + if (state->interrupt) { + state->interrupt((void * const) state, (void * const) internal); + if (F_status_set_fine(state->status) == F_interrupt) return F_true; + } + + internal->k += buffers->array[internal->j].used ? buffers->array[internal->j].used : f_string_ascii_quote_double_s.used * 2; + internal->k += f_fss_extended_next_s.used; + } // for + + state->status = f_memory_array_increase_by(internal->k, sizeof(f_char_t), (void **) &data->cache->string, &data->cache->used, &data->cache->size); + if (F_status_is_error(state->status)) return F_true; + + for (internal->j = 0; internal->j < buffers->used; ++internal->j) { + + if (state->interrupt) { + state->interrupt((void * const) state, (void * const) internal); + if (F_status_set_fine(state->status) == F_interrupt) return F_true; + } + + macro_f_fss_payload_header_write_process_dynamic_d(data, state, (*internal), buffers->array[internal->j]); + if (F_status_is_error(state->status)) return F_true; + } // for + + // The f_fss_extended_next_s is always added at the end of the loop to avoid an additional condition check in the loop. + data->cache->used -= f_fss_extended_next_s.used; + + state->status = f_string_dynamic_append(*data->cache, &destinations->array[destinations->used].value); + if (F_status_is_error(state->status)) return F_true; + + ++destinations->used; + + return F_false; + } +#endif // !defined(_di_fl_fss_payload_header_map_) + +#if !defined(_di_fl_fss_payload_header_map_) + void private_fl_payload_header_map_null_add(const f_fss_payload_header_internal_t internal, f_string_dynamic_t * const destination) { + + destination->string[destination->used++] = internal.quote ? internal.quote : f_string_ascii_quote_double_s.string[0]; + destination->string[destination->used++] = internal.quote ? internal.quote : f_string_ascii_quote_double_s.string[0]; + } +#endif // !defined(_di_fl_fss_payload_header_map_) + +#if !defined(_di_fl_fss_payload_header_map_) + uint8_t private_fl_payload_header_map_number_signed(f_fss_payload_header_state_t * const data, f_state_t * const state, f_fss_payload_header_internal_t * const internal, const f_number_signed_t number) { + + if (data->cache->used) { + state->status = f_string_dynamic_append(f_fss_extended_next_s, data->cache); + if (F_status_is_error(state->status)) return F_true; + } + + state->status = f_conversion_number_signed_to_string(number, data->conversion, data->cache); + if (F_status_is_error(state->status)) return F_true; + + return F_false; + } +#endif // !defined(_di_fl_fss_payload_header_map_) + +#if !defined(_di_fl_fss_payload_header_map_) + uint8_t private_fl_payload_header_map_number_unsigned(f_fss_payload_header_state_t * const data, f_state_t * const state, f_fss_payload_header_internal_t * const internal, const f_number_unsigned_t number) { + + if (data->cache->used) { + state->status = f_string_dynamic_append(f_fss_extended_next_s, data->cache); + if (F_status_is_error(state->status)) return F_true; + } + + state->status = f_conversion_number_unsigned_to_string(number, data->conversion, data->cache); + if (F_status_is_error(state->status)) return F_true; + + return F_false; + } +#endif // !defined(_di_fl_fss_payload_header_map_) +#if !defined(_di_fl_fss_payload_header_map_) + uint8_t private_fl_payload_header_map_strings(f_fss_payload_header_state_t * const data, f_state_t * const state, f_fss_payload_header_internal_t * const internal, f_string_t * const buffers, f_string_maps_t * const destinations) { + + f_string_static_t string_static = f_string_static_t_initialize; + + data->cache->used = 0; + internal->k = 0; + + for (internal->j = 0; buffers[internal->j]; ++internal->j) { + + if (state->interrupt) { + state->interrupt((void * const) state, (void * const) internal); + if (F_status_set_fine(state->status) == F_interrupt) return F_true; + } + + string_static.string = buffers[internal->j]; + string_static.used = string_static.string ? strnlen(string_static.string, F_string_t_size_d) : 0; + + internal->k += string_static.used ? string_static.used : f_string_ascii_quote_double_s.used * 2; + internal->k += f_fss_extended_next_s.used; + } // for + + // Save the total strings as internal.l so that intenal.j can be used for the loop counter later on. + internal->l = internal->j; + + if (data->flag & f_fss_payload_header_map_flag_join_strings_e) { + state->status = f_memory_array_increase_by(internal->k, sizeof(f_char_t), (void **) &data->cache->string, &data->cache->used, &data->cache->size); + if (F_status_is_error(state->status)) return F_true; + + for (internal->j = 0; internal->j < internal->l; ++internal->j) { + + if (state->interrupt) { + state->interrupt((void * const) state, (void * const) internal); + if (F_status_set_fine(state->status) == F_interrupt) return F_true; + } + + string_static.string = buffers[internal->j]; + string_static.used = string_static.string ? strnlen(string_static.string, F_string_t_size_d) : 0; + + if (string_static.used) { + internal->range.start = 0; + internal->range.stop = string_static.used - 1; + + private_fl_fss_basic_write(F_false, string_static, internal->quote, &internal->range, data->cache, state, (void * const) internal); + if (F_status_is_error(state->status)) return F_true; + + data->cache->string[data->cache->used++] = f_fss_extended_open_s.string[0]; + } + } // for + + if (data->cache->used) { + + // The f_fss_extended_next_s is always added at the end of the loop to avoid an additional condition check in the loop. + data->cache->used -= f_fss_extended_next_s.used; + } + else if (data->flag & f_fss_payload_header_map_flag_null_string_e) { + private_fl_payload_header_map_null_add(*internal, data->cache); + } + + if (data->cache->used) { + state->status = f_string_dynamic_append(*data->cache, &destinations->array[destinations->used].value); + } + } + else { + state->status = f_memory_array_increase_by(internal->k, sizeof(f_char_t), (void **) &destinations->array[destinations->used].value.string, &destinations->array[destinations->used].value.used, &destinations->array[destinations->used].value.size); + + for (internal->j = 0; internal->j < internal->l; ++internal->j) { + + if (state->interrupt) { + state->interrupt((void * const) state, (void * const) internal); + if (F_status_set_fine(state->status) == F_interrupt) return F_true; + } + + string_static.string = buffers[internal->j]; + string_static.used = string_static.string ? strnlen(string_static.string, F_string_t_size_d) : 0; + + state->status = f_string_dynamic_append(string_static, data->cache); + if (F_status_is_error(state->status)) return F_true; + + state->status = f_string_dynamic_append(f_fss_extended_next_s, data->cache); + if (F_status_is_error(state->status)) return F_true; + } // for + + // Do not include the f_fss_extended_next_s that is always added at the end of the loop. + data->cache->used -= f_fss_extended_next_s.used; + + internal->range.start = 0; + internal->range.stop = data->cache->used - 1; + + private_fl_fss_basic_write(F_false, *data->cache, internal->quote, &internal->range, &destinations->array[destinations->used].value, state, (void * const) internal); + if (F_status_is_error(state->status)) return F_true; + + state->status = f_string_dynamic_strip_null(&destinations->array[destinations->used].value); + } + + if (F_status_is_error(state->status)) return F_true; + + ++destinations->used; + state->status = F_okay; + + return F_false; + } +#endif // !defined(_di_fl_fss_payload_header_map_) + +#ifdef __cplusplus +} // extern "C" +#endif diff --git a/level_1/fl_fss/c/fss/private-payload.h b/level_1/fl_fss/c/fss/private-payload.h new file mode 100644 index 0000000..9fe91ba --- /dev/null +++ b/level_1/fl_fss/c/fss/private-payload.h @@ -0,0 +1,301 @@ +/** + * FLL - Level 1 + * + * Project: FSS + * API Version: 0.7 + * Licenses: lgpl-2.1-or-later + * + * These are provided for internal reduction in redundant code. + * These should not be exposed/used outside of this project. + */ +#ifndef _PRIVATE_FL_fss_payload_h +#define _PRIVATE_FL_fss_payload_h + +#ifdef __cplusplus +extern "C" { +#endif + +/** + * Write the cache to the destination. + * + * @param data + * The f_fss_payload_header_state_t pointer. + * This caller must reset data.cache.used as needed. + * if data.cache.used is not 0, then this will append a space before adding the converted number. + * Must not be NULL. + * @param state + * The state passed directly from the fl_fss_payload_header_map() parameters. + * + * This alters state.status: + * Success from: f_string_dynamic_strip_null(). + * + * Errors (with error bit) from: private_fl_fss_basic_write(). + * Errors (with error bit) from: f_string_dynamic_strip_null(). + * + * Must not be NULL. + * @param internal + * The internal state, f_fss_payload_header_internal_t, created inside of fl_fss_payload_header_map(). + * The internal.range is modified. + * Must not be NULL. + * + * @return + * F_true if the caller should break or exit due to an error or something similar. + * F_false, otherwise. + * + * @see private_fl_fss_basic_write() + * @see f_string_dynamic_strip_null() + * + * @see fl_fss_payload_header_map() + */ +#if !defined(_di_fl_fss_payload_header_map_) + extern uint8_t private_fl_payload_header_map_cache(f_fss_payload_header_state_t * const data, f_state_t * const state, f_fss_payload_header_internal_t * const internal) F_attribute_visibility_internal_d; +#endif // !defined(_di_fl_fss_payload_header_map_) + +/** + * Process the dynamic string, writing it into the packet with the appropriate escaping as necessary. + * + * This expects that the appropriate used and flag checks are performed prior to calling this. + * + * @param data + * The f_fss_payload_header_state_t pointer. + * Must not be NULL. + * @param state + * The state passed directly from the fl_fss_payload_header_map() parameters. + * + * This alters state.status: + * Success from: f_string_dynamic_strip_null(). + * Success from: private_fl_payload_header_map_null_add(). + * + * Errors (with error bit) from: f_memory_array_increase_by(). + * Errors (with error bit) from: f_string_dynamic_strip_null(). + * Errors (with error bit) from: private_fl_fss_basic_write(). + * Errors (with error bit) from: private_fl_payload_header_map_null_add(). + * + * Must not be NULL. + * @param internal + * The internal state, f_fss_payload_header_internal_t, created inside of fl_fss_payload_header_map(). + * Must not be NULL. + * @param buffer + * The dynamic string to read from. + * Must not be NULL. + * @param destinations + * A map of strings representing the header names and values after being safely converted into the valid payload header format. + * This built header names and values are appended onto this. + * This is updated as appropriate. + * Must not be NULL. + * + * @return + * F_true if the caller should break or exit due to an error or something similar. + * F_false, otherwise. + * + * @see f_memory_array_increase_by() + * @see f_string_dynamic_strip_null() + * + * @see private_fl_fss_basic_write() + * @see private_fl_payload_header_map_null_add() + * + * @see fl_fss_payload_header_map() + */ +#if !defined(_di_fl_fss_payload_header_map_) + extern uint8_t private_fl_payload_header_map_dynamic(f_fss_payload_header_state_t * const data, f_state_t * const state, f_fss_payload_header_internal_t * const internal, f_string_static_t * const buffer, f_string_maps_t * const destinations) F_attribute_visibility_internal_d; +#endif // !defined(_di_fl_fss_payload_header_map_) + +/** + * Process the array of dynamic strings, writing it into the packet with the appropriate escaping as necessary. + * + * This expects that the appropriate used and flag checks are performed prior to calling this. + * + * @param headers + * An abstruse map representing individual headers. + * @param data + * The f_fss_payload_header_state_t pointer. + * This modifies data.cache. + * Must not be NULL. + * @param state + * The state passed directly from the fl_fss_payload_header_map() parameters. + * Must not be NULL. + * @param internal + * The internal state, f_fss_payload_header_internal_t, created inside of fl_fss_payload_header_map(). + * Must not be NULL. + * @param buffers + * The array of dynamic strings to read from. + * Must not be NULL. + * @param destinations + * A map of strings representing the header names and values after being safely converted into the valid payload header format. + * This built header names and values are appended onto this. + * This is updated as appropriate. + * Must not be NULL. + * + * @return + * F_true if the caller should break or exit due to an error or something similar. + * F_false, otherwise. + * + * @see f_memory_array_increase_by() + * @see f_string_dynamic_strip_null() + * + * @see private_fl_fss_basic_write() + * @see private_fl_payload_header_map_null_add() + * + * @see fl_fss_payload_header_map() + */ +#if !defined(_di_fl_fss_payload_header_map_) + extern uint8_t private_fl_payload_header_map_dynamics(f_fss_payload_header_state_t * const data, f_state_t * const state, f_fss_payload_header_internal_t * const internal, f_string_statics_t * const buffers, f_string_maps_t * const destinations) F_attribute_visibility_internal_d; +#endif // !defined(_di_fl_fss_payload_header_map_) + +/** + * Add a NULL Content (column value), represented as an empty quoted string. + * + * @param internal + * The internal state, f_fss_payload_header_internal_t, created inside of fl_fss_payload_header_map(). + * @param destination + * The destination string to write to. + * This is not reallocated as needed. + * The caller must ensure enough space exists. + * Must not be NULL. + * + * @see f_memory_array_increase_by() + * + * @see fl_fss_payload_header_map() + */ +#if !defined(_di_fl_fss_payload_header_map_) + extern void private_fl_payload_header_map_null_add(const f_fss_payload_header_internal_t internal, f_string_dynamic_t * const destination) F_attribute_visibility_internal_d; +#endif // !defined(_di_fl_fss_payload_header_map_) + +/** + * Process the signed number, converting it to a string and appending that string onto data->cache. + * The resulting data->cache is then appended onto the destination value on success. + * If the number is not appended to data->cache, then nothing is appended to the destination value. + * + * @param data + * The f_fss_payload_header_state_t pointer. + * This caller must reset data.cache.used as needed. + * If data.cache.used is not 0, then this will append a space before adding the converted number. + * Must not be NULL. + * @param state + * The state passed directly from the fl_fss_payload_header_map() parameters. + * + * This alters state.status: + * Success from: f_conversion_number_signed_to_string(). + * + * Errors (with error bit) from: f_conversion_number_signed_to_string(). + * Errors (with error bit) from: f_string_dynamic_append(). + * + * Must not be NULL. + * @param internal + * The internal state, f_fss_payload_header_internal_t, created inside of fl_fss_payload_header_map(). + * Must not be NULL. + * @param number + * The signed number. + * Must not be NULL. + * + * @return + * F_true if the caller should break or exit due to an error or something similar. + * F_false, otherwise. + * + * @see f_conversion_number_unsigned_to_string() + * @see f_string_dynamic_append() + * + * @see fl_fss_payload_header_map() + */ +#if !defined(_di_fl_fss_payload_header_map_) + extern uint8_t private_fl_payload_header_map_number_signed(f_fss_payload_header_state_t * const data, f_state_t * const state, f_fss_payload_header_internal_t * const internal, const f_number_signed_t number) F_attribute_visibility_internal_d; +#endif // !defined(_di_fl_fss_payload_header_map_) + +/** + * Process the unsigned number, converting it to a string and appending that string onto data->cache. + * The resulting data->cache is then appended onto the destination value on success. + * If the number is not appended to data->cache, then nothing is appended to the destination value. + * + * @param data + * The f_fss_payload_header_state_t pointer. + * This caller must reset data.cache.used as needed. + * if data.cache.used is not 0, then this will append a space before adding the converted number. + * + * Must not be NULL. + * @param state + * The state passed directly from the fl_fss_payload_header_map() parameters. + * + * This alters state.status: + * Success from: f_conversion_number_unsigned_to_string(). + * + * Errors (with error bit) from: f_conversion_number_unsigned_to_string(). + * Errors (with error bit) from: f_string_dynamic_append(). + * + * Must not be NULL. + * @param internal + * The internal state, f_fss_payload_header_internal_t, created inside of fl_fss_payload_header_map(). + * Must not be NULL. + * @param number + * The unsigned number. + * Must not be NULL. + * + * @return + * F_true if the caller should break or exit due to an error or something similar. + * F_false, otherwise. + * + * @see f_conversion_number_unsigned_to_string() + * @see f_string_dynamic_append() + * + * @see fl_fss_payload_header_map() + */ +#if !defined(_di_fl_fss_payload_header_map_) + extern uint8_t private_fl_payload_header_map_number_unsigned(f_fss_payload_header_state_t * const data, f_state_t * const state, f_fss_payload_header_internal_t * const internal, const f_number_unsigned_t number) F_attribute_visibility_internal_d; +#endif // !defined(_di_fl_fss_payload_header_map_) + +/** + * Process the array of NULL terminated strings, writing it into the packet with the appropriate escaping as necessary. + * + * This expects that the appropriate used and flag checks are performed prior to calling this. + * + * @param headers + * An abstruse map representing individual headers. + * @param data + * The f_fss_payload_header_state_t pointer. + * This modifies data.cache. + * Must not be NULL. + * @param state + * The state passed directly from the fl_fss_payload_header_map() parameters. + * + * This alters state.status: + * F_okay on success. + * + * Errors (with error bit) from: f_memory_array_increase_by(). + * Errors (with error bit) from: f_string_dynamic_append(). + * Errors (with error bit) from: f_string_dynamic_strip_null(). + * Errors (with error bit) from: private_fl_fss_basic_write(). + * + * Must not be NULL. + * @param internal + * The internal state, f_fss_payload_header_internal_t, created inside of fl_fss_payload_header_map(). + * Must not be NULL. + * @param buffers + * The array of NULL terminated strings to read from. + * Must not be NULL. + * @param destinations + * A map of strings representing the header names and values after being safely converted into the valid payload header format. + * This built header names and values are appended onto this. + * This is updated as appropriate. + * Must not be NULL. + * + * @return + * F_true if the caller should break or exit due to an error or something similar. + * F_false, otherwise. + * + * @see f_memory_array_increase_by() + * @see f_string_dynamic_append() + * @see f_string_dynamic_strip_null() + * + * @see private_fl_fss_basic_write() + * @see private_fl_payload_header_map_null_add() + * + * @see fl_fss_payload_header_map() + */ +#if !defined(_di_fl_fss_payload_header_map_) + extern uint8_t private_fl_payload_header_map_strings(f_fss_payload_header_state_t * const data, f_state_t * const state, f_fss_payload_header_internal_t * const internal, f_string_t * const buffers, f_string_maps_t * const destinations) F_attribute_visibility_internal_d; +#endif // !defined(_di_fl_fss_payload_header_map_) + +#ifdef __cplusplus +} // extern "C" +#endif + +#endif // _PRIVATE_FL_fss_payload_h diff --git a/level_1/fl_fss/data/build/settings b/level_1/fl_fss/data/build/settings index ee9fc9f..628963d 100644 --- a/level_1/fl_fss/data/build/settings +++ b/level_1/fl_fss/data/build/settings @@ -32,7 +32,7 @@ build_language c build_libraries -lc build_libraries-individual -lf_abstruse -lf_conversion -lf_file -lf_fss -lf_memory -lf_string -lf_type_array -lf_utf -build_sources_library private-fss.c fss/basic.c fss/basic_list.c fss/embedded_list.c fss/extended.c fss/extended_list.c fss/payload.c +build_sources_library private-fss.c fss/basic.c fss/basic_list.c fss/embedded_list.c fss/extended.c fss/extended_list.c fss/payload.c fss/private-payload.c build_sources_headers fss.h fss/basic.h fss/basic_list.h fss/embedded_list.h fss/extended.h fss/extended_list.h fss/payload.h fss/payload/define.h fss/payload/type.h