|
|
// MODULE: APGTSLSTREAD.CPP
//
// PURPOSE: APGTS LST file reading classes
//
// COMPANY: Saltmine Creative, Inc. (206)-284-7511 [email protected]
//
// AUTHOR: Oleg Kalosha
//
// ORIGINAL DATE: 7-29-98
//
// NOTES:
// 1. Prior to 11/13/98, it wasis assumed that for a given DSC/TSM file, any other associated
// filenames (BES, HTI) would not change over time. This assumption is no longer good.
// It had the unfortunate consequence that if there was a typographical error in an LST
// file there was no way to fix it while the system was running.
// 2. While the Online Troubleshooter is running, it is possible to change the LST file in
// order to add new troubleshooter topics, but it is not possible to remove troubleshooter
// topics. Thus, even if a topic which was listed in the old LST file is missing from the
// new one, that is not a relevant difference.
// 3. Normal form of a line in this file: any of the following:
// MODEM.DSC MODEM.HTI
// MODEM.DSC MODEM.HTI MODEM.BES
// MODEM.DSC,MODEM.HTI,MODEM.BES
// MODEM.TSM,MODEM.HTI,MODEM.BES
// Commas and spaces are both valid separators.
// Order within a line is irrelevant, although for readability, it is best to put
// the DSC/TSM file first.
// Extensions are mandatory. The only way we know it's (say) a template file is
// the .HTI extension.
// DSC/TSM file is mandatory. The others are optional, although if the HTI file is missing,
// there had better be a HNetHTIOnline / HNetHTILocal property in this network.
// 4. If the same DSC/TSM file is listed more than once, the last appearance dominates the
// earlier appearances.
// 5. For multilingual, each language goes in a subdirectory under the resource directory.
// LST file needs to contain paths relative to the resource directory, such as:
// ES\MODEM.DSC ES\MODEM.HTI
// DE\MODEM.DSC DE\MODEM.HTI
// FR\MODEM.DSC FR\MODEM.HTI
//
// Version Date By Comments
//--------------------------------------------------------------------
// V3.0 08-04-98 OK
// V3.0.1 12-21-98 JM Multilingual
//
#include "stdafx.h"
#include "apgtslstread.h"
#include "sync.h"
#include <algorithm>
#include "event.h"
#include "CharConv.h"
#include "apgtsmfc.h"
#ifdef LOCAL_TROUBLESHOOTER
#include "CHMFileReader.h"
#endif
////////////////////////////////////////////////////////////////////////////////////
// static function(s)
////////////////////////////////////////////////////////////////////////////////////
CString FormFullPath(const CString& just_path, const CString& just_name) { #ifdef LOCAL_TROUBLESHOOTER
if (CCHMFileReader::IsPathToCHMfile(just_path)) return CCHMFileReader::FormCHMPath(just_path) + just_name; else return just_path + _T("\\") + just_name; #else
return just_path + _T("\\") + just_name; #endif
}
////////////////////////////////////////////////////////////////////////////////////
// CTopicInfo
////////////////////////////////////////////////////////////////////////////////////
bool CTopicInfo::Init(CString & strResourcePath, vector<CString> &vecstrWords) { bool bSomethingThere = false;
for (vector<CString>::iterator i = vecstrWords.begin(); i != vecstrWords.end(); i++) { CString str_extension = CString(".") + CAbstractFileReader::GetJustExtension(*i);
bSomethingThere = true; ///////////////////////////////////////////
// We require that all *.dsc etc //
// files are in the same directory //
// as lst file (the resource directory) //
// or (for multilingual) a subdirectory //
// of the resource directory. //
///////////////////////////////////////////
LPCTSTR extention = NULL; if (0 == _tcsicmp(str_extension, extention = APGTSLSTREAD_DSC) || 0 == _tcsicmp(str_extension, extention = APGTSLSTREAD_TSM) ) { m_DscFilePath = ::FormFullPath(strResourcePath, *i); m_DscFilePath.MakeLower(); if (! m_NetworkName.GetLength()) { // use name of DSC/TSM file, minus extension.
m_NetworkName = *i; int len = m_NetworkName.GetLength()-(_tcslen(extention)); m_NetworkName = m_NetworkName.Left(len); m_NetworkName.MakeLower(); } continue; } if (0 == _tcsicmp(str_extension, APGTSLSTREAD_HTI)) { m_HtiFilePath = ::FormFullPath(strResourcePath, *i); m_HtiFilePath.MakeLower(); continue; } if (0 == _tcsicmp(str_extension, APGTSLSTREAD_BES)) { m_BesFilePath = ::FormFullPath(strResourcePath, *i); m_BesFilePath.MakeLower(); continue; } #ifdef LOCAL_TROUBLESHOOTER
if (0 == _tcsicmp(str_extension, APGTSLSTREAD_TSC)) { m_TscFilePath = ::FormFullPath(strResourcePath, *i); m_TscFilePath.MakeLower(); continue; } #endif
/////////////////////////////////////
// Ignore anything unrecognized.
}
bool bRet = bSomethingThere && ! m_DscFilePath.IsEmpty();
if (bRet) { CAbstractFileReader::GetFileTime(m_DscFilePath, CFileReader::eFileTimeCreated, m_DscFileCreated); if ( ! m_HtiFilePath.IsEmpty()) CAbstractFileReader::GetFileTime(m_HtiFilePath, CFileReader::eFileTimeCreated, m_HtiFileCreated);
if ( ! m_BesFilePath.IsEmpty()) CAbstractFileReader::GetFileTime(m_BesFilePath, CFileReader::eFileTimeCreated, m_BesFileCreated); }
return bRet; }
////////////////////////////////////////////////////////////////////////////////////
// CAPGTSLSTReader
////////////////////////////////////////////////////////////////////////////////////
CAPGTSLSTReader::CAPGTSLSTReader(CPhysicalFileReader * pPhysicalFileReader) : CINIReader(pPhysicalFileReader, _T("APGTS")) { }
CAPGTSLSTReader::~CAPGTSLSTReader() { }
long CAPGTSLSTReader::GetInfoCount() { long ret = 0; LOCKOBJECT(); ret = m_arrTopicInfo.size(); UNLOCKOBJECT(); return ret; }
bool CAPGTSLSTReader::GetInfo(long index, CTopicInfo& out) { LOCKOBJECT(); if (index < m_arrTopicInfo.size()) { out = m_arrTopicInfo[index]; UNLOCKOBJECT(); return true; } UNLOCKOBJECT(); return false; }
bool CAPGTSLSTReader::GetInfo(const CString& network_name, CTopicInfo& out) { LOCKOBJECT(); for ( vector<CTopicInfo>::iterator i = m_arrTopicInfo.begin(); i != m_arrTopicInfo.end(); i++) { if (i->GetNetworkName() == network_name) { out = *i; UNLOCKOBJECT(); return true; } } UNLOCKOBJECT(); return false; }
void CAPGTSLSTReader::GetInfo(CTopicInfoVector & arrOut) { LOCKOBJECT(); arrOut = m_arrTopicInfo; UNLOCKOBJECT(); }
// This will identify new troubleshooting networks, or changes to (say) the associated
// HTI file, given the same DSC file. Note that we can only detect additions of topics,
// not deletions. (see notes at head of this source file).
// If pOld is NULL, this is equivalent to GetInfo(what_is_new).
void CAPGTSLSTReader::GetDifference(const CAPGTSLSTReader * pOld, CTopicInfoVector & what_is_new) { if (pOld) { CMultiMutexObj multiMutex; multiMutex.AddHandle(GetMutexHandle()); multiMutex.AddHandle(pOld->GetMutexHandle());
multiMutex.Lock(__FILE__, __LINE__); vector<CTopicInfo> old_arr = pOld->m_arrTopicInfo; // to avoid const
for (vector<CTopicInfo>::iterator i = m_arrTopicInfo.begin(); i != m_arrTopicInfo.end(); i++) { vector<CTopicInfo>::const_iterator res = find(old_arr.begin(), old_arr.end(), *i); if (res == old_arr.end()) { try { what_is_new.push_back( *i ); } catch (exception& x) { CString str; // Note STL exception in event log.
CBuildSrcFileLinenoStr SrcLoc( __FILE__, __LINE__ ); CEvent::ReportWFEvent( SrcLoc.GetSrcFileLineStr(), SrcLoc.GetSrcFileLineStr(), CCharConversion::ConvertACharToString(x.what(), str), _T(""), EV_GTS_STL_EXCEPTION ); } } } multiMutex.Unlock(); } else GetInfo(what_is_new); }
void CAPGTSLSTReader::Parse() { CINIReader::Parse();
// parse all INI strings into something more meaningful...
m_arrTopicInfo.clear(); for (vector<CString>::iterator i = m_arrLines.begin(); i != m_arrLines.end(); i++) { CTopicInfo& info = *GenerateTopicInfo(); if (ParseString(*i, info)) { // if CTopicInfo with the same Network Name is found
// we assign new object to what is already in the container
vector<CTopicInfo>::iterator res; for ( res = m_arrTopicInfo.begin(); res != m_arrTopicInfo.end(); res++) { if (res->GetNetworkName() == info.GetNetworkName()) break; }
if (res != m_arrTopicInfo.end()) *res = info; else { try { m_arrTopicInfo.push_back(info); } catch (exception& x) { CString str; // Note STL exception in event log.
CBuildSrcFileLinenoStr SrcLoc( __FILE__, __LINE__ ); CEvent::ReportWFEvent( SrcLoc.GetSrcFileLineStr(), SrcLoc.GetSrcFileLineStr(), CCharConversion::ConvertACharToString(x.what(), str), _T(""), EV_GTS_STL_EXCEPTION ); } } } delete &info; } }
bool CAPGTSLSTReader::ParseString(const CString& source, CTopicInfo& out) { bool ret = false; vector<CString> words; vector<TCHAR> separators;
try { separators.push_back(_T(' ')); separators.push_back(_T(',')); // remove possible trailing commas
GetWords(source, words, separators); } catch (exception& x) { CString str; // Note STL exception in event log.
CBuildSrcFileLinenoStr SrcLoc( __FILE__, __LINE__ ); CEvent::ReportWFEvent( SrcLoc.GetSrcFileLineStr(), SrcLoc.GetSrcFileLineStr(), CCharConversion::ConvertACharToString(x.what(), str), _T(""), EV_GTS_STL_EXCEPTION ); }
return out.Init(GetJustPath(), words); }
CTopicInfo* CAPGTSLSTReader::GenerateTopicInfo() { return new CTopicInfo; }
|