//---------------------------------------------------------------------------- // EgalTech 2015-2015 //---------------------------------------------------------------------------- // File : MachiningsMgr.cpp Data : 02.06.15 Versione : 1.6f1 // Contenuto : Implementazione gestore database lavorazioni. // // // // Modifiche : 02.06.15 DS Creazione modulo. // // //---------------------------------------------------------------------------- //--------------------------- Include ---------------------------------------- #include "stdafx.h" #include "MachiningsMgr.h" #include "MachiningDataFactory.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 "/EgtDEv/Include/EgtPointerOwner.h" #include #include using namespace std ; //---------------------------------------------------------------------------- const string MF_HEADER = "[HEADER]" ; const string MF_TOTAL = "TOTAL" ; //---------------------------------------------------------------------------- MachiningsMgr::MachiningsMgr( void) { m_nCounter = 0 ; } //---------------------------------------------------------------------------- MachiningsMgr::~MachiningsMgr( void) { // libero la memoria dalle lavorazioni for ( auto iIter = m_umData.begin() ; iIter != m_umData.end() ; ++ iIter) { if ( iIter->second != nullptr) delete iIter->second ; } // pulisco le tabelle m_umData.clear() ; m_suData.clear() ; } //---------------------------------------------------------------------------- bool MachiningsMgr::Init( const string& sMachsFile) { // salvo la path del file con i dati m_sMachsFile = sMachsFile ; // log string sOut = "MachiningsMgr Init : " + m_sMachsFile ; LOG_INFO( GetEMkLogger(), sOut.c_str()) return true ; } //---------------------------------------------------------------------------- bool MachiningsMgr::Load( void) { // inizializzo lo scanner Scanner TheScanner ; if ( ! TheScanner.Init( m_sMachsFile, ";")) { LOG_ERROR( GetEMkLogger(), "LoadMachinings : 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 = "LoadMachinings : Error on Header" ; LOG_ERROR( GetEMkLogger(), sOut.c_str()) } // dimensiono map const int MIN_BUCKETS = 163 ; m_umData.rehash( MIN_BUCKETS) ; // ciclo di lettura delle lavorazioni do { if ( ! LoadOneMachining( TheScanner, bEnd)) { bOk = false ; string sOut = "LoadMachinings : Error on line " + ToString( TheScanner.GetCurrLineNbr()) ; LOG_ERROR( GetEMkLogger(), sOut.c_str()) } } while ( bOk && ! bEnd) ; // termino lo scanner TheScanner.Terminate() ; return bOk ; } //---------------------------------------------------------------------------- bool MachiningsMgr::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 != MF_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) == MF_TOTAL) bOk = FromString( sVal, nTotal) ; else bOk = false ; } return bOk ; } //---------------------------------------------------------------------------- bool MachiningsMgr::LoadOneMachining( Scanner& TheScanner, bool& bEnd) { // 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 ; Trim( sLine, "[]") ; // separo tipo da contatore string sType, sCount ; SplitFirst( sLine, "_", sType, sCount) ; ToUpper( sType) ; // alloco la lavorazione del tipo corrispondente PtrOwner pMch( MCHDATA_CREATE( sType)) ; if ( IsNull( pMch)) return false ; bool bOk = true ; // leggo i dati della lavorazione bEnd = true ; const int DIM_BS = 64 ; bitset Flag ; assert( pMch->GetSize() <= DIM_BS) ; while ( bOk && TheScanner.GetLine( sLine)) { // se lavorazione successiva if ( sLine.front() == '[' && sLine.back() == ']') { TheScanner.UngetLine( sLine) ; bEnd = false ; break ; } // interpreto la linea int nKey = - 1 ; bOk = pMch->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() == pMch->GetSize()) ; // salvo i dati della lavorazione bOk = bOk && m_umData.emplace( pMch->m_Uuid, Get( pMch)).second ; bOk = bOk && m_suData.emplace( pMch->m_sName, pMch->m_Uuid).second ; Release( pMch) ; return bOk ; } //---------------------------------------------------------------------------- bool MachiningsMgr::Save( bool bCompressed) const { // faccio copia di backup del file originale CopyFileEgt( m_sMachsFile, m_sMachsFile + ".bak") ; // inizializzo il writer Writer TheWriter ; if ( ! TheWriter.Init( m_sMachsFile, bCompressed)) { LOG_ERROR( GetEMkLogger(), "SaveMachinings : Error on Init") return false ; } // scrivo linea di inizio file string sOut = "; --- " + m_sMachsFile + " " + CurrDateTime() + " ---" ; if ( ! TheWriter.OutText( sOut)) { LOG_ERROR( GetEMkLogger(), "SaveMachinings : Error on Start") return false ; } // scrivo l'intestazione if ( ! SaveHeader( TheWriter)) { LOG_ERROR( GetEMkLogger(), "SaveMachinings : Error on Header") return false ; } // ciclo su tutti i nomi delle lavorazioni for ( auto iIter = m_suData.cbegin() ; iIter != m_suData.cend() ; ++ iIter) { // salvo l'utensile if ( ! SaveOneMachining( iIter->second, TheWriter)) { string sOut = "SaveMachinings : Error on machining " + iIter->first ; LOG_ERROR( GetEMkLogger(), sOut.c_str()) return false ; } } // scrivo linea di fine file if ( ! TheWriter.OutText( "; --- End ---")) { LOG_ERROR( GetEMkLogger(), "SaveMachinings : Error on End") return false ; } // chiudo la scrittura TheWriter.Close() ; return true ; } //---------------------------------------------------------------------------- bool MachiningsMgr::SaveHeader( Writer& TheWriter) const { // scrivo l'intestazione bool bOk = true ; string sOut ; sOut = MF_HEADER ; bOk = bOk && TheWriter.OutText( sOut) ; sOut = MF_TOTAL + "=" + ToString( int( m_umData.size())) ; bOk = bOk && TheWriter.OutText( sOut) ; return bOk ; } //---------------------------------------------------------------------------- bool MachiningsMgr::SaveOneMachining( const EgtUUID& Uuid, Writer& TheWriter) const { // recupero i dati della lavorazione auto iIter = m_umData.find( Uuid) ; if ( iIter == m_umData.end()) return false ; const MachiningData* pmData = iIter->second ; // scrivo i dati della lavorazione string sOut = "[" + pmData->GetTitle() + "_" + ToString( ++ m_nCounter, 3) + "]" ; bool bOk = TheWriter.OutText( sOut) ; for ( int i = 0 ; i < pmData->GetSize() ; ++ i) { string sOut = pmData->ToString( i) ; bOk = bOk && ! sOut.empty() && TheWriter.OutText( sOut) ; } return bOk ; } //---------------------------------------------------------------------------- const MachiningData* MachiningsMgr::GetMachining( const EgtUUID& Uuid) const { auto iIter = m_umData.find( Uuid) ; if ( iIter == m_umData.end()) return nullptr ; return iIter->second ; } //---------------------------------------------------------------------------- const MachiningData* MachiningsMgr::GetMachining( const string& sName) const { auto iIter = m_suData.find( sName) ; if ( iIter == m_suData.end()) return nullptr ; return GetMachining( iIter->second) ; } //---------------------------------------------------------------------------- bool MachiningsMgr::GetFirstMachining( int nType, string& sName) const { // recupero primo nome m_suCIter = m_suData.begin() ; // lo verifico if ( VerifyCurrMachining( nType, sName)) return true ; // continuo ricerca return GetNextMachining( nType, sName) ; } //---------------------------------------------------------------------------- bool MachiningsMgr::GetNextMachining( int nType, string& sName) const { // mentre esiste utensile while ( m_suCIter != m_suData.end()) { // nome successivo ++ m_suCIter ; // lo verifico if ( VerifyCurrMachining( nType, sName)) return true ; } // non trovato return false ; } //---------------------------------------------------------------------------- bool MachiningsMgr::VerifyCurrMachining( int nType, string& sName) const { // il corrente deve esistere if ( m_suCIter == m_suData.end()) return false ; // relativa lavorazione auto iIter = m_umData.find( m_suCIter->second) ; if ( iIter == m_umData.end()) { m_suCIter = m_suData.end() ; return false ; } // se è del tipo richiesto, trovato if ( iIter->second->GetType() == nType) { sName = iIter->second->m_sName ; return true ; } return false ; }