Add our implementation for wcscoll() and wcsxfrm().
* add Wcscoll() and Wcsxfrm() ICU locale backend * provide implementations of wcscoll() and wcsxfrm() that are using the respective methods of the locale backend
This commit is contained in:
@@ -29,6 +29,10 @@ public:
|
|||||||
status_t Strcoll(const char* a, const char* b, int& out);
|
status_t Strcoll(const char* a, const char* b, int& out);
|
||||||
status_t Strxfrm(char* out, const char* in, size_t size,
|
status_t Strxfrm(char* out, const char* in, size_t size,
|
||||||
size_t& outSize);
|
size_t& outSize);
|
||||||
|
status_t Wcscoll(const wchar_t* a, const wchar_t* b,
|
||||||
|
int& out);
|
||||||
|
status_t Wcsxfrm(wchar_t* out, const wchar_t* in,
|
||||||
|
size_t size, size_t& outSize);
|
||||||
|
|
||||||
private:
|
private:
|
||||||
status_t _ToUnicodeString(const char* in,
|
status_t _ToUnicodeString(const char* in,
|
||||||
|
|||||||
@@ -61,6 +61,10 @@ public:
|
|||||||
virtual status_t Strcoll(const char* a, const char* b, int& out);
|
virtual status_t Strcoll(const char* a, const char* b, int& out);
|
||||||
virtual status_t Strxfrm(char* out, const char* in, size_t size,
|
virtual status_t Strxfrm(char* out, const char* in, size_t size,
|
||||||
size_t& outSize);
|
size_t& outSize);
|
||||||
|
virtual status_t Wcscoll(const wchar_t* a, const wchar_t* b,
|
||||||
|
int& out);
|
||||||
|
virtual status_t Wcsxfrm(wchar_t* out, const wchar_t* in,
|
||||||
|
size_t size, size_t& outSize);
|
||||||
|
|
||||||
virtual status_t TZSet(const char* timeZoneID, const char* tz);
|
virtual status_t TZSet(const char* timeZoneID, const char* tz);
|
||||||
virtual status_t Localtime(const time_t* inTime,
|
virtual status_t Localtime(const time_t* inTime,
|
||||||
|
|||||||
@@ -144,6 +144,10 @@ public:
|
|||||||
int& out) = 0;
|
int& out) = 0;
|
||||||
virtual status_t Strxfrm(char* out, const char* in, size_t size,
|
virtual status_t Strxfrm(char* out, const char* in, size_t size,
|
||||||
size_t& outSize) = 0;
|
size_t& outSize) = 0;
|
||||||
|
virtual status_t Wcscoll(const wchar_t* a, const wchar_t* b,
|
||||||
|
int& out) = 0;
|
||||||
|
virtual status_t Wcsxfrm(wchar_t* out, const wchar_t* in,
|
||||||
|
size_t size, size_t& outSize) = 0;
|
||||||
|
|
||||||
virtual status_t TZSet(const char* timeZoneID,
|
virtual status_t TZSet(const char* timeZoneID,
|
||||||
const char* tz) = 0;
|
const char* tz) = 0;
|
||||||
|
|||||||
@@ -7,9 +7,12 @@
|
|||||||
#include "ICUCollateData.h"
|
#include "ICUCollateData.h"
|
||||||
|
|
||||||
#include <string.h>
|
#include <string.h>
|
||||||
|
#include <wchar.h>
|
||||||
|
|
||||||
#include <unicode/unistr.h>
|
#include <unicode/unistr.h>
|
||||||
|
|
||||||
|
#include <AutoDeleter.h>
|
||||||
|
|
||||||
|
|
||||||
namespace BPrivate {
|
namespace BPrivate {
|
||||||
namespace Libroot {
|
namespace Libroot {
|
||||||
@@ -63,7 +66,7 @@ ICUCollateData::SetToPosix()
|
|||||||
status_t
|
status_t
|
||||||
ICUCollateData::Strcoll(const char* a, const char* b, int& result)
|
ICUCollateData::Strcoll(const char* a, const char* b, int& result)
|
||||||
{
|
{
|
||||||
if (strcmp(fPosixLocaleName, "POSIX") == 0) {
|
if (fCollator == NULL || strcmp(fPosixLocaleName, "POSIX") == 0) {
|
||||||
// handle POSIX here as the collator ICU uses for that (english) is
|
// handle POSIX here as the collator ICU uses for that (english) is
|
||||||
// incompatible in too many ways
|
// incompatible in too many ways
|
||||||
result = strcmp(a, b);
|
result = strcmp(a, b);
|
||||||
@@ -109,7 +112,7 @@ ICUCollateData::Strcoll(const char* a, const char* b, int& result)
|
|||||||
status_t
|
status_t
|
||||||
ICUCollateData::Strxfrm(char* out, const char* in, size_t size, size_t& outSize)
|
ICUCollateData::Strxfrm(char* out, const char* in, size_t size, size_t& outSize)
|
||||||
{
|
{
|
||||||
if (strcmp(fPosixLocaleName, "POSIX") == 0) {
|
if (fCollator == NULL || strcmp(fPosixLocaleName, "POSIX") == 0) {
|
||||||
// handle POSIX here as the collator ICU uses for that (english) is
|
// handle POSIX here as the collator ICU uses for that (english) is
|
||||||
// incompatible in too many ways
|
// incompatible in too many ways
|
||||||
outSize = strlcpy(out, in, size);
|
outSize = strlcpy(out, in, size);
|
||||||
@@ -125,13 +128,40 @@ ICUCollateData::Strxfrm(char* out, const char* in, size_t size, size_t& outSize)
|
|||||||
return B_OK;
|
return B_OK;
|
||||||
}
|
}
|
||||||
|
|
||||||
UErrorCode icuStatus = U_ZERO_ERROR;
|
|
||||||
|
|
||||||
UnicodeString unicodeIn;
|
UnicodeString unicodeIn;
|
||||||
if (_ToUnicodeString(in, unicodeIn) != B_OK)
|
if (_ToUnicodeString(in, unicodeIn) != B_OK)
|
||||||
return B_BAD_VALUE;
|
return B_BAD_VALUE;
|
||||||
|
|
||||||
outSize = fCollator->getSortKey(unicodeIn, (uint8_t*)out, size);
|
outSize = fCollator->getSortKey(unicodeIn, (uint8_t*)out, size);
|
||||||
|
|
||||||
|
return B_OK;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
status_t
|
||||||
|
ICUCollateData::Wcscoll(const wchar_t* a, const wchar_t* b, int& result)
|
||||||
|
{
|
||||||
|
if (fCollator == NULL || strcmp(fPosixLocaleName, "POSIX") == 0) {
|
||||||
|
// handle POSIX here as the collator ICU uses for that (english) is
|
||||||
|
// incompatible in too many ways
|
||||||
|
result = wcscmp(a, b);
|
||||||
|
for (const wchar_t* aIter = a; *aIter != 0; ++aIter) {
|
||||||
|
if (*aIter > 127)
|
||||||
|
return B_BAD_VALUE;
|
||||||
|
}
|
||||||
|
for (const wchar_t* bIter = b; *bIter != 0; ++bIter) {
|
||||||
|
if (*bIter > 127)
|
||||||
|
return B_BAD_VALUE;
|
||||||
|
}
|
||||||
|
return B_OK;
|
||||||
|
}
|
||||||
|
|
||||||
|
UnicodeString unicodeA = UnicodeString::fromUTF32((UChar32*)a, -1);
|
||||||
|
UnicodeString unicodeB = UnicodeString::fromUTF32((UChar32*)b, -1);
|
||||||
|
|
||||||
|
UErrorCode icuStatus = U_ZERO_ERROR;
|
||||||
|
result = fCollator->compare(unicodeA, unicodeB, icuStatus);
|
||||||
|
|
||||||
if (!U_SUCCESS(icuStatus))
|
if (!U_SUCCESS(icuStatus))
|
||||||
return B_BAD_VALUE;
|
return B_BAD_VALUE;
|
||||||
|
|
||||||
@@ -139,6 +169,40 @@ ICUCollateData::Strxfrm(char* out, const char* in, size_t size, size_t& outSize)
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
status_t
|
||||||
|
ICUCollateData::Wcsxfrm(wchar_t* out, const wchar_t* in, size_t size,
|
||||||
|
size_t& outSize)
|
||||||
|
{
|
||||||
|
if (in == NULL) {
|
||||||
|
outSize = 0;
|
||||||
|
return B_OK;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (fCollator == NULL || strcmp(fPosixLocaleName, "POSIX") == 0) {
|
||||||
|
// handle POSIX here as the collator ICU uses for that (english) is
|
||||||
|
// incompatible in too many ways
|
||||||
|
outSize = wcslcpy(out, in, size);
|
||||||
|
for (const wchar_t* inIter = in; *inIter != 0; ++inIter) {
|
||||||
|
if (*inIter > 127)
|
||||||
|
return B_BAD_VALUE;
|
||||||
|
}
|
||||||
|
return B_OK;
|
||||||
|
}
|
||||||
|
|
||||||
|
UnicodeString unicodeIn = UnicodeString::fromUTF32((UChar32*)in, -1);
|
||||||
|
size_t requiredSize = fCollator->getSortKey(unicodeIn, NULL, 0);
|
||||||
|
|
||||||
|
uint8_t* buffer = (uint8_t*)out;
|
||||||
|
outSize = fCollator->getSortKey(unicodeIn, buffer, requiredSize);
|
||||||
|
|
||||||
|
// convert 1-byte characters to 4-byte wide characters:
|
||||||
|
for (size_t i = 0; i < outSize; ++i)
|
||||||
|
out[outSize - 1 - i] = buffer[outSize - 1 - i];
|
||||||
|
|
||||||
|
return B_OK;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
status_t
|
status_t
|
||||||
ICUCollateData::_ToUnicodeString(const char* in, UnicodeString& out)
|
ICUCollateData::_ToUnicodeString(const char* in, UnicodeString& out)
|
||||||
{
|
{
|
||||||
|
|||||||
@@ -294,6 +294,25 @@ ICULocaleBackend::Strxfrm(char* out, const char* in, size_t size,
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
status_t
|
||||||
|
ICULocaleBackend::Wcscoll(const wchar_t* a, const wchar_t* b, int& result)
|
||||||
|
{
|
||||||
|
ErrnoMaintainer errnoMaintainer;
|
||||||
|
|
||||||
|
return fCollateData.Wcscoll(a, b, result);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
status_t
|
||||||
|
ICULocaleBackend::Wcsxfrm(wchar_t* out, const wchar_t* in, size_t size,
|
||||||
|
size_t& outSize)
|
||||||
|
{
|
||||||
|
ErrnoMaintainer errnoMaintainer;
|
||||||
|
|
||||||
|
return fCollateData.Wcsxfrm(out, in, size, outSize);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
status_t
|
status_t
|
||||||
ICULocaleBackend::TZSet(const char* timeZoneID, const char* tz)
|
ICULocaleBackend::TZSet(const char* timeZoneID, const char* tz)
|
||||||
{
|
{
|
||||||
|
|||||||
@@ -11,8 +11,6 @@
|
|||||||
|
|
||||||
#include <unicode/gregocal.h>
|
#include <unicode/gregocal.h>
|
||||||
|
|
||||||
#include <AutoDeleter.h>
|
|
||||||
|
|
||||||
|
|
||||||
namespace BPrivate {
|
namespace BPrivate {
|
||||||
namespace Libroot {
|
namespace Libroot {
|
||||||
|
|||||||
@@ -0,0 +1,32 @@
|
|||||||
|
/*
|
||||||
|
** Copyright 2011, Oliver Tappe, [email protected]. All rights reserved.
|
||||||
|
** Distributed under the terms of the Haiku License.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include <errno_private.h>
|
||||||
|
#include <LocaleBackend.h>
|
||||||
|
#include <wchar_private.h>
|
||||||
|
|
||||||
|
|
||||||
|
using BPrivate::Libroot::gLocaleBackend;
|
||||||
|
|
||||||
|
|
||||||
|
extern "C" int
|
||||||
|
__wcscoll(const wchar_t* wcs1, const wchar_t* wcs2)
|
||||||
|
{
|
||||||
|
if (gLocaleBackend != NULL) {
|
||||||
|
int result = 0;
|
||||||
|
status_t status = gLocaleBackend->Wcscoll(wcs1, wcs2, result);
|
||||||
|
|
||||||
|
if (status != B_OK)
|
||||||
|
__set_errno(EINVAL);
|
||||||
|
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
return wcscmp(wcs1, wcs2);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
extern "C"
|
||||||
|
B_DEFINE_WEAK_ALIAS(__wcscoll, wcscoll);
|
||||||
@@ -0,0 +1,34 @@
|
|||||||
|
/*
|
||||||
|
* Copyright 2011, Oliver Tappe, [email protected].
|
||||||
|
* All rights reserved. Distributed under the terms of the MIT license.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include <errno.h>
|
||||||
|
|
||||||
|
#include <errno_private.h>
|
||||||
|
#include <LocaleBackend.h>
|
||||||
|
#include <wchar_private.h>
|
||||||
|
|
||||||
|
|
||||||
|
using BPrivate::Libroot::gLocaleBackend;
|
||||||
|
|
||||||
|
|
||||||
|
extern "C" size_t
|
||||||
|
__wcsxfrm(wchar_t* dest, const wchar_t* src, size_t destSize)
|
||||||
|
{
|
||||||
|
if (gLocaleBackend != NULL) {
|
||||||
|
size_t outSize = 0;
|
||||||
|
status_t status = gLocaleBackend->Wcsxfrm(dest, src, destSize, outSize);
|
||||||
|
|
||||||
|
if (status != B_OK)
|
||||||
|
__set_errno(EINVAL);
|
||||||
|
|
||||||
|
return outSize;
|
||||||
|
}
|
||||||
|
|
||||||
|
return wcslcpy(dest, src, destSize);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
extern "C"
|
||||||
|
B_DEFINE_WEAK_ALIAS(__wcsxfrm, wcsxfrm);
|
||||||
Reference in New Issue
Block a user