@@ -36,26 +36,126 @@
template < typename P >
class PITextStream {
public :
PITextStream ( PIBinaryStream < P > * stream ) : s ( stream ) { }
//! \~english Floating-point numbers write format
//! \~russian Формат записи чисел с плавающей точкой
enum FloatFormat {
DecimalFormat /** \~english Decimal format, "*.*" \~russian Десятичный формат, "*.*" */ = ' f ' ,
ExponentFormat /** \~english Exponential format, "*e+-<E>" \~russian Экспонентный формат, "*e+-<E>" */ = ' e '
} ;
//! \~english String encoding
//! \~russian Кодировка строк
enum Encoding {
System /** \~english System encoding \~russian Системная кодировка */ ,
UTF8 /** \~english UTF-8 encoding \~russian Кодировка UTF-8 */ ,
} ;
//! \~english Construct text stream binded to "stream_"
//! \~russian Возвращает привязанный к "stream_" текстовый поток
PITextStream ( PIBinaryStream < P > * stream_ ) { setStream ( stream_ ) ; }
//! \~english Returns binded PIBinaryStream
//! \~russian Возвращает привязанный PIBinaryStream
PIBinaryStream < P > * stream ( ) const { return s ; }
void setStream ( PIBinaryStream < P > * stream_ ) {
s = stream_ ;
is_end = false ;
}
//! \~english Returns if end of stream reached
//! \~russian Возвращает достигнут ли конец потока
bool isEnd ( ) const { return is_end ; }
//! \~english Returns read/write encoding
//! \~russian Возвращает кодировку чтения/записи
Encoding encoding ( ) const { return enc ; }
//! \~english Set read/write encoding, default UTF8
//! \~russian Устанавливает кодировку чтения/записи, по умолчанию UTF8
void setEncoding ( Encoding e ) { enc = e ; }
//! \~english Returns float numbers write format
//! \~russian Возвращает формат записи чисел с плавающей точкой
FloatFormat floatFormat ( ) const { return format_ ; }
//! \~english Set float numbers write format, default DecimalFormat
//! \~russian Устанавливает формат записи чисел с плавающей точкой, по умолчанию DecimalFormat
void setFloatFormat ( FloatFormat format ) { format_ = format ; }
//! \~english Returns float numbers write precision
//! \~russian Возвращает точность записи чисел с плавающей точкой
int floatPrecision ( ) const { return prec_ ; }
//! \~english Set float numbers write precision to "prec_" digits, default 5
//! \~russian Устанавливает точность записи чисел с плавающей точкой, по умолчанию 5
void setFloatPrecision ( int prec ) { prec_ = prec ; }
//! \~english Append space
//! \~russian Добавляет пробел
PITextStream < P > & space ( ) { s - > binaryStreamAppend ( ' ' ) ; return * this ; }
//! \~english Append new line
//! \~russian Добавляет новую строку
PITextStream < P > & newLine ( ) { s - > binaryStreamAppend ( ' \n ' ) ; return * this ; }
//! \~english Append "v" string
//! \~russian Добавляет строку "v"
void append ( const PIString & v ) {
if ( v . isEmpty ( ) ) return ;
auto utf8 = v . toUTF8 ( ) ;
s - > binaryStreamAppend ( utf8 . data ( ) , utf8 . size ( ) ) ;
PIByteArray d ;
switch ( enc ) {
case System : d = v . toSystem ( ) ; break ;
case UTF8 : d = v . toUTF8 ( ) ; break ;
}
s - > binaryStreamAppend ( d . data ( ) , d . size ( ) ) ;
}
//! \~english Append "v" as ASCII
//! \~russian Добавляет "v" как ASCII
void append ( const PIConstChars & v ) { if ( ! v . isEmpty ( ) ) s - > binaryStreamAppend ( v . data ( ) , v . size ( ) ) ; }
//! \~english Append "v" char as character
//! \~russian Добавляет "v" как символ
void append ( char v ) { s - > binaryStreamAppend ( v ) ; }
//! \~english Append "v" as ASCII
//! \~russian Добавляет "v" как ASCII
void append ( const char * v ) { append ( PIConstChars ( v ) ) ; }
//! \~english Append boolean, "true" of "false"
//! \~russian Добавляет логическое, "true" of "false"
void append ( bool v ) { append ( v ? " true " : " false " ) ; }
//! \~english Append integer
//! \~russian Добавляет целое
void append ( int v ) { append ( PIString : : fromNumber ( v ) ) ; }
//! \~english Append integer
//! \~russian Добавляет целое
void append ( llong v ) { append ( PIString : : fromNumber ( v ) ) ; }
void append ( float v ) { append ( PIString : : fromNumber ( v ) ) ; }
void append ( double v ) { append ( PIString : : fromNumber ( v ) ) ; }
char takeChar ( bool * ok ) { return ( char ) s - > binaryStreamTakeByte ( ok ) ; }
//! \~english Append floating-point number, using \a floatFormat() and \a floatPrecision()
//! \~russian Добавляет число с плавающей точкой, используя \a floatFormat() и \a floatPrecision()
void append ( float v ) { append ( PIString : : fromNumber ( v , ( char ) format_ , prec_ ) ) ; }
//! \~english Append floating-point number, using \a floatFormat() and \a floatPrecision()
//! \~russian Добавляет число с плавающей точкой, используя \a floatFormat() и \a floatPrecision()
void append ( double v ) { append ( PIString : : fromNumber ( v , ( char ) format_ , prec_ ) ) ; }
//! \~english Read character
//! \~russian Читает символ
char takeChar ( bool * rok ) {
bool ok = true ;
char ret = ( char ) s - > binaryStreamTakeByte ( & ok ) ;
if ( ! ok ) is_end = true ;
if ( rok ) * rok = ok ;
return ret ;
}
//! \~english Read line
//! \~russian Читает строку
PIString takeLine ( ) {
PIByteArray ret ;
bool ok = true ;
@@ -65,23 +165,36 @@ public:
if ( b ! = ' \r ' )
ret . append ( ( uchar ) b ) ;
}
return PIString : : fromUTF8 ( ret ) ;
return fromBytes ( ret ) ;
}
//! \~english Read word, skip leading whitespaces, until next whitespace
//! \~russian Читает слово, пропуская начальные пробельные символы, до следующего пробельного символа
PIString takeWord ( ) {
static PIConstChars spaces ( " \t \n \r " ) ;
return takeUntil ( spaces ) ;
}
//! \~english
//! \~russian
PIString takeCWord ( ) {
static PIConstChars chars ( " \t \n \r :;%$&#@!?~/*-+=., \\ \" '`[](){}<> " ) ;
return takeUntil ( chars ) ;
}
private :
PIString fromBytes ( const PIByteArray & ba ) {
switch ( enc ) {
case System : return PIString : : fromSystem ( ba ) ;
case UTF8 : return PIString : : fromUTF8 ( ba ) ;
}
return PIString ( ) ;
}
PIString takeUntil ( const PIConstChars & chars ) {
static PIConstChars spaces( " \t \n \r " ) ;
// static PIConstChars spaces(" \t\n\r");
bool ok = true ;
char c = skipWhile ( space s, & ok ) ;
if ( ! ok | | chars . contains ( c ) ) return PIString ( ) ;
char c = skipWhile ( char s, & ok ) ;
if ( ! ok ) return PIString ( ) ;
PIByteArray ret ;
ret . append ( ( uchar ) c ) ;
for ( ; ; ) {
@@ -89,7 +202,7 @@ private:
if ( ! ok | | chars . contains ( c ) ) break ;
ret . append ( ( uchar ) c ) ;
}
return PIString : : fromUTF8 ( ret ) ;
return fromBytes ( ret ) ;
}
// returns first non-"chars" char
char skipWhile ( const PIConstChars & chars , bool * rok ) {
@@ -104,26 +217,125 @@ private:
}
PIBinaryStream < P > * s ;
Encoding enc = UTF8 ;
FloatFormat format_ = DecimalFormat ;
bool is_end = false ;
int prec_ = 5 ;
} ;
//! \~english Returns PITextStream for binary stream "stream"
//! \~russian Возвращает PITextStream для бинарного потока "stream"
template < typename P >
inline PITextStream < P > createPITextStream ( PIBinaryStream < P > * stream ) { return PITextStream < P > ( stream ) ; }
//! \~english Append boolean
//! \~russian Добавляет логическое
template < typename P > inline PITextStream < P > & operator < < ( PITextStream < P > & s , bool v ) { s . append ( v ) ; return s ; }
//! \~english Append character
//! \~russian Добавляет символ
template < typename P > inline PITextStream < P > & operator < < ( PITextStream < P > & s , char v ) { s . append ( v ) ; return s ; }
//! \~english Append integer
//! \~russian Добавляет целое
template < typename P > inline PITextStream < P > & operator < < ( PITextStream < P > & s , uchar v ) { s . append ( ( int ) v ) ; return s ; }
//! \~english Append integer
//! \~russian Добавляет целое
template < typename P > inline PITextStream < P > & operator < < ( PITextStream < P > & s , short v ) { s . append ( ( int ) v ) ; return s ; }
//! \~english Append integer
//! \~russian Добавляет целое
template < typename P > inline PITextStream < P > & operator < < ( PITextStream < P > & s , ushort v ) { s . append ( ( int ) v ) ; return s ; }
//! \~english Append integer
//! \~russian Добавляет целое
template < typename P > inline PITextStream < P > & operator < < ( PITextStream < P > & s , int v ) { s . append ( ( int ) v ) ; return s ; }
//! \~english Append integer
//! \~russian Добавляет целое
template < typename P > inline PITextStream < P > & operator < < ( PITextStream < P > & s , uint v ) { s . append ( ( int ) v ) ; return s ; }
//! \~english Append integer
//! \~russian Добавляет целое
template < typename P > inline PITextStream < P > & operator < < ( PITextStream < P > & s , llong v ) { s . append ( ( llong ) v ) ; return s ; }
//! \~english Append integer
//! \~russian Добавляет целое
template < typename P > inline PITextStream < P > & operator < < ( PITextStream < P > & s , ullong v ) { s . append ( ( llong ) v ) ; return s ; }
//! \~english Append floating-point number
//! \~russian Добавляет число с плавающей точкой
template < typename P > inline PITextStream < P > & operator < < ( PITextStream < P > & s , float v ) { s . append ( v ) ; return s ; }
//! \~english Append floating-point number
//! \~russian Добавляет число с плавающей точкой
template < typename P > inline PITextStream < P > & operator < < ( PITextStream < P > & s , double v ) { s . append ( v ) ; return s ; }
//! \~english Append string
//! \~russian Добавляет строку
template < typename P > inline PITextStream < P > & operator < < ( PITextStream < P > & s , const char * v ) { s . append ( v ) ; return s ; }
//! \~english Append string
//! \~russian Добавляет строку
template < typename P > inline PITextStream < P > & operator < < ( PITextStream < P > & s , const PIConstChars & v ) { s . append ( v ) ; return s ; }
//! \~english Append string
//! \~russian Добавляет строку
template < typename P > inline PITextStream < P > & operator < < ( PITextStream < P > & s , const PIString & v ) { s . append ( v ) ; return s ; }
//! \~english Read word as bool
//! \~russian Читает слово как логическое
template < typename P > inline PITextStream < P > & operator > > ( PITextStream < P > & s , bool & v ) { v = s . takeWord ( ) . toBool ( ) ; return s ; }
//! \~english Read character
//! \~russian Читает символ
template < typename P > inline PITextStream < P > & operator > > ( PITextStream < P > & s , char & v ) { v = s . takeChar ( ) ; return s ; }
//! \~english Read word as integer
//! \~russian Читает слово как целое
template < typename P > inline PITextStream < P > & operator > > ( PITextStream < P > & s , uchar & v ) { v = s . takeWord ( ) . toUInt ( ) ; return s ; }
//! \~english Read word as integer
//! \~russian Читает слово как целое
template < typename P > inline PITextStream < P > & operator > > ( PITextStream < P > & s , short & v ) { v = s . takeWord ( ) . toInt ( ) ; return s ; }
//! \~english Read word as integer
//! \~russian Читает слово как целое
template < typename P > inline PITextStream < P > & operator > > ( PITextStream < P > & s , ushort & v ) { v = s . takeWord ( ) . toUInt ( ) ; return s ; }
//! \~english Read word as integer
//! \~russian Читает слово как целое
template < typename P > inline PITextStream < P > & operator > > ( PITextStream < P > & s , int & v ) { v = s . takeWord ( ) . toInt ( ) ; return s ; }
//! \~english Read word as integer
//! \~russian Читает слово как целое
template < typename P > inline PITextStream < P > & operator > > ( PITextStream < P > & s , uint & v ) { v = s . takeWord ( ) . toUInt ( ) ; return s ; }
//! \~english Read word as integer
//! \~russian Читает слово как целое
template < typename P > inline PITextStream < P > & operator > > ( PITextStream < P > & s , llong & v ) { v = s . takeWord ( ) . toLLong ( ) ; return s ; }
//! \~english Read word as integer
//! \~russian Читает слово как целое
template < typename P > inline PITextStream < P > & operator > > ( PITextStream < P > & s , ullong & v ) { v = s . takeWord ( ) . toULLong ( ) ; return s ; }
//! \~english Read word as floating-point number
//! \~russian Читает слово как число с плавающей точкой
template < typename P > inline PITextStream < P > & operator > > ( PITextStream < P > & s , float & v ) { v = s . takeWord ( ) . toFloat ( ) ; return s ; }
//! \~english Read word as floating-point number
//! \~russian Читает слово как число с плавающей точкой
template < typename P > inline PITextStream < P > & operator > > ( PITextStream < P > & s , double & v ) { v = s . takeWord ( ) . toDouble ( ) ; return s ; }
//! \~english Read word
//! \~russian Читает слово
template < typename P > inline PITextStream < P > & operator > > ( PITextStream < P > & s , PIString & v ) { v = s . takeWord ( ) ; return s ; }
# endif