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:
parent
1b93a2e630
commit
bd55dcbefb
@ -29,6 +29,10 @@ public:
|
||||
status_t Strcoll(const char* a, const char* b, int& out);
|
||||
status_t Strxfrm(char* out, const char* in, size_t size,
|
||||
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:
|
||||
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 Strxfrm(char* out, const char* in, size_t size,
|
||||
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 Localtime(const time_t* inTime,
|
||||
|
@ -144,6 +144,10 @@ public:
|
||||
int& out) = 0;
|
||||
virtual status_t Strxfrm(char* out, const char* in, size_t size,
|
||||
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,
|
||||
const char* tz) = 0;
|
||||
|
@ -7,9 +7,12 @@
|
||||
#include "ICUCollateData.h"
|
||||
|
||||
#include <string.h>
|
||||
#include <wchar.h>
|
||||
|
||||
#include <unicode/unistr.h>
|
||||
|
||||
#include <AutoDeleter.h>
|
||||
|
||||
|
||||
namespace BPrivate {
|
||||
namespace Libroot {
|
||||
@ -63,7 +66,7 @@ ICUCollateData::SetToPosix()
|
||||
status_t
|
||||
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
|
||||
// incompatible in too many ways
|
||||
result = strcmp(a, b);
|
||||
@ -109,7 +112,7 @@ ICUCollateData::Strcoll(const char* a, const char* b, int& result)
|
||||
status_t
|
||||
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
|
||||
// incompatible in too many ways
|
||||
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;
|
||||
}
|
||||
|
||||
UErrorCode icuStatus = U_ZERO_ERROR;
|
||||
|
||||
UnicodeString unicodeIn;
|
||||
if (_ToUnicodeString(in, unicodeIn) != B_OK)
|
||||
return B_BAD_VALUE;
|
||||
|
||||
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))
|
||||
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
|
||||
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
|
||||
ICULocaleBackend::TZSet(const char* timeZoneID, const char* tz)
|
||||
{
|
||||
|
@ -11,8 +11,6 @@
|
||||
|
||||
#include <unicode/gregocal.h>
|
||||
|
||||
#include <AutoDeleter.h>
|
||||
|
||||
|
||||
namespace BPrivate {
|
||||
namespace Libroot {
|
||||
|
32
src/system/libroot/posix/wchar/wcscoll.cpp
Normal file
32
src/system/libroot/posix/wchar/wcscoll.cpp
Normal file
@ -0,0 +1,32 @@
|
||||
/*
|
||||
** Copyright 2011, Oliver Tappe, zooey@hirschkaefer.de. 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);
|
34
src/system/libroot/posix/wchar/wcsxfrm.cpp
Normal file
34
src/system/libroot/posix/wchar/wcsxfrm.cpp
Normal file
@ -0,0 +1,34 @@
|
||||
/*
|
||||
* Copyright 2011, Oliver Tappe, zooey@hirschkaefer.de.
|
||||
* 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);
|
Loading…
Reference in New Issue
Block a user