From: Kevin Day Date: Thu, 19 Oct 2023 04:26:42 +0000 (-0500) Subject: Progress: Continue adding FSS Payload processing code. X-Git-Url: https://git.kevux.org/?a=commitdiff_plain;h=568ac751591ef4314fc1f98ce0ce4e62fb67c6da;p=fll Progress: Continue adding FSS Payload processing code. I started doing some re-designing to improve the approach and prepare for signatures/checksums. I realized somewhere during that process that I wanted to eventually control or even randomize the header order for integrity, organization, or security reasons. The current approach makes that impractical. I decided to save the current state so that I can then pivot to a better approach that will accommodate the above needs. Appropriate todo notes are added to this end. A lot of the existing payload code will be re-designed, again, as a result of this. --- diff --git a/build/level_1/settings b/build/level_1/settings index fb4658e..926b599 100644 --- a/build/level_1/settings +++ b/build/level_1/settings @@ -50,7 +50,7 @@ build_sources_headers conversion.h conversion/common.h build_sources_headers directory.h directory/common.h build_sources_headers environment.h build_sources_headers execute.h execute/common.h -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 +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 build_sources_headers iki.h build_sources_headers path.h build_sources_headers print.h print/common.h diff --git a/build/monolithic/settings b/build/monolithic/settings index 886e92b..520d4ee 100644 --- a/build/monolithic/settings +++ b/build/monolithic/settings @@ -150,7 +150,7 @@ build_sources_headers level_1/conversion.h level_1/conversion/common.h build_sources_headers level_1/directory.h level_1/directory/common.h build_sources_headers level_1/environment.h build_sources_headers level_1/execute.h level_1/execute/common.h -build_sources_headers level_1/fss.h level_1/fss/basic.h level_1/fss/basic_list.h level_1/fss/embedded_list.h level_1/fss/extended.h level_1/fss/extended_list.h level_1/fss/payload.h +build_sources_headers level_1/fss.h level_1/fss/basic.h level_1/fss/basic_list.h level_1/fss/embedded_list.h level_1/fss/extended.h level_1/fss/extended_list.h level_1/fss/payload.h level_1/fss/payload/define.h level_1/fss/payload/type.h build_sources_headers level_1/iki.h build_sources_headers level_1/path.h build_sources_headers level_1/print.h level_1/print/common.h diff --git a/level_0/f_conversion/c/conversion.h b/level_0/f_conversion/c/conversion.h index 1167d4d..957fdf6 100644 --- a/level_0/f_conversion/c/conversion.h +++ b/level_0/f_conversion/c/conversion.h @@ -271,7 +271,7 @@ extern "C" { * @param data * The settings designating how to perform the conversion. * @param destination - * The destination the converted string is saved into. + * The destination the converted string is appended onto. * * @return * F_okay if the number was converted to a string. @@ -336,7 +336,7 @@ extern "C" { * @param data * The settings designating how to perform the conversion. * @param destination - * The destination the converted string is saved into. + * The destination the converted string is appended onto. * * @return * F_okay if the number was converted to a string. diff --git a/level_1/fl_fss/c/fss.h b/level_1/fl_fss/c/fss.h index 974dba4..c383458 100644 --- a/level_1/fl_fss/c/fss.h +++ b/level_1/fl_fss/c/fss.h @@ -4,6 +4,14 @@ * Project: FSS * API Version: 0.7 * Licenses: lgpl-2.1-or-later + * + * Unlike many of the other base project headers, this does not auto-include all of the headers. + * Each FSS type has its own base header to include that includes all necessary additional headers as follows: + * - basic.h: The fss-0000 (Basic). + * - basic_list.h: The fss-0002 (Basic List). + * - extended.h The fss-0001 (Extended). + * - extended_list.h: The fss-0003 (Extended List). + * - payload.h: The fss-000e (Payload). */ #ifndef _FL_fss_h #define _FL_fss_h diff --git a/level_1/fl_fss/c/fss/payload.c b/level_1/fl_fss/c/fss/payload.c index 8c5a34a..bb2a722 100644 --- a/level_1/fl_fss/c/fss/payload.c +++ b/level_1/fl_fss/c/fss/payload.c @@ -6,7 +6,115 @@ extern "C" { #endif #ifndef _di_fl_fss_payload_header_write_ - void fl_fss_payload_header_write(const f_abstruse_maps_t headers, const f_abstruse_maps_t * const signatures, f_string_dynamic_t * const destination, f_state_t * const state) { + /** + * 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_2. + * If the number is not appended to data->cache_2, then empty quotes are appended onto data->cache_2 to represent no data. + * + * @param data + * The f_fss_payload_header_write_state_t pointer. + * The caller is expected to reset data->cache_2.used as needed. + * The resulting data->cache_2 is then appended onto data->cache_1 on success. + * @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) { + + internal->k = data->cache_2->used; + + state->status = f_conversion_number_signed_to_string(number, data->conversion, data->cache_2); + if (F_status_is_error(state->status)) return F_true; + + if (data->cache_2->used > internal->k) { + internal->range.start = internal->k; + internal->range.stop = data->cache_2->used - 1; + + private_fl_fss_basic_write(F_false, *data->cache_2, 0, &internal->range, data->cache_2, state, (void * const) internal); + if (F_status_is_error(state->status)) return F_true; + } + 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)) return F_true; + } + + state->status = f_string_dynamic_append(f_string_ascii_quote_double_s, data->cache_2); + + if (F_status_is_error_not(state->status)) { + state->status = f_string_dynamic_append(f_string_ascii_quote_double_s, data->cache_2); + } + + if (F_status_is_error(state->status)) return F_true; + } + + 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_2. + * If the number is not appended to data->cache_2, then empty quotes are appended onto data->cache_2 to represent no data. + * + * @param data + * The f_fss_payload_header_write_state_t pointer. + * The caller is expected to reset data->cache_2.used as needed. + * The resulting data->cache_2 is then appended onto data->cache_1 on success. + * @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) { + + internal->k = data->cache_2->used; + + state->status = f_conversion_number_unsigned_to_string(number, data->conversion, data->cache_2); + if (F_status_is_error(state->status)) return F_true; + + if (data->cache_2->used > internal->k) { + internal->range.start = internal->k; + internal->range.stop = data->cache_2->used - 1; + + private_fl_fss_basic_write(F_false, *data->cache_2, 0, &internal->range, data->cache_2, state, (void * const) internal); + if (F_status_is_error(state->status)) return F_true; + } + 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)) return F_true; + } + + state->status = f_string_dynamic_append(f_string_ascii_quote_double_s, data->cache_2); + + if (F_status_is_error_not(state->status)) { + state->status = f_string_dynamic_append(f_string_ascii_quote_double_s, data->cache_2); + } + + if (F_status_is_error(state->status)) return F_true; + } + + return F_false; + } +#endif // _di_fl_fss_payload_header_write_ + +#ifndef _di_fl_fss_payload_header_write_ + void fl_fss_payload_header_write(const f_abstruse_maps_t headers, const f_uint8s_t * const signatures, f_string_dynamic_t * const destination, f_state_t * const state) { #ifndef _di_level_1_parameter_checking_ if (!state) return; @@ -24,7 +132,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_1 || !data->cache_2) { + if (!data->cache_1 || !data->cache_2 || !data->cache_3) { state->status = F_status_set_error(F_parameter); if (state->handle) { @@ -34,34 +142,20 @@ extern "C" { return; } - // Pre-allocate as much as possible to reduce memory reallocation chances, using 'j'. + // Pre-allocate as much as possible to reduce memory reallocation chances. { - internal.j = 0; + internal.k = state->step_large; if (state->code & f_fss_payload_write_comment_header_e) { - internal.j += f_fss_payload_comment_header_s.used + 1; + internal.k += f_fss_payload_comment_header_s.used + 1; } if (state->code & f_fss_payload_write_header_object_e) { - internal.j += f_fss_payload_object_header_s.used + 1; - } - - // This uses step large to at least do something for header content. - if (state->code & f_fss_payload_write_header_content_e) { - internal.j += state->step_large + headers.used + 1; - } - - if (state->code & f_fss_payload_write_signature_object_e) { - internal.j += f_fss_payload_object_signature_s.used + 1; - } - - // This uses step large to at least do something for signature content. - if ((state->code & f_fss_payload_write_signature_content_e) && signatures) { - internal.j += state->step_large + signatures->used + 1; + internal.k += f_fss_payload_object_header_s.used + 1; } if (state->code & f_fss_payload_write_payload_object_e) { - internal.j += f_fss_payload_object_payload_s.used + 1; + internal.k += f_fss_payload_object_payload_s.used + 1; } state->status = f_memory_array_increase_by(internal.j + 1, sizeof(f_char_t), (void **) &destination->string, &destination->used, &destination->size); @@ -85,9 +179,11 @@ extern "C" { macro_f_fss_payload_header_write_handle_error_d(destination, state, internal); } - if (state->code & f_fss_payload_write_header_content_e) { + if ((state->code & f_fss_payload_write_header_content_e) || (state->code & f_fss_payload_write_signature_content_e)) { internal.step = f_fss_payload_write_header_content_e; + data->cache_3->used = 0; + f_string_static_t string_static = f_string_static_t_initialize; for (; internal.i < headers.used ; ++internal.i) { @@ -102,7 +198,6 @@ extern "C" { internal.range.start = 0; internal.range.stop = headers.array[internal.i].key.used - 1; 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 + f_fss_extended_open_s.used + 2, sizeof(f_char_t), (void **) &data->cache_1->string, &data->cache_1->used, &data->cache_1->size); @@ -123,62 +218,78 @@ extern "C" { break; case f_abstruse_signed_e: - state->status = f_conversion_number_signed_to_string(headers.array[internal.i].value.is.a_signed, data->conversion, data->cache_1); + data->cache_2->used = 0; + + private_inline_f_payload_header_write_number_signed(data, state, &internal, headers.array[internal.i].value.is.a_signed); + + if (F_status_is_error_not(state->status) && data->cache_2->used) { + // @todo build signature, use a callback for this so that the caller can provide an appropriate algorithm. + + state->status = f_string_dynamic_append(*data->cache_2, data->cache_1); + } break; case f_abstruse_unsigned_e: - state->status = f_conversion_number_unsigned_to_string(headers.array[internal.i].value.is.a_unsigned, data->conversion, data->cache_1); + data->cache_2->used = 0; + + private_inline_f_payload_header_write_number_unsigned(data, state, &internal, headers.array[internal.i].value.is.a_unsigned); + + if (F_status_is_error_not(state->status) && data->cache_2->used) { + // @todo build signature, use a callback for this so that the caller can provide an appropriate algorithm. + + state->status = f_string_dynamic_append(*data->cache_2, 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); + macro_f_fss_payload_header_write_process_signed_numbers_d(data, state, internal, headers.array[internal.i].value.is.a_i8s, signatures); 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); + macro_f_fss_payload_header_write_process_signed_numbers_d(data, state, internal, headers.array[internal.i].value.is.a_i16s, signatures); 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); + macro_f_fss_payload_header_write_process_signed_numbers_d(data, state, internal, headers.array[internal.i].value.is.a_i32s, signatures); 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); + macro_f_fss_payload_header_write_process_signed_numbers_d(data, state, internal, headers.array[internal.i].value.is.a_i64s, signatures); 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); + macro_f_fss_payload_header_write_process_signed_numbers_d(data, state, internal, headers.array[internal.i].value.is.a_signeds, signatures); 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); + macro_f_fss_payload_header_write_process_unsigned_numbers_d(data, state, internal, headers.array[internal.i].value.is.a_u8s, signatures); 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); + macro_f_fss_payload_header_write_process_unsigned_numbers_d(data, state, internal, headers.array[internal.i].value.is.a_u16s, signatures); 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); + macro_f_fss_payload_header_write_process_unsigned_numbers_d(data, state, internal, headers.array[internal.i].value.is.a_u32s, signatures); 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); + macro_f_fss_payload_header_write_process_unsigned_numbers_d(data, state, internal, headers.array[internal.i].value.is.a_u64s, signatures); 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); + macro_f_fss_payload_header_write_process_unsigned_numbers_d(data, state, internal, headers.array[internal.i].value.is.a_unsigneds, signatures); break; @@ -190,7 +301,19 @@ extern "C" { 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_1, state, (void * const) &internal); + if (signatures && signatures->array[internal.i]) { + data->cache_2->used = 0; + + private_fl_fss_basic_write(F_false, string_static, 0, &internal.range, data->cache_2, state, (void * const) &internal); + + if (F_status_is_error_not(state->status) && data->cache_2->used) { + // @todo build signature, use a callback for this so that the caller can provide an appropriate algorithm. + + state->status = f_string_dynamic_append(*data->cache_2, data->cache_1); + } + } else { + private_fl_fss_basic_write(F_false, string_static, 0, &internal.range, data->cache_1, state, (void * const) &internal); + } } break; @@ -198,6 +321,7 @@ extern "C" { case f_abstruse_strings_e: data->cache_2->used = 0; + // @todo this needs to be updated to handle empty strings accordingly (appending ""). for (internal.j = 0; headers.array[internal.i].value.is.a_strings[internal.i]; ++internal.j) { if (state->interrupt) { @@ -227,26 +351,34 @@ extern "C" { } // for if (F_status_is_error_not(state->status) && data->cache_2->used) { + // @todo build signature, use a callback for this so that the caller can provide an appropriate algorithm. + 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; + data->cache_2->used = 0; - 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); + if (headers.array[internal.i].value.is.a_dynamic.used) { + internal.k = headers.array[internal.i].value.is.a_dynamic.used; } 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; - } + internal.k = f_string_ascii_quote_double_s.used * 2; + } + + if (data->cache_2->used + internal.k > data->cache_2->size) { + state->status = f_memory_array_increase_by(state->step_small + internal.k, 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; + } + + 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) && data->cache_2->used) { + // @todo build signature, use a callback for this so that the caller can provide an appropriate algorithm. - 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]; + state->status = f_string_dynamic_append(*data->cache_2, data->cache_1); } break; @@ -261,6 +393,8 @@ extern "C" { if (F_status_set_fine(state->status) == F_interrupt) return; } + // @todo rewrite this block to use structure as shown in f_abstruse_dynamic_e above. + 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); @@ -298,63 +432,72 @@ extern "C" { 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); + internal.k = headers.array[internal.i].value.is.a_map.name.used; + internal.k += 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; + internal.k = (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.k = f_string_ascii_quote_double_s.used * 4; } - internal.j += f_fss_extended_open_s.used; + internal.k += 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 (data->cache_2->used + internal.k > data->cache_2->size) { + state->status = f_memory_array_increase_by(state->step_small + internal.k, 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; + macro_f_fss_payload_header_write_process_dynamic_d(data, state, internal, headers.array[internal.i].value.is.a_map.name); - 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); + data->cache_2->string[data->cache_2->used++] = f_fss_extended_open_s.string[0]; + + macro_f_fss_payload_header_write_process_dynamic_d(data, state, internal, headers.array[internal.i].value.is.a_map.value); + + if (F_status_is_error_not(state->status) && data->cache_2->used) { + // @todo build signature, use a callback for this so that the caller can provide an appropriate algorithm. + + state->status = f_string_dynamic_append(*data->cache_2, data->cache_1); + } + + break; + + case f_abstruse_maps_e: + // @todo + break; + + case f_abstruse_map_multi_e: + data->cache_2->used = 0; + + if (headers.array[internal.i].value.is.a_map_multi.name.used) { + internal.k = headers.array[internal.i].value.is.a_map_multi.name.used; } 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]; + internal.k = f_string_ascii_quote_double_s.used * 2; } - data->cache_2->string[data->cache_2->used++] = f_fss_extended_open_s.string[0]; + internal.k += 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 (data->cache_2->used + internal.k > data->cache_2->size) { + state->status = f_memory_array_increase_by(state->step_small + internal.k, 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; + macro_f_fss_payload_header_write_process_dynamic_d(data, state, internal, headers.array[internal.i].value.is.a_map_multi.name); - 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]; + + // @todo loop over all values (which is a dynamics string). if (F_status_is_error_not(state->status) && data->cache_2->used) { + // @todo build signature, use a callback for this so that the caller can provide an appropriate algorithm. + state->status = f_string_dynamic_append(*data->cache_2, data->cache_1); } break; - case f_abstruse_maps_e: - // @todo - break; - - case f_abstruse_map_multi_e: case f_abstruse_map_multis_e: // @todo break; @@ -370,6 +513,62 @@ extern "C" { break; case f_abstruse_triple_e: + data->cache_2->used = 0; + + if (headers.array[internal.i].value.is.a_triple.a.used) { + internal.k = headers.array[internal.i].value.is.a_triple.a.used; + + if (headers.array[internal.i].value.is.a_triple.b.used) { + internal.k += headers.array[internal.i].value.is.a_triple.b.used; + internal.k += headers.array[internal.i].value.is.a_triple.c.used ? headers.array[internal.i].value.is.a_triple.c.used : (f_string_ascii_quote_double_s.used * 2); + } + else if (headers.array[internal.i].value.is.a_triple.c.used) { + internal.k += headers.array[internal.i].value.is.a_triple.c.used + (f_string_ascii_quote_double_s.used * 2); + } + else { + internal.k = f_string_ascii_quote_double_s.used * 4; + } + } + else if (headers.array[internal.i].value.is.a_triple.b.used) { + if (headers.array[internal.i].value.is.a_triple.c.used) { + internal.k = (f_string_ascii_quote_double_s.used * 2) + headers.array[internal.i].value.is.a_triple.b.used + headers.array[internal.i].value.is.a_triple.c.used; + } + else { + internal.k = (f_string_ascii_quote_double_s.used * 4) + headers.array[internal.i].value.is.a_triple.b.used; + } + } + else if (headers.array[internal.i].value.is.a_triple.c.used) { + internal.k = (f_string_ascii_quote_double_s.used * 4) + headers.array[internal.i].value.is.a_triple.c.used; + } + else { + internal.k = f_string_ascii_quote_double_s.used * 6; + } + + internal.k += f_fss_extended_open_s.used * 2; + + if (data->cache_2->used + internal.k > data->cache_2->size) { + state->status = f_memory_array_increase_by(state->step_small + internal.k, 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; + } + + macro_f_fss_payload_header_write_process_dynamic_d(data, state, internal, headers.array[internal.i].value.is.a_triple.a); + + data->cache_2->string[data->cache_2->used++] = f_fss_extended_open_s.string[0]; + + macro_f_fss_payload_header_write_process_dynamic_d(data, state, internal, headers.array[internal.i].value.is.a_triple.b); + + data->cache_2->string[data->cache_2->used++] = f_fss_extended_open_s.string[0]; + + macro_f_fss_payload_header_write_process_dynamic_d(data, state, internal, headers.array[internal.i].value.is.a_triple.c); + + if (F_status_is_error_not(state->status) && data->cache_2->used) { + // @todo build signature, use a callback for this so that the caller can provide an appropriate algorithm. + + state->status = f_string_dynamic_append(*data->cache_2, data->cache_1); + } + + break; + case f_abstruse_triples_e: // @todo break; @@ -403,82 +602,9 @@ extern "C" { macro_f_fss_payload_header_write_handle_error_d(destination, state, internal); } - if ((state->code & f_fss_payload_write_signature_content_e) && !signatures) { - internal.step = f_fss_payload_write_signature_content_e; - - for (internal.i = 0; internal.i < signatures->used ; ++internal.i) { - - if (state->interrupt) { - state->interrupt((void * const) state, (void * const) &internal); - if (F_status_set_fine(state->status) == F_interrupt) return; - } - - switch (signatures->array[internal.i].value.type) { - case f_abstruse_none_e: - case f_abstruse_void_e: - case f_abstruse_voids_e: - break; - - case f_abstruse_signed_e: - case f_abstruse_unsigned_e: - // @todo - break; - - case f_abstruse_int8s_e: - case f_abstruse_int16s_e: - case f_abstruse_int32s_e: - case f_abstruse_int64s_e: - case f_abstruse_signeds_e: - // @todo - break; - - case f_abstruse_uint8s_e: - case f_abstruse_uint16s_e: - case f_abstruse_uint32s_e: - case f_abstruse_uint64s_e: - case f_abstruse_unsigneds_e: - // @todo - break; - - case f_abstruse_string_e: - case f_abstruse_strings_e: - // @todo - break; - - case f_abstruse_dynamic_e: - case f_abstruse_dynamics_e: - // @todo - break; - - case f_abstruse_map_e: - case f_abstruse_maps_e: - // @todo - break; - - case f_abstruse_map_multi_e: - case f_abstruse_map_multis_e: - // @todo - break; - - case f_abstruse_quantity_e: - case f_abstruse_quantitys_e: - // @todo - break; - - case f_abstruse_range_e: - case f_abstruse_ranges_e: - // @todo - break; - - case f_abstruse_triple_e: - case f_abstruse_triples_e: - // @todo - break; - - default: - break; - } - } // for + if (data->cache_3->used) { + state->status = f_string_dynamic_append(*data->cache_3, data->cache_1); + macro_f_fss_payload_header_write_handle_error_d(destination, state, internal); } if (state->code & f_fss_payload_write_payload_object_e) { diff --git a/level_1/fl_fss/c/fss/payload.h b/level_1/fl_fss/c/fss/payload.h index c3a9f2d..ee2a397 100644 --- a/level_1/fl_fss/c/fss/payload.h +++ b/level_1/fl_fss/c/fss/payload.h @@ -27,213 +27,25 @@ // FLL-1 includes. #include +// FLL-1 FSS Payload includes. +#include +#include + #ifdef __cplusplus extern "C" { #endif -/** - * An internal structure for the fss_payload_header_write() passed to callbacks. - * - * Properties: - * - 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. - */ -#ifndef _di_f_fss_payload_header_write_internal_t_ - typedef struct { - 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; - - f_string_dynamic_t * const destination; - const f_number_unsigned_t original; - } f_fss_payload_header_write_internal_t; - - #define f_fss_payload_header_write_internal_t_initialize { \ - 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, k, range, conversion, destination, original) { \ - step, \ - i, \ - j, \ - k, \ - range, \ - conversion, \ - destination, \ - original, \ - } - - #define macro_f_fss_payload_header_write_internal_t_initialize_2(destination, original) { \ - 0, \ - 0, \ - 0, \ - 0, \ - f_string_range_t_initialize, \ - f_conversion_data_base_10_c, \ - destination, \ - original, \ - } -#endif // _di_f_fss_payload_header_write_internal_t_ - -/** - * A state structure for passing data to fss_payload_header_write(). - * - * Properties: - * - conversion: The conversion data. - * - 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_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, cache_1, cache_2) { \ - conversion, \ - cache_1, \ - cache_2, \ - } - - #define macro_f_fss_payload_header_write_state_t_initialize_2(cache_1, cache_2) { \ - f_conversion_data_base_10_c, \ - 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? /** * Write standard header of the FSS-000E (Payload). * + * @todo Rewrite this to use an array of strings to represent the built headers. + * This will allow for randomization, alphabetization, and other header order options. + * This will be a better approach because the signature and appropriate callbacks are not needed here. + * The caller can then loop over these to transmit the data (or construct its own giant string). + * Having a lot of smaller strings is better than one giant string when it comes to memory reallocations. + * * This implementation does not handle the following f_abstruse_*_e: * - none. * - void. @@ -247,8 +59,7 @@ extern "C" { * An abstruse map representing individual headers. * Ultimately, all headers are cast to a string or a binary representation (depending on implementation). * @param signatures - * (optional) An abstruse map representing individual signature headers. - * Ultimately, all headers are cast to a string or a binary representation (depending on implementation). + * (optional) An array whose indexes must match each index in the headers, where each value if set to F_true will result in the generation of a signature. * Set to NULL to not use. * @param destination * The string in which the resulting header is appended to. @@ -290,7 +101,7 @@ extern "C" { * @see f_memory_array_increase_by() */ #ifndef _di_fl_fss_payload_header_write_ - extern void fl_fss_payload_header_write(const f_abstruse_maps_t headers, const f_abstruse_maps_t * const signatures, f_string_dynamic_t * const destination, f_state_t * const state); + extern void fl_fss_payload_header_write(const f_abstruse_maps_t headers, const f_uint8s_t * const signatures, f_string_dynamic_t * const destination, f_state_t * const state); #endif // _di_fl_fss_payload_header_write_ #ifdef __cplusplus diff --git a/level_1/fl_fss/c/fss/payload/define.h b/level_1/fl_fss/c/fss/payload/define.h new file mode 100644 index 0000000..c5ae66d --- /dev/null +++ b/level_1/fl_fss/c/fss/payload/define.h @@ -0,0 +1,134 @@ +/** + * FLL - Level 1 + * + * Project: FSS + * API Version: 0.7 + * Licenses: lgpl-2.1-or-later + * + * This is the fss-000e implementation. + */ +#ifndef _FL_fss_payload_define_h +#define _FL_fss_payload_define_h + +#ifdef __cplusplus +extern "C" { +#endif + +/** + * 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. + * This requires private_inline_f_payload_header_write_number_signed() from payload.c. + * + * Parameters: + * - data: The f_fss_payload_header_write_state_t pointer. The data->cache_2.used is set to 0 and then appended onto. The resulting data->cache_2 is then appended onto data->cache_1 on success. + * - 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 representing the array of signed numbers. + * - signatures: (optional) An array whose indexes must match each index in the headers, where each value if set to F_true will result in the generation of a signature. Set to NULL to not use. + * + * 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. + */ +#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, signatures) \ + data->cache_2->used = 0; \ + \ + 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 (private_inline_f_payload_header_write_number_signed(data, state, &internal, (f_number_signed_t) numbers.array[internal.j])) break; \ + \ + if (internal.j + 1 < numbers.used) { \ + state->status = f_string_dynamic_append(f_fss_extended_open_s, data->cache_2); \ + if (F_status_is_error(state->status)) break; \ + } \ + } /* for */ \ + \ + if (F_status_is_error_not(state->status) && signatures && signatures->array[internal.i]) { \ + /* @todo build signature (against data->cache_2), use a callback for this so that the caller can provide an appropriate algorithm. */ \ + } \ + \ + if (F_status_is_error_not(state->status) && data->cache_2->used) { \ + state->status = f_string_dynamic_append(*data->cache_2, data->cache_1); \ + } + + #define macro_f_fss_payload_header_write_process_unsigned_numbers_d(data, state, internal, numbers, signatures) \ + data->cache_2->used = 0; \ + \ + 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 (private_inline_f_payload_header_write_number_unsigned(data, state, &internal, (f_number_unsigned_t) numbers.array[internal.j])) break; \ + \ + if (internal.j + 1 < numbers.used) { \ + state->status = f_string_dynamic_append(f_fss_extended_open_s, data->cache_2); \ + if (F_status_is_error(state->status)) break; \ + } \ + } /* for */ \ + \ + if (F_status_is_error_not(state->status) && signatures && signatures->array[internal.i]) { \ + /* @todo build signature (against data->cache_2), use a callback for this so that the caller can provide an appropriate algorithm. */ \ + } \ + \ + if (F_status_is_error_not(state->status) && data->cache_2->used) { \ + state->status = f_string_dynamic_append(*data->cache_2, data->cache_1); \ + } + + #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; \ + \ + private_fl_fss_basic_write(F_false, dynamic, 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]; +#endif // _di_f_fss_payload_header_write_d_ + +#ifdef __cplusplus +} // extern "C" +#endif + +#endif // _FL_fss_payload_define_h diff --git a/level_1/fl_fss/c/fss/payload/type.h b/level_1/fl_fss/c/fss/payload/type.h new file mode 100644 index 0000000..18cff0e --- /dev/null +++ b/level_1/fl_fss/c/fss/payload/type.h @@ -0,0 +1,120 @@ +/** + * FLL - Level 1 + * + * Project: FSS + * API Version: 0.7 + * Licenses: lgpl-2.1-or-later + * + * This is the fss-000e implementation. + */ +#ifndef _FL_fss_payload_type_h +#define _FL_fss_payload_type_h + +#ifdef __cplusplus +extern "C" { +#endif + +/** + * An internal structure for the fss_payload_header_write() passed to callbacks. + * + * Properties: + * - 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. + */ +#ifndef _di_f_fss_payload_header_write_internal_t_ + typedef struct { + 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; + + f_string_dynamic_t * const destination; + const f_number_unsigned_t original; + } f_fss_payload_header_write_internal_t; + + #define f_fss_payload_header_write_internal_t_initialize { \ + 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, k, range, conversion, destination, original) { \ + step, \ + i, \ + j, \ + k, \ + range, \ + conversion, \ + destination, \ + original, \ + } + + #define macro_f_fss_payload_header_write_internal_t_initialize_2(destination, original) { \ + 0, \ + 0, \ + 0, \ + 0, \ + f_string_range_t_initialize, \ + f_conversion_data_base_10_c, \ + destination, \ + original, \ + } +#endif // _di_f_fss_payload_header_write_internal_t_ + +/** + * A state structure for passing data to fss_payload_header_write(). + * + * Properties: + * - conversion: The conversion data. + * - 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). + * - cache_3: A string cache to use for building a complete signature of each header (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_1; + f_string_dynamic_t *cache_2; + f_string_dynamic_t *cache_3; + } f_fss_payload_header_write_state_t; + + #define f_fss_payload_header_write_state_t_initialize { \ + f_conversion_data_base_10_c, \ + 0, \ + 0, \ + 0, \ + } + + #define macro_f_fss_payload_header_write_state_t_initialize_1(conversion, cache_1, cache_2, cache_3) { \ + conversion, \ + cache_1, \ + cache_2, \ + cache_3, \ + } + + #define macro_f_fss_payload_header_write_state_t_initialize_2(cache_1, cache_2, cache_3) { \ + f_conversion_data_base_10_c, \ + cache_1, \ + cache_2, \ + cache_3, \ + } +#endif // _di_f_fss_payload_header_write_state_t_ + +#ifdef __cplusplus +} // extern "C" +#endif + +#endif // _FL_fss_payload_type_h diff --git a/level_1/fl_fss/data/build/settings b/level_1/fl_fss/data/build/settings index b46fa47..ee9fc9f 100644 --- a/level_1/fl_fss/data/build/settings +++ b/level_1/fl_fss/data/build/settings @@ -34,7 +34,7 @@ build_libraries-individual -lf_abstruse -lf_conversion -lf_file -lf_fss -lf_memo 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_headers fss.h fss/basic.h fss/basic_list.h fss/embedded_list.h fss/extended.h fss/extended_list.h fss/payload.h +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 build_script yes build_shared yes