/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- * vim: sw=2 ts=2 et lcs=trail\:.,tab\:>~ : * This Source Code Form is subject to the terms of the Mozilla Public * License, v. 2.0. If a copy of the MPL was not distributed with this * file, You can obtain one at http://mozilla.org/MPL/2.0/. */#include"mozilla/ArrayUtils.h"#include"SQLCollations.h"namespacemozilla{namespacestorage{//////////////////////////////////////////////////////////////////////////////////// Local Helper Functionsnamespace{/** * Helper function for the UTF-8 locale collations. * * @param aService * The Service that owns the nsICollation used by this collation. * @param aLen1 * The number of bytes in aStr1. * @param aStr1 * The string to be compared against aStr2 as provided by SQLite. It * must be a non-null-terminated char* buffer. * @param aLen2 * The number of bytes in aStr2. * @param aStr2 * The string to be compared against aStr1 as provided by SQLite. It * must be a non-null-terminated char* buffer. * @param aComparisonStrength * The sorting strength, one of the nsICollation constants. * @return aStr1 - aStr2. That is, if aStr1 < aStr2, returns a negative number. * If aStr1 > aStr2, returns a positive number. If aStr1 == aStr2, * returns 0. */intlocaleCollationHelper8(void*aService,intaLen1,constvoid*aStr1,intaLen2,constvoid*aStr2,int32_taComparisonStrength){NS_ConvertUTF8toUTF16str1(static_cast<constchar*>(aStr1),aLen1);NS_ConvertUTF8toUTF16str2(static_cast<constchar*>(aStr2),aLen2);Service*serv=static_cast<Service*>(aService);returnserv->localeCompareStrings(str1,str2,aComparisonStrength);}/** * Helper function for the UTF-16 locale collations. * * @param aService * The Service that owns the nsICollation used by this collation. * @param aLen1 * The number of bytes (not characters) in aStr1. * @param aStr1 * The string to be compared against aStr2 as provided by SQLite. It * must be a non-null-terminated char16_t* buffer. * @param aLen2 * The number of bytes (not characters) in aStr2. * @param aStr2 * The string to be compared against aStr1 as provided by SQLite. It * must be a non-null-terminated char16_t* buffer. * @param aComparisonStrength * The sorting strength, one of the nsICollation constants. * @return aStr1 - aStr2. That is, if aStr1 < aStr2, returns a negative number. * If aStr1 > aStr2, returns a positive number. If aStr1 == aStr2, * returns 0. */intlocaleCollationHelper16(void*aService,intaLen1,constvoid*aStr1,intaLen2,constvoid*aStr2,int32_taComparisonStrength){constchar16_t*buf1=static_cast<constchar16_t*>(aStr1);constchar16_t*buf2=static_cast<constchar16_t*>(aStr2);// The second argument to the nsDependentSubstring constructor is exclusive:// It points to the char16_t immediately following the last one in the target// substring. Since aLen1 and aLen2 are in bytes, divide by sizeof(char16_t)// so that the pointer arithmetic is correct.nsDependentSubstringstr1(buf1,buf1+(aLen1/sizeof(char16_t)));nsDependentSubstringstr2(buf2,buf2+(aLen2/sizeof(char16_t)));Service*serv=static_cast<Service*>(aService);returnserv->localeCompareStrings(str1,str2,aComparisonStrength);}// This struct is used only by registerCollations below, but ISO C++98 forbids// instantiating a template dependent on a locally-defined type. Boo-urns!structCollations{constchar*zName;intenc;int(*xCompare)(void*,int,constvoid*,int,constvoid*);};}// namespace//////////////////////////////////////////////////////////////////////////////////// Exposed FunctionsintregisterCollations(sqlite3*aDB,Service*aService){Collationscollations[]={{"locale",SQLITE_UTF8,localeCollation8},{"locale_case_sensitive",SQLITE_UTF8,localeCollationCaseSensitive8},{"locale_accent_sensitive",SQLITE_UTF8,localeCollationAccentSensitive8},{"locale_case_accent_sensitive",SQLITE_UTF8,localeCollationCaseAccentSensitive8},{"locale",SQLITE_UTF16,localeCollation16},{"locale_case_sensitive",SQLITE_UTF16,localeCollationCaseSensitive16},{"locale_accent_sensitive",SQLITE_UTF16,localeCollationAccentSensitive16},{"locale_case_accent_sensitive",SQLITE_UTF16,localeCollationCaseAccentSensitive16},};intrv=SQLITE_OK;for(size_ti=0;SQLITE_OK==rv&&i<ArrayLength(collations);++i){structCollations*p=&collations[i];rv=::sqlite3_create_collation(aDB,p->zName,p->enc,aService,p->xCompare);}returnrv;}//////////////////////////////////////////////////////////////////////////////////// SQL CollationsintlocaleCollation8(void*aService,intaLen1,constvoid*aStr1,intaLen2,constvoid*aStr2){returnlocaleCollationHelper8(aService,aLen1,aStr1,aLen2,aStr2,nsICollation::kCollationCaseInSensitive);}intlocaleCollationCaseSensitive8(void*aService,intaLen1,constvoid*aStr1,intaLen2,constvoid*aStr2){returnlocaleCollationHelper8(aService,aLen1,aStr1,aLen2,aStr2,nsICollation::kCollationAccentInsenstive);}intlocaleCollationAccentSensitive8(void*aService,intaLen1,constvoid*aStr1,intaLen2,constvoid*aStr2){returnlocaleCollationHelper8(aService,aLen1,aStr1,aLen2,aStr2,nsICollation::kCollationCaseInsensitiveAscii);}intlocaleCollationCaseAccentSensitive8(void*aService,intaLen1,constvoid*aStr1,intaLen2,constvoid*aStr2){returnlocaleCollationHelper8(aService,aLen1,aStr1,aLen2,aStr2,nsICollation::kCollationCaseSensitive);}intlocaleCollation16(void*aService,intaLen1,constvoid*aStr1,intaLen2,constvoid*aStr2){returnlocaleCollationHelper16(aService,aLen1,aStr1,aLen2,aStr2,nsICollation::kCollationCaseInSensitive);}intlocaleCollationCaseSensitive16(void*aService,intaLen1,constvoid*aStr1,intaLen2,constvoid*aStr2){returnlocaleCollationHelper16(aService,aLen1,aStr1,aLen2,aStr2,nsICollation::kCollationAccentInsenstive);}intlocaleCollationAccentSensitive16(void*aService,intaLen1,constvoid*aStr1,intaLen2,constvoid*aStr2){returnlocaleCollationHelper16(aService,aLen1,aStr1,aLen2,aStr2,nsICollation::kCollationCaseInsensitiveAscii);}intlocaleCollationCaseAccentSensitive16(void*aService,intaLen1,constvoid*aStr1,intaLen2,constvoid*aStr2){returnlocaleCollationHelper16(aService,aLen1,aStr1,aLen2,aStr2,nsICollation::kCollationCaseSensitive);}}// namespace storage}// namespace mozilla