⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 q3textstream.cpp

📁 奇趣公司比较新的qt/emd版本
💻 CPP
📖 第 1 页 / 共 4 页
字号:
/******************************************************************************** Copyright (C) 1992-2007 Trolltech ASA. All rights reserved.**** This file is part of the Qt3Support module of the Qt Toolkit.**** This file may be used under the terms of the GNU General Public** License version 2.0 as published by the Free Software Foundation** and appearing in the file LICENSE.GPL included in the packaging of** this file.  Please review the following information to ensure GNU** General Public Licensing requirements will be met:** http://trolltech.com/products/qt/licenses/licensing/opensource/**** If you are unsure which license is appropriate for your use, please** review the following information:** http://trolltech.com/products/qt/licenses/licensing/licensingoverview** or contact the sales department at sales@trolltech.com.**** In addition, as a special exception, Trolltech gives you certain** additional rights. These rights are described in the Trolltech GPL** Exception version 1.0, which can be found at** http://www.trolltech.com/products/qt/gplexception/ and in the file** GPL_EXCEPTION.txt in this package.**** In addition, as a special exception, Trolltech, as the sole copyright** holder for Qt Designer, grants users of the Qt/Eclipse Integration** plug-in the right for the Qt/Eclipse Integration to link to** functionality provided by Qt Designer and its related libraries.**** Trolltech reserves all rights not expressly granted herein.**** This file is provided AS IS with NO WARRANTY OF ANY KIND, INCLUDING THE** WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.******************************************************************************/#include "q3textstream.h"#include <qdebug.h>#ifndef QT_NO_TEXTSTREAM#include "qtextcodec.h"#include "qregexp.h"#include "qbuffer.h"#include "qfile.h"#include "q3cstring.h"#include <stdio.h>#include <ctype.h>#include <stdlib.h>#ifndef Q_OS_TEMP#include <locale.h>#endif#if defined(Q_OS_WIN32)#include "qt_windows.h"#endif#ifndef QT_NO_TEXTCODECstatic void resetCodecConverterState(QTextCodec::ConverterState *state) {    state->flags = QTextCodec::DefaultConversion;    state->remainingChars = state->invalidChars =           state->state_data[0] = state->state_data[1] = state->state_data[2] = 0;    if (state->d) qFree(state->d);    state->d = 0;}#endif/*!    \class Q3TextStream    \compat    \reentrant    \brief The Q3TextStream class provides basic functions for reading    and writing text using a QIODevice.    The text stream class has a functional interface that is very    similar to that of the standard C++ iostream class.    Qt provides several global functions similar to the ones in iostream:    \table    \header \i Function \i Meaning    \row \i bin \i sets the Q3TextStream to read/write binary numbers    \row \i oct \i sets the Q3TextStream to read/write octal numbers    \row \i dec \i sets the Q3TextStream to read/write decimal numbers    \row \i hex \i sets the Q3TextStream to read/write hexadecimal numbers    \row \i endl \i forces a line break    \row \i flush \i forces the QIODevice to flush any buffered data    \row \i ws \i eats any available whitespace (on input)    \row \i reset \i resets the Q3TextStream to its default mode (see reset())    \row \i qSetW(int) \i sets the \link width() field width \endlink    to the given argument    \row \i qSetFill(int) \i sets the \link fill() fill character    \endlink to the given argument    \row \i qSetPrecision(int) \i sets the \link precision() precision    \endlink to the given argument    \endtable    \warning By default Q3TextStream will automatically detect whether    integers in the stream are in decimal, octal, hexadecimal or    binary format when reading from the stream. In particular, a    leading '0' signifies octal, i.e. the sequence "0100" will be    interpreted as 64.    The Q3TextStream class reads and writes text; it is not appropriate    for dealing with binary data (but QDataStream is).    By default, output of Unicode text (i.e. QString) is done using    the local 8-bit encoding. This can be changed using the    setEncoding() method. For input, the Q3TextStream will auto-detect    standard Unicode "byte order marked" text files; otherwise the    local 8-bit encoding is used.    The QIODevice is set in the constructor, or later using    setDevice(). If the end of the input is reached atEnd() returns    TRUE. Data can be read into variables of the appropriate type    using the operator>>() overloads, or read in its entirety into a    single string using read(), or read a line at a time using    readLine(). Whitespace can be skipped over using skipWhiteSpace().    You can set flags for the stream using flags() or setf(). The    stream also supports width(), precision() and fill(); use reset()    to reset the defaults.    \sa QDataStream*//*!    \enum Q3TextStream::Encoding    \value Locale    \value Latin1    \value Unicode    \value UnicodeNetworkOrder    \value UnicodeReverse    \value RawUnicode    \value UnicodeUTF8    See setEncoding() for an explanation of the encodings.*//*  \class QTSManip  \internal*/#if defined(QT_CHECK_STATE)#undef  CHECK_STREAM_PRECOND#define CHECK_STREAM_PRECOND  if ( !dev ) {				\				qWarning( "Q3TextStream: No device" );	\				return *this; }#else#define CHECK_STREAM_PRECOND#endif#define I_SHORT		0x0010#define I_INT		0x0020#define I_LONG		0x0030#define I_TYPE_MASK	0x00f0#define I_BASE_2	Q3TextStream::bin#define I_BASE_8	Q3TextStream::oct#define I_BASE_10	Q3TextStream::dec#define I_BASE_16	Q3TextStream::hex#define I_BASE_MASK	(Q3TextStream::bin | Q3TextStream::oct | Q3TextStream::dec | Q3TextStream::hex)#define I_SIGNED	0x0100#define I_UNSIGNED	0x0200#define I_SIGN_MASK	0x0f00static const QChar QEOF = QChar((ushort)0xffff); //guaranteed not to be a character.static const uint getline_buf_size = 256; // bufsize used by ts_getline()const int Q3TextStream::basefield   = I_BASE_MASK;const int Q3TextStream::adjustfield = ( Q3TextStream::left |				       Q3TextStream::right |				       Q3TextStream::internal );const int Q3TextStream::floatfield  = ( Q3TextStream::scientific |				       Q3TextStream::fixed );class Q3TextStreamPrivate {public:#ifndef QT_NO_TEXTCODEC    Q3TextStreamPrivate()	: sourceType( NotSet ) { }    ~Q3TextStreamPrivate() {    }#else    Q3TextStreamPrivate() : sourceType( NotSet ) { }    ~Q3TextStreamPrivate() { }#endif    QString ungetcBuf;    enum SourceType { NotSet, IODevice, String, ByteArray, File };    SourceType sourceType;};// skips whitespace and returns the first non-whitespace characterQChar Q3TextStream::eat_ws(){    QChar c;    do { c = ts_getc(); } while ( c != QEOF && ts_isspace(c) );    return c;}void Q3TextStream::init(){    // ### ungetcBuf = QEOF;    dev = 0;    owndev = FALSE;    mapper = 0;#ifndef QT_NO_TEXTCODEC    ::resetCodecConverterState(&mapperReadState);    ::resetCodecConverterState(&mapperWriteState);#endif    d = new Q3TextStreamPrivate;    doUnicodeHeader = TRUE; // autodetect    latin1 = TRUE; // should use locale?    internalOrder = QChar::networkOrdered();    networkOrder = TRUE;}/*!    Constructs a data stream that has no IO device.*/Q3TextStream::Q3TextStream(){    init();    setEncoding( Locale );    reset();    d->sourceType = Q3TextStreamPrivate::NotSet;}/*!    Constructs a text stream that uses the IO device \a iod.*/Q3TextStream::Q3TextStream( QIODevice *iod ){    init();    setEncoding( Locale );    dev = iod;    reset();    d->sourceType = Q3TextStreamPrivate::IODevice;}// TODO: use special-case handling of this case in Q3TextStream, and//	 simplify this class to only deal with QChar or QString data.class QStringBuffer : public QIODevice {public:    QStringBuffer( QString* str );    ~QStringBuffer();    bool  open( OpenMode m );    void  close();    qint64 size() const;protected:    qint64 readData( char *p, qint64 len );    qint64 writeData( const char *p, qint64 len );    QString* s;private:    QStringBuffer( const QStringBuffer & );    QStringBuffer &operator=( const QStringBuffer & );};QStringBuffer::QStringBuffer( QString* str ){    s = str;}QStringBuffer::~QStringBuffer(){}bool QStringBuffer::open( OpenMode m ){    if ( !s ) {#if defined(QT_CHECK_STATE)	qWarning( "QStringBuffer::open: No string" );#endif	return FALSE;    }    if ( isOpen() ) {#if defined(QT_CHECK_STATE)	qWarning( "QStringBuffer::open: Buffer already open" );#endif	return FALSE;    }    setOpenMode( m );    if ( m & QIODevice::Truncate )	s->truncate( 0 );    if ( m & QIODevice::Append ) {	seek(s->length()*sizeof(QChar));    } else {	seek(0);    }    return TRUE;}void QStringBuffer::close(){    if ( isOpen() ) {	seek(0);        QIODevice::close();    }}qint64 QStringBuffer::size() const{    return s ? s->length()*sizeof(QChar) : 0;}qint64 QStringBuffer::readData( char *p, qint64 len ){#if defined(QT_CHECK_STATE)    Q_CHECK_PTR( p );    if ( !isOpen() ) {	qWarning( "QStringBuffer::readBlock: Buffer not open" );	return qint64(-1);    }    if ( !isReadable() ) {	qWarning( "QStringBuffer::readBlock: Read operation not permitted" );	return qint64(-1);    }#endif    if ( pos() + len > qint64(s->length()*sizeof(QChar)) ) {	// overflow	if ( pos() >= qint64(s->length()*sizeof(QChar)) ) {	    return -1;	} else {	    len = s->length()*2 - pos();	}    }    memcpy( p, ((const char*)(s->unicode()))+pos(), len );    return len;}qint64 QStringBuffer::writeData( const char *p, qint64 len ){#if defined(QT_CHECK_NULL)    if ( p == 0 && len != 0 )	qWarning( "QStringBuffer::writeBlock: Null pointer error" );#endif#if defined(QT_CHECK_STATE)    if ( !isOpen() ) {	qWarning( "QStringBuffer::writeBlock: Buffer not open" );	return -1;    }    if ( !isWritable() ) {	qWarning( "QStringBuffer::writeBlock: Write operation not permitted" );	return -1;    }    if ( pos()&1 ) {	qWarning( "QStringBuffer::writeBlock: non-even index - non Unicode" );	return -1;    }    if ( len&1 ) {	qWarning( "QStringBuffer::writeBlock: non-even length - non Unicode" );	return -1;    }#endif    s->replace(pos()/2, len/2, (QChar*)p, len/2);    return len;}/*!    Constructs a text stream that operates on the Unicode QString, \a    str, through an internal device. The \a filemode argument is    passed to the device's open() function; see \l{QIODevice::mode()}.    If you set an encoding or codec with setEncoding() or setCodec(),    this setting is ignored for text streams that operate on QString.    Example:    \code    QString str;    Q3TextStream ts( &str, IO_WriteOnly );    ts << "pi = " << 3.14; // str == "pi = 3.14"    \endcode    Writing data to the text stream will modify the contents of the    string. The string will be expanded when data is written beyond    the end of the string. Note that the string will not be truncated:    \code    QString str = "pi = 3.14";    Q3TextStream ts( &str, IO_WriteOnly );    ts <<  "2+2 = " << 2+2; // str == "2+2 = 414"    \endcode    Note that because QString is Unicode, you should not use    readRawBytes() or writeRawBytes() on such a stream.*/Q3TextStream::Q3TextStream( QString* str, int filemode ){    // TODO: optimize for this case as it becomes more common    //        (see QStringBuffer above)    init();    dev = new QStringBuffer( str );    ((QStringBuffer *)dev)->open( QIODevice::OpenMode(filemode) );    owndev = TRUE;    setEncoding(RawUnicode);    reset();    d->sourceType = Q3TextStreamPrivate::String;}/*! \obsolete  This constructor is equivalent to the constructor taking a QString*  parameter.*/Q3TextStream::Q3TextStream( QString& str, int filemode ){    init();    dev = new QStringBuffer( &str );    ((QStringBuffer *)dev)->open( QIODevice::OpenMode(filemode) );    owndev = TRUE;    setEncoding(RawUnicode);    reset();    d->sourceType = Q3TextStreamPrivate::String;}/*!    Constructs a text stream that operates on the byte array, \a a,    through an internal QBuffer device. The \a mode argument is passed    to the device's open() function; see \l{QIODevice::mode()}.    Example:    \code    QByteArray array;    Q3TextStream ts( array, IO_WriteOnly );    ts << "pi = " << 3.14 << '\0'; // array == "pi = 3.14"    \endcode    Writing data to the text stream will modify the contents of the    array. The array will be expanded when data is written beyond the    end of the string.    Same example, using a QBuffer:    \code    QByteArray array;    QBuffer buf( array );    buf.open( IO_WriteOnly );    Q3TextStream ts( &buf );    ts << "pi = " << 3.14 << '\0'; // array == "pi = 3.14"    buf.close();    \endcode*/Q3TextStream::Q3TextStream( QByteArray &a, int mode ){    init();    QBuffer *buffer = new QBuffer;    buffer->setBuffer( &a );    buffer->open( QIODevice::OpenMode(mode) );    dev = buffer;    owndev = TRUE;    setEncoding( Latin1 ); //### Locale???    reset();    d->sourceType = Q3TextStreamPrivate::ByteArray;}/*!    Constructs a text stream that operates on an existing file handle    \a fh through an internal QFile device. The \a mode argument is    passed to the device's open() function; see \l{QIODevice::mode()}.    Note that if you create a Q3TextStream \c cout or another name that    is also used for another variable of a different type, some    linkers may confuse the two variables, which will often cause    crashes.*/Q3TextStream::Q3TextStream( FILE *fh, int mode ){    init();    setEncoding( Locale ); //###    dev = new QFile;    ((QFile *)dev)->open( QIODevice::OpenMode(mode), fh );    owndev = TRUE;    reset();    d->sourceType = Q3TextStreamPrivate::File;}/*!    Destroys the text stream.    The destructor does not affect the current IO device.*/Q3TextStream::~Q3TextStream(){    if ( owndev )	delete dev;    delete d;}/*!    \since 4.2    Positions the read pointer at the first non-whitespace character.*/void Q3TextStream::skipWhiteSpace(){    ts_ungetc( eat_ws() );}/*!    Tries to read \a len characters from the stream and stores them in    \a buf. Returns the number of characters really read.    \warning There will no QEOF appended if the read reaches the end    of the file. EOF is reached when the return value does not equal    \a len.*/uint Q3TextStream::ts_getbuf( QChar* buf, uint len ){    if ( len < 1 )	return 0;    uint rnum = 0;   // the number of QChars really read    if ( d && d->ungetcBuf.length() ) {	while ( rnum < len && rnum < uint(d->ungetcBuf.length()) ) {	    *buf = d->ungetcBuf.constref( rnum );	    buf++;	    rnum++;	}	d->ungetcBuf = d->ungetcBuf.mid( rnum );	if ( rnum >= len )	    return rnum;    }    // we use dev->ungetch() for one of the bytes of the unicode    // byte-order mark, but a local unget hack for the other byte:    int ungetHack = EOF;    if ( doUnicodeHeader ) {	doUnicodeHeader = FALSE; // only at the top	int c1 = dev->getch();	if ( c1 == EOF )	    return rnum;	int c2 = dev->getch();	if ( c1 == 0xfe && c2 == 0xff ) {	    mapper = 0;	    latin1 = FALSE;	    internalOrder = QChar::networkOrdered();	    networkOrder = TRUE;	} else if ( c1 == 0xff && c2 == 0xfe ) {	    mapper = 0;	    latin1 = FALSE;	    internalOrder = !QChar::networkOrdered();	    networkOrder = FALSE;	} else {	    if ( c2 != EOF ) {	 	dev->ungetch( c2 );		ungetHack = c1;	    } else {		/*		  A small bug might hide here. If only the first byte		  of a file has made it so far, and that first byte		  is half of the byte-order mark, then the utfness		  will not be detected.		*/	 	dev->ungetch( c1 );	    }	}    }#ifndef QT_NO_TEXTCODEC    if ( mapper ) {	bool shortRead = FALSE;        while( rnum < len ) {	    QString s;	    bool readBlock = !( len == 1+rnum );	    for (;;) {		// for efficiency: normally read a whole block		if ( readBlock ) {		    // guess buffersize; this may be wrong (too small or too		    // big). But we can handle this (either iterate reading		    // or use ungetcBuf).		    // Note that this might cause problems for codecs where		    // one byte can result in >1 Unicode Characters if bytes		    // are written to the stream in the meantime (loss of		    // synchronicity).		    uint rlen = len - rnum;		    char *cbuf = new char[ rlen ];		    if ( ungetHack != EOF ) {			rlen = 1+dev->readBlock( cbuf+1, rlen-1 );			cbuf[0] = (char)ungetHack;			ungetHack = EOF;		    } else {			rlen = dev->readBlock( cbuf, rlen );		    }		    s += mapper->toUnicode( cbuf, rlen, &mapperWriteState );		    delete[] cbuf;		    // use buffered reading only for the first time, because we		    // have to get the stream synchronous again (this is easier		    // with single character reading)		    readBlock = FALSE;		}		// get stream (and codec) in sync		int c;		if ( ungetHack == EOF ) {

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -