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.
This commit is contained in:
Aleksander Morgado
2020-01-31 15:48:16 +01:00
parent 2020f1f2e7
commit 280363e0d6
2 changed files with 73 additions and 8 deletions
+58 -8
View File
@@ -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);
+15
View File
@@ -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);