diff mbox series

[3/6] sim: Move EFli and EFlp parsers to simutil

Message ID 20240213153524.1085649-3-denkenz@gmail.com (mailing list archive)
State Accepted
Commit dcc67adb9a014828460b5d4376d0205f2ae67a9b
Headers show
Series [1/6] sim: Drop glib use from sim_efli_format | expand

Commit Message

Denis Kenzior Feb. 13, 2024, 3:35 p.m. UTC
While here, convert from using g_slist to l_strv utilities and remove
other GLib usage.
---
 src/sim.c     | 105 ++++++++++++++------------------------------------
 src/simutil.c |  62 +++++++++++++++++++++++++++++
 src/simutil.h |   3 ++
 3 files changed, 93 insertions(+), 77 deletions(-)
diff mbox series

Patch

diff --git a/src/sim.c b/src/sim.c
index fedd000923b9..1873eccccf2e 100644
--- a/src/sim.c
+++ b/src/sim.c
@@ -2181,76 +2181,33 @@  static bool sim_efli_format(const unsigned char *ef, int length)
 	return true;
 }
 
-static GSList *parse_language_list(const unsigned char *ef, int length)
+static char **concat_lang_prefs(char **a, char **b)
 {
-	int i;
-	GSList *ret = NULL;
-
-	for (i = 0; i < length; i += 2) {
-		if (ef[i] > 0x7f || ef[i+1] > 0x7f)
-			continue;
-
-		/*
-		 * ISO 639 codes contain only characters that are coded
-		 * identically in SMS 7 bit charset, ASCII or UTF8 so
-		 * no conversion.
-		 */
-		ret = g_slist_prepend(ret, g_ascii_strdown((char *)ef + i, 2));
-	}
-
-	if (ret)
-		ret = g_slist_reverse(ret);
-
-	return ret;
-}
-
-static GSList *parse_eflp(const unsigned char *eflp, int length)
-{
-	int i;
-	char code[3];
-	GSList *ret = NULL;
-
-	for (i = 0; i < length; i++) {
-		if (!iso639_2_from_language(eflp[i], code))
-			continue;
-
-		ret = g_slist_prepend(ret, g_strdup(code));
-	}
-
-	if (ret)
-		ret = g_slist_reverse(ret);
-
-	return ret;
-}
-
-static char **concat_lang_prefs(GSList *a, GSList *b)
-{
-	GSList *l, *k;
 	char **ret;
-	int i = 0;
-	int total = g_slist_length(a) + g_slist_length(b);
+	int i;
+	int j;
+	int total = l_strv_length(a) + l_strv_length(b);
 
 	if (total == 0)
 		return NULL;
 
-	ret = g_new0(char *, total + 1);
-
-	for (l = a; l; l = l->next)
-		ret[i++] = g_strdup(l->data);
-
-	for (l = b; l; l = l->next) {
-		gboolean duplicate = FALSE;
+	ret = l_new(char *, total + 1);
 
-		for (k = a; k; k = k->next)
-			if (!strcmp(k->data, l->data))
-				duplicate = TRUE;
+	for (i = 0; a && a[i]; i++)
+		ret[i] = a[i];
 
-		if (duplicate)
+	for (j = 0; b && b[j]; j++) {
+		if (l_strv_contains(a, b[j])) {
+			l_free(b[j]);
 			continue;
+		}
 
-		ret[i++] = g_strdup(l->data);
+		ret[i++] = b[j];
 	}
 
+	l_free(a);
+	l_free(b);
+
 	return ret;
 }
 
@@ -2262,22 +2219,23 @@  static void sim_efpl_read_cb(int ok, int length, int record,
 	const char *path = __ofono_atom_get_path(sim->atom);
 	DBusConnection *conn = ofono_dbus_get_connection();
 	bool efli_format = true;
-	GSList *efli = NULL;
-	GSList *efpl = NULL;
+	char **efli = NULL;
+	char **efpl = NULL;
 
 	if (!ok || length < 2)
 		goto skip_efpl;
 
-	efpl = parse_language_list(data, length);
+	efpl = sim_parse_language_list(data, length);
 
 skip_efpl:
 	if (sim->efli && sim->efli_length > 0) {
 		efli_format = sim_efli_format(sim->efli, sim->efli_length);
 
 		if (efli_format)
-			efli = parse_language_list(sim->efli, sim->efli_length);
+			efli = sim_parse_language_list(sim->efli,
+							sim->efli_length);
 		else
-			efli = parse_eflp(sim->efli, sim->efli_length);
+			efli = sim_parse_eflp(sim->efli, sim->efli_length);
 	}
 
 	/*
@@ -2293,13 +2251,14 @@  skip_efpl:
 	 */
 	if (efli_format) {
 		if (sim->efli_length >= 2 && sim->efli[0] == 0xff &&
-				sim->efli[1] == 0xff)
-			sim->language_prefs = concat_lang_prefs(NULL, efpl);
-		else
-			sim->language_prefs = concat_lang_prefs(efli, efpl);
-	} else {
+				sim->efli[1] == 0xff) {
+			l_strfreev(efli);
+			efli = NULL;
+		}
+
+		sim->language_prefs = concat_lang_prefs(efli, efpl);
+	} else
 		sim->language_prefs = concat_lang_prefs(efpl, efli);
-	}
 
 	if (sim->efli) {
 		g_free(sim->efli);
@@ -2307,14 +2266,6 @@  skip_efpl:
 		sim->efli_length = 0;
 	}
 
