/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 |