//---------------------------------------------------------------------------- // EgalTech 2015-2015 //---------------------------------------------------------------------------- // File : ToolsMgr.cpp Data : 01.06.15 Versione : 1.6f1 // Contenuto : Implementazione gestore database utensili. // // // // Modifiche : 01.06.15 DS Creazione modulo. // // //---------------------------------------------------------------------------- //--------------------------- Include ---------------------------------------- #include "stdafx.h" #include "ToolsMgr.h" #include "DllMain.h" #include "/EgtDEv/Include/EGnStringUtils.h" #include "/EgtDEv/Include/EGnFileUtils.h" #include "/EgtDEv/Include/EGnScanner.h" #include "/EgtDEv/Include/EGnWriter.h" #include #include using namespace std ; //---------------------------------------------------------------------------- const string TF_HEADER = "[HEADER]" ; const string TF_TOTAL = "TOTAL" ; //---------------------------------------------------------------------------- ToolsMgr::ToolsMgr( void) { m_suCIter = m_suData.cend() ; m_nCounter = 0 ; } //---------------------------------------------------------------------------- bool ToolsMgr::Init( const string& sToolsFile) { // salvo la path del file con i dati m_sToolsFile = sToolsFile ; // log string sOut = "ToolsMgr Init : " + m_sToolsFile ; LOG_INFO( GetEMkLogger(), sOut.c_str()) return true ; } //---------------------------------------------------------------------------- bool ToolsMgr::Load( void) { // inizializzo lo scanner Scanner TheScanner ; if ( ! TheScanner.Init( m_sToolsFile, ";")) { LOG_ERROR( GetEMkLogger(), "LoadTools : Error on Init") return false ; } // variabili di stato della lettura bool bOk = true ; bool bEnd = false ; // leggo l'intestazione int nTotal = 0 ; if ( ! LoadHeader( TheScanner, nTotal, bEnd)) { bOk = false ; string sOut = "LoadTools : Error on Header" ; LOG_ERROR( GetEMkLogger(), sOut.c_str()) } // dimensiono maps const int MIN_BUCKETS = 53 ; m_utData.rehash( MIN_BUCKETS) ; // ciclo di lettura degli utensili do { if ( ! LoadOneTool( TheScanner, bEnd)) { bOk = false ; string sOut = "LoadTools : Error on line " + ToString( TheScanner.GetCurrLineNbr()) ; LOG_ERROR( GetEMkLogger(), sOut.c_str()) } } while ( bOk && ! bEnd) ; // termino lo scanner TheScanner.Terminate() ; // verifico di aver letto il numero di utensili indicato in header if ( m_utData.size() != nTotal) { bOk = false ; LOG_ERROR( GetEMkLogger(), "LoadTools : Tools number wrong") } return bOk ; } //---------------------------------------------------------------------------- bool ToolsMgr::LoadHeader( Scanner& TheScanner, int& nTotal, bool& bEnd) { // leggo la prossima linea string sLine ; if ( ! TheScanner.GetLine( sLine)) { // fine file bEnd = true ; return true ; } // deve essere intestazione if ( sLine != TF_HEADER) return false ; bool bOk = true ; // leggo le linee successive bEnd = true ; nTotal = 0 ; while ( bOk && TheScanner.GetLine( sLine)) { // se utensile successivo if ( sLine.front() == '[' && sLine.back() == ']') { TheScanner.UngetLine( sLine) ; bEnd = false ; break ; } // separo chiave da valore string sKey, sVal ; SplitFirst( sLine, "=", sKey, sVal) ; // riconosco la chiave if ( ToUpper( sKey) == TF_TOTAL) bOk = FromString( sVal, nTotal) ; else bOk = false ; } return bOk ; } //---------------------------------------------------------------------------- bool ToolsMgr::LoadOneTool( Scanner& TheScanner, bool& bEnd) { ToolData tData ; // leggo la prossima linea string sLine ; if ( ! TheScanner.GetLine( sLine)) { // fine file bEnd = true ; return true ; } // deve essere intestazione if ( sLine.front() != '[' || sLine.back() != ']') return false ; // uso temporaneamente come nome utensile tData.m_sName = sLine.substr( 1, sLine.length() - 2) ; bool bOk = ! tData.m_sName.empty() ; // dati successivi bEnd = true ; const int DIM_BS = 64 ; bitset Flag ; assert( tData.GetSize() <= DIM_BS) ; while ( bOk && TheScanner.GetLine( sLine)) { // se utensile successivo if ( sLine.front() == '[' && sLine.back() == ']') { TheScanner.UngetLine( sLine) ; bEnd = false ; break ; } // interpreto la linea int nKey = - 1 ; bOk = tData.FromString( sLine, nKey) ; // se tutto bene, dichiaro letto il campo if ( bOk) Flag.set( nKey) ; } // verifico di aver letto tutti i campi bOk = bOk && ( Flag.count() == tData.GetSize()) ; // salvo i dati dell'utensile bOk = bOk && m_utData.emplace( tData.m_Uuid, tData).second ; bOk = bOk && m_suData.emplace( tData.m_sName, tData.m_Uuid).second ; return bOk ; } //---------------------------------------------------------------------------- bool ToolsMgr::Save( bool bCompressed) const { // faccio copia di backup del file originale CopyFileEgt( m_sToolsFile, m_sToolsFile + ".bak") ; // inizializzo il writer Writer TheWriter ; if ( ! TheWriter.Init( m_sToolsFile, bCompressed)) { LOG_ERROR( GetEMkLogger(), "SaveTools : Error on Init") return false ; } // scrivo linea di inizio file string sOut = "; --- " + m_sToolsFile + " " + CurrDateTime() + " ---" ; if ( ! TheWriter.OutText( sOut)) { LOG_ERROR( GetEMkLogger(), "SaveTools : Error on Start") return false ; } // scrivo l'intestazione if ( ! SaveHeader( TheWriter)) { LOG_ERROR( GetEMkLogger(), "SaveTools : Error on Header") return false ; } // ciclo su tutti i nomi degli utensili m_nCounter = 0 ; for ( auto iIter = m_suData.cbegin() ; iIter != m_suData.cend() ; ++ iIter) { // salvo l'utensile if ( ! SaveOneTool( iIter->second, TheWriter)) { string sOut = "SaveTools : Error on tool " + iIter->first ; LOG_ERROR( GetEMkLogger(), sOut.c_str()) return false ; } } // scrivo linea di fine file if ( ! TheWriter.OutText( "; --- End ---")) { LOG_ERROR( GetEMkLogger(), "SaveTools : Error on End") return false ; } // chiudo la scrittura TheWriter.Close() ; return true ; } //---------------------------------------------------------------------------- bool ToolsMgr::SaveHeader( Writer& TheWriter) const { // scrivo l'intestazione bool bOk = true ; string sOut ; sOut = TF_HEADER ; bOk = bOk && TheWriter.OutText( sOut) ; sOut = TF_TOTAL + "=" + ToString( int( m_utData.size())) ; bOk = bOk && TheWriter.OutText( sOut) ; return bOk ; } //---------------------------------------------------------------------------- bool ToolsMgr::SaveOneTool( const EgtUUID& Uuid, Writer& TheWriter) const { // recupero i dati dell'utensile auto iIter = m_utData.find( Uuid) ; if ( iIter == m_utData.end()) return false ; const ToolData& tData = iIter->second ; // scrivo i dati dell'utensile string sOut = "[TOOL_" + ToString( ++ m_nCounter, 3) + "]" ; bool bOk = TheWriter.OutText( sOut) ; for ( int i = 0 ; i < tData.GetSize() ; ++ i) { string sOut = tData.ToString( i) ; bOk = bOk && ! sOut.empty() && TheWriter.OutText( sOut) ; } return bOk ; } //---------------------------------------------------------------------------- const ToolData* ToolsMgr::GetTool( const EgtUUID& Uuid) const { auto iIter = m_utData.find( Uuid) ; if ( iIter == m_utData.end()) return nullptr ; return &( iIter->second) ; } //---------------------------------------------------------------------------- const ToolData* ToolsMgr::GetTool( const string& sName) const { auto iIter = m_suData.find( sName) ; if ( iIter == m_suData.end()) return nullptr ; return GetTool( iIter->second) ; } //---------------------------------------------------------------------------- bool ToolsMgr::GetFirstTool( int nFamily, string& sName, int& nType) const { // primo nome m_suCIter = m_suData.begin() ; // lo verifico if ( VerifyCurrTool( nFamily, sName, nType)) return true ; // continuo ricerca return GetNextTool( nFamily, sName, nType) ; } //---------------------------------------------------------------------------- bool ToolsMgr::GetNextTool( int nFamily, string& sName, int& nType) const { // mentre esiste utensile while ( m_suCIter != m_suData.end()) { // nome successivo ++ m_suCIter ; // lo verifico if ( VerifyCurrTool( nFamily, sName, nType)) return true ; } // non trovato return false ; } //---------------------------------------------------------------------------- bool ToolsMgr::VerifyCurrTool( int nFamily, string& sName, int& nType) const { // il corrente deve esistere if ( m_suCIter == m_suData.end()) return false ; // relativo utensile auto iIter = m_utData.find( m_suCIter->second) ; if ( iIter == m_utData.end()) { m_suCIter = m_suData.end() ; return false ; } // se appartiene alla famiglia richiesta, trovato if ( ( iIter->second.m_nType & nFamily) != 0) { sName = iIter->second.m_sName ; nType = iIter->second.m_nType ; return true ; } return false ; }