42#include "sixtp-utils.h"
47static QofLogModule log_module = GNC_MOD_IO;
50isspace_str (
const gchar* str,
int nomorethan)
52 const gchar* cursor = str;
53 while (*cursor && (nomorethan != 0))
55 if (!isspace (*cursor))
66allow_and_ignore_only_whitespace (GSList* sibling_data,
73 return (isspace_str (text, length));
77generic_accumulate_chars (GSList* sibling_data,
85 gchar* copytxt = g_strndup (text, length);
86 g_return_val_if_fail (result, FALSE);
94generic_free_data_for_children (gpointer data_for_children,
95 GSList* data_from_children,
102 if (data_for_children) g_free (data_for_children);
106concatenate_child_result_chars (GSList* data_from_children)
109 gchar* name = g_strdup (
"");
111 g_return_val_if_fail (name, NULL);
114 data_from_children = g_slist_reverse (g_slist_copy (data_from_children));
116 for (lp = data_from_children; lp; lp = lp->next)
118 sixtp_child_result* cr = (sixtp_child_result*) lp->data;
119 if (cr->type != SIXTP_CHILD_RESULT_CHARS)
121 PERR (
"result type is not chars");
122 g_slist_free (data_from_children);
129 temp = g_strconcat (name, (gchar*) cr->data,
nullptr);
134 g_slist_free (data_from_children);
144static bool parse_chars_into_num (std::string_view sv, T* num_ptr)
149 while (!sv.empty() && std::isspace (sv.front ())) sv.remove_prefix (1);
150 while (!sv.empty() && std::isspace (sv.back ())) sv.remove_suffix (1);
152 auto res = std::from_chars (sv.begin(), sv.end(), *num_ptr);
153 return (res.ec == std::errc{} && res.ptr == sv.end());
161string_to_double (std::string_view sv,
double* result)
163#if __cpp_lib_to_chars >= 201611L
164 return parse_chars_into_num<double>(sv, result);
167 g_return_val_if_fail (result,
false);
169 char* endptr =
nullptr;
170 *result = std::strtod (str.c_str(), &endptr);
171 return (endptr != str.c_str());
179string_to_gint64 (std::string_view sv, gint64* v)
181 return parse_chars_into_num<gint64>(sv, v);
188string_to_guint16 (std::string_view sv, guint16* v)
190 return parse_chars_into_num<guint16>(sv, v);
197string_to_guint (std::string_view sv, guint* v)
199 return parse_chars_into_num<guint>(sv, v);
207hex_string_to_binary (
const gchar* str,
void** v, guint64* data_len)
210 const gchar* cursor = str;
212 gboolean error = FALSE;
214 g_return_val_if_fail (str, FALSE);
215 g_return_val_if_fail (v, FALSE);
216 g_return_val_if_fail (data_len, FALSE);
218 str_len = strlen (str);
222 if ((str_len % 2) != 0)
return (FALSE);
224 *v = g_new0 (
char, str_len / 2);
226 g_return_val_if_fail (*v, FALSE);
228 while (*cursor && * (cursor + 1))
233 if (isspace (*cursor) || isspace (* (cursor + 1)))
241 tmpstr[0] = * (cursor + 1);
243 if ((sscanf (tmpstr,
"%x%n", &tmpint, &num_read) < 1)
250 * ((gchar*) (v + *data_len)) = tmpint;
257 if (error || (*data_len != (str_len / 2)))
290generic_return_chars_end_handler (gpointer data_for_children,
291 GSList* data_from_children,
292 GSList* sibling_data,
293 gpointer parent_data,
294 gpointer global_data,
300 txt = concatenate_child_result_chars (data_from_children);
301 g_return_val_if_fail (txt, FALSE);
308simple_chars_only_parser_new (sixtp_end_handler end_handler)
310 return sixtp_set_any (
312 SIXTP_END_HANDLER_ID, (end_handler
314 : generic_return_chars_end_handler),
315 SIXTP_CHARACTERS_HANDLER_ID, generic_accumulate_chars,
316 SIXTP_CLEANUP_RESULT_ID, sixtp_child_free_data,
317 SIXTP_CLEANUP_CHARS_ID, sixtp_child_free_data,
318 SIXTP_RESULT_FAIL_ID, sixtp_child_free_data,
319 SIXTP_CHARS_FAIL_ID, sixtp_child_free_data,
320 SIXTP_NO_MORE_HANDLERS);
358generic_timespec_start_handler (GSList* sibling_data, gpointer parent_data,
359 gpointer global_data,
360 gpointer* data_for_children, gpointer* result,
361 const gchar* tag, gchar** attrs)
364 g_return_val_if_fail (tsp, FALSE);
365 *data_for_children = tsp;
376 return info->s_block_count != 1;
400generic_timespec_secs_end_handler (gpointer data_for_children,
401 GSList* data_from_children, GSList* sibling_data,
402 gpointer parent_data, gpointer global_data,
403 gpointer* result,
const gchar* tag)
408 g_return_val_if_fail (parent_data, FALSE);
410 txt = concatenate_child_result_chars (data_from_children);
411 g_return_val_if_fail (txt, FALSE);
413 info->time = gnc_iso8601_to_time64_gmt (txt);
417 g_return_val_if_fail (info->time < INT64_MAX, FALSE);
419 info->s_block_count++;
441generic_timespec_nsecs_end_handler (gpointer data_for_children,
442 GSList* data_from_children, GSList* sibling_data,
443 gpointer parent_data, gpointer global_data,
444 gpointer* result,
const gchar* tag)
450timespec_sixtp_new (sixtp_end_handler ender)
452 return sixtp_set_any (
454 SIXTP_CHARACTERS_HANDLER_ID, generic_accumulate_chars,
455 SIXTP_END_HANDLER_ID, ender,
456 SIXTP_CLEANUP_CHARS_ID, sixtp_child_free_data,
457 SIXTP_CHARS_FAIL_ID, sixtp_child_free_data,
458 SIXTP_NO_MORE_HANDLERS);
462generic_timespec_parser_new (sixtp_end_handler end_handler)
465 sixtp_set_any (sixtp_new (), FALSE,
466 SIXTP_START_HANDLER_ID, generic_timespec_start_handler,
467 SIXTP_CHARACTERS_HANDLER_ID, allow_and_ignore_only_whitespace,
468 SIXTP_END_HANDLER_ID, end_handler,
469 SIXTP_CLEANUP_RESULT_ID, sixtp_child_free_data,
470 SIXTP_FAIL_HANDLER_ID, generic_free_data_for_children,
471 SIXTP_RESULT_FAIL_ID, sixtp_child_free_data,
472 SIXTP_NO_MORE_HANDLERS);
473 g_return_val_if_fail (top_level, NULL);
475 if (!sixtp_add_some_sub_parsers (
477 "s", timespec_sixtp_new (generic_timespec_secs_end_handler),
478 "ns", timespec_sixtp_new (generic_timespec_nsecs_end_handler),
509generic_guid_end_handler (gpointer data_for_children,
510 GSList* data_from_children, GSList* sibling_data,
511 gpointer parent_data, gpointer global_data,
512 gpointer* result,
const gchar* tag)
518 txt = concatenate_child_result_chars (data_from_children);
519 g_return_val_if_fail (txt, FALSE);
528 ok = string_to_guid (txt, gid);
533 PERR (
"couldn't parse GncGUID");
543generic_guid_parser_new (
void)
545 return sixtp_set_any (
547 SIXTP_CHARACTERS_HANDLER_ID, generic_accumulate_chars,
548 SIXTP_CLEANUP_CHARS_ID, sixtp_child_free_data,
549 SIXTP_CHARS_FAIL_ID, sixtp_child_free_data,
550 SIXTP_END_HANDLER_ID, generic_guid_end_handler,
551 SIXTP_RESULT_FAIL_ID, sixtp_child_free_data,
552 SIXTP_CLEANUP_RESULT_ID, sixtp_child_free_data,
553 SIXTP_NO_MORE_HANDLERS);
578generic_gnc_numeric_end_handler (gpointer data_for_children,
579 GSList* data_from_children, GSList* sibling_data,
580 gpointer parent_data, gpointer global_data,
581 gpointer* result,
const gchar* tag)
583 gnc_numeric* num = NULL;
587 txt = concatenate_child_result_chars (data_from_children);
591 num = g_new (gnc_numeric, 1);
595 if (!gnc_numeric_check (*num))
606 PERR (
"couldn't parse numeric quantity");
614generic_gnc_numeric_parser_new (
void)
616 return sixtp_set_any (
618 SIXTP_CHARACTERS_HANDLER_ID, generic_accumulate_chars,
619 SIXTP_CLEANUP_CHARS_ID, sixtp_child_free_data,
620 SIXTP_CHARS_FAIL_ID, sixtp_child_free_data,
621 SIXTP_END_HANDLER_ID, generic_gnc_numeric_end_handler,
622 SIXTP_RESULT_FAIL_ID, sixtp_child_free_data,
623 SIXTP_CLEANUP_RESULT_ID, sixtp_child_free_data,
624 SIXTP_NO_MORE_HANDLERS);
630restore_char_generator (sixtp_end_handler ender)
632 return sixtp_set_any (
634 SIXTP_CHARACTERS_HANDLER_ID, generic_accumulate_chars,
635 SIXTP_END_HANDLER_ID, ender,
636 SIXTP_CLEANUP_CHARS_ID, sixtp_child_free_data,
637 SIXTP_CHARS_FAIL_ID, sixtp_child_free_data,
638 SIXTP_NO_MORE_HANDLERS);
Date and Time handling routines.
#define PERR(format, args...)
Log a serious error.
gnc_numeric gnc_numeric_from_string(const gchar *str)
Read a gnc_numeric from str, skipping any leading whitespace.
The type used to store guids in C.