[evolution-data-server/openismus-work-master: 39/74] Added EAlphabetIndex
- From: Tristan Van Berkom <tvb src gnome org>
- To: commits-list gnome org
- Cc:
- Subject: [evolution-data-server/openismus-work-master: 39/74] Added EAlphabetIndex
- Date: Thu, 18 Jul 2013 22:11:32 +0000 (UTC)
commit ce80ed526b0c71a4259e6d87688fa727fdf702d6
Author: Tristan Van Berkom <tristanvb openismus com>
Date: Fri Jun 7 22:42:25 2013 +0900
Added EAlphabetIndex
A private accessory used internally by ECollator to implement AlphabeticIndex
features. This is in a separate file since we need to use C++ APIs to use
the AlphabeticIndex, so we compile it into a separate archive to be statically
linked in with libedataserver.la.
configure.ac | 26 ++---
libedataserver/Makefile.am | 8 ++
libedataserver/e-alphabet-index-private.cpp | 158 +++++++++++++++++++++++++++
libedataserver/e-alphabet-index-private.h | 62 +++++++++++
4 files changed, 237 insertions(+), 17 deletions(-)
---
diff --git a/configure.ac b/configure.ac
index c6172d5..7bae582 100644
--- a/configure.ac
+++ b/configure.ac
@@ -175,7 +175,6 @@ dnl *********************************************
dnl Figure out early if we'll need a C++ compiler
dnl *********************************************
-evo_with_cxx=no
EVO_PHONENUMBER_ARGS
dnl ******************************
@@ -214,22 +213,15 @@ dnl -Wstrict-aliasing=2
AM_CFLAGS="$WARNING_FLAGS -fno-strict-aliasing"
AC_SUBST(AM_CFLAGS)
-if test "x$evo_with_cxx" = xyes; then
- AC_PROG_CXX
+dnl C++ Compiler flags, needed for ICU C++ access and libphonenumber usage
+AC_PROG_CXX
- AC_LANG_PUSH([C++])
- AS_COMPILER_FLAGS(CXX_WARNING_FLAGS, [$proposed_cxx_warning_flags])
- AC_SUBST(CXX_WARNING_FLAGS)
- AM_CXXFLAGS="$CXX_WARNING_FLAGS"
- AC_SUBST(AM_CXXFLAGS)
- AC_LANG_POP([C++])
-else
- dnl Autoconf requires those automake conditionals to be defined when
- dnl generating the config files, but apparently it forgets to initialize
- dnl them dnl if AC_PROG_CXX never gets called. Therefore we do it manually.
- am__fastdepCXX_TRUE='#'
- am__fastdepCXX_FALSE=
-fi
+AC_LANG_PUSH([C++])
+AS_COMPILER_FLAGS(CXX_WARNING_FLAGS, [$proposed_cxx_warning_flags])
+AC_SUBST(CXX_WARNING_FLAGS)
+AM_CXXFLAGS="$CXX_WARNING_FLAGS"
+AC_SUBST(AM_CXXFLAGS)
+AC_LANG_POP([C++])
dnl Permits linking of C++ based libraries using the C linker if needed.
AC_SUBST([predeps_CXX])
diff --git a/libedataserver/Makefile.am b/libedataserver/Makefile.am
index 4fda136..156f7a1 100644
--- a/libedataserver/Makefile.am
+++ b/libedataserver/Makefile.am
@@ -16,6 +16,7 @@ ENUM_GENERATED = e-source-enumtypes.h e-source-enumtypes.c
BUILT_SOURCES = $(ENUM_GENERATED)
lib_LTLIBRARIES = libedataserver-1.2.la
+noinst_LTLIBRARIES = libealphabetindex-private.la
libedataserver_1_2_la_CPPFLAGS = \
$(AM_CPPFLAGS) \
@@ -41,6 +42,7 @@ libedataserver_1_2_la_CPPFLAGS = \
libedataserver_1_2_la_SOURCES = \
$(BUILT_SOURCES) \
+ e-alphabet-index-private.h \
e-cancellable-locks.c \
e-categories.c \
e-client.c \
@@ -172,6 +174,12 @@ libedataserverinclude_HEADERS = \
e-xml-hash-utils.h \
eds-version.h
+# We put the C++ code into a separate static library, so that we can use
+# the C linker for libebook-contacts.
+libealphabetindex_private_la_SOURCES = e-alphabet-index-private.cpp
+libealphabetindex_private_la_CPPFLAGS = $(libedataserver_1_2_la_CPPFLAGS)
+libedataserver_1_2_la_LIBADD += @predeps_CXX@ libealphabetindex-private.la @postdeps_CXX@
+
%-$(API_VERSION).pc: %.pc
cp $< $@
diff --git a/libedataserver/e-alphabet-index-private.cpp b/libedataserver/e-alphabet-index-private.cpp
new file mode 100644
index 0000000..8eb2056
--- /dev/null
+++ b/libedataserver/e-alphabet-index-private.cpp
@@ -0,0 +1,158 @@
+/* -*- Mode: C; tab-width: 8; indent-tabs-mode: t; c-basic-offset: 8 -*- */
+/*
+ * Copyright (C) 2013 Intel Corporation
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of version 2 of the GNU Lesser General Public
+ * License as published by the Free Software Foundation.
+ *
+ * This program 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 Lesser General Public
+ * License along with this program; if not, write to the
+ * Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
+ * Boston, MA 02110-1301, USA.
+ *
+ * Author: Tristan Van Berkom <tristanvb openismus com>
+ */
+
+#ifdef HAVE_CONFIG_H
+#include <config.h>
+#endif
+
+#include "e-alphabet-index-private.h"
+
+/* C++ standard library */
+#include <string>
+#include <memory>
+
+/* system headers */
+#include <langinfo.h>
+#include <locale.h>
+
+/* ICU headers */
+#include <unicode/alphaindex.h>
+
+using icu::AlphabeticIndex;
+using icu::Locale;
+
+struct _EAlphabetIndex {
+ AlphabeticIndex *priv;
+};
+
+/* Create an AlphabetIndex for a given language code (normally
+ * language codes are 2 letter codes, eg. 'en' = English 'es' = Spanish.
+ */
+EAlphabetIndex *
+_e_alphabet_index_cxx_new_for_language (const gchar *language)
+{
+ UErrorCode status = U_ZERO_ERROR;
+ EAlphabetIndex *alphabet_index;
+
+ g_return_val_if_fail (language != NULL, NULL);
+
+ alphabet_index = g_slice_new (EAlphabetIndex);
+ alphabet_index->priv = new AlphabeticIndex (Locale (language), status);
+
+ return alphabet_index;
+}
+
+/* Frees an EAlphabetIndex and it's associated resources
+ */
+void
+_e_alphabet_index_cxx_free (EAlphabetIndex *alphabet_index)
+{
+ if (alphabet_index) {
+ delete alphabet_index->priv;
+ g_slice_free (EAlphabetIndex, alphabet_index);
+ }
+}
+
+/* Fetch the given index where 'word' should sort
+ */
+gint
+_e_alphabet_index_cxx_get_index (EAlphabetIndex *alphabet_index,
+ const gchar *word)
+{
+ UErrorCode status = U_ZERO_ERROR;
+ UnicodeString string;
+ gint index;
+
+ g_return_val_if_fail (alphabet_index != NULL, -1);
+ g_return_val_if_fail (word != NULL, -1);
+
+ string = icu::UnicodeString::fromUTF8 (word);
+ index = alphabet_index->priv->getBucketIndex (string, status);
+
+ return index;
+}
+
+/* Fetch the list of labels in the alphabetic index.
+ *
+ * Returns an array of UTF-8 labels for each alphabetic
+ * index position 'n_labels' long, the returned array
+ * of strings can be freed with g_strfreev()
+ *
+ * The underflow, overflow and inflow parameters will be
+ * set to the appropriate indexes (reffers to indexes in the
+ * returned labels).
+ */
+gchar **
+_e_alphabet_index_cxx_get_labels (EAlphabetIndex *alphabet_index,
+ gint *n_labels,
+ gint *underflow,
+ gint *inflow,
+ gint *overflow)
+{
+ UErrorCode status = U_ZERO_ERROR;
+ gchar **labels = NULL;
+ gint count, i;
+
+ g_return_val_if_fail (alphabet_index != NULL, NULL);
+ g_return_val_if_fail (n_labels != NULL, NULL);
+ g_return_val_if_fail (underflow != NULL, NULL);
+ g_return_val_if_fail (inflow != NULL, NULL);
+ g_return_val_if_fail (overflow != NULL, NULL);
+
+ count = alphabet_index->priv->getBucketCount (status);
+
+ labels = g_new0 (gchar *, count + 1);
+
+ /* In case they are missing, they should be set to -1 */
+ *underflow = *inflow = *overflow = -1;
+
+ /* Iterate over the AlphabeticIndex and collect UTF-8 versions
+ * of the bucket labels
+ */
+ alphabet_index->priv->resetBucketIterator (status);
+
+ for (i = 0; alphabet_index->priv->nextBucket (status); i++) {
+ UAlphabeticIndexLabelType label_type;
+ UnicodeString ustring;
+ std::string string;
+
+ label_type = alphabet_index->priv->getBucketLabelType ();
+
+ switch (label_type) {
+ case U_ALPHAINDEX_UNDERFLOW: *underflow = i; break;
+ case U_ALPHAINDEX_INFLOW: *inflow = i; break;
+ case U_ALPHAINDEX_OVERFLOW: *overflow = i; break;
+ case U_ALPHAINDEX_NORMAL: /* do nothing */ break;
+ }
+
+ /* This is annoyingly heavy but not a function called
+ * very often, this could be improved by calling icu::UnicodeString::toUTF8()
+ * and implementing ICU's ByteSync class using glib's memory allocator.
+ */
+ ustring = alphabet_index->priv->getBucketLabel ();
+ string = ustring.toUTF8String (string);
+ labels[i] = g_strdup (string.c_str());
+ }
+
+ *n_labels = count;
+
+ return labels;
+}
diff --git a/libedataserver/e-alphabet-index-private.h b/libedataserver/e-alphabet-index-private.h
new file mode 100644
index 0000000..4e01f24
--- /dev/null
+++ b/libedataserver/e-alphabet-index-private.h
@@ -0,0 +1,62 @@
+/* -*- Mode: C; tab-width: 8; indent-tabs-mode: t; c-basic-offset: 8 -*- */
+/*
+ * Copyright (C) 2013 Intel Corporation
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of version 2 of the GNU Lesser General Public
+ * License as published by the Free Software Foundation.
+ *
+ * This program 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 Lesser General Public
+ * License along with this program; if not, write to the
+ * Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
+ * Boston, MA 02110-1301, USA.
+ *
+ * Author: Tristan Van Berkom <tristanvb openismus com>
+ */
+
+#if !defined (__LIBEDATASERVER_H_INSIDE__) && !defined (LIBEDATASERVER_COMPILATION)
+#error "Only <libedataserver/libedataserver.h> should be included directly."
+#endif
+
+#ifndef E_ALPHABET_INDEX_PRIVATE_H
+#define E_ALPHABET_INDEX_PRIVATE_H
+
+#include <glib-object.h>
+
+G_BEGIN_DECLS
+
+#if __GNUC__ >= 4
+# define E_ALPHABET_INDEX_LOCAL __attribute__ ((visibility ("hidden")))
+#else
+# define E_ALPHABET_INDEX_LOCAL
+#endif
+
+/**
+ * EAlphabetIndex:
+ *
+ * A private opaque type describing an alphabetic index
+ *
+ * Since: 3.10
+ **/
+typedef struct _EAlphabetIndex EAlphabetIndex;
+
+/* defined in e-alphabet-index-private.cpp, and used by by e-collator.c */
+
+E_ALPHABET_INDEX_LOCAL EAlphabetIndex *_e_alphabet_index_cxx_new_for_language (const gchar *language);
+E_ALPHABET_INDEX_LOCAL void _e_alphabet_index_cxx_free (EAlphabetIndex
*alphabet_index);
+E_ALPHABET_INDEX_LOCAL gint _e_alphabet_index_cxx_get_index (EAlphabetIndex
*alphabet_index,
+ const gchar *word);
+E_ALPHABET_INDEX_LOCAL gchar **_e_alphabet_index_cxx_get_labels (EAlphabetIndex
*alphabet_index,
+ gint *n_labels,
+ gint *underflow,
+ gint *inflow,
+ gint *overflow);
+
+G_END_DECLS
+
+#endif /* E_ALPHABET_INDEX_PRIVATE_H */
[
Date Prev][
Date Next] [
Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]