From: Kevin Day Date: Tue, 17 Oct 2023 03:12:41 +0000 (-0500) Subject: Progress: Continue adding FSS Payload processing code. X-Git-Url: https://git.kevux.org/?a=commitdiff_plain;h=49fbc74ee38f381e17b1bb72356e374da0deb787;p=fll Progress: Continue adding FSS Payload processing code. I decided to use two caches. One for the main cache. The other for a smaller, multi-purpose cache. The second cache should be smaller and so re-allocations should be cheaper. Use re-allocations on this as much as possible. There are some code changes that I was indecisive around and jumped around on implementation. I think I cleaned that all up but I may have missed something. --- diff --git a/level_1/fl_fss/c/fss/payload.c b/level_1/fl_fss/c/fss/payload.c index d6c7564..8c5a34a 100644 --- a/level_1/fl_fss/c/fss/payload.c +++ b/level_1/fl_fss/c/fss/payload.c @@ -24,7 +24,7 @@ extern "C" { 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(destination, destination->used); - if (!data->cache) { + if (!data->cache_1 || !data->cache_2) { state->status = F_status_set_error(F_parameter); if (state->handle) { @@ -68,68 +68,21 @@ extern "C" { internal.j = 0; - if (F_status_is_error(state->status)) { - if (state->handle) { - state->handle((void * const) state, (void * const) &internal); - - if (F_status_is_error(state->status)) { - destination->used = internal.original; - - return; - } - } - else { - destination->used = internal.original; - - return; - } - } + macro_f_fss_payload_header_write_handle_error_d(destination, state, internal); } if (state->code & f_fss_payload_write_comment_header_e) { internal.step = f_fss_payload_write_comment_header_e; state->status = f_string_dynamic_append(f_fss_payload_comment_header_s, destination); - - if (F_status_is_error(state->status)) { - if (state->handle) { - state->handle((void * const) state, (void * const) &internal); - - if (F_status_is_error(state->status)) { - destination->used = internal.original; - - return; - } - } - else { - destination->used = internal.original; - - return; - } - } + macro_f_fss_payload_header_write_handle_error_d(destination, state, internal); } if (state->code & f_fss_payload_write_header_object_e) { internal.step = f_fss_payload_write_header_object_e; state->status = f_string_dynamic_append(f_fss_payload_object_header_s, destination); - - if (F_status_is_error(state->status)) { - if (state->handle) { - state->handle((void * const) state, (void * const) &internal); - - if (F_status_is_error(state->status)) { - destination->used = internal.original; - - return; - } - } - else { - destination->used = internal.original; - - return; - } - } + macro_f_fss_payload_header_write_handle_error_d(destination, state, internal); } if (state->code & f_fss_payload_write_header_content_e) { @@ -148,15 +101,18 @@ extern "C" { internal.range.start = 0; internal.range.stop = headers.array[internal.i].key.used - 1; - data->cache->used = 0; + data->cache_1->used = 0; + data->cache_2->used = 0; // Pre-allocate space for the key, value (using step_large), separator space, EOL, and terminating NULL if necessary. - state->status = f_memory_array_increase_by(headers.array[internal.i].key.used + state->step_large + 3, sizeof(f_char_t), (void **) &data->cache->string, &data->cache->used, &data->cache->size); + state->status = f_memory_array_increase_by(headers.array[internal.i].key.used + state->step_large + f_fss_extended_open_s.used + 2, sizeof(f_char_t), (void **) &data->cache_1->string, &data->cache_1->used, &data->cache_1->size); if (F_status_is_error_not(state->status)) { - data->cache->string[data->cache->used++] = f_fss_extended_open_s.string[0]; + private_fl_fss_basic_write(F_true, headers.array[internal.i].key, 0, &internal.range, data->cache_1, state, (void * const) &internal); + } - private_fl_fss_basic_write(F_true, headers.array[internal.i].key, 0, &internal.range, data->cache, state, (void * const) &internal); + if (F_status_is_error_not(state->status)) { + data->cache_1->string[data->cache_1->used++] = f_fss_extended_open_s.string[0]; } if (F_status_is_error_not(state->status)) { @@ -167,58 +123,233 @@ extern "C" { break; case f_abstruse_signed_e: - data->cache->used = 0; - - state->status = f_conversion_number_signed_to_string(headers.array[internal.i].value.is.a_signed, data->conversion, data->cache); + state->status = f_conversion_number_signed_to_string(headers.array[internal.i].value.is.a_signed, data->conversion, data->cache_1); break; case f_abstruse_unsigned_e: - data->cache->used = 0; - - state->status = f_conversion_number_unsigned_to_string(headers.array[internal.i].value.is.a_unsigned, data->conversion, data->cache); + state->status = f_conversion_number_unsigned_to_string(headers.array[internal.i].value.is.a_unsigned, data->conversion, data->cache_1); 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); + + 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); + + 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); + + 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); + + break; + case f_abstruse_signeds_e: - // @todo + macro_f_fss_payload_header_write_process_signed_numbers_d(data, state, internal, headers.array[internal.i].value.is.a_signeds); + 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); + + 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); + + 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); + + 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); + + break; + case f_abstruse_unsigneds_e: - // @todo + macro_f_fss_payload_header_write_process_unsigned_numbers_d(data, state, internal, headers.array[internal.i].value.is.a_unsigneds); + break; case f_abstruse_string_e: string_static.string = headers.array[internal.i].value.is.a_string; string_static.used = strnlen(headers.array[internal.i].value.is.a_string, F_string_t_size_d); - internal.range.start = 0; - internal.range.stop = string_static.used; + 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)) { - destination->used = internal.original; + private_fl_fss_basic_write(F_false, string_static, 0, &internal.range, data->cache_1, state, (void * const) &internal); } + break; + case f_abstruse_strings_e: - // @todo + data->cache_2->used = 0; + + for (internal.j = 0; headers.array[internal.i].value.is.a_strings[internal.i]; ++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 = strnlen(headers.array[internal.i].value.is.a_strings[internal.j], F_string_t_size_d); + + if (string_static.used) { + if (data->cache_2->used + f_fss_extended_open_s.used + string_static.used > data->cache_2->size) { + state->status = f_memory_array_increase_by(state->step_small + f_fss_extended_open_s.used + string_static.used, sizeof(f_char_t), (void **) &data->cache_2->string, &data->cache_2->used, &data->cache_2->size); + if (F_status_is_error(state->status)) break; + } + + 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_2, state, (void * const) &internal); + if (F_status_is_error(state->status)) break; + + if (headers.array[internal.i].value.is.a_strings[internal.i + 1]) { + data->cache_2->string[data->cache_2->used++] = f_fss_extended_open_s.string[0]; + } + } + } // for + + if (F_status_is_error_not(state->status) && data->cache_2->used) { + state->status = f_string_dynamic_append(*data->cache_2, data->cache_1); + } + break; case f_abstruse_dynamic_e: + if (headers.array[internal.i].value.is.a_dynamic.used) { + internal.range.start = 0; + internal.range.stop = headers.array[internal.i].value.is.a_dynamic.used - 1; + + private_fl_fss_basic_write(F_false, headers.array[internal.i].value.is.a_dynamic, 0, &internal.range, data->cache_1, state, (void * const) &internal); + } + else { + if (data->cache_1->used + (f_string_ascii_quote_double_s.used * 2) > data->cache_1->size) { + state->status = f_memory_array_increase_by(state->step_small + (f_string_ascii_quote_double_s.used * 2), sizeof(f_char_t), (void **) &data->cache_1->string, &data->cache_1->used, &data->cache_1->size); + if (F_status_is_error(state->status)) break; + } + + data->cache_1->string[data->cache_1->used++] = f_string_ascii_quote_double_s.string[0]; + data->cache_1->string[data->cache_1->used++] = f_string_ascii_quote_double_s.string[0]; + } + + break; + case f_abstruse_dynamics_e: - // @todo + data->cache_2->used = 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; + } + + if (headers.array[internal.i].value.is.a_dynamics.array[internal.j].used) { + if (data->cache_2->used + f_fss_extended_open_s.used + headers.array[internal.i].value.is.a_dynamics.array[internal.j].used > data->cache_2->size) { + state->status = f_memory_array_increase_by(state->step_small + f_fss_extended_open_s.used + headers.array[internal.i].value.is.a_dynamics.array[internal.j].used, sizeof(f_char_t), (void **) &data->cache_2->string, &data->cache_2->used, &data->cache_2->size); + if (F_status_is_error(state->status)) break; + } + + internal.range.start = 0; + internal.range.stop = headers.array[internal.i].value.is.a_dynamics.array[internal.j].used - 1; + + private_fl_fss_basic_write(F_false, headers.array[internal.i].value.is.a_dynamics.array[internal.j], 0, &internal.range, data->cache_2, state, (void * const) &internal); + if (F_status_is_error(state->status)) break; + + if (headers.array[internal.i].value.is.a_strings[internal.i + 1]) { + data->cache_2->string[data->cache_2->used++] = f_fss_extended_open_s.string[0]; + } + } + else { + if (data->cache_2->used + (f_string_ascii_quote_double_s.used * 2) > data->cache_2->size) { + state->status = f_memory_array_increase_by(state->step_small + (f_string_ascii_quote_double_s.used * 2), sizeof(f_char_t), (void **) &data->cache_2->string, &data->cache_2->used, &data->cache_2->size); + if (F_status_is_error(state->status)) break; + } + + data->cache_2->string[data->cache_2->used++] = f_string_ascii_quote_double_s.string[0]; + data->cache_2->string[data->cache_2->used++] = f_string_ascii_quote_double_s.string[0]; + } + } // for + + if (F_status_is_error_not(state->status) && data->cache_2->used) { + state->status = f_string_dynamic_append(*data->cache_2, data->cache_1); + } + break; case f_abstruse_map_e: + data->cache_2->used = 0; + + if (headers.array[internal.i].value.is.a_map.name.used) { + internal.j = headers.array[internal.i].value.is.a_map.name.used; + internal.j += headers.array[internal.i].value.is.a_map.value.used ? headers.array[internal.i].value.is.a_map.value.used : (f_string_ascii_quote_double_s.used * 2); + } + else if (headers.array[internal.i].value.is.a_map.value.used) { + internal.j = (f_string_ascii_quote_double_s.used * 2) + headers.array[internal.i].value.is.a_map.value.used; + } + else { + internal.j = f_string_ascii_quote_double_s.used * 4; + } + + internal.j += f_fss_extended_open_s.used; + + if (data->cache_2->used + internal.j > data->cache_2->size) { + state->status = f_memory_array_increase_by(state->step_small + internal.j, sizeof(f_char_t), (void **) &data->cache_2->string, &data->cache_2->used, &data->cache_2->size); + if (F_status_is_error(state->status)) break; + } + + if (headers.array[internal.i].value.is.a_map.name.used) { + internal.range.start = 0; + internal.range.stop = headers.array[internal.i].value.is.a_map.name.used - 1; + + private_fl_fss_basic_write(F_false, headers.array[internal.i].value.is.a_map.name, 0, &internal.range, data->cache_2, state, (void * const) &internal); + } + else { + data->cache_2->string[data->cache_2->used++] = f_string_ascii_quote_double_s.string[0]; + data->cache_2->string[data->cache_2->used++] = f_string_ascii_quote_double_s.string[0]; + } + + data->cache_2->string[data->cache_2->used++] = f_fss_extended_open_s.string[0]; + + if (data->cache_2->used + internal.j > data->cache_2->size) { + state->status = f_memory_array_increase_by(state->step_small + internal.j, sizeof(f_char_t), (void **) &data->cache_2->string, &data->cache_2->used, &data->cache_2->size); + if (F_status_is_error(state->status)) break; + } + + if (headers.array[internal.i].value.is.a_map.name.used) { + internal.range.start = 0; + internal.range.stop = headers.array[internal.i].value.is.a_map.name.used - 1; + + private_fl_fss_basic_write(F_false, headers.array[internal.i].value.is.a_map.name, 0, &internal.range, data->cache_2, state, (void * const) &internal); + } + else { + data->cache_2->string[data->cache_2->used++] = f_string_ascii_quote_double_s.string[0]; + data->cache_2->string[data->cache_2->used++] = f_string_ascii_quote_double_s.string[0]; + } + + if (F_status_is_error_not(state->status) && data->cache_2->used) { + state->status = f_string_dynamic_append(*data->cache_2, data->cache_1); + } + + break; + case f_abstruse_maps_e: // @todo break; @@ -248,34 +379,20 @@ extern "C" { } } + // Pre-allocate space for the built string, close string, and terminating NULL if necessary. if (F_status_is_error_not(state->status)) { - if (data->cache->used) { - - // Pre-allocate space for the built string and terminating NULL if necessary. - state->status = f_memory_array_increase_by(data->cache->used + 1, sizeof(f_char_t), (void **) &destination->string, &destination->used, &destination->size); - - if (F_status_is_error_not(state->status)) { - state->status = f_string_dynamic_append(*data->cache, destination); - } - } + state->status = f_memory_array_increase_by(data->cache_1->used + f_fss_extended_close_s.used + 1, sizeof(f_char_t), (void **) &destination->string, &destination->used, &destination->size); } - if (F_status_is_error(state->status)) { - if (state->handle) { - state->handle((void * const) state, (void * const) &internal); - - if (F_status_is_error(state->status)) { - destination->used = internal.original; - - return; - } - } - else { - destination->used = internal.original; + if (F_status_is_error_not(state->status) && data->cache_1->used) { + state->status = f_string_dynamic_append(*data->cache_1, destination); + } - return; - } + if (F_status_is_error_not(state->status)) { + state->status = f_string_dynamic_append(f_fss_extended_close_s, destination); } + + macro_f_fss_payload_header_write_handle_error_d(destination, state, internal); } // for } @@ -283,23 +400,7 @@ extern "C" { internal.step = f_fss_payload_write_signature_object_e; state->status = f_string_dynamic_append(f_fss_payload_object_signature_s, destination); - - if (F_status_is_error(state->status)) { - if (state->handle) { - state->handle((void * const) state, (void * const) &internal); - - if (F_status_is_error(state->status)) { - destination->used = internal.original; - - return; - } - } - else { - destination->used = internal.original; - - return; - } - } + macro_f_fss_payload_header_write_handle_error_d(destination, state, internal); } if ((state->code & f_fss_payload_write_signature_content_e) && !signatures) { @@ -384,23 +485,7 @@ extern "C" { internal.step = f_fss_payload_write_payload_object_e; state->status = f_string_dynamic_append(f_fss_payload_object_payload_s, destination); - - if (F_status_is_error(state->status)) { - if (state->handle) { - state->handle((void * const) state, (void * const) &internal); - - if (F_status_is_error(state->status)) { - destination->used = internal.original; - - return; - } - } - else { - destination->used = internal.original; - - return; - } - } + macro_f_fss_payload_header_write_handle_error_d(destination, state, internal); } state->status = F_okay; diff --git a/level_1/fl_fss/c/fss/payload.h b/level_1/fl_fss/c/fss/payload.h index 0b17b04..c3a9f2d 100644 --- a/level_1/fl_fss/c/fss/payload.h +++ b/level_1/fl_fss/c/fss/payload.h @@ -38,6 +38,7 @@ extern "C" { * - step: The current step. * - i: A counter used for the "headers" and "signatures" 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. * - conversion: The conversion data. * - destination: The destination string being written to. * - original: The original destination used length. @@ -47,6 +48,7 @@ extern "C" { uint16_t step; f_number_unsigned_t i; f_number_unsigned_t j; + f_number_unsigned_t k; f_string_range_t range; f_conversion_data_t conversion; @@ -58,16 +60,18 @@ extern "C" { 0, \ 0, \ 0, \ + 0, \ f_string_range_t_initialize, \ f_conversion_data_base_10_c, \ 0, \ 0, \ } - #define macro_f_fss_payload_header_write_internal_t_initialize_1(step, i, j, range, conversion, destination, original) { \ + #define macro_f_fss_payload_header_write_internal_t_initialize_1(step, i, j, k, range, conversion, destination, original) { \ step, \ i, \ j, \ + k, \ range, \ conversion, \ destination, \ @@ -78,6 +82,7 @@ extern "C" { 0, \ 0, \ 0, \ + 0, \ f_string_range_t_initialize, \ f_conversion_data_base_10_c, \ destination, \ @@ -90,31 +95,140 @@ extern "C" { * * Properties: * - conversion: The conversion data. - * - cache: A string cache to use (generally required to be not NULL). + * - cache_1: A string cache to use for building a complete header line (generally required to be not NULL). + * - cache_2: A string cache to use for building small individual strings (generally required to be not NULL). */ #ifndef _di_f_fss_payload_header_write_state_t_ typedef struct { f_conversion_data_t conversion; - f_string_dynamic_t *cache; + f_string_dynamic_t *cache_1; + f_string_dynamic_t *cache_2; } f_fss_payload_header_write_state_t; #define f_fss_payload_header_write_state_t_initialize { \ f_conversion_data_base_10_c, \ 0, \ + 0, \ } - #define macro_f_fss_payload_header_write_state_t_initialize_1(conversion, destination) { \ + #define macro_f_fss_payload_header_write_state_t_initialize_1(conversion, cache_1, cache_2) { \ conversion, \ - destination, \ + cache_1, \ + cache_2, \ } - #define macro_f_fss_payload_header_write_state_t_initialize_2(destination) { \ + #define macro_f_fss_payload_header_write_state_t_initialize_2(cache_1, cache_2) { \ f_conversion_data_base_10_c, \ - destination, \ + cache_1, \ + cache_2, \ } #endif // _di_f_fss_payload_header_write_state_t_ +/** + * Defines for f_fss_payload_header_write(). + * + * macro_f_fss_payload_header_write_handle_error_d: + * Handle error return status, calling handle and reset destination.used. + * + * Parameters: + * - destination: The destination 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(). + * + * macro_f_fss_payload_header_write_process_signed_numbers_d: + * Process the numbers array, converting it to a string. + * The data->cache_1 is appended to. + * The data->cache_2 is reset and used. + * + * 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(). + * - numbers: The is.a array representing the number. + */ +#ifndef _di_f_fss_payload_header_write_d_ + #define macro_f_fss_payload_header_write_handle_error_d(destination, state, internal) \ + if (F_status_is_error(state->status)) { \ + if (state->handle) { \ + state->handle((void * const) state, (void * const) &internal); \ + \ + if (F_status_is_error(state->status)) { \ + destination->used = internal.original; \ + \ + return; \ + } \ + } \ + else { \ + destination->used = internal.original; \ + \ + return; \ + } \ + } + + #define macro_f_fss_payload_header_write_process_signed_numbers_d(data, state, internal, numbers) \ + 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) return; \ + } \ + \ + data->cache_2->used = 0; \ + \ + state->status = f_conversion_number_signed_to_string(numbers.array[internal.j], data->conversion, data->cache_2); \ + if (F_status_is_error(state->status)) break; \ + \ + if (data->cache_2->used) { \ + if (data->cache_1->used + f_fss_extended_open_s.used + data->cache_2->used > data->cache_1->size) { \ + state->status = f_memory_array_increase_by(state->step_small + f_fss_extended_open_s.used + data->cache_2->used, sizeof(f_char_t), (void **) &data->cache_1->string, &data->cache_1->used, &data->cache_1->size); \ + if (F_status_is_error(state->status)) break; \ + } \ + \ + internal.range.start = 0; \ + internal.range.stop = data->cache_2->used - 1; \ + \ + private_fl_fss_basic_write(F_false, *data->cache_2, 0, &internal.range, data->cache_1, state, (void * const) &internal); \ + if (F_status_is_error(state->status)) break; \ + \ + if (internal.j + 1 < numbers.used) { \ + data->cache_1->string[data->cache_1->used++] = f_fss_extended_open_s.string[0]; \ + } \ + } \ + } // for + + #define macro_f_fss_payload_header_write_process_unsigned_numbers_d(data, state, internal, numbers) \ + 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) return; \ + } \ + \ + data->cache_2->used = 0; \ + \ + state->status = f_conversion_number_unsigned_to_string(numbers.array[internal.j], data->conversion, data->cache_2); \ + if (F_status_is_error(state->status)) break; \ + \ + if (data->cache_2->used) { \ + if (data->cache_1->used + f_fss_extended_open_s.used + data->cache_2->used > data->cache_1->size) { \ + state->status = f_memory_array_increase_by(state->step_small + f_fss_extended_open_s.used + data->cache_2->used, sizeof(f_char_t), (void **) &data->cache_1->string, &data->cache_1->used, &data->cache_1->size); \ + if (F_status_is_error(state->status)) break; \ + } \ + \ + internal.range.start = 0; \ + internal.range.stop = data->cache_2->used - 1; \ + \ + private_fl_fss_basic_write(F_false, *data->cache_2, 0, &internal.range, data->cache_1, state, (void * const) &internal); \ + if (F_status_is_error(state->status)) break; \ + \ + if (internal.j + 1 < numbers.used) { \ + data->cache_1->string[data->cache_1->used++] = f_fss_extended_open_s.string[0]; \ + } \ + } \ + } // for +#endif // _di_f_fss_payload_header_write_d_ + // @todo fl_fss_payload_header_read() to build an array of f_abstruse for the headers? /** @@ -122,10 +236,13 @@ extern "C" { * * This implementation does not handle the following f_abstruse_*_e: * - none. - * - strings. * - void. * - voids. * + * Any f_abstruse_strings_e must be NULL terminated. + * + * For dynamic string data, such as f_abstruse_dynamic_e and f_abstruse_map_e, an empty quoted string is printed if the ".used" is 0. + * * @param headers * An abstruse map representing individual headers. * Ultimately, all headers are cast to a string or a binary representation (depending on implementation).