tor-browser

The Tor Browser
git clone https://git.dasho.dev/tor-browser.git
Log | Files | Refs | README | LICENSE

SQLCollations.cpp (7553B)


      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/intl/Collator.h"
      8 
      9 #include "SQLCollations.h"
     10 
     11 using mozilla::intl::Collator;
     12 
     13 namespace mozilla {
     14 namespace storage {
     15 
     16 ////////////////////////////////////////////////////////////////////////////////
     17 //// Local Helper Functions
     18 
     19 namespace {
     20 
     21 /**
     22 * Helper function for the UTF-8 locale collations.
     23 *
     24 * @param  aService
     25 *         The Service that owns the collator used by this collation.
     26 * @param  aLen1
     27 *         The number of bytes in aStr1.
     28 * @param  aStr1
     29 *         The string to be compared against aStr2 as provided by SQLite.  It
     30 *         must be a non-null-terminated char* buffer.
     31 * @param  aLen2
     32 *         The number of bytes in aStr2.
     33 * @param  aStr2
     34 *         The string to be compared against aStr1 as provided by SQLite.  It
     35 *         must be a non-null-terminated char* buffer.
     36 * @param  aSensitivity
     37 *         The sorting sensitivity.
     38 * @return aStr1 - aStr2.  That is, if aStr1 < aStr2, returns a negative number.
     39 *         If aStr1 > aStr2, returns a positive number.  If aStr1 == aStr2,
     40 *         returns 0.
     41 */
     42 int localeCollationHelper8(void* aService, int aLen1, const void* aStr1,
     43                           int aLen2, const void* aStr2,
     44                           Collator::Sensitivity aSensitivity) {
     45  NS_ConvertUTF8toUTF16 str1(static_cast<const char*>(aStr1), aLen1);
     46  NS_ConvertUTF8toUTF16 str2(static_cast<const char*>(aStr2), aLen2);
     47  Service* serv = static_cast<Service*>(aService);
     48  return serv->localeCompareStrings(str1, str2, aSensitivity);
     49 }
     50 
     51 /**
     52 * Helper function for the UTF-16 locale collations.
     53 *
     54 * @param  aService
     55 *         The Service that owns the collator used by this collation.
     56 * @param  aLen1
     57 *         The number of bytes (not characters) in aStr1.
     58 * @param  aStr1
     59 *         The string to be compared against aStr2 as provided by SQLite.  It
     60 *         must be a non-null-terminated char16_t* buffer.
     61 * @param  aLen2
     62 *         The number of bytes (not characters) in aStr2.
     63 * @param  aStr2
     64 *         The string to be compared against aStr1 as provided by SQLite.  It
     65 *         must be a non-null-terminated char16_t* buffer.
     66 * @param  aSensitivity
     67 *         The sorting sensitivity.
     68 * @return aStr1 - aStr2.  That is, if aStr1 < aStr2, returns a negative number.
     69 *         If aStr1 > aStr2, returns a positive number.  If aStr1 == aStr2,
     70 *         returns 0.
     71 */
     72 int localeCollationHelper16(void* aService, int aLen1, const void* aStr1,
     73                            int aLen2, const void* aStr2,
     74                            Collator::Sensitivity aSensitivity) {
     75  const char16_t* buf1 = static_cast<const char16_t*>(aStr1);
     76  const char16_t* buf2 = static_cast<const char16_t*>(aStr2);
     77 
     78  // The second argument to the nsDependentSubstring constructor is exclusive:
     79  // It points to the char16_t immediately following the last one in the target
     80  // substring.  Since aLen1 and aLen2 are in bytes, divide by sizeof(char16_t)
     81  // so that the pointer arithmetic is correct.
     82  nsDependentSubstring str1(buf1, buf1 + (aLen1 / sizeof(char16_t)));
     83  nsDependentSubstring str2(buf2, buf2 + (aLen2 / sizeof(char16_t)));
     84  Service* serv = static_cast<Service*>(aService);
     85  return serv->localeCompareStrings(str1, str2, aSensitivity);
     86 }
     87 
     88 // This struct is used only by registerCollations below, but ISO C++98 forbids
     89 // instantiating a template dependent on a locally-defined type.  Boo-urns!
     90 struct Collations {
     91  const char* zName;
     92  int enc;
     93  int (*xCompare)(void*, int, const void*, int, const void*);
     94 };
     95 
     96 }  // namespace
     97 
     98 ////////////////////////////////////////////////////////////////////////////////
     99 //// Exposed Functions
    100 
    101 int registerCollations(sqlite3* aDB, Service* aService) {
    102  Collations collations[] = {
    103      {"locale", SQLITE_UTF8, localeCollation8},
    104      {"locale_case_sensitive", SQLITE_UTF8, localeCollationCaseSensitive8},
    105      {"locale_accent_sensitive", SQLITE_UTF8, localeCollationAccentSensitive8},
    106      {"locale_case_accent_sensitive", SQLITE_UTF8,
    107       localeCollationCaseAccentSensitive8},
    108      {"locale", SQLITE_UTF16_ALIGNED, localeCollation16},
    109      {"locale_case_sensitive", SQLITE_UTF16_ALIGNED,
    110       localeCollationCaseSensitive16},
    111      {"locale_accent_sensitive", SQLITE_UTF16_ALIGNED,
    112       localeCollationAccentSensitive16},
    113      {"locale_case_accent_sensitive", SQLITE_UTF16_ALIGNED,
    114       localeCollationCaseAccentSensitive16},
    115  };
    116 
    117  int rv = SQLITE_OK;
    118  for (size_t i = 0; SQLITE_OK == rv && i < std::size(collations); ++i) {
    119    struct Collations* p = &collations[i];
    120    rv = ::sqlite3_create_collation(aDB, p->zName, p->enc, aService,
    121                                    p->xCompare);
    122  }
    123 
    124  return rv;
    125 }
    126 
    127 ////////////////////////////////////////////////////////////////////////////////
    128 //// SQL Collations
    129 
    130 int localeCollation8(void* aService, int aLen1, const void* aStr1, int aLen2,
    131                     const void* aStr2) {
    132  return localeCollationHelper8(aService, aLen1, aStr1, aLen2, aStr2,
    133                                Collator::Sensitivity::Base);
    134 }
    135 
    136 int localeCollationCaseSensitive8(void* aService, int aLen1, const void* aStr1,
    137                                  int aLen2, const void* aStr2) {
    138  return localeCollationHelper8(aService, aLen1, aStr1, aLen2, aStr2,
    139                                Collator::Sensitivity::Case);
    140 }
    141 
    142 int localeCollationAccentSensitive8(void* aService, int aLen1,
    143                                    const void* aStr1, int aLen2,
    144                                    const void* aStr2) {
    145  return localeCollationHelper8(aService, aLen1, aStr1, aLen2, aStr2,
    146                                Collator::Sensitivity::Accent);
    147 }
    148 
    149 int localeCollationCaseAccentSensitive8(void* aService, int aLen1,
    150                                        const void* aStr1, int aLen2,
    151                                        const void* aStr2) {
    152  return localeCollationHelper8(aService, aLen1, aStr1, aLen2, aStr2,
    153                                Collator::Sensitivity::Variant);
    154 }
    155 
    156 int localeCollation16(void* aService, int aLen1, const void* aStr1, int aLen2,
    157                      const void* aStr2) {
    158  return localeCollationHelper16(aService, aLen1, aStr1, aLen2, aStr2,
    159                                 Collator::Sensitivity::Base);
    160 }
    161 
    162 int localeCollationCaseSensitive16(void* aService, int aLen1, const void* aStr1,
    163                                   int aLen2, const void* aStr2) {
    164  return localeCollationHelper16(aService, aLen1, aStr1, aLen2, aStr2,
    165                                 Collator::Sensitivity::Case);
    166 }
    167 
    168 int localeCollationAccentSensitive16(void* aService, int aLen1,
    169                                     const void* aStr1, int aLen2,
    170                                     const void* aStr2) {
    171  return localeCollationHelper16(aService, aLen1, aStr1, aLen2, aStr2,
    172                                 Collator::Sensitivity::Accent);
    173 }
    174 
    175 int localeCollationCaseAccentSensitive16(void* aService, int aLen1,
    176                                         const void* aStr1, int aLen2,
    177                                         const void* aStr2) {
    178  return localeCollationHelper16(aService, aLen1, aStr1, aLen2, aStr2,
    179                                 Collator::Sensitivity::Variant);
    180 }
    181 
    182 }  // namespace storage
    183 }  // namespace mozilla