Bug 1527719 [wpt PR 15359] - KV storage: make backingStore return the same frozen...
[gecko.git] / storage / SQLCollations.cpp
blob56ba44da9c5fd38681ccf5d2aee8d59440537637
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/. */
7 #include "mozilla/ArrayUtils.h"
9 #include "SQLCollations.h"
11 namespace mozilla {
12 namespace storage {
14 ////////////////////////////////////////////////////////////////////////////////
15 //// Local Helper Functions
17 namespace {
19 /**
20 * Helper function for the UTF-8 locale collations.
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.
40 int localeCollationHelper8(void *aService, int aLen1, const void *aStr1,
41 int aLen2, const void *aStr2,
42 int32_t aComparisonStrength) {
43 NS_ConvertUTF8toUTF16 str1(static_cast<const char *>(aStr1), aLen1);
44 NS_ConvertUTF8toUTF16 str2(static_cast<const char *>(aStr2), aLen2);
45 Service *serv = static_cast<Service *>(aService);
46 return serv->localeCompareStrings(str1, str2, aComparisonStrength);
49 /**
50 * Helper function for the UTF-16 locale collations.
52 * @param aService
53 * The Service that owns the nsICollation used by this collation.
54 * @param aLen1
55 * The number of bytes (not characters) in aStr1.
56 * @param aStr1
57 * The string to be compared against aStr2 as provided by SQLite. It
58 * must be a non-null-terminated char16_t* buffer.
59 * @param aLen2
60 * The number of bytes (not characters) in aStr2.
61 * @param aStr2
62 * The string to be compared against aStr1 as provided by SQLite. It
63 * must be a non-null-terminated char16_t* buffer.
64 * @param aComparisonStrength
65 * The sorting strength, one of the nsICollation constants.
66 * @return aStr1 - aStr2. That is, if aStr1 < aStr2, returns a negative number.
67 * If aStr1 > aStr2, returns a positive number. If aStr1 == aStr2,
68 * returns 0.
70 int localeCollationHelper16(void *aService, int aLen1, const void *aStr1,
71 int aLen2, const void *aStr2,
72 int32_t aComparisonStrength) {
73 const char16_t *buf1 = static_cast<const char16_t *>(aStr1);
74 const char16_t *buf2 = static_cast<const char16_t *>(aStr2);
76 // The second argument to the nsDependentSubstring constructor is exclusive:
77 // It points to the char16_t immediately following the last one in the target
78 // substring. Since aLen1 and aLen2 are in bytes, divide by sizeof(char16_t)
79 // so that the pointer arithmetic is correct.
80 nsDependentSubstring str1(buf1, buf1 + (aLen1 / sizeof(char16_t)));
81 nsDependentSubstring str2(buf2, buf2 + (aLen2 / sizeof(char16_t)));
82 Service *serv = static_cast<Service *>(aService);
83 return serv->localeCompareStrings(str1, str2, aComparisonStrength);
86 // This struct is used only by registerCollations below, but ISO C++98 forbids
87 // instantiating a template dependent on a locally-defined type. Boo-urns!
88 struct Collations {
89 const char *zName;
90 int enc;
91 int (*xCompare)(void *, int, const void *, int, const void *);
94 } // namespace
96 ////////////////////////////////////////////////////////////////////////////////
97 //// Exposed Functions
99 int registerCollations(sqlite3 *aDB, Service *aService) {
100 Collations collations[] = {
101 {"locale", SQLITE_UTF8, localeCollation8},
102 {"locale_case_sensitive", SQLITE_UTF8, localeCollationCaseSensitive8},
103 {"locale_accent_sensitive", SQLITE_UTF8, localeCollationAccentSensitive8},
104 {"locale_case_accent_sensitive", SQLITE_UTF8,
105 localeCollationCaseAccentSensitive8},
106 {"locale", SQLITE_UTF16, localeCollation16},
107 {"locale_case_sensitive", SQLITE_UTF16, localeCollationCaseSensitive16},
108 {"locale_accent_sensitive", SQLITE_UTF16,
109 localeCollationAccentSensitive16},
110 {"locale_case_accent_sensitive", SQLITE_UTF16,
111 localeCollationCaseAccentSensitive16},
114 int rv = SQLITE_OK;
115 for (size_t i = 0; SQLITE_OK == rv && i < ArrayLength(collations); ++i) {
116 struct Collations *p = &collations[i];
117 rv = ::sqlite3_create_collation(aDB, p->zName, p->enc, aService,
118 p->xCompare);
121 return rv;
124 ////////////////////////////////////////////////////////////////////////////////
125 //// SQL Collations
127 int localeCollation8(void *aService, int aLen1, const void *aStr1, int aLen2,
128 const void *aStr2) {
129 return localeCollationHelper8(aService, aLen1, aStr1, aLen2, aStr2,
130 nsICollation::kCollationCaseInSensitive);
133 int localeCollationCaseSensitive8(void *aService, int aLen1, const void *aStr1,
134 int aLen2, const void *aStr2) {
135 return localeCollationHelper8(aService, aLen1, aStr1, aLen2, aStr2,
136 nsICollation::kCollationAccentInsenstive);
139 int localeCollationAccentSensitive8(void *aService, int aLen1,
140 const void *aStr1, int aLen2,
141 const void *aStr2) {
142 return localeCollationHelper8(aService, aLen1, aStr1, aLen2, aStr2,
143 nsICollation::kCollationCaseInsensitiveAscii);
146 int localeCollationCaseAccentSensitive8(void *aService, int aLen1,
147 const void *aStr1, int aLen2,
148 const void *aStr2) {
149 return localeCollationHelper8(aService, aLen1, aStr1, aLen2, aStr2,
150 nsICollation::kCollationCaseSensitive);
153 int localeCollation16(void *aService, int aLen1, const void *aStr1, int aLen2,
154 const void *aStr2) {
155 return localeCollationHelper16(aService, aLen1, aStr1, aLen2, aStr2,
156 nsICollation::kCollationCaseInSensitive);
159 int localeCollationCaseSensitive16(void *aService, int aLen1, const void *aStr1,
160 int aLen2, const void *aStr2) {
161 return localeCollationHelper16(aService, aLen1, aStr1, aLen2, aStr2,
162 nsICollation::kCollationAccentInsenstive);
165 int localeCollationAccentSensitive16(void *aService, int aLen1,
166 const void *aStr1, int aLen2,
167 const void *aStr2) {
168 return localeCollationHelper16(aService, aLen1, aStr1, aLen2, aStr2,
169 nsICollation::kCollationCaseInsensitiveAscii);
172 int localeCollationCaseAccentSensitive16(void *aService, int aLen1,
173 const void *aStr1, int aLen2,
174 const void *aStr2) {
175 return localeCollationHelper16(aService, aLen1, aStr1, aLen2, aStr2,
176 nsICollation::kCollationCaseSensitive);
179 } // namespace storage
180 } // namespace mozilla