aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorAleksander Morgado <aleksander@aleksander.es>2020-01-31 15:46:14 +0100
committerAleksander Morgado <aleksander@aleksander.es>2020-01-31 15:48:16 +0100
commit280363e0d639a77a4072f26b9ec499de6575c0f2 (patch)
tree5d1e0fb1ac6fa5798be20cbb1eb825df74529dfb
parent2020f1f2e748beb3f919cd0818a32673b39aecbc (diff)
libmm-glib,helpers: allow \r\n in string to number conversions
It's not uncommon that we may want to parse a simple AT response that contains a single number by doing mm_strip_tag() followed by mm_get_uint_from_str(). In order to do this, we need to have the helper methods that convert strings to numbers support \r\n characters at the end of the string, as we would have in AT responses.
-rw-r--r--libmm-glib/mm-common-helpers.c66
-rw-r--r--libmm-glib/tests/test-common-helpers.c15
2 files changed, 73 insertions, 8 deletions
diff --git a/libmm-glib/mm-common-helpers.c b/libmm-glib/mm-common-helpers.c
index ac352c60..484771b3 100644
--- a/libmm-glib/mm-common-helpers.c
+++ b/libmm-glib/mm-common-helpers.c
@@ -1331,14 +1331,27 @@ mm_get_int_from_str (const gchar *str,
gint *out)
{
glong num;
+ guint eol = 0;
if (!str || !str[0])
return FALSE;
for (num = 0; str[num]; num++) {
- if (str[num] != '+' && str[num] != '-' && !g_ascii_isdigit (str[num]))
+ if (str[num] != '+' && str[num] != '-' && !g_ascii_isdigit (str[num])) {
+ /* ignore \r\n at the end of the string */
+ if ((str[num] == '\r') || (str[num] == '\n')) {
+ eol++;
+ continue;
+ }
+ return FALSE;
+ }
+ /* if eol found before a valid char, the string is not parseable */
+ if (eol)
return FALSE;
}
+ /* if all characters were eol, the string is not parseable */
+ if (eol == num)
+ return FALSE;
errno = 0;
num = strtol (str, NULL, 10);
@@ -1385,14 +1398,27 @@ mm_get_u64_from_str (const gchar *str,
guint64 *out)
{
guint64 num;
+ guint eol = 0;
if (!str || !str[0])
return FALSE;
for (num = 0; str[num]; num++) {
- if (!g_ascii_isdigit (str[num]))
+ if (!g_ascii_isdigit (str[num])) {
+ /* ignore \r\n at the end of the string */
+ if ((str[num] == '\r') || (str[num] == '\n')) {
+ eol++;
+ continue;
+ }
+ return FALSE;
+ }
+ /* if eol found before a valid char, the string is not parseable */
+ if (eol)
return FALSE;
}
+ /* if all characters were eol, the string is not parseable */
+ if (eol == num)
+ return FALSE;
errno = 0;
num = (guint64) strtoull (str, NULL, 10);
@@ -1421,6 +1447,7 @@ mm_get_u64_from_hex_str (const gchar *str,
guint64 *out)
{
guint64 num;
+ guint eol = 0;
if (!str)
return FALSE;
@@ -1432,9 +1459,21 @@ mm_get_u64_from_hex_str (const gchar *str,
return FALSE;
for (num = 0; str[num]; num++) {
- if (!g_ascii_isxdigit (str[num]))
+ if (!g_ascii_isxdigit (str[num])) {
+ /* ignore \r\n at the end of the string */
+ if ((str[num] == '\r') || (str[num] == '\n')) {
+ eol++;
+ continue;
+ }
+ return FALSE;
+ }
+ /* if eol found before a valid char, the string is not parseable */
+ if (eol)
return FALSE;
}
+ /* if all characters were eol, the string is not parseable */
+ if (eol == num)
+ return FALSE;
errno = 0;
num = (guint64) strtoull (str, NULL, 16);
@@ -1481,8 +1520,9 @@ gboolean
mm_get_double_from_str (const gchar *str,
gdouble *out)
{
- gdouble num;
- guint i;
+ gdouble num;
+ guint i;
+ guint eol = 0;
if (!str || !str[0])
return FALSE;
@@ -1490,11 +1530,21 @@ mm_get_double_from_str (const gchar *str,
for (i = 0; str[i]; i++) {
/* we don't really expect numbers in scientific notation, so
* don't bother looking for exponents and such */
- if (str[i] != '-' &&
- str[i] != '.' &&
- !g_ascii_isdigit (str[i]))
+ if ((str[i] != '-') && (str[i] != '.') && !g_ascii_isdigit (str[i])) {
+ /* ignore \r\n at the end of the string */
+ if ((str[i] == '\r') || (str[i] == '\n')) {
+ eol++;
+ continue;
+ }
+ return FALSE;
+ }
+ /* if eol found before a valid char, the string is not parseable */
+ if (eol)
return FALSE;
}
+ /* if all characters were eol, the string is not parseable */
+ if (eol == i)
+ return FALSE;
errno = 0;
num = strtod (str, NULL);
diff --git a/libmm-glib/tests/test-common-helpers.c b/libmm-glib/tests/test-common-helpers.c
index aa15b172..78432bed 100644
--- a/libmm-glib/tests/test-common-helpers.c
+++ b/libmm-glib/tests/test-common-helpers.c
@@ -366,6 +366,8 @@ field_parser_int (void)
g_assert (mm_get_int_from_str ("100a", &num) == FALSE);
+ g_assert (mm_get_int_from_str ("\r\n", &num) == FALSE);
+
str = g_strdup_printf ("%" G_GINT64_FORMAT, (gint64)G_MAXINT + 1);
g_assert (mm_get_int_from_str (str, &num) == FALSE);
g_free (str);
@@ -385,6 +387,9 @@ field_parser_int (void)
g_assert (mm_get_int_from_str ("100", &num) == TRUE);
g_assert_cmpint (num, ==, 100);
+ g_assert (mm_get_int_from_str ("-256\r\n", &num) == TRUE);
+ g_assert_cmpint (num, ==, -256);
+
str = g_strdup_printf ("%" G_GINT64_FORMAT, (gint64)G_MAXINT);
g_assert (mm_get_int_from_str (str, &num) == TRUE);
g_assert_cmpint (num, ==, G_MAXINT);
@@ -416,6 +421,8 @@ field_parser_uint (void)
g_assert (mm_get_uint_from_str ("-100", &num) == FALSE);
+ g_assert (mm_get_uint_from_str ("\r\n", &num) == FALSE);
+
str = g_strdup_printf ("%" G_GUINT64_FORMAT, (guint64)(G_MAXUINT) + 1);
g_assert (mm_get_uint_from_str (str, &num) == FALSE);
g_free (str);
@@ -428,6 +435,9 @@ field_parser_uint (void)
g_assert (mm_get_uint_from_str ("100", &num) == TRUE);
g_assert_cmpuint (num, ==, 100);
+ g_assert (mm_get_uint_from_str ("256\r\n", &num) == TRUE);
+ g_assert_cmpuint (num, ==, 256);
+
str = g_strdup_printf ("%" G_GUINT64_FORMAT, (guint64)G_MAXUINT);
g_assert (mm_get_uint_from_str (str, &num) == TRUE);
g_assert_cmpuint (num, ==, G_MAXUINT);
@@ -452,6 +462,8 @@ field_parser_double (void)
g_assert (mm_get_double_from_str ("100a", &num) == FALSE);
+ g_assert (mm_get_double_from_str ("\r\n", &num) == FALSE);
+
/* Successes */
g_assert (mm_get_double_from_str ("-100", &num) == TRUE);
@@ -475,6 +487,9 @@ field_parser_double (void)
g_assert (mm_get_double_from_str ("100.7567", &num) == TRUE);
g_assert (num - (100.7567) < 0000000.1);
+ g_assert (mm_get_double_from_str ("100.7567\r\n", &num) == TRUE);
+ g_assert (num - (100.7567) < 0000000.1);
+
str = g_strdup_printf ("%lf", (gdouble)G_MINDOUBLE);
g_assert (mm_get_double_from_str (str, &num) == TRUE);
g_assert (num - G_MINDOUBLE < 0000000.1);