📄 kwqtextcodec.cpp
字号:
/*
* Copyright (C) 2004 Apple Computer, Inc. All rights reserved.
* Portions Copyright (c) 2005 Nokia Corporation, Inc. All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
*
* THIS SOFTWARE IS PROVIDED BY APPLE COMPUTER, INC. ``AS IS'' AND ANY
* EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
* PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE COMPUTER, INC. OR
* CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
* EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
* PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
* PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
* OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
#include "KWQTextCodec.h"
#include "KWQString.h"
#include "KWQAssertions.h"
#include "KWQCharsets.h"
#include "KWQGlobalServices.h"
#include "KWQCharsetData.c"
#include "KWQKDebug.h"
#define _DEBUG1 0
#ifdef _DEBUG1
#include <flogger.h>
#endif
#define BrDefaultEnc KCharacterSetIdentifierIso88591;
#define BrDefaultEncStr "iso-8859-1";
const char FF = 0xff;
const char EF = 0xef;
const char FE = 0xfe;
const char BF = 0xbf;
const char BB = 0xbb;
class KWQTextDecoder : public QTextDecoder {
friend class QTextCodec;
public:
KWQTextDecoder(TUint aEnc) : iEncoding(aEnc), iRemainderBuf( NULL ) {}
~KWQTextDecoder() { delete iRemainderBuf; }
QString toUnicode(const char *chs, int len, bool flush);
QCString fromUnicode(const QString &);
bool IsConversionSupportedL();
QString windows125xToUnicode( const char *chs, int len );
private:
KWQTextDecoder(const KWQTextDecoder &);
KWQTextDecoder &operator=(const KWQTextDecoder &);
QString convertLatin1(const unsigned char *chs, int len);
static CArrayFix<CCnvCharacterSetConverter::SCharacterSet>* iArrayOfCharacterSetsAvailable;
TUint iEncoding;
HBufC8 * iRemainderBuf;
};
CArrayFix<CCnvCharacterSetConverter::SCharacterSet>* KWQTextDecoder::iArrayOfCharacterSetsAvailable = NULL;
static bool encodingNamesEqual(const void *value1, const void *value2)
{
const char *s1 = static_cast<const char *>(value1);
const char *s2 = static_cast<const char *>(value2);
while (1) {
char c1;
do {
c1 = *s1++;
} while (c1 && !isalnum(c1));
char c2;
do {
c2 = *s2++;
} while (c2 && !isalnum(c2));
if (tolower(c1) != tolower(c2)) {
return false;
}
if (!c1 || !c2) {
return !c1 && !c2;
}
}
}
QTextCodec::~QTextCodec()
{ delete iQTextDecoder; }
/**
* we need to convert the charset name from internet-standard name
* to Symbian charset id, which is required by system's text coverter
*/
QTextCodec *QTextCodec::codecForName(const char *name)
{
TUint enc = 0;
KWQEncodingFlags flags = NoEncodingFlags;
for (int i=0; supportedCharsetTable[i].charsetName != NULL; i++)
{
if (encodingNamesEqual(name, supportedCharsetTable[i].charsetName))
{
enc = supportedCharsetTable[i].uid;
flags = supportedCharsetTable[i].flags;
break;
}
}
if( enc == 0 )
enc = BrDefaultEnc;
return new QTextCodec( enc, flags );
}
/**
* This function is very similar to codecForName, except that
* it's called only when caller knows the buffer is single byte
* encoding. Therefore, if ucs2 is detected for charset, it has
* to be UTF-8.
*/
QTextCodec *QTextCodec::codecForNameEightBitOnly(const char *name)
{
TUint enc = 0;
KWQEncodingFlags flags = NoEncodingFlags;
for (int i = 0; supportedCharsetTable[i].charsetName != NULL; i++)
{
if (encodingNamesEqual(name, supportedCharsetTable[i].charsetName))
{
enc = supportedCharsetTable[i].uid;
flags = supportedCharsetTable[i].flags;
break;
}
}
switch (enc) {
case 0:
enc = BrDefaultEnc;
break;
case KCharacterSetIdentifierUcs2:
enc = KCharacterSetIdentifierUtf8;
break;
}
return new QTextCodec( enc, flags );
}
QTextCodec *QTextCodec::codecForLocale()
{
// FIXME NOKIA: how to get the system encoding in Symbian OS?
// only UTF8 used here
return new QTextCodec( KCharacterSetIdentifierIso88591 );
}
QChar QTextCodec::backslashAsCurrencySymbol() const
{
// FIXME: We should put this information into KWQCharsetData instead of having a switch here.
switch (iEncoding) {
case KCharacterSetIdentifierShiftJis:
case KCharacterSetIdentifierEucJpPacked:
return 0x00A5; // yen sign
default:
return '\\';
}
}
const char *QTextCodec::name() const
{
for (int i=0; supportedCharsetTable[i].charsetName != NULL; i++)
{
if (supportedCharsetTable[i].uid == iEncoding)
{
return supportedCharsetTable[i].charsetName;
}
}
// if not found in the supported charset table, return the default encoding.
return BrDefaultEncStr;
}
QTextDecoder *QTextCodec::makeDecoder() const
{
return iQTextDecoder? iQTextDecoder : new KWQTextDecoder( iEncoding );
}
QCString QTextCodec::fromUnicode(const QString &qcs) const
{
return makeDecoder()->fromUnicode( qcs );
}
QString QTextCodec::toUnicode(const char *chs, int len) const
{
return makeDecoder()->toUnicode(chs, len, true);
}
QString QTextCodec::toUnicode(const QByteArray &qba, int len) const
{
return makeDecoder()->toUnicode(qba.data(), len, true);
}
bool operator==(const QTextCodec &a, const QTextCodec &b)
{
return a.iEncoding == b.iEncoding;
}
QString KWQTextDecoder::convertLatin1(const unsigned char *s, int length)
{
//ASSERT(_numBufferedBytes == 0);
int i;
for (i = 0; i != length; ++i) {
if (s[i] == 0) {
break;
}
}
if (i == length) {
return QString(reinterpret_cast<const char *>(s), length);
}
QString result("");
result.reserve(length);
result.append(reinterpret_cast<const char *>(s), i);
int start = ++i;
for (; i != length; ++i) {
if (s[i] == 0) {
if (start != i) {
result.append(reinterpret_cast<const char *>(&s[start]), i - start);
}
start = i + 1;
}
}
if (start != length) {
result.append(reinterpret_cast<const char *>(&s[start]), length - start);
}
return result;
}
/**
* this function creates the static array of converters available in the file system
* checks the available converter array to see if the converter is available
* return a bool to indicate availability
*/
bool KWQTextDecoder::IsConversionSupportedL()
{
if (iEncoding == KCharacterSetIdentifierIso88591)
return true;
if( !iArrayOfCharacterSetsAvailable )
{
iArrayOfCharacterSetsAvailable =
CCnvCharacterSetConverter::CreateArrayOfCharacterSetsAvailableL(
KWQGlobalServices::InstanceL()->FileSession() );
User::LeaveIfNull( iArrayOfCharacterSetsAvailable );
}
int count = iArrayOfCharacterSetsAvailable->Count();
for (int index = 0; index < count; index++)
{
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -