Coverage Report

Created: 2018-09-25 14:53

/src/mozilla-central/storage/SQLCollations.cpp
Line
Count
Source (jump to first uncovered line)
1
/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*-
2
 * vim: sw=2 ts=2 et lcs=trail\:.,tab\:>~ :
3
 * This Source Code Form is subject to the terms of the Mozilla Public
4
 * License, v. 2.0. If a copy of the MPL was not distributed with this
5
 * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
6
7
#include "mozilla/ArrayUtils.h"
8
9
#include "SQLCollations.h"
10
11
namespace mozilla {
12
namespace storage {
13
14
////////////////////////////////////////////////////////////////////////////////
15
//// Local Helper Functions
16
17
namespace {
18
19
/**
20
 * Helper function for the UTF-8 locale collations.
21
 *
22
 * @param  aService
23
 *         The Service that owns the nsICollation used by this collation.
24
 * @param  aLen1
25
 *         The number of bytes in aStr1.
26
 * @param  aStr1
27
 *         The string to be compared against aStr2 as provided by SQLite.  It
28
 *         must be a non-null-terminated char* buffer.
29
 * @param  aLen2
30
 *         The number of bytes in aStr2.
31
 * @param  aStr2
32
 *         The string to be compared against aStr1 as provided by SQLite.  It
33
 *         must be a non-null-terminated char* buffer.
34
 * @param  aComparisonStrength
35
 *         The sorting strength, one of the nsICollation constants.
36
 * @return aStr1 - aStr2.  That is, if aStr1 < aStr2, returns a negative number.
37
 *         If aStr1 > aStr2, returns a positive number.  If aStr1 == aStr2,
38
 *         returns 0.
39
 */
40
int
41
localeCollationHelper8(void *aService,
42
                       int aLen1,
43
                       const void *aStr1,
44
                       int aLen2,
45
                       const void *aStr2,
46
                       int32_t aComparisonStrength)
47
0
{
48
0
  NS_ConvertUTF8toUTF16 str1(static_cast<const char *>(aStr1), aLen1);
49
0
  NS_ConvertUTF8toUTF16 str2(static_cast<const char *>(aStr2), aLen2);
50
0
  Service *serv = static_cast<Service *>(aService);
51
0
  return serv->localeCompareStrings(str1, str2, aComparisonStrength);
52
0
}
53
54
/**
55
 * Helper function for the UTF-16 locale collations.
56
 *
57
 * @param  aService
58
 *         The Service that owns the nsICollation used by this collation.
59
 * @param  aLen1
60
 *         The number of bytes (not characters) in aStr1.
61
 * @param  aStr1
62
 *         The string to be compared against aStr2 as provided by SQLite.  It
63
 *         must be a non-null-terminated char16_t* buffer.
64
 * @param  aLen2
65
 *         The number of bytes (not characters) in aStr2.
66
 * @param  aStr2
67
 *         The string to be compared against aStr1 as provided by SQLite.  It
68
 *         must be a non-null-terminated char16_t* buffer.
69
 * @param  aComparisonStrength
70
 *         The sorting strength, one of the nsICollation constants.
71
 * @return aStr1 - aStr2.  That is, if aStr1 < aStr2, returns a negative number.
72
 *         If aStr1 > aStr2, returns a positive number.  If aStr1 == aStr2,
73
 *         returns 0.
74
 */
75
int
76
localeCollationHelper16(void *aService,
77
                        int aLen1,
78
                        const void *aStr1,
79
                        int aLen2,
80
                        const void *aStr2,
81
                        int32_t aComparisonStrength)
82
0
{
83
0
  const char16_t *buf1 = static_cast<const char16_t *>(aStr1);
84
0
  const char16_t *buf2 = static_cast<const char16_t *>(aStr2);
85
0
86
0
  // The second argument to the nsDependentSubstring constructor is exclusive:
87
0
  // It points to the char16_t immediately following the last one in the target
88
0
  // substring.  Since aLen1 and aLen2 are in bytes, divide by sizeof(char16_t)
89
0
  // so that the pointer arithmetic is correct.
90
0
  nsDependentSubstring str1(buf1, buf1 + (aLen1 / sizeof(char16_t)));
91
0
  nsDependentSubstring str2(buf2, buf2 + (aLen2 / sizeof(char16_t)));
92
0
  Service *serv = static_cast<Service *>(aService);
93
0
  return serv->localeCompareStrings(str1, str2, aComparisonStrength);
94
0
}
95
96
// This struct is used only by registerCollations below, but ISO C++98 forbids
97
// instantiating a template dependent on a locally-defined type.  Boo-urns!
98
struct Collations {
99
  const char *zName;
100
  int enc;
101
  int(*xCompare)(void*, int, const void*, int, const void*);
102
};
103
104
} // namespace
105
106
////////////////////////////////////////////////////////////////////////////////
107
//// Exposed Functions
108
109
int
110
registerCollations(sqlite3 *aDB,
111
                   Service *aService)
112
0
{
113
0
  Collations collations[] = {
114
0
    {"locale",
115
0
     SQLITE_UTF8,
116
0
     localeCollation8},
117
0
    {"locale_case_sensitive",
118
0
     SQLITE_UTF8,
119
0
     localeCollationCaseSensitive8},
120
0
    {"locale_accent_sensitive",
121
0
     SQLITE_UTF8,
122
0
     localeCollationAccentSensitive8},
123
0
    {"locale_case_accent_sensitive",
124
0
     SQLITE_UTF8,
125
0
     localeCollationCaseAccentSensitive8},
126
0
    {"locale",
127
0
     SQLITE_UTF16,
128
0
     localeCollation16},
129
0
    {"locale_case_sensitive",
130
0
     SQLITE_UTF16,
131
0
     localeCollationCaseSensitive16},
132
0
    {"locale_accent_sensitive",
133
0
     SQLITE_UTF16,
134
0
     localeCollationAccentSensitive16},
135
0
    {"locale_case_accent_sensitive",
136
0
     SQLITE_UTF16,
137
0
     localeCollationCaseAccentSensitive16},
138
0
  };
139
0
140
0
  int rv = SQLITE_OK;
141
0
  for (size_t i = 0; SQLITE_OK == rv && i < ArrayLength(collations); ++i) {
142
0
    struct Collations *p = &collations[i];
143
0
    rv = ::sqlite3_create_collation(aDB, p->zName, p->enc, aService,
144
0
                                    p->xCompare);
145
0
  }
146
0
147
0
  return rv;
148
0
}
149
150
////////////////////////////////////////////////////////////////////////////////
151
//// SQL Collations
152
153
int
154
localeCollation8(void *aService,
155
                 int aLen1,
156
                 const void *aStr1,
157
                 int aLen2,
158
                 const void *aStr2)
159
0
{
160
0
  return localeCollationHelper8(aService, aLen1, aStr1, aLen2, aStr2,
161
0
                                nsICollation::kCollationCaseInSensitive);
162
0
}
163
164
int
165
localeCollationCaseSensitive8(void *aService,
166
                              int aLen1,
167
                              const void *aStr1,
168
                              int aLen2,
169
                              const void *aStr2)
170
0
{
171
0
  return localeCollationHelper8(aService, aLen1, aStr1, aLen2, aStr2,
172
0
                                nsICollation::kCollationAccentInsenstive);
173
0
}
174
175
int
176
localeCollationAccentSensitive8(void *aService,
177
                                int aLen1,
178
                                const void *aStr1,
179
                                int aLen2,
180
                                const void *aStr2)
181
0
{
182
0
  return localeCollationHelper8(aService, aLen1, aStr1, aLen2, aStr2,
183
0
                                nsICollation::kCollationCaseInsensitiveAscii);
184
0
}
185
186
int
187
localeCollationCaseAccentSensitive8(void *aService,
188
                                    int aLen1,
189
                                    const void *aStr1,
190
                                    int aLen2,
191
                                    const void *aStr2)
192
0
{
193
0
  return localeCollationHelper8(aService, aLen1, aStr1, aLen2, aStr2,
194
0
                                nsICollation::kCollationCaseSensitive);
195
0
}
196
197
int
198
localeCollation16(void *aService,
199
                  int aLen1,
200
                  const void *aStr1,
201
                  int aLen2,
202
                  const void *aStr2)
203
0
{
204
0
  return localeCollationHelper16(aService, aLen1, aStr1, aLen2, aStr2,
205
0
                                 nsICollation::kCollationCaseInSensitive);
206
0
}
207
208
int
209
localeCollationCaseSensitive16(void *aService,
210
                               int aLen1,
211
                               const void *aStr1,
212
                               int aLen2,
213
                               const void *aStr2)
214
0
{
215
0
  return localeCollationHelper16(aService, aLen1, aStr1, aLen2, aStr2,
216
0
                                 nsICollation::kCollationAccentInsenstive);
217
0
}
218
219
int
220
localeCollationAccentSensitive16(void *aService,
221
                                 int aLen1,
222
                                 const void *aStr1,
223
                                 int aLen2,
224
                                 const void *aStr2)
225
0
{
226
0
  return localeCollationHelper16(aService, aLen1, aStr1, aLen2, aStr2,
227
0
                                 nsICollation::kCollationCaseInsensitiveAscii);
228
0
}
229
230
int
231
localeCollationCaseAccentSensitive16(void *aService,
232
                                     int aLen1,
233
                                     const void *aStr1,
234
                                     int aLen2,
235
                                     const void *aStr2)
236
0
{
237
0
  return localeCollationHelper16(aService, aLen1, aStr1, aLen2, aStr2,
238
0
                                 nsICollation::kCollationCaseSensitive);
239
0
}
240
241
} // namespace storage
242
} // namespace mozilla