-	if (efli) {
-		g_slist_free_full(efli, g_free);
-	}
-
-	if (efpl) {
-		g_slist_free_full(efpl, g_free);
-	}
-
 	if (sim->language_prefs != NULL)
 		ofono_dbus_signal_array_property_changed(conn, path,
 						OFONO_SIM_MANAGER_INTERFACE,
diff --git a/src/simutil.c b/src/simutil.c
index 0354cafd087f..7345f38db571 100644
--- a/src/simutil.c
+++ b/src/simutil.c
@@ -1827,3 +1827,65 @@  gboolean sim_parse_gsm_authenticate(const unsigned char *buffer, int len,
 gsm_end:
 	return FALSE;
 }
+
+char **sim_parse_language_list(const unsigned char *ef, int length)
+{
+	int i;
+	size_t n_languages = 0;
+	char **ret;
+
+	for (i = 0; i + 1 < length; i += 2) {
+		if (ef[i] > 0x7f || ef[i + 1] > 0x7f)
+			continue;
+
+		n_languages += 1;
+	}
+
+	if (!n_languages)
+		return NULL;
+
+	ret = l_new(char *, n_languages + 1);
+
+	for (i = 0, n_languages = 0; i + 1 < length; i += 2) {
+		if (ef[i] > 0x7f || ef[i + 1] > 0x7f)
+			continue;
+
+		/*
+		 * ISO 639 codes contain only characters that are coded
+		 * identically in SMS 7 bit charset, ASCII or UTF8 so
+		 * no conversion.
+		 */
+		ret[n_languages++] = l_ascii_strdown((const char *)ef + i, 2);
+	}
+
+	return ret;
+}
+
+char **sim_parse_eflp(const unsigned char *eflp, int length)
+{
+	int i;
+	char code[3];
+	char **ret;
+	size_t n_languages = 0;
+
+	for (i = 0; i < length; i++) {
+		if (!iso639_2_from_language(eflp[i], code))
+			continue;
+
+		n_languages += 1;
+	}
+
+	if (!n_languages)
+		return NULL;
+
+	ret = l_new(char *, n_languages + 1);
+
+	for (i = 0, n_languages = 0; i < length; i++) {
+		if (!iso639_2_from_language(eflp[i], code))
+			continue;
+
+		ret[n_languages++] = l_strdup(code);
+	}
+
+	return ret;
+}
diff --git a/src/simutil.h b/src/simutil.h
index fd3967ffd336..9584d4d9cd62 100644
--- a/src/simutil.h
+++ b/src/simutil.h
@@ -541,3 +541,6 @@  gboolean sim_parse_umts_authenticate(const unsigned char *buffer, int len,
 
 gboolean sim_parse_gsm_authenticate(const unsigned char *buffer, int len,
 		const unsigned char **sres, const unsigned char **kc);
+
+char **sim_parse_language_list(const unsigned char *ef, int length);
+char **sim_parse_eflp(const unsigned char *eflp, int length);