📄 q3textstream.cpp
字号:
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 Q3TextStream::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.toLatin1() ) { 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.toLatin1(); 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.*/Q3TextStream &Q3TextStream::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.*/Q3TextStream &Q3TextStream::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.*/Q3TextStream &Q3TextStream::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.*/Q3TextStream &Q3TextStream::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.*/Q3TextStream &Q3TextStream::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.*/Q3TextStream &Q3TextStream::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.*/Q3TextStream &Q3TextStream::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.*/Q3TextStream &Q3TextStream::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.*/Q3TextStream &Q3TextStream::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.toLatin1(); 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.*/Q3TextStream &Q3TextStream::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.*/Q3TextStream &Q3TextStream::operator>>( Q3CString &str ){ CHECK_STREAM_PRECOND Q3CString *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 Q3CString(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.toLatin1(); c = ts_getc(); } str.resize( i ); memcpy( str.data(), s, i ); delete dynbuf; return *this;}/*! \since 4.2 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 Q3TextStream::readLine(){#if defined(QT_CHECK_STATE) if ( !dev ) { qWarning( "Q3TextStream::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] != QLatin1Char('\n') ) { if ( c[pos] == QLatin1Char('\r') ) { // ( handle mac and dos ) QChar nextc = ts_getc(); if ( nextc != QLatin1Char('\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;}/*! \since 4.2 Reads the entire stream from the current position, and returns a string containing the text. \sa readLine()*/QString Q3TextStream::read(){#if defined(QT_CHECK_STATE) if ( !dev ) { qWarning( "Q3TextStream::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] == QLatin1Char('\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] != QLatin1Char('\n') ) { // Should not have skipped it result += QLatin1Char('\n'); } skipped_cr = FALSE; } } } if ( start < num ) result += QString( &buf[start], i-start ); if ( num != bufsize ) // if ( EOF ) break; } return result;}/***************************************************************************** Q3TextStream write functions *****************************************************************************//*! \since 4.2 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 Q3TextStream.*/Q3TextStream &Q3TextStream::operator<<( QChar c ){ CHECK_STREAM_PRECOND ts_putc( c ); return *this;}/*! \overload \since 4.2 Writes character \a c to the stream and returns a reference to the stream.*/Q3TextStream &Q3TextStream::operator<<( char c ){ CHECK_STREAM_PRECOND unsigned char uc = (unsigned char) c; ts_putc( uc ); return *this;}Q3TextStream &Q3TextStream::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(QLatin1Char(*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;
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -