You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
332 lines
9.8 KiB
332 lines
9.8 KiB
// 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;
|
|
}
|
|
|