This also adds the beginnings of unit tests for the fl_fss project, specifically for the fl_fss_payload_header_map() function.
The tests for fl_fss_payload_header_map() will be rather complex and so I will likely break the tests for fl_fss_payload_header_map() into multiple files.
f_number_unsigned_t used;
} f_abstruse_maps_t;
- #define f_abstruses_t_initialize { 0, 0, 0 }
+ #define f_abstruse_maps_t_initialize { 0, 0, 0 }
#define macro_f_abstruse_maps_t_initialize_1(array, size, used) { array, size, used }
#define macro_f_abstruse_maps_t_initialize_2(array, length) { array, length, length }
/**
* FLL - Level 0
*
- * Project: IKI
+ * Project: Abstruse
* API Version: 0.7
* Licenses: lgpl-2.1-or-later
*
* When both *_split_range_e and *_split_ranges_e are set, then both the individual ranges and the range sets are split into separate Content (separate columns).
*
* Values of f_fss_payload_header_map_flag_*_e:
- * - none: No flag set.
- * - join_digits: Types of digits are combined into a single Content (single column).
- * - join_dynamics: Types of dynamics are combined into a single Content (single column).
- * - join_map: Types of map are combined into a single Content (single column), example: "key1 value1" "key2 value2" as opposed to "key1" "value1" "key2" "value2".
- * - join_maps: Types of maps are combined into a single Content (single column), example: "key1 value1 key2 value2" as opposed to "key1 value1" "key2 value2" or "key1" "value1" "key2" "value2".
- * - join_range: Types of range are combined into a single Content (single column).
- * - join_ranges: Types of ranges are combined into a single Content (single column) (this effectively forces join_range to always be treated as set).
- * - join_strings: Types of strings are combined into a single Content (single column).
- * - join_triple: Types of triple are combined into a single Content (single column), example: "a b c" "d e f" as opposed to "a" "b" "c" "d" "e" "f".
- * - join_triples: Types of triples are combined into a single Content (single column), example: "a b c d e f" as opposed to "a b c" "d e f" or "a" "b" "c" "d" "e" "f".
- * - null: When the key has no header Content (header value.used is 0), still add the Object (header key) (When this is not set then the Object (header key) is not added).
- * - null_dynamic: Types of dynamic and dynamics have empty strings (such as "") added for NULL values (used is 0).
- * - null_map_key: Types of map and maps has empty strings (such as "") added for NULL values (used is 0) for the map key.
- * - null_map_value: Types of map and maps has empty strings (such as "") added for NULL values (used is 0) for the map value.
- * - null_maps: Types of dynamic and dynamics have empty strings (such as "") added for when null_map_key and null_map_value are not set and both map key and map value have NULL values (used is 0).
- * - null_string: Types of string and strings have empty strings (such as "") for NULL values.
- * - null_triple_a: Types of triple and triples has empty strings (such as "") added for NULL values (used is 0) for the "a" property.
- * - null_triple_b: Types of triple and triples has empty strings (such as "") added for NULL values (used is 0) for the "b" property.
- * - null_triple_c: Types of triple and triples has empty strings (such as "") added for NULL values (used is 0) for the "c" property.
- * - quote_double: Use double quotes (U+0022) when quoting strings.
- * - quote_grave: Use grave (U+0060) when quoting strings.
- * - quote_single: Use single quotes (U+0027) when quoting strings.
- * - last: This does nothing and is provided to be used as a starting point for anything extending this (there should be a max total of 64 bits allowed).
+ * - none: No flag set.
+ * - join_digits: Types of digits are combined into a single Content (single column).
+ * - join_dynamics: Types of dynamics are combined into a single Content (single column).
+ * - join_map: Types of map are combined into a single Content (single column), example: "key1 value1" "key2 value2" as opposed to "key1" "value1" "key2" "value2".
+ * - join_maps: Types of maps are combined into a single Content (single column), example: "key1 value1 key2 value2" as opposed to "key1 value1" "key2 value2" or "key1" "value1" "key2" "value2".
+ * - join_range: Types of range are combined into a single Content (single column).
+ * - join_ranges: Types of ranges are combined into a single Content (single column) (this effectively forces join_range to always be treated as set).
+ * - join_strings: Types of strings are combined into a single Content (single column).
+ * - join_triple: Types of triple are combined into a single Content (single column), example: "a b c" "d e f" as opposed to "a" "b" "c" "d" "e" "f".
+ * - join_triples: Types of triples are combined into a single Content (single column), example: "a b c d e f" as opposed to "a b c" "d e f" or "a" "b" "c" "d" "e" "f".
+ * - null: When the key has no header Content (header value.used is 0), still add the Object (header key) (When this is not set then the Object (header key) is not added).
+ * - null_dynamic: Types of dynamic and dynamics have empty strings (such as "") added for NULL values (used is 0).
+ * - null_map_name: Types of map and maps has empty strings (such as "") added for NULL values (used is 0) for the map key.
+ * - null_map_value: Types of map and maps has empty strings (such as "") added for NULL values (used is 0) for the map value.
+ * - null_map_name_value: An enumeration value representing both null_map_name and null_map_value keys being set.
+ * - null_maps: Types of dynamic and dynamics have empty strings (such as "") added for when null_map_key and null_map_value are not set and both map key and map value have NULL values (used is 0).
+ * - null_string: Types of string and strings have empty strings (such as "") for NULL values.
+ * - null_triple_a: Types of triple and triples has empty strings (such as "") added for NULL values (used is 0) for the "a" property.
+ * - null_triple_b: Types of triple and triples has empty strings (such as "") added for NULL values (used is 0) for the "b" property.
+ * - null_triple_c: Types of triple and triples has empty strings (such as "") added for NULL values (used is 0) for the "c" property.
+ * - quote_double: Use double quotes (U+0022) when quoting strings.
+ * - quote_grave: Use grave (U+0060) when quoting strings.
+ * - quote_single: Use single quotes (U+0027) when quoting strings.
+ * - last: This does nothing and is provided to be used as a starting point for anything extending this (there should be a max total of 64 bits allowed).
*/
#ifndef _di_f_fss_payload_header_map_flag_e_
enum {
- f_fss_payload_header_map_flag_none_e = 0x0,
- f_fss_payload_header_map_flag_join_digits_e = 0x1,
- f_fss_payload_header_map_flag_join_dynamics_e = 0x2,
- f_fss_payload_header_map_flag_join_range_e = 0x4,
- f_fss_payload_header_map_flag_join_ranges_e = 0x8,
- f_fss_payload_header_map_flag_join_strings_e = 0x10,
- f_fss_payload_header_map_flag_join_triple_e = 0x20,
- f_fss_payload_header_map_flag_join_triples_e = 0x40,
- f_fss_payload_header_map_flag_null_e = 0x80,
- f_fss_payload_header_map_flag_null_dynamic_e = 0x100,
- f_fss_payload_header_map_flag_null_map_key_e = 0x200,
- f_fss_payload_header_map_flag_null_map_value_e = 0x400,
- f_fss_payload_header_map_flag_null_maps_e = 0x800,
- f_fss_payload_header_map_flag_null_triple_a_e = 0x1000,
- f_fss_payload_header_map_flag_null_triple_b_e = 0x2000,
- f_fss_payload_header_map_flag_null_triple_c_e = 0x4000,
- f_fss_payload_header_map_flag_null_string_e = 0x8000,
- f_fss_payload_header_map_flag_quote_double_e = 0x10000,
- f_fss_payload_header_map_flag_quote_grave_e = 0x20000,
- f_fss_payload_header_map_flag_quote_single_e = 0x40000,
- f_fss_payload_header_map_flag_last_e = 0x80000,
+ f_fss_payload_header_map_flag_none_e = 0x0,
+ f_fss_payload_header_map_flag_join_digits_e = 0x1,
+ f_fss_payload_header_map_flag_join_dynamics_e = 0x2,
+ f_fss_payload_header_map_flag_join_map_e = 0x4,
+ f_fss_payload_header_map_flag_join_maps_e = 0x8,
+ f_fss_payload_header_map_flag_join_range_e = 0x10,
+ f_fss_payload_header_map_flag_join_ranges_e = 0x20,
+ f_fss_payload_header_map_flag_join_strings_e = 0x40,
+ f_fss_payload_header_map_flag_join_triple_e = 0x80,
+ f_fss_payload_header_map_flag_join_triples_e = 0x100,
+ f_fss_payload_header_map_flag_null_e = 0x200,
+ f_fss_payload_header_map_flag_null_dynamic_e = 0x400,
+ f_fss_payload_header_map_flag_null_map_name_e = 0x800,
+ f_fss_payload_header_map_flag_null_map_value_e = 0x1000,
+ f_fss_payload_header_map_flag_null_map_name_value_e = 0x2000,
+ f_fss_payload_header_map_flag_null_maps_e = 0x4000,
+ f_fss_payload_header_map_flag_null_triple_a_e = 0x8000,
+ f_fss_payload_header_map_flag_null_triple_b_e = 0x10000,
+ f_fss_payload_header_map_flag_null_triple_c_e = 0x20000,
+ f_fss_payload_header_map_flag_null_string_e = 0x40000,
+ f_fss_payload_header_map_flag_quote_double_e = 0x80000,
+ f_fss_payload_header_map_flag_quote_grave_e = 0x100000,
+ f_fss_payload_header_map_flag_quote_single_e = 0x200000,
+ f_fss_payload_header_map_flag_last_e = 0x400000,
}; // enum
#endif // _di_f_fss_payload_header_flag_map_e_
internal.j = 0;
internal.k = 0;
internal.l = 0;
- internal.quote = f_fss_payload_header_map_flag_quote_double_e
- ? f_string_ascii_quote_double_s.string[0]
- : f_fss_payload_header_map_flag_quote_single_e
- ? f_string_ascii_quote_single_s.string[0]
- : f_fss_payload_header_map_flag_quote_grave_e
- ? f_string_ascii_grave_s.string[0]
- : 0;
+
+ if (data->flag & f_fss_payload_header_map_flag_quote_double_e) {
+ internal.quote = f_string_ascii_quote_double_s.string[0];
+ internal.quote_null = f_fss_quote_double_null_s;
+ }
+ else if (data->flag & f_fss_payload_header_map_flag_quote_single_e) {
+ internal.quote = f_string_ascii_quote_single_s.string[0];
+ internal.quote_null = f_fss_quote_single_null_s;
+ }
+ else if (data->flag & f_fss_payload_header_map_flag_quote_grave_e) {
+ internal.quote = f_string_ascii_grave_s.string[0];
+ internal.quote_null = f_fss_quote_grave_null_s;
+ }
+ else {
+ internal.quote = 0;
+ internal.quote_null = f_fss_quote_double_null_s;
+ }
state->status = f_memory_array_increase_by(headers.used, sizeof(f_string_map_t), (void **) &destinations->array, &destinations->used, &destinations->size);
private_fl_payload_header_map_strings(data, state, &internal, headers.array[internal.i].value.is.a_strings, destinations);
}
else if (data->flag & f_fss_payload_header_map_flag_null_string_e) {
- state->status = f_memory_array_increase_by(2, sizeof(f_char_t), (void **) &destinations->array[destinations->used].value.string, &destinations->array[destinations->used].value.used, &destinations->array[destinations->used].value.size);
- if (F_status_is_error(state->status)) break;
-
- private_fl_payload_header_map_null_add(internal, &destinations->array[destinations->used].value);
+ state->status = f_string_dynamic_append(internal.quote_null, &destinations->array[destinations->used].value);
if (F_status_is_error(state->status)) break;
++destinations->used;
if (headers.array[internal.i].value.is.a_dynamics.used) {
private_fl_payload_header_map_dynamics(data, state, &internal, &headers.array[internal.i].value.is.a_dynamics, destinations);
}
+ else if (data->flag & f_fss_payload_header_map_flag_null_dynamic_e) {
+ state->status = f_string_dynamic_append(internal.quote_null, &destinations->array[destinations->used].value);
+ if (F_status_is_error(state->status)) break;
+
+ ++destinations->used;
+ }
else if (data->flag & f_fss_payload_header_map_flag_null_e) {
++destinations->used;
}
break;
-// @todo resume here.
case f_abstruse_map_e:
- data->cache->used = 0;
- internal.k = f_fss_extended_next_s.used;
-
- if (headers.array[internal.i].value.is.a_map.name.used) {
- 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.k += (f_string_ascii_quote_double_s.used * 2) + headers.array[internal.i].value.is.a_map.value.used;
- }
- else {
- internal.k += f_string_ascii_quote_double_s.used * 4;
+ if (headers.array[internal.i].value.is.a_map.name.used || headers.array[internal.i].value.is.a_map.value.used) {
+ private_fl_payload_header_map_map(data, state, &internal, &headers.array[internal.i].value.is.a_map, destinations);
}
+ else if (data->flag & f_fss_payload_header_map_flag_null_map_name_value_e) {
+ if (data->flag & f_fss_payload_header_map_flag_join_map_e) {
+ state->status = f_string_dynamic_append(internal.quote_null, &destinations->array[destinations->used].value);
+ if (F_status_is_error(state->status)) break;
- state->status = f_memory_array_increase_by(internal.k, sizeof(f_char_t), (void **) &data->cache->string, &data->cache->used, &data->cache->size);
- if (F_status_is_error(state->status)) break;
-
- // @todo this should be different, in regards to the f_fss_payload_header_map_flag_null_dynamic_e bit.
- macro_f_fss_payload_header_write_process_dynamic_d(data, state, internal, headers.array[internal.i].value.is.a_map.name);
- if (F_status_is_error(state->status)) break;
-
- 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)) {
-
- // The f_fss_extended_next_s is always added at the end of the macro.
- data->cache->used -= f_fss_extended_next_s.used;
-
- state->status = f_string_dynamic_append(*data->cache, &destinations->array[destinations->used].value);
+ ++destinations->used;
+ }
+ else {
+ private_fl_payload_header_map_map_name_value_null(data, state, &internal, destinations);
+ }
}
-
- if (F_status_is_error_not(state->status)) {
+ else if (data->flag & f_fss_payload_header_map_flag_null_e) {
++destinations->used;
}
break;
case f_abstruse_maps_e:
- // @todo
- break;
-
- case f_abstruse_map_multi_e:
- data->cache->used = 0;
- internal.k = headers.array[internal.i].value.is.a_map_multi.name.used ? headers.array[internal.i].value.is.a_map_multi.name.used : f_string_ascii_quote_double_s.used * 2;
- internal.k += f_fss_extended_next_s.used;
-
- if (headers.array[internal.i].value.is.a_map_multi.value.used) {
- for (internal.l = 0; internal.l < headers.array[internal.i].value.is.a_map_multi.value.used; ++internal.l) {
-
- if (state->interrupt) {
- state->interrupt((void * const) state, (void * const) &internal);
- if (F_status_set_fine(state->status) == F_interrupt) return;
- }
-
- internal.k += headers.array[internal.i].value.is.a_map_multi.value.array[internal.l].used ? headers.array[internal.i].value.is.a_map_multi.value.array[internal.l].used : f_string_ascii_quote_double_s.used * 2;
- internal.k += f_fss_extended_next_s.used;
- } // for
-
- state->status = f_memory_array_increase_by(internal.k, sizeof(f_char_t), (void **) &data->cache->string, &data->cache->used, &data->cache->size);
- if (F_status_is_error(state->status)) break;
-
- macro_f_fss_payload_header_write_process_dynamic_d(data, state, internal, headers.array[internal.i].value.is.a_map_multi.name);
-
- data->cache->string[data->cache->used++] = f_fss_extended_next_s.string[0];
-
- for (internal.l = 0; internal.l < headers.array[internal.i].value.is.a_map_multi.value.used; ++internal.l) {
-
- if (state->interrupt) {
- state->interrupt((void * const) state, (void * const) &internal);
- if (F_status_set_fine(state->status) == F_interrupt) return;
- }
-
- if (headers.array[internal.i].value.is.a_map_multi.value.array[internal.l].used) {
- state->status = f_string_dynamic_append(headers.array[internal.i].value.is.a_map_multi.value.array[internal.l], data->cache);
- if (F_status_is_error(state->status)) break;
- }
- else {
- data->cache->string[data->cache->used++] = f_string_ascii_quote_double_s.string[0];
- data->cache->string[data->cache->used++] = f_string_ascii_quote_double_s.string[0];
- }
-
- data->cache->string[data->cache->used++] = f_fss_extended_next_s.string[0];
- } // for
-
- if (F_status_is_error_not(state->status)) {
-
- // The f_fss_extended_next_s is always added at the end of the loop to avoid an additional condition check in the loop.
- data->cache->used -= f_fss_extended_next_s.used;
+ if (headers.array[internal.i].value.is.a_maps.used) {
+ private_fl_payload_header_map_maps(data, state, &internal, &headers.array[internal.i].value.is.a_maps, destinations);
+ }
+ else if (data->flag & f_fss_payload_header_map_flag_null_map_name_value_e) {
+ if (data->flag & f_fss_payload_header_map_flag_join_maps_e) {
+ state->status = f_string_dynamic_append(internal.quote_null, &destinations->array[destinations->used].value);
+ if (F_status_is_error(state->status)) break;
- state->status = f_string_dynamic_append(*data->cache, &destinations->array[destinations->used].value);
+ ++destinations->used;
+ }
+ else {
+ private_fl_payload_header_map_map_name_value_null(data, state, &internal, destinations);
}
}
- else if (headers.array[internal.i].value.is.a_map_multi.name.used) {
- state->status = f_string_dynamic_append(headers.array[internal.i].value.is.a_map_multi.name, &destinations->array[destinations->used].value);
- }
-
- if (F_status_is_error_not(state->status)) {
+ else if (data->flag & f_fss_payload_header_map_flag_null_e) {
++destinations->used;
}
break;
+// @todo resume after here.
+ case f_abstruse_map_multi_e:
+ // @todo
+ break;
+
case f_abstruse_map_multis_e:
// @todo
break;
break;
case f_abstruse_triple_e:
+ // @todo update this.
data->cache->used = 0;
if (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);
+ internal.k += headers.array[internal.i].value.is.a_triple.c.used ? headers.array[internal.i].value.is.a_triple.c.used : internal.quote_null.used;
}
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);
+ internal.k += headers.array[internal.i].value.is.a_triple.c.used + internal.quote_null.used;
}
else {
- internal.k = f_string_ascii_quote_double_s.used * 4;
+ internal.k = internal.quote_null.used * 2;
}
}
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;
+ internal.k = internal.quote_null.used + 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;
+ internal.k = internal.quote_null.used * 2 + 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;
+ internal.k = internal.quote_null.used * 2 + headers.array[internal.i].value.is.a_triple.c.used;
}
else {
- internal.k = f_string_ascii_quote_double_s.used * 6;
+ internal.k = internal.quote_null.used * 3;
}
internal.k += f_fss_extended_next_s.used * 2;
*
* This alters state.status:
* F_okay on success.
- * F_okay_eos on success after reaching the end of the buffer.
- * F_okay_stop on success after reaching the range stop.
- * F_data_not if object is empty (object.used is 0).
- * F_data_not_eos no data to write due start location being greater than or equal to buffer size.
- * F_data_not_stop no data to write due start location being greater than stop location.
+ * F_data_not if headers is empty (headers.used is 0).
*
* F_interrupt (with error bit) if stopping due to an interrupt.
- * F_okay_eol (with error bit) after reaching an EOL, which is not supported by the standard.
* F_parameter (with error bit) if a parameter is invalid.
*
* Errors (with error bit) from: f_memory_array_increase().
private_fl_fss_basic_write(F_false, dynamic, internal.quote, &internal.range, data->cache, state, (void * const) &internal); \
} \
else { \
- private_fl_payload_header_map_null_add(internal, data->cache); \
+ state->status = f_string_dynamic_append(internal.quote_null, data->cache); \
} \
\
if (F_status_is_error_not(state->status)) { \
* - l: A counter used for more complex use cases such as with multi-maps.
* - range: Used for passing a given string range to the FSS write functions.
* - conversion: The conversion data.
+ * - quote_null: The string representing an empty, aka NULL, Content. This is generally double-quotes.
* - destinations: The destinations map being appended to.
* - original: The original destination used length.
*/
f_range_t range;
f_conversion_data_t conversion;
+ f_string_static_t quote_null;
f_string_maps_t * const destinations;
const f_number_unsigned_t original;
} f_fss_payload_header_internal_t;
0, \
f_range_t_initialize, \
f_conversion_data_base_10_c, \
+ f_string_static_t_initialize, \
0, \
0, \
}
- #define macro_f_fss_payload_header_internal_t_initialize_1(quote, step, i, j, k, l, range, conversion, destinations, original) { \
+ #define macro_f_fss_payload_header_internal_t_initialize_1(quote, step, i, j, k, l, range, conversion, destinations, quote_null, original) { \
quote, \
step, \
i, \
range, \
conversion, \
destinations, \
+ quote_null, \
original, \
}
0, \
f_range_t_initialize, \
f_conversion_data_base_10_c, \
+ f_string_static_t_initialize, \
destinations, \
original, \
}
state->status = f_string_dynamic_strip_null(&internal->destinations->array[internal->destinations->used].value);
if (F_status_is_error(state->status)) return F_true;
+ state->status = F_okay;
+
return F_false;
}
#endif // !defined(_di_fl_fss_payload_header_map_)
state->status = f_string_dynamic_strip_null(&destinations->array[destinations->used].value);
}
else {
- state->status = f_memory_array_increase_by(2, sizeof(f_char_t), (void **) &destinations->array[destinations->used].value.string, &destinations->array[destinations->used].value.used, &destinations->array[destinations->used].value.size);
- if (F_status_is_error(state->status)) return F_true;
-
- private_fl_payload_header_map_null_add(*internal, &destinations->array[destinations->used].value);
+ state->status = f_string_dynamic_append(internal->quote_null, &destinations->array[destinations->used].value);
}
if (F_status_is_error(state->status)) return F_true;
++destinations->used;
+ state->status = F_okay;
return F_false;
}
#if !defined(_di_fl_fss_payload_header_map_)
uint8_t private_fl_payload_header_map_dynamics(f_fss_payload_header_state_t * const data, f_state_t * const state, f_fss_payload_header_internal_t * const internal, f_string_statics_t * const buffers, f_string_maps_t * const destinations) {
- // @todo this needs to implement f_fss_payload_header_map_flag_join_dynamics_e.
-
data->cache->used = 0;
internal->k = 0;
+ state->status = f_memory_array_increase_by(buffers->used + ((f_fss_extended_next_s.used + internal->quote_null.used) * buffers->used), sizeof(f_char_t), (void **) &destinations->array[destinations->used].value.string, &destinations->array[destinations->used].value.used, &destinations->array[destinations->used].value.size);
+ if (F_status_is_error(state->status)) return F_true;
+
+ if (data->flag & f_fss_payload_header_map_flag_join_dynamics_e) {
+ state->status = f_memory_array_increase_by(buffers->used + ((f_fss_extended_next_s.used + internal->quote_null.used) * buffers->used), sizeof(f_char_t), (void **) &data->cache->string, &data->cache->used, &data->cache->size);
+ if (F_status_is_error(state->status)) return F_true;
+ }
+
for (internal->j = 0; internal->j < buffers->used; ++internal->j) {
if (state->interrupt) {
if (F_status_set_fine(state->status) == F_interrupt) return F_true;
}
- internal->k += buffers->array[internal->j].used ? buffers->array[internal->j].used : f_string_ascii_quote_double_s.used * 2;
- internal->k += f_fss_extended_next_s.used;
+ if (data->flag & f_fss_payload_header_map_flag_join_dynamics_e) {
+ state->status = f_string_dynamic_append(buffers->array[internal->j], data->cache);
+ if (F_status_is_error(state->status)) return F_true;
+
+ state->status = f_string_dynamic_append_assure(f_string_space_s, data->cache);
+ if (F_status_is_error(state->status)) return F_true;
+ }
+ else {
+ if (buffers->array[internal->j].used) {
+ internal->range.start = 0;
+ internal->range.stop = buffers->array[internal->j].used - 1;
+
+ private_fl_fss_basic_write(F_false, buffers->array[internal->j], internal->quote, &internal->range, &destinations->array[destinations->used].value, state, (void * const) internal);
+ if (F_status_is_error(state->status)) return F_true;
+
+ state->status = f_string_dynamic_append_assure(f_fss_extended_next_s, data->cache);
+ if (F_status_is_error(state->status)) return F_true;
+ }
+ else if (data->flag & f_fss_payload_header_map_flag_null_string_e) {
+ state->status = f_string_dynamic_append(internal->quote_null, &destinations->array[destinations->used].value);
+ if (F_status_is_error(state->status)) return F_true;
+ }
+ }
} // for
- state->status = f_memory_array_increase_by(internal->k, sizeof(f_char_t), (void **) &data->cache->string, &data->cache->used, &data->cache->size);
+ if (data->flag & f_fss_payload_header_map_flag_join_dynamics_e) {
+ if (data->cache->used) {
+
+ // Do not include the f_string_space_s that is always added at the end of the loop.
+ data->cache->used -= f_string_space_s.used;
+
+ internal->range.start = 0;
+ internal->range.stop = data->cache->used - 1;
+
+ private_fl_fss_basic_write(F_false, *data->cache, internal->quote, &internal->range, &destinations->array[destinations->used].value, state, (void * const) internal);
+ if (F_status_is_error(state->status)) return F_true;
+ }
+ else {
+ if (data->flag & f_fss_payload_header_map_flag_null_string_e) {
+ state->status = f_string_dynamic_append(internal->quote_null, &destinations->array[destinations->used].value);
+ if (F_status_is_error(state->status)) return F_true;
+ }
+ }
+ }
+
+ state->status = f_string_dynamic_strip_null(&destinations->array[destinations->used].value);
if (F_status_is_error(state->status)) return F_true;
- for (internal->j = 0; internal->j < buffers->used; ++internal->j) {
+ ++destinations->used;
+ state->status = F_okay;
- if (state->interrupt) {
- state->interrupt((void * const) state, (void * const) internal);
- if (F_status_set_fine(state->status) == F_interrupt) return F_true;
+ return F_false;
+ }
+#endif // !defined(_di_fl_fss_payload_header_map_)
+
+#if !defined(_di_fl_fss_payload_header_map_)
+ uint8_t private_fl_payload_header_map_map(f_fss_payload_header_state_t * const data, f_state_t * const state, f_fss_payload_header_internal_t * const internal, f_string_map_t * const map, f_string_maps_t * const destinations) {
+
+ if (data->flag & f_fss_payload_header_map_flag_join_map_e) {
+ state->status = f_memory_array_increase_by(map->name.used + map->value.used + f_string_space_s.used, sizeof(f_char_t), (void **) &destinations->array[destinations->used].value.string, &destinations->array[destinations->used].value.used, &destinations->array[destinations->used].value.size);
+ if (F_status_is_error(state->status)) return F_true;
+
+ data->cache->used = 0;
+
+ if (map->name.used) {
+ f_string_dynamic_append(map->name, data->cache);
+ if (F_status_is_error(state->status)) return F_true;
+
+ if (map->value.used) {
+ f_string_dynamic_append_assure(f_fss_extended_next_s, data->cache);
+ if (F_status_is_error(state->status)) return F_true;
+ }
+ }
+
+ if (map->value.used) {
+ f_string_dynamic_append(map->value, data->cache);
+ if (F_status_is_error(state->status)) return F_true;
}
- macro_f_fss_payload_header_write_process_dynamic_d(data, state, (*internal), buffers->array[internal->j]);
+ private_fl_fss_basic_write(F_false, *data->cache, 0, &internal->range, &destinations->array[destinations->used].value, state, (void * const) internal);
if (F_status_is_error(state->status)) return F_true;
- } // for
+ }
+ else {
+ if (map->name.used) {
+ internal->range.start = 0;
+ internal->range.stop = map->name.used - 1;
+
+ private_fl_fss_basic_write(F_false, map->name, 0, &internal->range, &destinations->array[destinations->used].value, state, (void * const) internal);
+ if (F_status_is_error(state->status)) return F_true;
+
+ if (map->value.used) {
+ f_string_dynamic_append_assure(f_string_space_s, &destinations->array[destinations->used].value);
+ if (F_status_is_error(state->status)) return F_true;
+ }
+ }
- // The f_fss_extended_next_s is always added at the end of the loop to avoid an additional condition check in the loop.
- data->cache->used -= f_fss_extended_next_s.used;
+ if (map->value.used) {
+ internal->range.start = 0;
+ internal->range.stop = map->value.used - 1;
- state->status = f_string_dynamic_append(*data->cache, &destinations->array[destinations->used].value);
+ private_fl_fss_basic_write(F_false, map->value, 0, &internal->range, &destinations->array[destinations->used].value, state, (void * const) internal);
+ if (F_status_is_error(state->status)) return F_true;
+ }
+ }
+
+ state->status = f_string_dynamic_strip_null(&destinations->array[destinations->used].value);
if (F_status_is_error(state->status)) return F_true;
++destinations->used;
+ state->status = F_okay;
return F_false;
}
#endif // !defined(_di_fl_fss_payload_header_map_)
#if !defined(_di_fl_fss_payload_header_map_)
- void private_fl_payload_header_map_null_add(const f_fss_payload_header_internal_t internal, f_string_dynamic_t * const destination) {
+ uint8_t private_fl_payload_header_map_map_name_value_null(f_fss_payload_header_state_t * const data, f_state_t * const state, f_fss_payload_header_internal_t * const internal, f_string_maps_t * const destinations) {
+
+ state->status = f_memory_array_increase_by(internal->quote_null.used * 2 + f_fss_extended_next_s.used, sizeof(f_char_t), (void **) &destinations->array[destinations->used].value.string, &destinations->array[destinations->used].value.used, &destinations->array[destinations->used].value.size);
+ if (F_status_is_error(state->status)) return F_true;
+
+ state->status = f_string_dynamic_append(internal->quote_null, &destinations->array[destinations->used].value);
+ if (F_status_is_error(state->status)) return F_true;
+
+ state->status = f_string_dynamic_append_assure(f_fss_extended_next_s, &destinations->array[destinations->used].value);
+ if (F_status_is_error(state->status)) return F_true;
- destination->string[destination->used++] = internal.quote ? internal.quote : f_string_ascii_quote_double_s.string[0];
- destination->string[destination->used++] = internal.quote ? internal.quote : f_string_ascii_quote_double_s.string[0];
+ state->status = f_string_dynamic_append(internal->quote_null, &destinations->array[destinations->used].value);
+ if (F_status_is_error(state->status)) return F_true;
+
+ ++destinations->used;
+ state->status = F_none;
+
+ return F_false;
}
#endif // !defined(_di_fl_fss_payload_header_map_)
+#if !defined(_di_fl_fss_payload_header_maps_)
+ uint8_t private_fl_payload_header_map_maps(f_fss_payload_header_state_t * const data, f_state_t * const state, f_fss_payload_header_internal_t * const internal, f_string_maps_t * const maps, f_string_maps_t * const destinations) {
+
+ if (data->flag & f_fss_payload_header_map_flag_join_maps_e) {
+ // @todo
+ }
+ else if (data->flag & f_fss_payload_header_map_flag_null_map_name_value_e) {
+ // @todo
+ }
+ else {
+ for (internal->k = 0; internal->k < maps->used; ++internal->k) {
+
+ if (maps->array[internal->k].name.used) {
+ internal->k += maps->array[internal->k].name.used + f_fss_extended_next_s.used + internal->quote_null.used;
+ }
+ else if (data->flag & f_fss_payload_header_map_flag_null_map_name_e) {
+ internal->k += f_fss_extended_next_s.used + internal->quote_null.used;
+ }
+
+ if (maps->array[internal->k].value.used) {
+ internal->k += maps->array[internal->k].value.used + f_fss_extended_next_s.used + internal->quote_null.used;
+ }
+ else if (data->flag & f_fss_payload_header_map_flag_null_map_value_e) {
+ internal->k += f_fss_extended_next_s.used + internal->quote_null.used;
+ }
+ } // for
+
+ // @todo all of this below.
+
+ if (data->flag & f_fss_payload_header_map_flag_join_map_e) {
+ data->cache->used = 0;
+
+ state->status = f_memory_array_increase_by(internal->k, sizeof(f_char_t), (void **) &data->cache->string, &data->cache->used, &data->cache->size);
+ if (F_status_is_error(state->status)) return F_true;
+
+ for (internal->l = 0; internal->l < maps->used; ++internal->l) {
+
+ if (maps->array[internal->l].name.used || (data->flag & f_fss_payload_header_map_flag_null_map_name_e)) {
+ if (maps->array[internal->l].name.used) {
+ f_string_dynamic_append(maps->array[internal->l].name, data->cache);
+ }
+ else if (data->flag & f_fss_payload_header_map_flag_null_map_name_e) {
+ state->status = f_string_dynamic_append(internal->quote_null, data->cache);
+ }
+
+ if (F_status_is_error(state->status)) return F_true;
+
+ if (maps->array[internal->l].value.used) {
+ f_string_dynamic_append_assure(f_fss_extended_next_s, data->cache);
+ if (F_status_is_error(state->status)) return F_true;
+ }
+ }
+
+ if (maps->array[internal->l].value.used) {
+ f_string_dynamic_append(maps->array[internal->l].value, data->cache);
+ }
+ else if (data->flag & f_fss_payload_header_map_flag_null_map_value_e) {
+ state->status = f_string_dynamic_append(internal->quote_null, data->cache);
+ }
+
+ if (F_status_is_error(state->status)) return F_true;
+
+ state->status = f_string_dynamic_append_assure(f_fss_extended_next_s, data->cache);
+ if (F_status_is_error(state->status)) return F_true;
+ } // for
+
+ // Remove any trailing "extended_next".
+ if (data->cache->used) {
+ data->cache->used -= f_fss_extended_next_s.used;
+ }
+
+ private_fl_fss_basic_write(F_false, *data->cache, 0, &internal->range, &destinations->array[destinations->used].value, state, (void * const) internal);
+ if (F_status_is_error(state->status)) return F_true;
+ }
+ else {
+ state->status = f_memory_array_increase_by(internal->k, sizeof(f_char_t), (void **) &destinations->array[destinations->used].value.string, &destinations->array[destinations->used].value.used, &destinations->array[destinations->used].value.size);
+ if (F_status_is_error(state->status)) return F_true;
+
+ // @todo
+ }
+ }
+
+ state->status = f_string_dynamic_strip_null(&destinations->array[destinations->used].value);
+ if (F_status_is_error(state->status)) return F_true;
+
+ ++destinations->used;
+ state->status = F_okay;
+
+ return F_false;
+ }
+#endif // !defined(_di_fl_fss_payload_header_maps_)
+
#if !defined(_di_fl_fss_payload_header_map_)
uint8_t private_fl_payload_header_map_number_signed(f_fss_payload_header_state_t * const data, f_state_t * const state, f_fss_payload_header_internal_t * const internal, const f_number_signed_t number) {
if (data->cache->used) {
- state->status = f_string_dynamic_append(f_fss_extended_next_s, data->cache);
+ state->status = f_string_dynamic_append_assure(f_fss_extended_next_s, data->cache);
if (F_status_is_error(state->status)) return F_true;
}
state->status = f_conversion_number_signed_to_string(number, data->conversion, data->cache);
if (F_status_is_error(state->status)) return F_true;
+ state->status = F_okay;
+
return F_false;
}
#endif // !defined(_di_fl_fss_payload_header_map_)
uint8_t private_fl_payload_header_map_number_unsigned(f_fss_payload_header_state_t * const data, f_state_t * const state, f_fss_payload_header_internal_t * const internal, const f_number_unsigned_t number) {
if (data->cache->used) {
- state->status = f_string_dynamic_append(f_fss_extended_next_s, data->cache);
+ state->status = f_string_dynamic_append_assure(f_fss_extended_next_s, data->cache);
if (F_status_is_error(state->status)) return F_true;
}
state->status = f_conversion_number_unsigned_to_string(number, data->conversion, data->cache);
if (F_status_is_error(state->status)) return F_true;
+ state->status = F_okay;
+
return F_false;
}
#endif // !defined(_di_fl_fss_payload_header_map_)
+
#if !defined(_di_fl_fss_payload_header_map_)
uint8_t private_fl_payload_header_map_strings(f_fss_payload_header_state_t * const data, f_state_t * const state, f_fss_payload_header_internal_t * const internal, f_string_t * const buffers, f_string_maps_t * const destinations) {
data->cache->used = 0;
internal->k = 0;
+ // Pre-process the string lengths to allow for a single allocation.
for (internal->j = 0; buffers[internal->j]; ++internal->j) {
if (state->interrupt) {
string_static.string = buffers[internal->j];
string_static.used = string_static.string ? strnlen(string_static.string, F_string_t_size_d) : 0;
-
- internal->k += string_static.used ? string_static.used : f_string_ascii_quote_double_s.used * 2;
- internal->k += f_fss_extended_next_s.used;
+ internal->k += string_static.used + f_fss_extended_next_s.used + internal->quote_null.used;
} // for
- // Save the total strings as internal.l so that intenal.j can be used for the loop counter later on.
- internal->l = internal->j;
+ state->status = f_memory_array_increase_by(internal->k, sizeof(f_char_t), (void **) &destinations->array[destinations->used].value.string, &destinations->array[destinations->used].value.used, &destinations->array[destinations->used].value.size);
+ if (F_status_is_error(state->status)) return F_true;
if (data->flag & f_fss_payload_header_map_flag_join_strings_e) {
state->status = f_memory_array_increase_by(internal->k, sizeof(f_char_t), (void **) &data->cache->string, &data->cache->used, &data->cache->size);
if (F_status_is_error(state->status)) return F_true;
+ }
- for (internal->j = 0; internal->j < internal->l; ++internal->j) {
+ for (internal->l = internal->j, internal->j = 0; internal->j < internal->l; ++internal->j) {
- if (state->interrupt) {
- state->interrupt((void * const) state, (void * const) internal);
- if (F_status_set_fine(state->status) == F_interrupt) return F_true;
- }
+ if (state->interrupt) {
+ state->interrupt((void * const) state, (void * const) internal);
+ if (F_status_set_fine(state->status) == F_interrupt) return F_true;
+ }
- string_static.string = buffers[internal->j];
- string_static.used = string_static.string ? strnlen(string_static.string, F_string_t_size_d) : 0;
+ string_static.string = buffers[internal->j];
+ string_static.used = string_static.string ? strnlen(string_static.string, F_string_t_size_d) : 0;
+
+ if (data->flag & f_fss_payload_header_map_flag_join_strings_e) {
+ state->status = f_string_dynamic_append(string_static, data->cache);
+ if (F_status_is_error(state->status)) return F_true;
+ state->status = f_string_dynamic_append_assure(f_string_space_s, data->cache);
+ if (F_status_is_error(state->status)) return F_true;
+ }
+ else {
if (string_static.used) {
internal->range.start = 0;
internal->range.stop = string_static.used - 1;
- private_fl_fss_basic_write(F_false, string_static, internal->quote, &internal->range, data->cache, state, (void * const) internal);
+ private_fl_fss_basic_write(F_false, string_static, internal->quote, &internal->range, &destinations->array[destinations->used].value, state, (void * const) internal);
if (F_status_is_error(state->status)) return F_true;
- data->cache->string[data->cache->used++] = f_fss_extended_open_s.string[0];
+ state->status = f_string_dynamic_append_assure(f_fss_extended_next_s, data->cache);
+ if (F_status_is_error(state->status)) return F_true;
+ }
+ else if (data->flag & f_fss_payload_header_map_flag_null_string_e) {
+ state->status = f_string_dynamic_append(internal->quote_null, &destinations->array[destinations->used].value);
+ if (F_status_is_error(state->status)) return F_true;
}
- } // for
-
- if (data->cache->used) {
-
- // The f_fss_extended_next_s is always added at the end of the loop to avoid an additional condition check in the loop.
- data->cache->used -= f_fss_extended_next_s.used;
- }
- else if (data->flag & f_fss_payload_header_map_flag_null_string_e) {
- private_fl_payload_header_map_null_add(*internal, data->cache);
}
+ } // for
+ if (data->flag & f_fss_payload_header_map_flag_join_strings_e) {
if (data->cache->used) {
- state->status = f_string_dynamic_append(*data->cache, &destinations->array[destinations->used].value);
- }
- }
- else {
- state->status = f_memory_array_increase_by(internal->k, sizeof(f_char_t), (void **) &destinations->array[destinations->used].value.string, &destinations->array[destinations->used].value.used, &destinations->array[destinations->used].value.size);
-
- for (internal->j = 0; internal->j < internal->l; ++internal->j) {
- if (state->interrupt) {
- state->interrupt((void * const) state, (void * const) internal);
- if (F_status_set_fine(state->status) == F_interrupt) return F_true;
- }
+ // Do not include the f_string_space_s that is always added at the end of the loop.
+ data->cache->used -= f_string_space_s.used;
- string_static.string = buffers[internal->j];
- string_static.used = string_static.string ? strnlen(string_static.string, F_string_t_size_d) : 0;
+ internal->range.start = 0;
+ internal->range.stop = data->cache->used - 1;
- state->status = f_string_dynamic_append(string_static, data->cache);
- if (F_status_is_error(state->status)) return F_true;
-
- state->status = f_string_dynamic_append(f_fss_extended_next_s, data->cache);
+ private_fl_fss_basic_write(F_false, *data->cache, internal->quote, &internal->range, &destinations->array[destinations->used].value, state, (void * const) internal);
if (F_status_is_error(state->status)) return F_true;
- } // for
-
- // Do not include the f_fss_extended_next_s that is always added at the end of the loop.
- data->cache->used -= f_fss_extended_next_s.used;
-
- internal->range.start = 0;
- internal->range.stop = data->cache->used - 1;
-
- private_fl_fss_basic_write(F_false, *data->cache, internal->quote, &internal->range, &destinations->array[destinations->used].value, state, (void * const) internal);
- if (F_status_is_error(state->status)) return F_true;
-
- state->status = f_string_dynamic_strip_null(&destinations->array[destinations->used].value);
+ }
+ else {
+ if (data->flag & f_fss_payload_header_map_flag_null_string_e) {
+ state->status = f_string_dynamic_append(internal->quote_null, &destinations->array[destinations->used].value);
+ if (F_status_is_error(state->status)) return F_true;
+ }
+ }
}
+ state->status = f_string_dynamic_strip_null(&destinations->array[destinations->used].value);
if (F_status_is_error(state->status)) return F_true;
++destinations->used;
* The state passed directly from the fl_fss_payload_header_map() parameters.
*
* This alters state.status:
- * Success from: f_string_dynamic_strip_null().
+ * F_okay on success.
*
* Errors (with error bit) from: private_fl_fss_basic_write().
* Errors (with error bit) from: f_string_dynamic_strip_null().
* The state passed directly from the fl_fss_payload_header_map() parameters.
*
* This alters state.status:
- * Success from: f_string_dynamic_strip_null().
- * Success from: private_fl_payload_header_map_null_add().
+ * F_okay on success.
*
- * Errors (with error bit) from: f_memory_array_increase_by().
* Errors (with error bit) from: f_string_dynamic_strip_null().
* Errors (with error bit) from: private_fl_fss_basic_write().
- * Errors (with error bit) from: private_fl_payload_header_map_null_add().
*
* Must not be NULL.
* @param internal
* F_true if the caller should break or exit due to an error or something similar.
* F_false, otherwise.
*
- * @see f_memory_array_increase_by()
+ * @see f_string_dynamic_append()
* @see f_string_dynamic_strip_null()
*
* @see private_fl_fss_basic_write()
- * @see private_fl_payload_header_map_null_add()
*
* @see fl_fss_payload_header_map()
*/
* Must not be NULL.
* @param state
* The state passed directly from the fl_fss_payload_header_map() parameters.
+ *
+ * This alters state.status:
+ * F_okay on success.
+ *
+ * Errors (with error bit) from: f_memory_array_increase_by().
+ * Errors (with error bit) from: f_string_dynamic_append().
+ * Errors (with error bit) from: f_string_dynamic_append_assure().
+ * Errors (with error bit) from: f_string_dynamic_strip_null().
+ *
+ * Errors (with error bit) from: private_fl_fss_basic_write().
+ *
* Must not be NULL.
* @param internal
* The internal state, f_fss_payload_header_internal_t, created inside of fl_fss_payload_header_map().
* F_false, otherwise.
*
* @see f_memory_array_increase_by()
+ * @see f_string_dynamic_append()
+ * @see f_string_dynamic_append_assure()
* @see f_string_dynamic_strip_null()
*
* @see private_fl_fss_basic_write()
- * @see private_fl_payload_header_map_null_add()
*
* @see fl_fss_payload_header_map()
*/
#endif // !defined(_di_fl_fss_payload_header_map_)
/**
- * Add a NULL Content (column value), represented as an empty quoted string.
+ * Process the map strings, writing it into the packet with the appropriate escaping as necessary.
+ *
+ * This expects that the appropriate used and flag checks are performed prior to calling this.
+ *
+ * @param data
+ * The f_fss_payload_header_state_t pointer.
+ * Must not be NULL.
+ * @param state
+ * The state passed directly from the fl_fss_payload_header_map() parameters.
+ *
+ * This alters state.status:
+ * F_okay on success.
+ *
+ * Errors (with error bit) from: f_memory_array_increase_by().
+ * Errors (with error bit) from: f_string_dynamic_strip_null().
+ * Errors (with error bit) from: private_fl_fss_basic_write().
+ *
+ * Must not be NULL.
+ * @param internal
+ * The internal state, f_fss_payload_header_internal_t, created inside of fl_fss_payload_header_map().
+ * Must not be NULL.
+ * @param map
+ * The map to read from.
+ * Must not be NULL.
+ * @param destinations
+ * A map of strings representing the header names and values after being safely converted into the valid payload header format.
+ * This built header names and values are appended onto this.
+ * This is updated as appropriate.
+ * Must not be NULL.
+ *
+ * @return
+ * F_true if the caller should break or exit due to an error or something similar.
+ * F_false, otherwise.
+ *
+ * @see f_memory_array_increase_by()
+ * @see f_string_dynamic_append()
+ * @see f_string_dynamic_strip_null()
+ *
+ * @see private_fl_fss_basic_write()
+ *
+ * @see fl_fss_payload_header_map()
+ */
+#if !defined(_di_fl_fss_payload_header_map_)
+ extern uint8_t private_fl_payload_header_map_map(f_fss_payload_header_state_t * const data, f_state_t * const state, f_fss_payload_header_internal_t * const internal, f_string_map_t * const map, f_string_maps_t * const destinations) F_attribute_visibility_internal_d;
+#endif // !defined(_di_fl_fss_payload_header_map_)
+
+/**
+ * Process the case where a map is added with the appropriate NULL flag bits set.
+ *
+ * This adds the data.quote_null strings for both the map name and the map value, depending on the f_fss_payload_header_map_flag_null_map_name_e and f_fss_payload_header_map_flag_null_map_value_e flags.
+ *
+ * This expects that the appropriate used and flag checks are performed prior to calling this.
+ *
+ * @param data
+ * The f_fss_payload_header_state_t pointer.
+ * Must not be NULL.
+ * @param state
+ * The state passed directly from the fl_fss_payload_header_map() parameters.
*
+ * This alters state.status:
+ * F_okay on success.
+ *
+ * Errors (with error bit) from: f_memory_array_increase_by().
+ * Errors (with error bit) from: f_string_dynamic_strip_null().
+ * Errors (with error bit) from: private_fl_fss_basic_write().
+ *
+ * Must not be NULL.
* @param internal
* The internal state, f_fss_payload_header_internal_t, created inside of fl_fss_payload_header_map().
- * @param destination
- * The destination string to write to.
- * This is not reallocated as needed.
- * The caller must ensure enough space exists.
* Must not be NULL.
+ * @param destinations
+ * A map of strings representing the header names and values after being safely converted into the valid payload header format.
+ * This built header names and values are appended onto this.
+ * This is updated as appropriate.
+ * Must not be NULL.
+ *
+ * @return
+ * F_true if the caller should break or exit due to an error or something similar.
+ * F_false, otherwise.
*
* @see f_memory_array_increase_by()
+ * @see f_string_dynamic_append()
+ * @see f_string_dynamic_strip_null()
+ *
+ * @see private_fl_fss_basic_write()
*
* @see fl_fss_payload_header_map()
*/
#if !defined(_di_fl_fss_payload_header_map_)
- extern void private_fl_payload_header_map_null_add(const f_fss_payload_header_internal_t internal, f_string_dynamic_t * const destination) F_attribute_visibility_internal_d;
+ extern uint8_t private_fl_payload_header_map_map_name_value_null(f_fss_payload_header_state_t * const data, f_state_t * const state, f_fss_payload_header_internal_t * const internal, f_string_maps_t * const destinations) F_attribute_visibility_internal_d;
#endif // !defined(_di_fl_fss_payload_header_map_)
/**
+ * Process the map strings, writing it into the packet with the appropriate escaping as necessary.
+ *
+ * This expects that the appropriate used and flag checks are performed prior to calling this.
+ *
+ * @param data
+ * The f_fss_payload_header_state_t pointer.
+ * Must not be NULL.
+ * @param state
+ * The state passed directly from the fl_fss_payload_header_map() parameters.
+ *
+ * This alters state.status:
+ * F_okay on success.
+ *
+ * Errors (with error bit) from: f_memory_array_increase_by().
+ * Errors (with error bit) from: f_string_dynamic_strip_null().
+ * Errors (with error bit) from: private_fl_fss_basic_write().
+ *
+ * Must not be NULL.
+ * @param internal
+ * The internal state, f_fss_payload_header_internal_t, created inside of fl_fss_payload_header_map().
+ * Must not be NULL.
+ * @param maps
+ * The maps to read from.
+ * Must not be NULL.
+ * @param destinations
+ * A map of strings representing the header names and values after being safely converted into the valid payload header format.
+ * This built header names and values are appended onto this.
+ * This is updated as appropriate.
+ * Must not be NULL.
+ *
+ * @return
+ * F_true if the caller should break or exit due to an error or something similar.
+ * F_false, otherwise.
+ *
+ * @see f_memory_array_increase_by()
+ * @see f_string_dynamic_append()
+ * @see f_string_dynamic_strip_null()
+ *
+ * @see private_fl_fss_basic_write()
+ *
+ * @see fl_fss_payload_header_map()
+ */
+#if !defined(_di_fl_fss_payload_header_maps_)
+ extern uint8_t private_fl_payload_header_map_maps(f_fss_payload_header_state_t * const data, f_state_t * const state, f_fss_payload_header_internal_t * const internal, f_string_maps_t * const maps, f_string_maps_t * const destinations) F_attribute_visibility_internal_d;
+#endif // !defined(_di_fl_fss_payload_header_maps_)
+
+/**
* Process the signed number, converting it to a string and appending that string onto data->cache.
* The resulting data->cache is then appended onto the destination value on success.
* If the number is not appended to data->cache, then nothing is appended to the destination value.
* The state passed directly from the fl_fss_payload_header_map() parameters.
*
* This alters state.status:
- * Success from: f_conversion_number_signed_to_string().
+ * F_okay on success.
*
* Errors (with error bit) from: f_conversion_number_signed_to_string().
- * Errors (with error bit) from: f_string_dynamic_append().
+ * Errors (with error bit) from: f_string_dynamic_append_assure().
*
* Must not be NULL.
* @param internal
* F_false, otherwise.
*
* @see f_conversion_number_unsigned_to_string()
- * @see f_string_dynamic_append()
+ * @see f_string_dynamic_append_assure()
*
* @see fl_fss_payload_header_map()
*/
* The state passed directly from the fl_fss_payload_header_map() parameters.
*
* This alters state.status:
- * Success from: f_conversion_number_unsigned_to_string().
+ * F_okay on success.
*
* Errors (with error bit) from: f_conversion_number_unsigned_to_string().
- * Errors (with error bit) from: f_string_dynamic_append().
+ * Errors (with error bit) from: f_string_dynamic_append_assure().
*
* Must not be NULL.
* @param internal
* F_false, otherwise.
*
* @see f_conversion_number_unsigned_to_string()
- * @see f_string_dynamic_append()
+ * @see f_string_dynamic_append_assure()
*
* @see fl_fss_payload_header_map()
*/
*
* Errors (with error bit) from: f_memory_array_increase_by().
* Errors (with error bit) from: f_string_dynamic_append().
+ * Errors (with error bit) from: f_string_dynamic_append_assure().
* Errors (with error bit) from: f_string_dynamic_strip_null().
* Errors (with error bit) from: private_fl_fss_basic_write().
*
*
* @see f_memory_array_increase_by()
* @see f_string_dynamic_append()
+ * @see f_string_dynamic_append_assure()
* @see f_string_dynamic_strip_null()
*
* @see private_fl_fss_basic_write()
- * @see private_fl_payload_header_map_null_add()
*
* @see fl_fss_payload_header_map()
*/
--- /dev/null
+# fss-0001
+
+cmocka 1.*
--- /dev/null
+# fss-0001
+#
+# Builds a program that is links to the generated library and is executed to perform tests.
+#
+# Memory leaks in the test program can be checked for by running valgrind with this executable.
+#
+
+build_name test-fl_fss
+
+version_major 0
+version_minor 6
+version_micro 4
+version_file micro
+version_target minor
+
+modes individual clang test coverage
+modes_default individual test
+
+build_compiler gcc
+build_compiler-clang clang
+build_indexer ar
+build_indexer_arguments rcs
+build_language c
+
+build_libraries -lc -lcmocka
+build_libraries-individual -lf_abstruse -lf_conversion -lf_file -lf_fss -lf_memory -lf_string -lf_type_array -lf_utf -lfl_fss
+
+build_sources_program test-fss-payload_header_map.c
+
+build_sources_program test-fss.c
+
+build_script no
+build_shared yes
+build_static no
+
+path_headers tests/unit/c
+path_sources tests/unit/c
+
+has_path_standard no
+preserve_path_headers yes
+
+search_exclusive yes
+search_shared yes
+search_static yes
+
+environment PATH LD_LIBRARY_PATH
+environment LANG LC_ALL LC_COLLATE LC_CTYPE LC_FASTMSG LC_MESSAGES LC_MONETARY LC_NUMERIC LC_TIME LOCPATH NLSPATH
+
+defines -Ibuild/includes
+defines_static -Lbuild/libraries/static
+defines_shared -Lbuild/libraries/shared
+
+flags -O2 -z now -g -fdiagnostics-color=always -Wno-logical-not-parentheses -Wno-parentheses
+flags-clang -Wno-logical-op-parentheses
+flags-test -fstack-protector -Wall
+flags-coverage -O0 --coverage -fprofile-abs-path -fprofile-dir=build/coverage/
+
+flags_program -fPIE
--- /dev/null
+#include "test-fss.h"
+#include "test-fss-payload_header_map.h"
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+void test__fl_fss_payload_header_map__parameter_checking(void **void_state) {
+
+ const f_abstruse_maps_t headers = f_abstruse_maps_t_initialize;
+ f_state_t state = f_state_t_initialize;
+ f_fss_payload_header_state_t data = f_fss_payload_header_state_t_initialize;
+ f_string_dynamic_t cache = f_string_dynamic_t_initialize;
+ f_string_maps_t destinations = f_string_maps_t_initialize;
+
+ {
+ state.status = F_none;
+ state.data = &data;
+ data.cache = &cache;
+
+ fl_fss_payload_header_map(headers, 0, &state);
+
+ assert_int_equal(state.status, F_status_set_error(F_parameter));
+ }
+
+ {
+ state.status = F_none;
+ state.data = 0;
+ data.cache = 0;
+
+ fl_fss_payload_header_map(headers, &destinations, &state);
+
+ assert_int_equal(state.status, F_status_set_error(F_parameter));
+ }
+
+ {
+ state.status = F_none;
+ state.data = &data;
+ data.cache = 0;
+
+ fl_fss_payload_header_map(headers, &destinations, &state);
+
+ assert_int_equal(state.status, F_status_set_error(F_parameter));
+ }
+
+ {
+ state.status = F_none;
+ state.data = 0;
+ data.cache = &cache;
+
+ fl_fss_payload_header_map(headers, &destinations, &state);
+
+ assert_int_equal(state.status, F_status_set_error(F_parameter));
+ }
+}
+
+void test__fl_fss_payload_header_map__returns_data_not(void **void_state) {
+
+ const f_abstruse_maps_t headers = f_abstruse_maps_t_initialize;
+ f_state_t state = f_state_t_initialize;
+ f_fss_payload_header_state_t data = f_fss_payload_header_state_t_initialize;
+ f_string_dynamic_t cache = f_string_dynamic_t_initialize;
+ f_string_maps_t destinations = f_string_maps_t_initialize;
+
+ {
+ state.status = F_none;
+ state.data = &data;
+ data.cache = &cache;
+
+ fl_fss_payload_header_map(headers, &destinations, &state);
+
+ assert_int_equal(state.status, F_data_not);
+ }
+}
+
+#ifdef __cplusplus
+} // extern "C"
+#endif
--- /dev/null
+/**
+ * FLL - Level 2
+ *
+ * Project: IKI
+ * API Version: 0.6
+ * Licenses: lgpl-2.1-or-later
+ *
+ * Test the fl_fss project.
+ */
+#ifndef _TEST__FL_fss_payload_header_map_h
+#define _TEST__FL_fss_payload_header_map_h
+
+/**
+ * Test that parameter checking works as expected.
+ *
+ * @see fl_fss_payload_header_map()
+ */
+extern void test__fl_fss_payload_header_map__parameter_checking(void **state);
+
+/**
+ * Test that the function returns F_data_not.
+ *
+ * @see fl_fss_payload_header_map()
+ */
+extern void test__fl_fss_payload_header_map__returns_data_not(void **state);
+
+
+#endif // _TEST__FL_fss_payload_header_map_h
--- /dev/null
+#include "test-fss.h"
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+int setup(void **state) {
+
+ return 0;
+}
+
+int setdown(void **state) {
+
+ errno = 0;
+
+ return 0;
+}
+
+int main(void) {
+
+ const struct CMUnitTest tests[] = {
+ cmocka_unit_test(test__fl_fss_payload_header_map__returns_data_not),
+
+ #ifndef _di_level_0_parameter_checking_
+ cmocka_unit_test(test__fl_fss_payload_header_map__parameter_checking),
+ #endif // _di_level_0_parameter_checking_
+ };
+
+ return cmocka_run_group_tests(tests, setup, setdown);
+}
+
+#ifdef __cplusplus
+} // extern "C"
+#endif
--- /dev/null
+/**
+ * FLL - Level 2
+ *
+ * Project: FSS
+ * API Version: 0.6
+ * Licenses: lgpl-2.1-or-later
+ *
+ * Test the fl_fss project.
+ */
+#ifndef _TEST__FL_fss_h
+#define _TEST__FL_fss_h
+
+// Libc includes.
+#include <stdarg.h>
+#include <stddef.h>
+#include <setjmp.h>
+#include <stdint.h>
+#include <string.h>
+#include <unistd.h>
+
+// cmocka includes.
+#include <cmocka.h>
+
+// FLL-1 includes.
+#include <fll/level_1/fss.h>
+#include <fll/level_1/fss/payload.h>
+
+// Mock includes.
+//#include "mock-fss.h"
+
+// Test includes.
+#include "test-fss-payload_header_map.h"
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/**
+ * Perform any setup operations.
+ *
+ * @param state
+ * The test state.
+ *
+ * @return
+ * The status of this function, where 0 means success.
+ */
+extern int setup(void **state);
+
+/**
+ * Peform any setdown operations.
+ *
+ * @param state
+ * The test state.
+ *
+ * @return
+ * The status of this function, where 0 means success.
+ */
+extern int setdown(void **state);
+
+/**
+ * Run all tests.
+ *
+ * @return
+ * The final result of the tests.
+ *
+ * @see cmocka_run_group_tests()
+ * @see cmocka_unit_test()
+ */
+extern int main(void);
+
+#ifdef __cplusplus
+} // extern "C"
+#endif
+
+#endif // _TEST__FL_fss_h