]> Kevux Git Server - fll/commitdiff
Progress: Continue adding FSS Payload processing code.
authorKevin Day <thekevinday@gmail.com>
Thu, 19 Oct 2023 04:26:42 +0000 (23:26 -0500)
committerKevin Day <thekevinday@gmail.com>
Thu, 19 Oct 2023 04:26:42 +0000 (23:26 -0500)
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.

build/level_1/settings
build/monolithic/settings
level_0/f_conversion/c/conversion.h
level_1/fl_fss/c/fss.h
level_1/fl_fss/c/fss/payload.c
level_1/fl_fss/c/fss/payload.h
level_1/fl_fss/c/fss/payload/define.h [new file with mode: 0644]
level_1/fl_fss/c/fss/payload/type.h [new file with mode: 0644]
level_1/fl_fss/data/build/settings

index fb4658eb8b16b072fed3e7caad539d60db060583..926b59933e026e1c67b2339d0cd8b15f484ca4a8 100644 (file)
@@ -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
index 886e92ba5735cae7b3bc83efc06034d362d26895..520d4ee6e7ccbdf6380fd9ee952311abf5f82ef8 100644 (file)
@@ -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
index 1167d4dade52fd0567641760632499679887cb61..957fdf68d43ed6e3fec70fccc24922559c7f5180 100644 (file)
@@ -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.
index 974dba47760b057b449e20800446c68efd93c73d..c383458c3ee176ab3af1b7c8b2c63aa4b69d1734 100644 (file)
@@ -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
index 8c5a34a5e992832a0ff1d1d8b4846284b88ada50..bb2a722453e3750a7dbc1a295da22fea74114b5f 100644 (file)
@@ -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) {
index c3a9f2d1683bec561c3465b1d0c124173952fa0e..ee2a3979122bae75f2c774b398af871d2e5f6212 100644 (file)
 // FLL-1 includes.
 #include <fll/level_1/fss.h>
 
+// FLL-1 FSS Payload includes.
+#include <fll/level_1/fss/payload/define.h>
+#include <fll/level_1/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).
- */
-#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 (file)
index 0000000..c5ae66d
--- /dev/null
@@ -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 (file)
index 0000000..18cff0e
--- /dev/null
@@ -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
index b46fa47c7a5b0fc9853cecf033c66c29a5323002..ee9fc9ff633f5cf4f0e0ad8d06d5ecb73581eca6 100644 (file)
@@ -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