/* * Copyright (C) 2007-2023 Xagasoft, All rights reserved. * * This file is part of the libbu++ library and is released under the * terms of the license contained in the file LICENSE. */ #include "bu/formatter.h" #include "bu/stream.h" #include template<> float Bu::tlog( float x ) { return logf( x ); } template<> double Bu::tlog( double x ) { return log( x ); } template<> long double Bu::tlog( long double x ) { return logl( x ); } template<> float Bu::tfloor( float x ) { return floorf( x ); } template<> double Bu::tfloor( double x ) { return floor( x ); } template<> long double Bu::tfloor( long double x ) { return floorl( x ); } template<> float Bu::tpow( float x, float y ) { return powf( x, y ); } template<> double Bu::tpow( double x, double y ) { return pow( x, y ); } template<> long double Bu::tpow( long double x, long double y ) { return powl( x, y ); } Bu::Formatter::Formatter( Stream &rStream ) : rStream( rStream ), bTempFmt( false ), uIndent( 0 ), cIndent( '\t' ) { } Bu::Formatter::~Formatter() { } void Bu::Formatter::write( const Bu::String &sStr ) { rStream.write( sStr ); } void Bu::Formatter::write( const void *sStr, int iLen ) { rStream.write( sStr, iLen ); } void Bu::Formatter::writeAligned( const Bu::String &sStr ) { int iLen = sStr.getSize(); if( iLen == 0 ) return; if( iLen > fLast.uMinWidth ) { write( sStr ); } else { int iRem = fLast.uMinWidth - iLen; switch( fLast.uAlign ) { case Fmt::Right: for( int k = 0; k < iRem; k++ ) write( &fLast.cFillChar, 1 ); write( sStr ); break; case Fmt::Center: { int iHlf = iRem/2; for( int k = 0; k < iHlf; k++ ) write( &fLast.cFillChar, 1 ); write( sStr ); iHlf = iRem-iHlf;; for( int k = 0; k < iHlf; k++ ) write( &fLast.cFillChar, 1 ); } break; case Fmt::Left: write( sStr ); for( int k = 0; k < iRem; k++ ) write( &fLast.cFillChar, 1 ); break; } } usedFormat(); } void Bu::Formatter::writeAligned( const char *sStr, int iLen ) { if( iLen > fLast.uMinWidth ) { write( sStr, iLen ); } else { int iRem = fLast.uMinWidth - iLen; switch( fLast.uAlign ) { case Fmt::Right: for( int k = 0; k < iRem; k++ ) write( &fLast.cFillChar, 1 ); write( sStr, iLen ); break; case Fmt::Center: { int iHlf = iRem/2; for( int k = 0; k < iHlf; k++ ) write( &fLast.cFillChar, 1 ); write( sStr, iLen ); iHlf = iRem-iHlf;; for( int k = 0; k < iHlf; k++ ) write( &fLast.cFillChar, 1 ); } break; case Fmt::Left: write( sStr, iLen ); for( int k = 0; k < iRem; k++ ) write( &fLast.cFillChar, 1 ); break; } } usedFormat(); } void Bu::Formatter::read( void *sStr, int iLen ) { rStream.read( sStr, iLen ); } Bu::String Bu::Formatter::readToken() { Bu::String sRet; if( fLast.bTokenize ) { for(;;) { char buf; int iRead = rStream.read( &buf, 1 ); if( iRead == 0 ) return sRet; if( buf == ' ' || buf == '\t' || buf == '\n' || buf == '\r' ) continue; else { sRet += buf; break; } } for(;;) { char buf; int iRead = rStream.read( &buf, 1 ); if( iRead == 0 ) return sRet; if( buf == ' ' || buf == '\t' || buf == '\n' || buf == '\r' ) return sRet; else sRet += buf; } } else { for(;;) { char buf; int iRead = rStream.read( &buf, 1 ); if( iRead == 0 ) return sRet; else sRet += buf; } } } void Bu::Formatter::incIndent() { if( uIndent < 0xFFU ) uIndent++; } void Bu::Formatter::decIndent() { if( uIndent > 0 ) uIndent--; } void Bu::Formatter::setIndent( uint8_t uLevel ) { uIndent = uLevel; } void Bu::Formatter::clearIndent() { uIndent = 0; } void Bu::Formatter::setIndentChar( char cIndent ) { this->cIndent = cIndent; } void Bu::Formatter::doFlush() { rStream.flush(); } Bu::Fmt &Bu::Fmt::width( unsigned int uWidth ) { this->uMinWidth = uWidth; return *this; } Bu::Fmt &Bu::Fmt::fill( char cFill ) { this->cFillChar = (unsigned char)cFill; return *this; } Bu::Fmt &Bu::Fmt::radix( unsigned int uRadix ) { this->uRadix = uRadix; return *this; } Bu::Fmt &Bu::Fmt::align( Alignment eAlign ) { this->uAlign = eAlign; return *this; } Bu::Fmt &Bu::Fmt::left() { this->uAlign = Fmt::Left; return *this; } Bu::Fmt &Bu::Fmt::center() { this->uAlign = Fmt::Center; return *this; } Bu::Fmt &Bu::Fmt::right() { this->uAlign = Fmt::Right; return *this; } Bu::Fmt &Bu::Fmt::plus( bool bPlus ) { this->bPlus = bPlus; return *this; } Bu::Fmt &Bu::Fmt::caps( bool bCaps ) { this->bCaps = bCaps; return *this; } Bu::Fmt &Bu::Fmt::upper() { this->bCaps = true; return *this; } Bu::Fmt &Bu::Fmt::lower() { this->bCaps = false; return *this; } Bu::Fmt &Bu::Fmt::tokenize( bool bTokenize ) { this->bTokenize = bTokenize; return *this; } Bu::Formatter &Bu::operator<<( Bu::Formatter &f, const Bu::Fmt &fmt ) { f.setTempFormat( fmt ); return f; } Bu::Formatter &Bu::operator<<( Bu::Formatter &f, Bu::Formatter::Special s ) { switch( s ) { case Formatter::nl: { #ifdef WIN32 f.write("\r\n", 2 ); #else f.write("\n", 1 ); #endif char ci = f.getIndentChar(); for( int j = 0; j < f.getIndent(); j++ ) f.write( &ci, 1 ); f.doFlush(); } break; case Formatter::flush: f.doFlush(); break; } return f; } Bu::Formatter &Bu::operator<<( Bu::Formatter &f, const char *sStr ) { f.writeAligned( sStr, strlen( sStr ) ); return f; } Bu::Formatter &Bu::operator<<( Bu::Formatter &f, const Bu::String &sStr ) { f.writeAligned( sStr ); return f; } Bu::Formatter &Bu::operator<<( Bu::Formatter &f, signed char c ) { f.ifmt( c ); //f.write( (char *)&c, 1 ); return f; } Bu::Formatter &Bu::operator<<( Bu::Formatter &f, char c ) { f.write( (char *)&c, 1 ); return f; } Bu::Formatter &Bu::operator<<( Bu::Formatter &f, unsigned char c ) { f.ufmt( c ); //f.write( (char *)&c, 1 ); return f; } Bu::Formatter &Bu::operator<<( Bu::Formatter &f, signed short int i ) { f.ifmt( i ); return f; } Bu::Formatter &Bu::operator<<( Bu::Formatter &f, unsigned short int i ) { f.ufmt( i ); return f; } Bu::Formatter &Bu::operator<<( Bu::Formatter &f, signed int i ) { f.ifmt( i ); return f; } Bu::Formatter &Bu::operator<<( Bu::Formatter &f, unsigned int i ) { f.ufmt( i ); return f; } Bu::Formatter &Bu::operator<<( Bu::Formatter &f, signed long int i ) { f.ifmt( i ); return f; } Bu::Formatter &Bu::operator<<( Bu::Formatter &f, unsigned long int i ) { f.ufmt( i ); return f; } Bu::Formatter &Bu::operator<<( Bu::Formatter &f, signed long long int i ) { f.ifmt( i ); return f; } Bu::Formatter &Bu::operator<<( Bu::Formatter &f, unsigned long long int i ) { f.ufmt( i ); return f; } Bu::Formatter &Bu::operator<<( Bu::Formatter &f, float flt ) { f.ffmt( flt ); return f; } Bu::Formatter &Bu::operator<<( Bu::Formatter &f, double flt ) { f.ffmt( flt ); return f; } Bu::Formatter &Bu::operator<<( Bu::Formatter &f, long double flt ) { f.ffmt( flt ); return f; } Bu::Formatter &Bu::operator<<( Bu::Formatter &f, bool b ) { f.writeAligned( b?("true"):("false") ); return f; } Bu::Formatter &Bu::operator>>( Bu::Formatter &f, Bu::String &sStr ) { sStr = f.readToken(); return f; } Bu::Formatter &Bu::operator>>( Bu::Formatter &f, signed char &c ) { f.read( &c, 1 ); return f; } Bu::Formatter &Bu::operator>>( Bu::Formatter &f, char &c ) { f.read( &c, 1 ); return f; } Bu::Formatter &Bu::operator>>( Bu::Formatter &f, unsigned char &c ) { f.read( &c, 1 ); return f; } Bu::Formatter &Bu::operator>>( Bu::Formatter &f, signed short int &i ) { f.iparse( i, f.readToken() ); return f; } Bu::Formatter &Bu::operator>>( Bu::Formatter &f, unsigned short int &i ) { f.uparse( i, f.readToken() ); return f; } Bu::Formatter &Bu::operator>>( Bu::Formatter &f, signed int &i ) { f.iparse( i, f.readToken() ); return f; } Bu::Formatter &Bu::operator>>( Bu::Formatter &f, unsigned int &i ) { f.uparse( i, f.readToken() ); return f; } Bu::Formatter &Bu::operator>>( Bu::Formatter &f, signed long int &i ) { f.iparse( i, f.readToken() ); return f; } Bu::Formatter &Bu::operator>>( Bu::Formatter &f, unsigned long int &i ) { f.uparse( i, f.readToken() ); return f; } Bu::Formatter &Bu::operator>>( Bu::Formatter &f, signed long long int &i ) { f.iparse( i, f.readToken() ); return f; } Bu::Formatter &Bu::operator>>( Bu::Formatter &f, unsigned long long int &i ) { f.uparse( i, f.readToken() ); return f; } Bu::Formatter &Bu::operator>>( Bu::Formatter &f, float &flt ) { f.fparse( flt, f.readToken() ); return f; } Bu::Formatter &Bu::operator>>( Bu::Formatter &f, double &flt ) { f.fparse( flt, f.readToken() ); return f; } Bu::Formatter &Bu::operator>>( Bu::Formatter &f, long double &flt ) { f.fparse( flt, f.readToken() ); return f; } Bu::Formatter &Bu::operator>>( Bu::Formatter &f, bool &b ) { Bu::String sStr = f.readToken(); if( !sStr.isSet() ) return f; char c = *sStr.begin(); if( c == 'y' || c == 'Y' || c == 't' || c == 'T' ) b = true; else if( c == 'n' || c == 'N' || c == 'f' || c == 'F' ) b = false; return f; }