[tracker/collation: 2/6] libtracker-data: Implemented collation functions
- From: Aleksander Morgado <aleksm src gnome org>
- To: commits-list gnome org
- Cc:
- Subject: [tracker/collation: 2/6] libtracker-data: Implemented collation functions
- Date: Tue, 24 Aug 2010 09:52:05 +0000 (UTC)
commit 2a0e00ba7175d8e7d57fbc55176eb80c1b64e0b2
Author: Aleksander Morgado <aleksander lanedo com>
Date: Thu Aug 19 13:38:22 2010 +0200
libtracker-data: Implemented collation functions
src/libtracker-data/Makefile.am | 6 +-
src/libtracker-data/tracker-collation.c | 206 +++++++++++++++++++++++++++++++
src/libtracker-data/tracker-collation.h | 39 ++++++
3 files changed, 250 insertions(+), 1 deletions(-)
---
diff --git a/src/libtracker-data/Makefile.am b/src/libtracker-data/Makefile.am
index f72fde0..71e1eee 100644
--- a/src/libtracker-data/Makefile.am
+++ b/src/libtracker-data/Makefile.am
@@ -13,7 +13,8 @@ INCLUDES = \
$(DBUS_CFLAGS) \
$(UUID_CFLAGS) \
$(GCOV_CFLAGS) \
- $(SQLITE3_CFLAGS)
+ $(SQLITE3_CFLAGS) \
+ $(UNICODE_SUPPORT_CFLAGS)
BUILT_SOURCES = libtracker-data.vala.stamp
@@ -29,6 +30,7 @@ libtracker_data_la_VALASOURCES = \
libtracker_data_la_SOURCES = \
tracker-class.c \
+ tracker-collation.c \
tracker-data-backup.c \
tracker-data-manager.c \
tracker-data-query.c \
@@ -49,6 +51,7 @@ libtracker_data_la_SOURCES = \
noinst_HEADERS = \
tracker-class.h \
tracker-data.h \
+ tracker-collation.h \
tracker-data-backup.h \
tracker-data-manager.h \
tracker-data-query.h \
@@ -87,6 +90,7 @@ libtracker_data_la_LIBADD = \
$(GLIB2_LIBS) \
$(UUID_LIBS) \
$(GCOV_LIBS) \
+ $(UNICODE_SUPPORT_LIBS) \
-lz \
-lm
diff --git a/src/libtracker-data/tracker-collation.c b/src/libtracker-data/tracker-collation.c
new file mode 100644
index 0000000..4601c96
--- /dev/null
+++ b/src/libtracker-data/tracker-collation.c
@@ -0,0 +1,206 @@
+/*
+ * Copyright (C) 2010, Nokia <ivan frade nokia com>
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public
+ * License along with this library; if not, write to the
+ * Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
+ * Boston, MA 02110-1301, USA.
+ */
+
+#include "config.h"
+#include <glib.h>
+#include <string.h>
+
+#include "tracker-collation.h"
+
+/* If defined, will dump some additional logs as prints,
+ * instead of debugs*/
+#ifdef PRINT_INSTEADOF_LOG
+#undef g_debug
+#define g_debug(message, ...) \
+ g_print ("(debug) %s:%d: " message "\n", \
+ __FILE__, __LINE__, ##__VA_ARGS__)
+#undef g_warning
+#define g_warning(message, ...) \
+ g_print ("(warning) %s:%d: " message "\n", \
+ __FILE__, __LINE__, ##__VA_ARGS__)
+#undef g_critical
+#define g_critical(message, ...) \
+ g_print ("(critical) %s:%d: " message "\n", \
+ __FILE__, __LINE__, ##__VA_ARGS__)
+#endif /* PRINT_INSTEADOF_LOG */
+
+#ifdef HAVE_LIBUNISTRING
+/* libunistring versions prior to 9.1.2 need this hack */
+#define _UNUSED_PARAMETER_
+#include <unistr.h>
+#elif HAVE_LIBICU
+#include <locale.h>
+#include <unicode/ucol.h>
+#endif
+
+/* If string lenth less than this value, allocating from the stack */
+#define MAX_STACK_STR_SIZE 8192
+
+#ifdef HAVE_LIBUNISTRING /* ---- GNU libunistring based collation ---- */
+
+gpointer
+tracker_collation_init (void)
+{
+ g_debug ("[libunistring collation] Initializing collator");
+ /* Nothing to do */
+ return NULL;
+}
+
+void
+tracker_collation_deinit (gpointer collator)
+{
+ /* Nothing to do */
+}
+
+gint
+tracker_collation_utf8 (gpointer collator,
+ gint len1,
+ gconstpointer str1,
+ gint len2,
+ gconstpointer str2)
+{
+ gint result;
+ gchar *aux1;
+ gchar *aux2;
+
+ /* Note: str1 and str2 are NOT NUL-terminated */
+ aux1 = (len1 < MAX_STACK_STR_SIZE) ? g_alloca (len1+1) : g_malloc (len1+1);
+ aux2 = (len2 < MAX_STACK_STR_SIZE) ? g_alloca (len2+1) : g_malloc (len2+1);
+
+ memcpy (aux1, str1, len1); aux1[len1] = '\0';
+ memcpy (aux2, str2, len2); aux2[len2] = '\0';
+
+ result = u8_strcoll (aux1, aux2);
+
+ if (len1 >= MAX_STACK_STR_SIZE)
+ g_free (aux1);
+ if (len2 >= MAX_STACK_STR_SIZE)
+ g_free (aux2);
+ return result;
+}
+
+#elif HAVE_LIBICU /* ---- ICU based collation (UTF-16) ----*/
+
+gpointer
+tracker_collation_init (void)
+{
+ UCollator *collator = NULL;
+ UErrorCode status = U_ZERO_ERROR;
+ const gchar *locale = setlocale (LC_ALL, NULL);
+
+ g_debug ("[ICU collation] Initializing collator for locale '%s'", locale);
+ collator = ucol_open (locale, &status);
+ if (!collator) {
+ g_warning ("[ICU collation] Collator for locale '%s' cannot be created: %s",
+ locale, u_errorName (status));
+ /* Try to get UCA collator then... */
+ status = U_ZERO_ERROR;
+ collator = ucol_open ("root", &status);
+ if (!collator) {
+ g_critical ("[ICU collation] UCA Collator cannot be created: %s",
+ u_errorName (status));
+ }
+ }
+ return collator;
+}
+
+void
+tracker_collation_deinit (gpointer collator)
+{
+ if (collator)
+ ucol_close ((UCollator *)collator);
+}
+
+gint
+tracker_collation_utf8 (gpointer collator,
+ gint len1,
+ gconstpointer str1,
+ gint len2,
+ gconstpointer str2)
+{
+ UErrorCode status = U_ZERO_ERROR;
+ UCharIterator iter1;
+ UCharIterator iter2;
+ UCollationResult result;
+
+ /* Collator must be created before trying to collate */
+ g_return_val_if_fail (collator, -1);
+
+ /* Setup iterators */
+ uiter_setUTF8 (&iter1, str1, len1);
+ uiter_setUTF8 (&iter2, str2, len2);
+
+ result = ucol_strcollIter ((UCollator *)collator,
+ &iter1,
+ &iter2,
+ &status);
+ if (status != U_ZERO_ERROR)
+ g_critical ("Error collating: %s", u_errorName (status));
+
+ if (result == UCOL_GREATER)
+ return 1;
+ if (result == UCOL_LESS)
+ return -1;
+ return 0;
+}
+
+#else /* ---- GLib based collation ---- */
+
+gpointer
+tracker_collation_init (void)
+{
+ g_debug ("[GLib collation] Initializing collator");
+ /* Nothing to do */
+ return NULL;
+}
+
+void
+tracker_collation_deinit (gpointer collator)
+{
+ /* Nothing to do */
+}
+
+gint
+tracker_collation_utf8 (gpointer collator,
+ gint len1,
+ gconstpointer str1,
+ gint len2,
+ gconstpointer str2)
+{
+ gint result;
+ gchar *aux1;
+ gchar *aux2;
+
+ /* Note: str1 and str2 are NOT NUL-terminated */
+ aux1 = (len1 < MAX_STACK_STR_SIZE) ? g_alloca (len1+1) : g_malloc (len1+1);
+ aux2 = (len2 < MAX_STACK_STR_SIZE) ? g_alloca (len2+1) : g_malloc (len2+1);
+
+ memcpy (aux1, str1, len1); aux1[len1] = '\0';
+ memcpy (aux2, str2, len2); aux2[len2] = '\0';
+
+ result = g_utf8_collate (aux1, aux2);
+
+ if (len1 >= MAX_STACK_STR_SIZE)
+ g_free (aux1);
+ if (len2 >= MAX_STACK_STR_SIZE)
+ g_free (aux2);
+ return result;
+}
+
+#endif
diff --git a/src/libtracker-data/tracker-collation.h b/src/libtracker-data/tracker-collation.h
new file mode 100644
index 0000000..6f9ec3c
--- /dev/null
+++ b/src/libtracker-data/tracker-collation.h
@@ -0,0 +1,39 @@
+/*
+ * Copyright (C) 2010 Nokia <ivan frade nokia com>
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.1 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the
+ * Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
+ * Boston, MA 02110-1301, USA.
+ */
+
+#ifndef __LIBTRACKER_COMMON_COLLATION_H__
+#define __LIBTRACKER_COMMON_COLLATION_H__
+
+G_BEGIN_DECLS
+
+#if !defined (__LIBTRACKER_COMMON_INSIDE__) && !defined (TRACKER_COMPILATION)
+#error "only <libtracker-common/tracker-common.h> must be included directly."
+#endif
+
+gpointer tracker_collation_init (void);
+void tracker_collation_deinit (gpointer collator);
+gint tracker_collation_utf8 (gpointer collator,
+ gint len1,
+ gconstpointer str1,
+ gint len2,
+ gconstpointer str2);
+
+G_END_DECLS
+
+#endif /* __LIBTRACKER_COMMON_COLLATION_H__ */
[
Date Prev][
Date Next] [
Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]