Arena pool macros don't want to die.
[mozilla-central.git] / storage / src / SQLCollations.cpp
blobf27aa9dae60453ea25abafa00821b86982bfbd32
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 * ***** BEGIN LICENSE BLOCK *****
4 * Version: MPL 1.1/GPL 2.0/LGPL 2.1
6 * The contents of this file are subject to the Mozilla Public License Version
7 * 1.1 (the "License"); you may not use this file except in compliance with
8 * the License. You may obtain a copy of the License at
9 * http://www.mozilla.org/MPL/
11 * Software distributed under the License is distributed on an "AS IS" basis,
12 * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
13 * for the specific language governing rights and limitations under the
14 * License.
16 * The Original Code is Mozilla Storage code.
18 * The Initial Developer of the Original Code is
19 * Mozilla Corporation.
20 * Portions created by the Initial Developer are Copyright (C) 2009
21 * the Initial Developer. All Rights Reserved.
23 * Contributor(s):
24 * Drew Willcoxon <adw@mozilla.com> (Original Author)
26 * Alternatively, the contents of this file may be used under the terms of
27 * either the GNU General Public License Version 2 or later (the "GPL"), or
28 * the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
29 * in which case the provisions of the GPL or the LGPL are applicable instead
30 * of those above. If you wish to allow use of your version of this file only
31 * under the terms of either the GPL or the LGPL, and not to allow others to
32 * use your version of this file under the terms of the MPL, indicate your
33 * decision by deleting the provisions above and replace them with the notice
34 * and other provisions required by the GPL or the LGPL. If you do not delete
35 * the provisions above, a recipient may use your version of this file under
36 * the terms of any one of the MPL, the GPL or the LGPL.
38 * ***** END LICENSE BLOCK ***** */
40 #include "SQLCollations.h"
42 namespace mozilla {
43 namespace storage {
45 ////////////////////////////////////////////////////////////////////////////////
46 //// Local Helper Functions
48 namespace {
50 /**
51 * Helper function for the UTF-8 locale collations.
53 * @param aService
54 * The Service that owns the nsICollation used by this collation.
55 * @param aLen1
56 * The number of bytes in aStr1.
57 * @param aStr1
58 * The string to be compared against aStr2 as provided by SQLite. It
59 * must be a non-null-terminated char* buffer.
60 * @param aLen2
61 * The number of bytes in aStr2.
62 * @param aStr2
63 * The string to be compared against aStr1 as provided by SQLite. It
64 * must be a non-null-terminated char* buffer.
65 * @param aComparisonStrength
66 * The sorting strength, one of the nsICollation constants.
67 * @return aStr1 - aStr2. That is, if aStr1 < aStr2, returns a negative number.
68 * If aStr1 > aStr2, returns a positive number. If aStr1 == aStr2,
69 * returns 0.
71 int
72 localeCollationHelper8(void *aService,
73 int aLen1,
74 const void *aStr1,
75 int aLen2,
76 const void *aStr2,
77 PRInt32 aComparisonStrength)
79 NS_ConvertUTF8toUTF16 str1(static_cast<const char *>(aStr1), aLen1);
80 NS_ConvertUTF8toUTF16 str2(static_cast<const char *>(aStr2), aLen2);
81 Service *serv = static_cast<Service *>(aService);
82 return serv->localeCompareStrings(str1, str2, aComparisonStrength);
85 /**
86 * Helper function for the UTF-16 locale collations.
88 * @param aService
89 * The Service that owns the nsICollation used by this collation.
90 * @param aLen1
91 * The number of bytes (not characters) in aStr1.
92 * @param aStr1
93 * The string to be compared against aStr2 as provided by SQLite. It
94 * must be a non-null-terminated PRUnichar* buffer.
95 * @param aLen2
96 * The number of bytes (not characters) in aStr2.
97 * @param aStr2
98 * The string to be compared against aStr1 as provided by SQLite. It
99 * must be a non-null-terminated PRUnichar* buffer.
100 * @param aComparisonStrength
101 * The sorting strength, one of the nsICollation constants.
102 * @return aStr1 - aStr2. That is, if aStr1 < aStr2, returns a negative number.
103 * If aStr1 > aStr2, returns a positive number. If aStr1 == aStr2,
104 * returns 0.
107 localeCollationHelper16(void *aService,
108 int aLen1,
109 const void *aStr1,
110 int aLen2,
111 const void *aStr2,
112 PRInt32 aComparisonStrength)
114 const PRUnichar *buf1 = static_cast<const PRUnichar *>(aStr1);
115 const PRUnichar *buf2 = static_cast<const PRUnichar *>(aStr2);
117 // The second argument to the nsDependentSubstring constructor is exclusive:
118 // It points to the PRUnichar immediately following the last one in the target
119 // substring. Since aLen1 and aLen2 are in bytes, divide by sizeof(PRUnichar)
120 // so that the pointer arithmetic is correct.
121 nsDependentSubstring str1(buf1, buf1 + (aLen1 / sizeof(PRUnichar)));
122 nsDependentSubstring str2(buf2, buf2 + (aLen2 / sizeof(PRUnichar)));
123 Service *serv = static_cast<Service *>(aService);
124 return serv->localeCompareStrings(str1, str2, aComparisonStrength);
127 } // anonymous namespace
129 ////////////////////////////////////////////////////////////////////////////////
130 //// Exposed Functions
133 registerCollations(sqlite3 *aDB,
134 Service *aService)
136 struct Collations {
137 const char *zName;
138 int enc;
139 int(*xCompare)(void*, int, const void*, int, const void*);
140 } collations[] = {
141 {"locale",
142 SQLITE_UTF8,
143 localeCollation8},
144 {"locale_case_sensitive",
145 SQLITE_UTF8,
146 localeCollationCaseSensitive8},
147 {"locale_accent_sensitive",
148 SQLITE_UTF8,
149 localeCollationAccentSensitive8},
150 {"locale_case_accent_sensitive",
151 SQLITE_UTF8,
152 localeCollationCaseAccentSensitive8},
153 {"locale",
154 SQLITE_UTF16,
155 localeCollation16},
156 {"locale_case_sensitive",
157 SQLITE_UTF16,
158 localeCollationCaseSensitive16},
159 {"locale_accent_sensitive",
160 SQLITE_UTF16,
161 localeCollationAccentSensitive16},
162 {"locale_case_accent_sensitive",
163 SQLITE_UTF16,
164 localeCollationCaseAccentSensitive16},
167 int rv = SQLITE_OK;
168 for (size_t i = 0; SQLITE_OK == rv && i < NS_ARRAY_LENGTH(collations); ++i) {
169 struct Collations *p = &collations[i];
170 rv = ::sqlite3_create_collation(aDB, p->zName, p->enc, aService,
171 p->xCompare);
174 return rv;
177 ////////////////////////////////////////////////////////////////////////////////
178 //// SQL Collations
181 localeCollation8(void *aService,
182 int aLen1,
183 const void *aStr1,
184 int aLen2,
185 const void *aStr2)
187 return localeCollationHelper8(aService, aLen1, aStr1, aLen2, aStr2,
188 nsICollation::kCollationCaseInSensitive);
192 localeCollationCaseSensitive8(void *aService,
193 int aLen1,
194 const void *aStr1,
195 int aLen2,
196 const void *aStr2)
198 return localeCollationHelper8(aService, aLen1, aStr1, aLen2, aStr2,
199 nsICollation::kCollationAccentInsenstive);
203 localeCollationAccentSensitive8(void *aService,
204 int aLen1,
205 const void *aStr1,
206 int aLen2,
207 const void *aStr2)
209 return localeCollationHelper8(aService, aLen1, aStr1, aLen2, aStr2,
210 nsICollation::kCollationCaseInsensitiveAscii);
214 localeCollationCaseAccentSensitive8(void *aService,
215 int aLen1,
216 const void *aStr1,
217 int aLen2,
218 const void *aStr2)
220 return localeCollationHelper8(aService, aLen1, aStr1, aLen2, aStr2,
221 nsICollation::kCollationCaseSensitive);
225 localeCollation16(void *aService,
226 int aLen1,
227 const void *aStr1,
228 int aLen2,
229 const void *aStr2)
231 return localeCollationHelper16(aService, aLen1, aStr1, aLen2, aStr2,
232 nsICollation::kCollationCaseInSensitive);
236 localeCollationCaseSensitive16(void *aService,
237 int aLen1,
238 const void *aStr1,
239 int aLen2,
240 const void *aStr2)
242 return localeCollationHelper16(aService, aLen1, aStr1, aLen2, aStr2,
243 nsICollation::kCollationAccentInsenstive);
247 localeCollationAccentSensitive16(void *aService,
248 int aLen1,
249 const void *aStr1,
250 int aLen2,
251 const void *aStr2)
253 return localeCollationHelper16(aService, aLen1, aStr1, aLen2, aStr2,
254 nsICollation::kCollationCaseInsensitiveAscii);
258 localeCollationCaseAccentSensitive16(void *aService,
259 int aLen1,
260 const void *aStr1,
261 int aLen2,
262 const void *aStr2)
264 return localeCollationHelper16(aService, aLen1, aStr1, aLen2, aStr2,
265 nsICollation::kCollationCaseSensitive);
268 } // namespace storage
269 } // namespace mozilla