~ubuntu-branches/ubuntu/utopic/evolution-data-server/utopic-proposed

« back to all changes in this revision

Viewing changes to libedataserver/e-alphabet-index-private.cpp

  • Committer: Package Import Robot
  • Author(s): Iain Lane
  • Date: 2014-06-13 12:02:14 UTC
  • mfrom: (1.1.116) (1.2.35 sid)
  • Revision ID: package-import@ubuntu.com-20140613120214-1zx93d8jxwt093aw
Tags: 3.12.2-1ubuntu1
* Merge with Debian, remaining changes:
  - debian/control: build depend on hardening-wrapper
  - Add build-depends and pass configure flag to enable Ubuntu Online
    Accounts support.
  - Filter out -Bsymbolic-functions from LDFLAGS (for future people
    wondering about this change, see e.g. BGO #594473 and duplicates).
  - Enable Ubuntu Online Accounts and split it and GOA into a separate
    package

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
1
/* -*- Mode: C; tab-width: 8; indent-tabs-mode: t; c-basic-offset: 8 -*- */
 
2
/*
 
3
 * Copyright (C) 2013 Intel Corporation
 
4
 *
 
5
 * This program is free software; you can redistribute it and/or modify it
 
6
 * under the terms of the GNU Lesser General Public License as published by
 
7
 * the Free Software Foundation.
 
8
 *
 
9
 * This program is distributed in the hope that it will be useful, but
 
10
 * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
 
11
 * or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
 
12
 * for more details.
 
13
 *
 
14
 * You should have received a copy of the GNU Lesser General Public License
 
15
 * along with this program; if not, see <http://www.gnu.org/licenses/>.
 
16
 *
 
17
 * Author: Tristan Van Berkom <tristanvb@openismus.com>
 
18
 */
 
19
 
 
20
#ifdef HAVE_CONFIG_H
 
21
#include <config.h>
 
22
#endif
 
23
 
 
24
#include "e-alphabet-index-private.h"
 
25
 
 
26
/* C++ standard library */
 
27
#include <string>
 
28
#include <memory>
 
29
 
 
30
/* system headers */
 
31
#include <langinfo.h>
 
32
#include <locale.h>
 
33
 
 
34
/* ICU headers */
 
35
#include <unicode/alphaindex.h>
 
36
 
 
37
using icu::AlphabeticIndex;
 
38
using icu::Locale;
 
39
 
 
40
struct _EAlphabetIndex {
 
41
        AlphabeticIndex *priv;
 
42
};
 
43
 
 
44
/* Create an AlphabetIndex for a given language code (normally
 
45
 * language codes are 2 letter codes, eg. 'en' = English 'es' = Spanish.
 
46
 */
 
47
EAlphabetIndex *
 
48
_e_alphabet_index_cxx_new_for_language (const gchar *language)
 
49
{
 
50
        UErrorCode status = U_ZERO_ERROR;
 
51
        EAlphabetIndex *alphabet_index;
 
52
 
 
53
        g_return_val_if_fail (language != NULL, NULL);
 
54
 
 
55
        alphabet_index = g_slice_new (EAlphabetIndex);
 
56
        alphabet_index->priv = new AlphabeticIndex (Locale (language), status);
 
57
 
 
58
        return alphabet_index;
 
59
}
 
60
 
 
61
/* Frees an EAlphabetIndex and it's associated resources
 
62
 */
 
63
void
 
64
_e_alphabet_index_cxx_free (EAlphabetIndex *alphabet_index)
 
65
{
 
66
        if (alphabet_index) {
 
67
                delete alphabet_index->priv;
 
68
                g_slice_free (EAlphabetIndex, alphabet_index);
 
69
        }
 
70
}
 
71
 
 
72
/* Fetch the given index where 'word' should sort
 
73
 */
 
74
gint
 
75
_e_alphabet_index_cxx_get_index (EAlphabetIndex  *alphabet_index,
 
76
                                 const gchar     *word)
 
77
{
 
78
        UErrorCode status = U_ZERO_ERROR;
 
79
        UnicodeString string;
 
80
        gint index;
 
81
 
 
82
        g_return_val_if_fail (alphabet_index != NULL, -1);
 
83
        g_return_val_if_fail (word != NULL, -1);
 
84
 
 
85
        string = icu::UnicodeString::fromUTF8 (word);
 
86
        index = alphabet_index->priv->getBucketIndex (string, status);
 
87
 
 
88
        return index;
 
89
}
 
90
 
 
91
/* Fetch the list of labels in the alphabetic index.
 
92
 *
 
93
 * Returns an array of UTF-8 labels for each alphabetic
 
94
 * index position 'n_labels' long, the returned array
 
95
 * of strings can be freed with g_strfreev()
 
96
 *
 
97
 * The underflow, overflow and inflow parameters will be
 
98
 * set to the appropriate indexes (reffers to indexes in the
 
99
 * returned labels).
 
100
 */
 
101
gchar **
 
102
_e_alphabet_index_cxx_get_labels (EAlphabetIndex  *alphabet_index,
 
103
                                  gint            *n_labels,
 
104
                                  gint            *underflow,
 
105
                                  gint            *inflow,
 
106
                                  gint            *overflow)
 
107
{
 
108
        UErrorCode status = U_ZERO_ERROR;
 
109
        gchar **labels = NULL;
 
110
        gint count, i;
 
111
 
 
112
        g_return_val_if_fail (alphabet_index != NULL, NULL);
 
113
        g_return_val_if_fail (n_labels != NULL, NULL);
 
114
        g_return_val_if_fail (underflow != NULL, NULL);
 
115
        g_return_val_if_fail (inflow != NULL, NULL);
 
116
        g_return_val_if_fail (overflow != NULL, NULL);
 
117
 
 
118
        count = alphabet_index->priv->getBucketCount (status);
 
119
 
 
120
        labels = g_new0 (gchar *, count + 1);
 
121
 
 
122
        /* In case they are missing, they should be set to -1 */
 
123
        *underflow = *inflow = *overflow = -1;
 
124
 
 
125
        /* Iterate over the AlphabeticIndex and collect UTF-8 versions
 
126
         * of the bucket labels
 
127
         */
 
128
        alphabet_index->priv->resetBucketIterator (status);
 
129
 
 
130
        for (i = 0; alphabet_index->priv->nextBucket (status); i++) {
 
131
                UAlphabeticIndexLabelType label_type;
 
132
                UnicodeString ustring;
 
133
                std::string string;
 
134
 
 
135
                label_type = alphabet_index->priv->getBucketLabelType ();
 
136
 
 
137
                switch (label_type) {
 
138
                case U_ALPHAINDEX_UNDERFLOW: *underflow = i; break;
 
139
                case U_ALPHAINDEX_INFLOW:    *inflow    = i; break;
 
140
                case U_ALPHAINDEX_OVERFLOW:  *overflow  = i; break;
 
141
                case U_ALPHAINDEX_NORMAL:  /* do nothing */  break;
 
142
                }
 
143
 
 
144
                /* This is annoyingly heavy but not a function called
 
145
                 * very often, this could be improved by calling icu::UnicodeString::toUTF8()
 
146
                 * and implementing ICU's ByteSync class using glib's memory allocator.
 
147
                 */
 
148
                ustring   = alphabet_index->priv->getBucketLabel ();
 
149
                string    = ustring.toUTF8String (string);
 
150
                labels[i] = g_strdup (string.c_str());
 
151
        }
 
152
 
 
153
        *n_labels = count;
 
154
 
 
155
        return labels;
 
156
}