From e5692b384e56f19f605f4f3889cd0cae3d0ae5ec Mon Sep 17 00:00:00 2001 From: shatty Date: Tue, 30 Dec 2003 03:28:29 +0000 Subject: [PATCH] MOVED: --------------------------------------------------------------------------- RCS file: /cvsroot/open-beos/current/src/kits/support/utf8_conversions.cpp,v Working file: utf8_conversions.cpp head: 1.8 branch: locks: strict access list: symbolic names: keyword substitution: kv total revisions: 8; selected revisions: 8 description: ---------------------------- revision 1.8 date: 2003/08/13 05:38:07; author: shatty; state: Exp; lines: +24 -4 refine the error handling behavior. note: we depart from the bebook specification for returning B_ERROR when no characters are converted. we do this in exactly one situation: when there are no bytes in the input. this behavior is the behavior given by the R5 libs themselves. not having this behavior caused an error in our stylededit as well. stylededit has been fixed to not exercise this functionality. also added in the two most popular chinese encodings for my own evil purposes. GB18030 support is required to legally sell an operating system in mainland china as well. GB18030 support encompasses GBK and GB2312, additionally. ---------------------------- revision 1.7 date: 2003/08/02 09:01:13; author: shatty; state: Exp; lines: +1 -1 no const for now ---------------------------- revision 1.6 date: 2003/07/31 07:34:30; author: shatty; state: Exp; lines: +0 -1 dunno when beos changes the state, but it seems to leave at 0 for a while so I am going to have it be consistent that way ---------------------------- revision 1.5 date: 2003/07/31 07:18:15; author: shatty; state: Exp; lines: +0 -3 remove debugging print things ---------------------------- revision 1.4 date: 2003/07/31 07:17:30; author: shatty; state: Exp; lines: +35 -30 new and better working implementations for conversion functions, including better abstraction ---------------------------- revision 1.3 date: 2003/07/31 04:57:37; author: shatty; state: Exp; lines: +6 -2 added iconv_close to free resources and made a new input_buffer_t typedef to ease switching iconv implementations ---------------------------- revision 1.2 date: 2003/07/31 00:04:53; author: shatty; state: Exp; lines: +43 -4 written to use iconv.h ---------------------------- revision 1.1 date: 2003/07/26 21:28:02; author: shatty; state: Exp; utf8 conversions file with stub implementations of convert_to_utf8 and convert_from_utf8 git-svn-id: file:///srv/svn/repos/haiku/trunk/current@5810 a95241bf-73f2-0310-859d-f6bbb57e9c96 --- src/kits/textencoding/utf8_conversions.cpp | 85 ++++++++++++++++++++++ 1 file changed, 85 insertions(+) create mode 100644 src/kits/textencoding/utf8_conversions.cpp diff --git a/src/kits/textencoding/utf8_conversions.cpp b/src/kits/textencoding/utf8_conversions.cpp new file mode 100644 index 0000000000..e322828695 --- /dev/null +++ b/src/kits/textencoding/utf8_conversions.cpp @@ -0,0 +1,85 @@ +#include +#include +#include +#include +#include +#include + +using namespace BPrivate; + +typedef char ** input_buffer_t; + +status_t +convert_encoding(const char * from, const char * to, + const char * src, int32 * srcLen, + char * dst, int32 * dstLen, + int32 * state) +{ + if (*srcLen == 0) { + // nothing to do! + return B_OK; + } + iconv_t conversion = iconv_open(to,from); + if (conversion == (iconv_t)-1) { + return B_ERROR; + } + if (state == 0) { + return B_ERROR; + } + if (*state == 0) { + iconv(conversion,0,0,0,0); + } + input_buffer_t inputBuffer = const_cast(&src); + size_t inputLeft = *srcLen; + size_t outputLeft = *dstLen; + size_t nonReversibleConversions = iconv(conversion,inputBuffer,&inputLeft,&dst,&outputLeft); + *srcLen -= inputLeft; + *dstLen -= outputLeft; + iconv_close(conversion); + if (nonReversibleConversions == -1) { + switch (errno) { + case EILSEQ: // invalid multibyte sequence in the source + return B_ERROR; + case EINVAL: // incomplete multibyte sequence in the input + return B_OK; + case E2BIG: // not enough room in the output buffer for the next converted character + return B_OK; + default: + // unknown error + int err = errno; + } + } + if (*srcLen != 0) { + // able to convert at least one character + return B_OK; + } else { + // not able to convert at least one character + return B_ERROR; + } +} + +status_t +convert_to_utf8(uint32 srcEncoding, + const char * src, int32 * srcLen, + char * dst, int32 * dstLen, + int32 * state, char substitute = B_SUBSTITUTE) +{ + const BCharacterSet * charset = BCharacterSetRoster::GetCharacterSetByConversionID(srcEncoding); + if (charset == 0) { + return B_ERROR; + } + return convert_encoding(charset->GetName(),"UTF-8",src,srcLen,dst,dstLen,state); +} + +status_t +convert_from_utf8(uint32 dstEncoding, + const char * src, int32 * srcLen, + char * dst, int32 * dstLen, + int32 * state, char substitute = B_SUBSTITUTE) +{ + const BCharacterSet * charset = BCharacterSetRoster::GetCharacterSetByConversionID(dstEncoding); + if (charset == 0) { + return B_ERROR; + } + return convert_encoding("UTF-8",charset->GetName(),src,srcLen,dst,dstLen,state); +}