···88#define unimpErr -4
99#define fnfErr -43 // file not found
1010#define paramErr -50
1111+#define kUCOutputBufferTooSmall -25340
11121213#endif
+9-2
src/CoreServices/MacLocales.cpp
···4949 iconv_close(g_icUtf32ToUtf16);
5050}
51515252-static int getLocaleUID(const std::string& str)
5252+namespace Darling
5353+{
5454+5555+int getLocaleUID(const std::string& str)
5356{
5457 auto it = g_mapLocaleString.find(str);
5558 if (it != g_mapLocaleString.end())
···6770 }
6871}
69727070-static const char* getLocaleString(int uid)
7373+const char* getLocaleString(int uid)
7174{
7275 auto it = g_mapLocaleStringRev.find(uid);
7376 if (it != g_mapLocaleStringRev.end())
···7578 else
7679 return "INVALID";
7780}
8181+8282+}
8383+8484+using namespace Darling;
78857986OSStatus LocaleRefFromLangOrRegionCode(LangCode langCode, RegionCode regionCode, LocaleRef* refOut)
8087{
+188
src/CoreServices/UnicodeUtilities.cpp
···11+/*
22+This file is part of Darling.
33+44+Copyright (C) 2013 Lubos Dolezel
55+66+Darling is free software: you can redistribute it and/or modify
77+it under the terms of the GNU General Public License as published by
88+the Free Software Foundation, either version 3 of the License, or
99+(at your option) any later version.
1010+1111+Darling is distributed in the hope that it will be useful,
1212+but WITHOUT ANY WARRANTY; without even the implied warranty of
1313+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
1414+GNU General Public License for more details.
1515+1616+You should have received a copy of the GNU General Public License
1717+along with Darling. If not, see <http://www.gnu.org/licenses/>.
1818+*/
1919+2020+2121+#include "UnicodeUtilities.h"
2222+#include <unicode/coll.h>
2323+#include <unicode/sortkey.h>
2424+#include <string>
2525+#include <cstring>
2626+#include "MacErrors.h"
2727+2828+namespace Darling
2929+{
3030+ int getLocaleUID(const std::string& str);
3131+ const char* getLocaleString(int uid);
3232+}
3333+3434+static UColAttributeValue optsToColAttr(uint32_t options)
3535+{
3636+ UColAttributeValue strength = UCOL_DEFAULT_STRENGTH;
3737+3838+ if (options & kUCCollateComposeInsensitiveMask)
3939+ strength = UCOL_QUATERNARY;
4040+ //if (options & kUCCollateWidthInsensitiveMask)
4141+ if (options & kUCCollateCaseInsensitiveMask)
4242+ strength = UCOL_SECONDARY;
4343+ if (options & kUCCollateDiacritInsensitiveMask)
4444+ strength = UCOL_PRIMARY;
4545+4646+ return strength;
4747+}
4848+4949+OSStatus UCCreateCollator(LocaleRef locale, LocaleOperationVariant opVariant, uint32_t options, CollatorRef* collator)
5050+{
5151+ UErrorCode code;
5252+ Collator* c = Collator::createInstance(Darling::getLocaleString(locale), code);
5353+5454+ *collator = c;
5555+5656+ if (!c)
5757+ return paramErr;
5858+5959+ c->setAttribute(UCOL_STRENGTH, optsToColAttr(options), code);
6060+ return noErr;
6161+}
6262+6363+OSStatus UCGetCollationKey(CollatorRef collator, const UniChar* text, unsigned long textlen, unsigned long maxKeySize, unsigned long* actualKeySize, uint32_t* collationKey)
6464+{
6565+ if (!text || !actualKeySize || !collationKey || !collator)
6666+ return paramErr;
6767+6868+ UnicodeString str1((const char*) text, textlen*2, "UTF-16");
6969+ Collator* c = static_cast<Collator*>(collator);
7070+ CollationKey key;
7171+ UErrorCode code;
7272+ int32_t count;
7373+ const uint8_t* data;
7474+7575+ *actualKeySize = 0;
7676+ c->getCollationKey(str1, key, code);
7777+7878+ if (code != U_ZERO_ERROR)
7979+ return -1;
8080+8181+ data = key.getByteArray(count);
8282+ if (count > sizeof(uint32_t)*maxKeySize)
8383+ return kUCOutputBufferTooSmall;
8484+8585+ *actualKeySize = (count + sizeof(uint32_t) - 1) / sizeof(uint32_t);
8686+ memset(collationKey, 0, *actualKeySize);
8787+ memcpy(collationKey, data, count);
8888+8989+ return noErr;
9090+}
9191+9292+OSStatus UCCompareCollationKeys(const uint32_t* key1, unsigned long key1len, const uint32_t* key2, unsigned long key2len, Boolean* equiv, int32_t* order)
9393+{
9494+ if (!equiv && !order)
9595+ return paramErr;
9696+9797+ CollationKey ckey1((const uint8_t*)key1, key1len);
9898+ CollationKey ckey2((const uint8_t*)key2, key2len);
9999+ UCollationResult result;
100100+ UErrorCode code;
101101+102102+ result = ckey1.compareTo(ckey2, code);
103103+104104+ if (code != U_ZERO_ERROR)
105105+ return -1;
106106+107107+ if (equiv != nullptr)
108108+ *equiv = result == UCOL_EQUAL;
109109+110110+ if (order != nullptr)
111111+ {
112112+ if (result == UCOL_GREATER)
113113+ *order = 1;
114114+ else if (result == UCOL_LESS)
115115+ *order = -1;
116116+ else
117117+ *order = 0;
118118+ }
119119+120120+ return noErr;
121121+}
122122+123123+OSStatus UCCompareText(CollatorRef collator, const UniChar* text1, unsigned long text1len, const UniChar* text2, unsigned long text2len, Boolean* equiv, int32_t* order)
124124+{
125125+ if (!equiv && !order)
126126+ return paramErr;
127127+ if (!text1 || !text2 || !collator)
128128+ return paramErr;
129129+130130+ UnicodeString str1((const char*) text1, text1len*2, "UTF-16");
131131+ UnicodeString str2((const char*) text2, text2len*2, "UTF-16");
132132+ Collator* c = static_cast<Collator*>(collator);
133133+ UCollationResult result;
134134+ UErrorCode code;
135135+136136+ result = c->compare(str1, str2, code);
137137+138138+ if (code != U_ZERO_ERROR)
139139+ return -1;
140140+141141+ if (equiv != nullptr)
142142+ *equiv = result == UCOL_EQUAL;
143143+144144+ if (order != nullptr)
145145+ {
146146+ if (result == UCOL_GREATER)
147147+ *order = 1;
148148+ else if (result == UCOL_LESS)
149149+ *order = -1;
150150+ else
151151+ *order = 0;
152152+ }
153153+154154+ return noErr;
155155+}
156156+157157+OSStatus UCDisposeCollator(CollatorRef* collator)
158158+{
159159+ delete static_cast<Collator*>(*collator);
160160+ *collator = nullptr;
161161+ return noErr;
162162+}
163163+164164+OSStatus UCCompareTextDefault(uint32_t options, const UniChar* text1, unsigned long text1len, const UniChar* text2, unsigned long text2len, Boolean* equiv, int32_t* order)
165165+{
166166+ UErrorCode code;
167167+ Collator* col = Collator::createInstance(code);
168168+ OSStatus rv;
169169+170170+ col->setAttribute(UCOL_STRENGTH, optsToColAttr(options), code);
171171+ rv = UCCompareText(col, text1, text1len, text2, text2len, equiv, order);
172172+173173+ delete col;
174174+ return rv;
175175+}
176176+177177+OSStatus UCCompareTextNoLocale(uint32_t options, const UniChar* text1, unsigned long text1len, const UniChar* text2, unsigned long text2len, Boolean* equiv, int32_t* order)
178178+{
179179+ UErrorCode code;
180180+ Collator* col = Collator::createInstance(Locale::getRoot(), code); // is getRoot correct?
181181+ OSStatus rv;
182182+183183+ col->setAttribute(UCOL_STRENGTH, optsToColAttr(options), code);
184184+ rv = UCCompareText(col, text1, text1len, text2, text2len, equiv, order);
185185+186186+ delete col;
187187+ return rv;
188188+}
+52
src/CoreServices/UnicodeUtilities.h
···11+/*
22+This file is part of Darling.
33+44+Copyright (C) 2013 Lubos Dolezel
55+66+Darling is free software: you can redistribute it and/or modify
77+it under the terms of the GNU General Public License as published by
88+the Free Software Foundation, either version 3 of the License, or
99+(at your option) any later version.
1010+1111+Darling is distributed in the hope that it will be useful,
1212+but WITHOUT ANY WARRANTY; without even the implied warranty of
1313+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
1414+GNU General Public License for more details.
1515+1616+You should have received a copy of the GNU General Public License
1717+along with Darling. If not, see <http://www.gnu.org/licenses/>.
1818+*/
1919+120#ifndef UNICODEUTILITIES_H
221#define UNICODEUTILITIES_H
2222+#include "MacTypes.h"
2323+#include "MacLocales.h"
2424+#include <stdint.h>
3252626+extern "C"
2727+{
4282929+typedef void* CollatorRef;
3030+enum : uint32_t
3131+{
3232+ kUCCollateComposeInsensitiveMask = 0x2,
3333+ kUCCollateWidthInsensitiveMask = 0x4,
3434+ kUCCollateCaseInsensitiveMask = 0x8,
3535+ kUCCollateDiacritInsensitiveMask = 0x10,
3636+ kUCCollatePunctuationSignificantMask = 0x8000,
3737+ kUCCollateDigitsOverrideMask = 0x10000,
3838+ kUCCollateDigitsAsNumberMask = 0x20000
3939+};
4040+4141+4242+OSStatus UCCreateCollator(LocaleRef locale, LocaleOperationVariant opVariant, uint32_t options, CollatorRef* collator);
4343+4444+OSStatus UCGetCollationKey(CollatorRef collator, const UniChar * text, unsigned long textlen, unsigned long maxKeySize, unsigned long* actualKeySize, uint32_t* collationKey);
4545+4646+OSStatus UCCompareCollationKeys(const uint32_t* key1, unsigned long key1len, const uint32_t* key2, unsigned long key2len, Boolean* equiv, int32_t* order);
4747+4848+OSStatus UCCompareText(CollatorRef collator, const UniChar* text1, unsigned long text1len, const UniChar* text2, unsigned long text2len, Boolean* equiv, int32_t* order);
4949+5050+OSStatus UCDisposeCollator(CollatorRef* collator);
5151+5252+OSStatus UCCompareTextDefault(uint32_t options, const UniChar* text1, unsigned long text1len, const UniChar* text2, unsigned long text2len, Boolean* equiv, int32_t* order);
5353+5454+OSStatus UCCompareTextNoLocale(uint32_t options, const UniChar* text1, unsigned long text1len, const UniChar* text2, unsigned long text2len, Boolean* equiv, int32_t* order);
5555+5656+}
557658#endif