#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;
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) {
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);
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) {
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);
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;
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;
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) {
} // 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;
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);
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;
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;
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) {
// 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.
* 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.
* @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
--- /dev/null
+/**
+ * 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