Files
EgtMachKernel/MachiningsMgr.cpp
T
Dario Sassi 64ed8babd1 EgtMachKernel 1.6f1 :
- aggiunta gestione DB utensili
- aggiunta gestione DB lavorazioni.
2015-06-06 17:50:38 +00:00

348 lines
10 KiB
C++

//----------------------------------------------------------------------------
// 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 <cassert>
#include <bitset>
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<MachiningData> 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<DIM_BS> 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 ;
}