[tracker/cuesheets: 16/18] libtracker-common: Add tracker_case_match_filename_without_extension()



commit 01fffb4f46e30d7400a9af3f4c416c1feb00f881
Author: Sam Thursfield <samthursfield codethink co uk>
Date:   Thu Aug 18 11:26:25 2011 +0100

    libtracker-common: Add tracker_case_match_filename_without_extension()
    
    This is used by the cue sheet parser to match audio files which are
    listed with incorrect extensions.

 src/libtracker-common/tracker-utils.c        |   76 ++++++++++++++++++++++++++
 src/libtracker-common/tracker-utils.h        |    3 +
 tests/libtracker-common/tracker-utils-test.c |   31 +++++++++++
 3 files changed, 110 insertions(+), 0 deletions(-)
---
diff --git a/src/libtracker-common/tracker-utils.c b/src/libtracker-common/tracker-utils.c
index a9b3612..b58d5a1 100644
--- a/src/libtracker-common/tracker-utils.c
+++ b/src/libtracker-common/tracker-utils.c
@@ -209,3 +209,79 @@ tracker_strhex (const guint8 *data,
 	/* Set output string */
 	return new_str;
 }
+
+/**
+ * tracker_case_match_filename_without_extension:
+ * @a: a string containing a file name
+ * @b: filename to be compared with @a
+ *
+ * This function performs a case-insensitive comparison of @a and @b.
+ * Additionally, text beyond the last '.' in a string is not considered
+ * part of the match, so for example given the inputs "file.mp3" and
+ * "file.wav" this function will return %TRUE.
+ *
+ * Internally, the g_ascii_tolower() function is used - this means that
+ * @a and @b must be in an encoding in which ASCII characters always
+ * represent themselves, such as UTF-8 or the ISO-8859-* charsets.
+ *
+ * Returns: %TRUE if the two file names match.
+ **/
+gboolean
+tracker_case_match_filename_without_extension (const gchar *a,
+                                               const gchar *b)
+{
+	const gchar *ca = a;
+	const gchar *cb = b;
+	gboolean period_a = FALSE;
+	gboolean period_b = FALSE;
+	gboolean match = TRUE;
+
+	g_return_val_if_fail (a != NULL, FALSE);
+	g_return_val_if_fail (b != NULL, FALSE);
+
+	while (1) {
+		if (*ca == '\0' && *cb == '\0')
+			break;
+
+		if (*ca != '\0' && *cb != '\0') {
+			if (g_ascii_tolower (*ca) != g_ascii_tolower (*cb)) {
+				match = FALSE;
+				break;
+			}
+		}
+
+		if (*ca == '.')
+			period_a = TRUE;
+
+		if (*cb == '.')
+			period_b = TRUE;
+
+		if (*ca == '\0' || *cb == '\0') {
+			match = FALSE;
+			break;
+		}
+
+		ca ++; cb ++;
+	}
+
+	if (!match) {
+		/* If the mismatch was past the last '.' then forgive it. */
+		if (*ca != '\0' && period_a) {
+			match = TRUE;
+
+			while (*(ca ++) != '\0')
+				if (*ca == '.')
+					match = FALSE;
+		}
+
+		if (*cb != '\0' && period_b) {
+			match = TRUE;
+
+			while (*(cb ++) != '\0')
+				if (*cb == '.')
+					match = FALSE;
+		}
+	}
+
+	return match;
+}
diff --git a/src/libtracker-common/tracker-utils.h b/src/libtracker-common/tracker-utils.h
index 035be96..a891611 100644
--- a/src/libtracker-common/tracker-utils.h
+++ b/src/libtracker-common/tracker-utils.h
@@ -44,6 +44,9 @@ gchar *  tracker_strhex                     (const guint8 *data,
                                              gsize         size,
                                              gchar         delimiter);
 
+gboolean tracker_case_match_filename_without_extension (const gchar *a,
+                                                        const gchar *b);
+
 G_END_DECLS
 
 #endif /* __LIBTRACKER_COMMON_UTILS_H__ */
diff --git a/tests/libtracker-common/tracker-utils-test.c b/tests/libtracker-common/tracker-utils-test.c
index 504ae80..07364ca 100644
--- a/tests/libtracker-common/tracker-utils-test.c
+++ b/tests/libtracker-common/tracker-utils-test.c
@@ -74,6 +74,34 @@ test_seconds_estimate_to_string ()
 	g_print ("%s\n", result);
 }
 
+#define assert_filename_match(a, b) { \
+	g_assert (tracker_case_match_filename_without_extension (a, b) == TRUE); \
+	g_assert (tracker_case_match_filename_without_extension (b, a) == TRUE); }
+
+#define assert_no_filename_match(a, b) { \
+	g_assert (tracker_case_match_filename_without_extension (a, b) == FALSE); \
+	g_assert (tracker_case_match_filename_without_extension (b, a) == FALSE); }
+
+static void
+test_case_match_filename_without_extension ()
+{
+	assert_filename_match ("test.mp3", "test.mp3");
+	assert_filename_match ("test.mp3", "test.wav");
+	assert_filename_match ("test.mp3", "test.mp");
+	assert_filename_match ("test.mp3", "test.");
+	assert_filename_match ("test.mp3", "test");
+	assert_filename_match ("01 - Song 1 (Remix).wav", "01 - Song 1 (Remix).flac");
+
+	assert_no_filename_match ("test.mp3", "bacon.mp3");
+
+	/* Pathological cases, mainly testing that nothing crashes */
+	assert_no_filename_match (".", "\n");
+	assert_no_filename_match ("as", "as..");
+	assert_no_filename_match ("...as", "...as..");
+	assert_no_filename_match (".", "test.");
+	assert_filename_match ("", ".");
+}
+
 int
 main (int argc, char **argv)
 {
@@ -90,6 +118,9 @@ main (int argc, char **argv)
 	g_test_add_func ("/libtracker-common/tracker-utils/seconds_estimate_to_string",
 	                 test_seconds_estimate_to_string);
 
+	g_test_add_func ("/libtracker-common/tracker-utils/case_match_filename_without_extension",
+	                 test_case_match_filename_without_extension);
+
 	ret = g_test_run ();
 
 	tracker_locale_shutdown ();



[Date Prev][Date Next]   [Thread Prev][Thread Next]   [Thread Index] [Date Index] [Author Index]