📄 qtextcodec.cpp
字号:
/****************************************************************************** $Id: qt/src/tools/qtextcodec.cpp 2.2.3 edited 2000-12-07 $**** Implementation of QTextCodec class**** Created : 981015**** Copyright (C)1998-2000 Trolltech AS. All rights reserved.**** This file is part of the tools module of the Qt GUI Toolkit.**** This file may be distributed under the terms of the Q Public License** as defined by Trolltech AS of Norway and appearing in the file** LICENSE.QPL included in the packaging of this file.**** This file may be distributed and/or modified under the terms of the** GNU General Public License version 2 as published by the Free Software** Foundation and appearing in the file LICENSE.GPL included in the** packaging of this file.**** Licensees holding valid Qt Enterprise Edition or Qt Professional Edition** licenses may use this file in accordance with the Qt Commercial License** Agreement provided with the Software.**** This file is provided AS IS with NO WARRANTY OF ANY KIND, INCLUDING THE** WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.**** See http://www.trolltech.com/pricing.html or email sales@trolltech.com for** information about Qt Commercial License Agreements.** See http://www.trolltech.com/qpl/ for QPL licensing information.** See http://www.trolltech.com/gpl/ for GPL licensing information.**** Contact info@trolltech.com if any conditions of this licensing are** not clear to you.************************************************************************/#include "qtextcodec.h"#ifndef QT_NO_TEXTCODEC#include "qlist.h"#ifndef QT_NO_CODECS#include "qutfcodec.h"#include "qgbkcodec.h"#include "qeucjpcodec.h"#include "qjiscodec.h"#include "qsjiscodec.h"#include "qeuckrcodec.h"#include "qbig5codec.h"#include "qrtlcodec.h"#include "qtsciicodec.h"#endif#include "qfile.h"#include "qstrlist.h"#include "qstring.h"#include <stdlib.h>#include <ctype.h>#include <locale.h>static QList<QTextCodec> * all = 0;static bool destroying_is_ok; // starts out as 0/*! Deletes all the created codecs. \warning Do not call this function. QApplication calls this just before exiting, to delete any QTextCodec objects that may be lying around. Since various other classes hold pointers to QTextCodec objects, it is not safe to call this function earlier. If you are using the utility classes (like QString) but not using QApplication, calling this function at the very end of your application can be helpful to chasing down memory leaks, as QTextCodec objects will not show up.*/void QTextCodec::deleteAllCodecs(){ if ( !all ) return; destroying_is_ok = TRUE; QList<QTextCodec> * ball = all; all = 0; ball->clear(); delete ball; destroying_is_ok = FALSE;}static void setupBuiltinCodecs();static void realSetup(){#if defined(CHECK_STATE) if ( destroying_is_ok ) qWarning( "creating new codec during codec cleanup" );#endif all = new QList<QTextCodec>; all->setAutoDelete( TRUE ); setupBuiltinCodecs();}static inline void setup(){ if ( !all ) realSetup();}class QTextStatelessEncoder: public QTextEncoder { const QTextCodec* codec;public: QTextStatelessEncoder(const QTextCodec*); QCString fromUnicode(const QString& uc, int& lenInOut);};class QTextStatelessDecoder : public QTextDecoder { const QTextCodec* codec;public: QTextStatelessDecoder(const QTextCodec*); QString toUnicode(const char* chars, int len);};QTextStatelessEncoder::QTextStatelessEncoder(const QTextCodec* c) : codec(c){}QCString QTextStatelessEncoder::fromUnicode(const QString& uc, int& lenInOut){ return codec->fromUnicode(uc,lenInOut);}QTextStatelessDecoder::QTextStatelessDecoder(const QTextCodec* c) : codec(c){}QString QTextStatelessDecoder::toUnicode(const char* chars, int len){ return codec->toUnicode(chars,len);}// NOT REVISED/*! \class QTextCodec qtextcodec.h \brief Provides conversion between text encodings. By making objects of subclasses of QTextCodec, support for new text encodings can be added to Qt. The abstract virtual functions describe the encoder to the system and the coder is used as required in the different text file formats supported QTextStream and, under X11 for the locale-specific character input and output (under Windows NT codecs are not needed for GUI I/O since the system works with Unicode already, and Windows 95/98 has built-in convertors for the 8-bit local encoding). More recently created QTextCodec objects take precedence over earlier ones. To add support for another 8-bit encoding to Qt, make a subclass or QTextCodec and implement at least the following methods: <dl> <dt>\c const char* name() const <dd>Return the official name for the encoding. <dt>\c int mibEnum() const <dd>Return the MIB enum for the encoding if it is listed in the <a href=ftp://ftp.isi.edu/in-notes/iana/assignments/character-sets> IANA character-sets encoding file</a>. </dl> If the encoding is multi-byte then it will have "state"; that is, the interpretation of some bytes will be dependent on some preceding bytes. For such an encoding, you will need to implement <dl> <dt> \c QTextDecoder* makeDecoder() const <dd>Return a QTextDecoder that remembers incomplete multibyte sequence prefixes or other required state. </dl> If the encoding does \e not require state, you should implement: <dl> <dt> \c QString toUnicode(const char* chars, int len) const <dd>Converts \e len characters from \e chars to Unicode. </dl> The base QTextCodec class has default implementations of the above two functions, <i>but they are mutually recursive</i>, so you must re-implement at least one of them, or both for improved efficiency. For conversion from Unicode to 8-bit encodings, it is rarely necessary to maintain state. However, two functions similar to the two above are used for encoding: <dl> <dt> \c QTextEncoder* makeEncoder() const <dd>Return a QTextDecoder. <dt> \c QCString fromUnicode(const QString& uc, int& lenInOut ) const; <dd>Converts \e lenInOut characters (of type QChar) from the start of the string \a uc, returning a QCString result, and also returning the \link QCString::length() length\endlink of the result in lenInOut. </dl> Again, these are mutually recursive so only one needs to be implemented, or both if better efficiency is possible. Finally, you must implement: <dl> <dt> \c int heuristicContentMatch(const char* chars, int len) const <dd>Gives a value indicating how likely it is that \e len characters from \e chars are in the encoding. </dl> A good model for this function is the QWindowsLocalCodec::heuristicContentMatch function found in the Qt sources. A QTextCodec subclass might have improved performance if you also re-implement: <dl> <dt> \c bool canEncode( QChar ) const <dd>Test if a Unicode character can be encoded. <dt> \c bool canEncode( const QString& ) const <dd>Test if a string of Unicode characters can be encoded. <dt> \c int heuristicNameMatch(const char* hint) const <dd>Test if a possibly non-standard name is referring to the codec. </dl>*//*! Constructs a QTextCodec, making it of highest precedence. The QTextCodec should always be constructed on the heap (with new), and once constructed it becomes the responsibility of Qt to delete it (which is done at QApplication destruction).*/QTextCodec::QTextCodec(){ setup(); all->insert(0,this);}/*! Destructs the QTextCodec. Note that you should not delete codecs yourself - once created they become the responsibility of Qt to delete.*/QTextCodec::~QTextCodec(){ if ( !destroying_is_ok ) qWarning("QTextCodec::~QTextCodec() called by application"); if ( all ) all->remove( this );}/*! Returns a value indicating how likely this decoder is for decoding some format that has the given name. A good match returns a positive number around the length of the string. A bad match is negative. The default implementation calls simpleHeuristicNameMatch() with the name of the codec.*/int QTextCodec::heuristicNameMatch(const char* hint) const{ return simpleHeuristicNameMatch(name(),hint);}// returns a string cotnaining the letters and numbers from input,// with a space separating run of a character class. e.g. "iso8859-1"// becomes "iso 8859 1"static QString lettersAndNumbers( const char * input ){ QString result; QChar c; while( input && *input ) { c = *input; if ( c.isLetter() || c.isNumber() ) result += c.lower(); if ( input[1] ) { // add space at character class transition, except // transition from upper-case to lower-case letter QChar n( input[1] ); if ( c.isLetter() && n.isLetter() ) { if ( c == c.lower() && n == n.upper() ) result += ' '; } else if ( c.category() != n.category() ) { result += ' '; } } input++; } return result.simplifyWhiteSpace();}/*! A simple utility function for heuristicNameMatch() - it does some very minor character-skipping so that almost-exact matches score high.*/int QTextCodec::simpleHeuristicNameMatch(const char* name, const char* hint){ // if they're the same, return a perfect score. if ( name && hint && qstrcmp( name, hint ) == 0 ) return qstrlen( hint ); // if the letters and numbers are the same, we have an "almost" // perfect match. QString h( lettersAndNumbers( hint ) ); QString n( lettersAndNumbers( name ) ); if ( h == n ) return qstrlen( hint )-1; if ( h.stripWhiteSpace() == n.stripWhiteSpace() ) return qstrlen( hint )-2; // could do some more here, but I don't think it's worth it return 0;}/*! Returns the QTextCodec \a i places from the more recently
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -