📄 qtextstream.cpp
字号:
} else { if ( !(c == '-' || c == '+') ) ts_ungetc( ch ); if ( c == '-' ) { ulong v = input_dec(); if ( v ) { // ensure that LONG_MIN can be read v--; val = -((long)v) - 1; } else { val = 0; } } else { val = (long)input_dec(); } } break; case hex: val = (long)input_hex(); break; default: val = 0; c = ch = eat_ws(); if ( c == '0' ) { // bin, oct or hex c = ch = ts_getc(); if ( tolower((uchar) c) == 'x' ) val = (long)input_hex(); else if ( tolower((uchar) c) == 'b' ) val = (long)input_bin(); else { // octal ts_ungetc( ch ); if ( c >= '0' && c <= '7' ) { val = (long)input_oct(); } else { val = 0; } } } else if ( ts_isdigit(ch) ) { ts_ungetc( ch ); val = (long)input_dec(); } else if ( c == '-' || c == '+' ) { ulong v = input_dec(); if ( c == '-' ) { if ( v ) { // ensure that LONG_MIN can be read v--; val = -((long)v) - 1; } else { val = 0; } } else { val = (long)v; } } } return val;}//// We use a table-driven FSM to parse floating point numbers// strtod() cannot be used directly since we're reading from a QIODevice//double QTextStream::input_double(){ const int Init = 0; // states const int Sign = 1; const int Mantissa = 2; const int Dot = 3; const int Abscissa = 4; const int ExpMark = 5; const int ExpSign = 6; const int Exponent = 7; const int Done = 8; const int InputSign = 1; // input tokens const int InputDigit = 2; const int InputDot = 3; const int InputExp = 4; static const uchar table[8][5] = { /* None InputSign InputDigit InputDot InputExp */ { 0, Sign, Mantissa, Dot, 0, }, // Init { 0, 0, Mantissa, Dot, 0, }, // Sign { Done, Done, Mantissa, Dot, ExpMark,}, // Mantissa { 0, 0, Abscissa, 0, 0, }, // Dot { Done, Done, Abscissa, Done, ExpMark,}, // Abscissa { 0, ExpSign, Exponent, 0, 0, }, // ExpMark { 0, 0, Exponent, 0, 0, }, // ExpSign { Done, Done, Exponent, Done, Done } // Exponent }; int state = Init; // parse state int input; // input token char buf[256]; int i = 0; QChar c = eat_ws(); for (;;) { switch ( c ) { case '+': case '-': input = InputSign; break; case '0': case '1': case '2': case '3': case '4': case '5': case '6': case '7': case '8': case '9': input = InputDigit; break; case '.': input = InputDot; break; case 'e': case 'E': input = InputExp; break; default: input = 0; break; } state = table[state][input]; if ( state == 0 || state == Done || i > 250 ) { if ( i > 250 ) { // ignore rest of digits do { c = ts_getc(); } while ( c != QEOF && ts_isdigit(c) ); } if ( c != QEOF ) ts_ungetc( c ); buf[i] = '\0'; char *end; return strtod( buf, &end ); } buf[i++] = c; c = ts_getc(); }#if !defined(Q_CC_EDG) return 0.0;#endif}/*! \overload Reads a signed \c short integer \a i from the stream and returns a reference to the stream. See flags() for an explanation of the expected input format.*/QTextStream &QTextStream::operator>>( signed short &i ){ CHECK_STREAM_PRECOND i = (signed short)input_int(); return *this;}/*! \overload Reads an unsigned \c short integer \a i from the stream and returns a reference to the stream. See flags() for an explanation of the expected input format.*/QTextStream &QTextStream::operator>>( unsigned short &i ){ CHECK_STREAM_PRECOND i = (unsigned short)input_int(); return *this;}/*! \overload Reads a signed \c int \a i from the stream and returns a reference to the stream. See flags() for an explanation of the expected input format.*/QTextStream &QTextStream::operator>>( signed int &i ){ CHECK_STREAM_PRECOND i = (signed int)input_int(); return *this;}/*! \overload Reads an unsigned \c int \a i from the stream and returns a reference to the stream. See flags() for an explanation of the expected input format.*/QTextStream &QTextStream::operator>>( unsigned int &i ){ CHECK_STREAM_PRECOND i = (unsigned int)input_int(); return *this;}/*! \overload Reads a signed \c long int \a i from the stream and returns a reference to the stream. See flags() for an explanation of the expected input format.*/QTextStream &QTextStream::operator>>( signed long &i ){ CHECK_STREAM_PRECOND i = (signed long)input_int(); return *this;}/*! \overload Reads an unsigned \c long int \a i from the stream and returns a reference to the stream. See flags() for an explanation of the expected input format.*/QTextStream &QTextStream::operator>>( unsigned long &i ){ CHECK_STREAM_PRECOND i = (unsigned long)input_int(); return *this;}/*! \overload Reads a \c float \a f from the stream and returns a reference to the stream. See flags() for an explanation of the expected input format.*/QTextStream &QTextStream::operator>>( float &f ){ CHECK_STREAM_PRECOND f = (float)input_double(); return *this;}/*! \overload Reads a \c double \a f from the stream and returns a reference to the stream. See flags() for an explanation of the expected input format.*/QTextStream &QTextStream::operator>>( double &f ){ CHECK_STREAM_PRECOND f = input_double(); return *this;}/*! \overload Reads a "word" from the stream into \a s and returns a reference to the stream. A word consists of characters for which isspace() returns FALSE.*/QTextStream &QTextStream::operator>>( char *s ){ CHECK_STREAM_PRECOND int maxlen = width( 0 ); QChar c = eat_ws(); if ( !maxlen ) maxlen = -1; while ( c != QEOF ) { if ( ts_isspace(c) || maxlen-- == 0 ) { ts_ungetc( c ); break; } *s++ = c; c = ts_getc(); } *s = '\0'; return *this;}/*! \overload Reads a "word" from the stream into \a str and returns a reference to the stream. A word consists of characters for which isspace() returns FALSE.*/QTextStream &QTextStream::operator>>( QString &str ){ CHECK_STREAM_PRECOND str=QString::fromLatin1(""); QChar c = eat_ws(); while ( c != QEOF ) { if ( ts_isspace(c) ) { ts_ungetc( c ); break; } str += c; c = ts_getc(); } return *this;}/*! \overload Reads a "word" from the stream into \a str and returns a reference to the stream. A word consists of characters for which isspace() returns FALSE.*/QTextStream &QTextStream::operator>>( QCString &str ){ CHECK_STREAM_PRECOND QCString *dynbuf = 0; const int buflen = 256; char buffer[buflen]; char *s = buffer; int i = 0; QChar c = eat_ws(); while ( c != QEOF ) { if ( ts_isspace(c) ) { ts_ungetc( c ); break; } if ( i >= buflen-1 ) { if ( !dynbuf ) { // create dynamic buffer dynbuf = new QCString(buflen*2); memcpy( dynbuf->data(), s, i ); // copy old data } else if ( i >= (int)dynbuf->size()-1 ) { dynbuf->resize( dynbuf->size()*2 ); } s = dynbuf->data(); } s[i++] = c; c = ts_getc(); } str.resize( i+1 ); memcpy( str.data(), s, i ); delete dynbuf; return *this;}/*! Reads a line from the stream and returns a string containing the text. The returned string does not contain any trailing newline or carriage return. Note that this is different from QIODevice::readLine(), which does not strip the newline at the end of the line. On EOF you will get a QString that is null. On reading an empty line the returned QString is empty but not null. \sa QIODevice::readLine()*/QString QTextStream::readLine(){#if defined(QT_CHECK_STATE) if ( !dev ) { qWarning( "QTextStream::readLine: No device" ); return QString::null; }#endif bool readCharByChar = TRUE; QString result;#if 0 if ( !doUnicodeHeader && ( (latin1) || (mapper != 0 && mapper->mibEnum() == 106 ) // UTF 8 ) ) { readCharByChar = FALSE; // use optimized read line QChar c[getline_buf_size]; int pos = 0; bool eof = FALSE; for (;;) { pos = ts_getline( c ); if ( pos == 0 ) { // something went wrong; try fallback readCharByChar = TRUE; //dev->resetStatus(); break; } if ( c[pos-1] == QEOF || c[pos-1] == '\n' ) { if ( pos>2 && c[pos-1]==QEOF && c[pos-2]=='\n' ) { result += QString( c, pos-2 ); } else if ( pos > 1 ) { result += QString( c, pos-1 ); } if ( pos == 1 && c[pos-1] == QEOF ) eof = TRUE; break; } else { result += QString( c, pos ); } } if ( eof && result.isEmpty() ) return QString::null; }#endif if ( readCharByChar ) { const int buf_size = 256; QChar c[buf_size]; int pos = 0; c[pos] = ts_getc(); if ( c[pos] == QEOF ) return QString::null; while ( c[pos] != QEOF && c[pos] != '\n' ) { if ( c[pos] == '\r' ) { // ( handle mac and dos ) QChar nextc = ts_getc(); if ( nextc != '\n' ) ts_ungetc( nextc ); break; } pos++; if ( pos >= buf_size ) { result += QString( c, pos ); pos = 0; } c[pos] = ts_getc(); } result += QString( c, pos ); } return result;}/*! Reads the entire stream and returns a string containing the text. \sa QIODevice::readLine()*/QString QTextStream::read(){#if defined(QT_CHECK_STATE) if ( !dev ) { qWarning( "QTextStream::read: No device" ); return QString::null; }#endif QString result; const uint bufsize = 512; QChar buf[bufsize]; uint i, num, start; bool skipped_cr = FALSE; for (;;) { num = ts_getbuf(buf,bufsize); // convert dos (\r\n) and mac (\r) style eol to unix style (\n) start = 0; for ( i=0; i<num; i++ ) { if ( buf[i] == '\r' ) { // Only skip single cr's preceding lf's if ( skipped_cr ) { result += buf[i]; start++; } else { result += QString( &buf[start], i-start ); start = i+1; skipped_cr = TRUE; } } else { if ( skipped_cr ) { if ( buf[i] != '\n' ) { // Should not have skipped it result += '\n'; } skipped_cr = FALSE; } } } if ( start < num ) result += QString( &buf[start], i-start ); if ( num != bufsize ) // if ( EOF ) break; } return result;}/***************************************************************************** QTextStream write functions *****************************************************************************//*! Writes character \c char to the stream and returns a reference to the stream. The character \a c is assumed to be Latin1 encoded independent of the Encoding set for the QTextStream.*/QTextStream &QTextStream::operator<<( QChar c ){ CHECK_STREAM_PRECOND ts_putc( c ); return *this;}/*! \overload Writes character \a c to the stream and returns a reference to the stream.*/QTextStream &QTextStream::operator<<( char c ){ CHECK_STREAM_PRECOND unsigned char uc = (unsigned char) c; ts_putc( uc ); return *this;}QTextStream &QTextStream::output_int( int format, ulong n, bool neg ){ static const char hexdigits_lower[] = "0123456789abcdef"; static const char hexdigits_upper[] = "0123456789ABCDEF"; CHECK_STREAM_PRECOND char buf[76]; register char *p; int len; const char *hexdigits; switch ( flags() & I_BASE_MASK ) { case I_BASE_2: // output binary number switch ( format & I_TYPE_MASK ) { case I_SHORT: len=16; break; case I_INT: len=sizeof(int)*8; break; case I_LONG: len=32; break; default: len = 0; } p = &buf[74]; // go reverse order *p = '\0'; while ( len-- ) { *--p = (char)(n&1) + '0'; n >>= 1; if ( !n ) break; } if ( flags() & showbase ) { // show base *--p = (flags() & uppercase) ? 'B' : 'b'; *--p = '0'; } break; case I_BASE_8: // output octal number p = &buf[74]; *p = '\0'; do { *--p = (char)(n&7) + '0'; n >>= 3; } while ( n ); if ( flags() & showbase ) *--p = '0'; break; case I_BASE_16: // output hexadecimal number p = &buf[74]; *p = '\0'; hexdigits = (flags() & uppercase) ? hexdigits_upper : hexdigits_lower; do { *--p = hexdigits[(int)n&0xf]; n >>= 4; } while ( n ); if ( flags() & showbase ) { *--p = (flags() & uppercase) ? 'X' : 'x'; *--p = '0'; } break; default: // decimal base is default p = &buf[74]; *p = '\0'; if ( neg ) n = (ulong)(-(long)n); do { *--p = ((int)(n%10)) + '0'; n /= 10; } while ( n ); if ( neg ) *--p = '-'; else if ( flags() & showpos ) *--p = '+'; if ( (flags() & internal) && fwidth && !ts_isdigit(*p) ) { ts_putc( *p ); // special case for internal ++p; // padding fwidth--; return *this << (const char*)p; } } if ( fwidth ) { // adjustment required if ( !(flags() & left) ) { // but NOT left adjustment len = qstrlen(p); int padlen = fwidth - len; if ( padlen <= 0 ) { // no padding required writeBlock( p, len ); } else if ( padlen < (int)(p-buf) ) { // speeds up padding memset( p-padlen, (char)fillchar, padlen ); writeBlock( p-padlen, padlen+len ); } else // standard padding *this << (const char*)p; } else *this << (const char*)p; fwidth = 0; // reset field width } else writeBlock( p, qstrlen(p) ); return *this;}/*!
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -