//---------------------------------------------------------------------------- // EgalTech 2013-2014 //---------------------------------------------------------------------------- // File : Scanner.cpp Data : 17.06.14 Versione : 1.5f3 // Contenuto : Implementazione della classe Scanner. // Scansione di file di testo con codifica UTF-8 (anche con BOM) // e quindi anche ASCII. // // // Modifiche : 30.09.13 DS Creazione modulo. // 06.03.14 DS Aggiunta UngetLine. // 17.04.14 DS Aggiunto parametro bSkipEmptyLine a Init. // 17.06.14 DS Lettura di file compressi con formato gzip. // //---------------------------------------------------------------------------- //--------------------------- Include ---------------------------------------- #include "stdafx.h" #include "/EgtDEv/Include/EGnScanner.h" #include "/EgtDEv/Include/EGnStringUtils.h" #include "/EgtDEv/Include/EgtStringConverter.h" #include "/EgtDev/Extern/Zlib/Include/zlib.h" using namespace std ; //---------------------------------------------------------------------------- bool Scanner::Init( const string& sFile, const char* szRemInit, bool bSkipEmptyLine) { // apertura del file di ingresso m_InFile = gzopen_w( stringtoW( sFile), "rb") ; if ( m_InFile != nullptr) { const int DIM_BUFFER = 65536 ; gzbuffer( m_InFile, DIM_BUFFER) ; } // reset vari m_nLineNbr = 0 ; m_bUnget = false ; m_nDeltaLineUnget = 0 ; // salvo path file m_sFName = sFile ; // assegno i caratteri di inizio commento if ( szRemInit != nullptr) m_sRemInit = szRemInit ; else m_sRemInit = "" ; m_bFindRem = ! m_sRemInit.empty() ; // assegno flag per saltare linee vuote m_bSkipEmptyLine = bSkipEmptyLine ; return ( m_InFile != nullptr) ; } //---------------------------------------------------------------------------- bool Scanner::Terminate( void) { if ( m_InFile != nullptr) { bool bOk = ( gzclose( m_InFile) == Z_OK) ; m_InFile = nullptr ; return bOk ; } return true ; } //---------------------------------------------------------------------------- bool Scanner::GetLine( string& sLine) { if ( m_InFile == nullptr) return false ; if ( m_bUnget) { sLine = m_sUnget ; m_bUnget = false ; m_nLineNbr += m_nDeltaLineUnget ; } else { int nOldLineNbr = m_nLineNbr ; const int DIM_BUFF = 512 ; char szBuffer[DIM_BUFF] ; do { // leggo una linea (nei limiti del buffer) if ( gzgets( m_InFile, szBuffer, DIM_BUFF) == nullptr) { sLine = "" ; m_nDeltaLineUnget = m_nLineNbr - nOldLineNbr ; return false ; } // copio nel parametro di ritorno sLine = szBuffer ; // gestione linee più lunghe del buffer (non c'è '\n' alla fine) while ( sLine.empty() || sLine.back() != '\n') { // continuo lettura linea (nei limiti del buffer), se c'è qualcosa if ( gzgets( m_InFile, szBuffer, DIM_BUFF) == nullptr) break ; // accodo al parametro di ritorno sLine += szBuffer ; } // se prima linea, eliminazione eventuale Bom if ( m_nLineNbr == 0) TrimUtf8Bom( sLine) ; // eliminazione ' ', '\t', '\r', '\n' agli estremi Trim( sLine) ; // incremento contatore di linee m_nLineNbr ++ ; } while ( ( m_bSkipEmptyLine && sLine.empty()) || ( m_bFindRem && sLine.rfind( m_sRemInit, 0) == 0)) ; m_nDeltaLineUnget = m_nLineNbr - nOldLineNbr ; } return true ; } //---------------------------------------------------------------------------- bool Scanner::UngetLine( string& sLine) { if ( m_bUnget) return false ; m_sUnget = sLine ; m_bUnget = true ; m_nLineNbr -= m_nDeltaLineUnget ; return true ; }