[evolution-data-server/openismus-work-master: 39/74] Added EAlphabetIndex



commit 4fd9e11cbf9cb1ea2435aabfadb56bfdda65e0ff
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 563c304..045fe27 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]