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.
1456 lines
42 KiB
1456 lines
42 KiB
//
|
|
// MODULE: APGTSHTIREAD.CPP
|
|
//
|
|
// PURPOSE: HTI template file reading classes
|
|
//
|
|
// COMPANY: Saltmine Creative, Inc. (206)-284-7511 [email protected]
|
|
//
|
|
// AUTHOR: Oleg Kalosha
|
|
//
|
|
// ORIGINAL DATE: 8-27-98
|
|
//
|
|
// NOTES:
|
|
// 1. HTI is loosely modeled on a Microsoft format called HTX. It's a template for an
|
|
// HTML file. Most of it is HTML, but certain pseudo-comments of the form
|
|
// <!GTS whatever> are intended to be interpreted as conditionals, places to
|
|
// insert text, etc.
|
|
//
|
|
// Variables are limited to the values
|
|
// $ProblemAsk
|
|
// $Recommendations
|
|
// $States
|
|
// $Questions
|
|
// $Success (introduced 9/24/98)
|
|
// $StartForm
|
|
// See class CHTMLFragmentsTS for more details.
|
|
|
|
// Commands are if/else/endif, forany/endfor, display
|
|
// There is also a notion of a "resource", basically an include file.
|
|
//
|
|
// EXAMPLE 1
|
|
// <!GTS forany $States >
|
|
// <!GTS display $States >
|
|
// <!GTS endfor>
|
|
//
|
|
// EXAMPLE 2
|
|
// <!GTS if $ProblemAsk >
|
|
// lots of HTML or nested calls to more GTS stuff could go here
|
|
// <!GTS else >
|
|
// lots of other HTML or nested calls to other GTS stuff could go here
|
|
// <!GTS endif >
|
|
//
|
|
// each <!GTS...> command must fit on a single line.
|
|
//
|
|
// Version Date By Comments
|
|
//--------------------------------------------------------------------
|
|
// V3.0 08-04-98 OK
|
|
//
|
|
|
|
#pragma warning(disable:4786)
|
|
#include "stdafx.h"
|
|
#include "apgtshtiread.h"
|
|
#include "event.h"
|
|
#include "CharConv.h"
|
|
#include "apgtsMFC.h"
|
|
|
|
#ifdef LOCAL_TROUBLESHOOTER
|
|
#include "htmlfraglocal.h"
|
|
#endif
|
|
|
|
namespace
|
|
{
|
|
CString k_strHTMLtag= _T("/HTML");
|
|
}
|
|
|
|
///////////////////////////////////////////////////////////////////////////////////////////
|
|
// CAPGTSHTIReader
|
|
///////////////////////////////////////////////////////////////////////////////////////////
|
|
CAPGTSHTIReader::CAPGTSHTIReader(CPhysicalFileReader * pPhysicalFileReader, LPCTSTR szDefaultContents /* NULL */)
|
|
: CTemplateReader(pPhysicalFileReader, szDefaultContents),
|
|
m_pFragments(NULL)
|
|
{
|
|
}
|
|
|
|
CAPGTSHTIReader::~CAPGTSHTIReader()
|
|
{
|
|
}
|
|
|
|
void CAPGTSHTIReader::Parse()
|
|
{
|
|
#ifdef LOCAL_TROUBLESHOOTER
|
|
// OVERVIEW: For the Local Troubleshooter, search for a <!GTS resource $Previous.script>
|
|
// token in the stream. If one is not found, then insert one for backwards
|
|
// compatibility.
|
|
try
|
|
{
|
|
// Load the stream into a vector while searching for a "Previous.script" token and also
|
|
// determining the position of the last closing HTML tag location in order to know where
|
|
// to insert the generated_previous() function.
|
|
CString str;
|
|
vector<CString> str_arr;
|
|
long indexLastHTML = -1;
|
|
|
|
// Place the content of m_StreamData, line by line, into str_arr
|
|
SetPos( m_StreamData, 0 );
|
|
while (GetLine( m_StreamData, str ))
|
|
{
|
|
// Determine whether or not this line contains the "Previous.script" token.
|
|
CString strCommand;
|
|
if (GetCommand( str, strCommand))
|
|
{
|
|
// Check if the command is the right type.
|
|
if (strCommand == COMMAND_RESOURCESTR)
|
|
{
|
|
CString strVariable;
|
|
if (GetVariable( str, strVariable ))
|
|
{
|
|
// Check if the variable is the right type.
|
|
if (strVariable == VAR_PREVIOUS_SCRIPT)
|
|
{
|
|
// We found what we were looking for.
|
|
// Reset the stream position and exit function.
|
|
SetPos( m_StreamData, 0 );
|
|
return;
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
// Add this line to the vector.
|
|
str_arr.push_back( str );
|
|
|
|
// Look for an HTML closing tag in this line.
|
|
if (str.Find( k_strHTMLtag ) != -1)
|
|
{
|
|
// Mark the location of the last \HTML tag found.
|
|
indexLastHTML= str_arr.size() - 1;
|
|
}
|
|
}
|
|
|
|
// Rebuild the input stream from the vector and insert the "Previous.script" token
|
|
// in the location determined above.
|
|
vector<CString>::iterator iLastElement = str_arr.end();
|
|
iLastElement--;
|
|
m_StreamData.clear();
|
|
CString strResult;
|
|
|
|
long index = 0;
|
|
for (vector<CString>::iterator i = str_arr.begin(); i < str_arr.end(); i++, index++)
|
|
{
|
|
if (index == indexLastHTML)
|
|
{
|
|
// Add the required token to the string.
|
|
strResult+= COMMAND_STARTSTR;
|
|
strResult+= _T(" ");
|
|
strResult+= COMMAND_RESOURCESTR;
|
|
strResult+= _T(" ");
|
|
strResult+= COMMAND_STARTVARSTR;
|
|
strResult+= VAR_PREVIOUS_SCRIPT;
|
|
strResult+= COMMAND_ENDSTR;
|
|
strResult+= _T("\r\n");
|
|
}
|
|
|
|
strResult += *i;
|
|
|
|
if (i != iLastElement)
|
|
strResult+= _T("\r\n");
|
|
}
|
|
m_StreamData.str( (LPCTSTR) strResult );
|
|
SetPos( m_StreamData, 0 );
|
|
}
|
|
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 );
|
|
}
|
|
#endif
|
|
}
|
|
|
|
// JSM V3.2 adapted from CreatePage()
|
|
// builds list of all Network props in this HTI file which appear
|
|
// in lines like <!GTI property "fooprop">
|
|
//
|
|
// called by apgtscontext to find network properties to pass to CHTMLFragmentsTS
|
|
void CAPGTSHTIReader::ExtractNetProps(vector <CString> &arr_props)
|
|
{
|
|
LOCKOBJECT();
|
|
try
|
|
{
|
|
arr_props.clear();
|
|
// InitializeInterpreted populates m_arrInterpreted and
|
|
// performs cookie substitutions. This is correct behavior,
|
|
// because cookie substitution is supposed to happen
|
|
// before !GTS processing, and it is conceivable
|
|
// that a cookie's value could be "<!GTS property fooprop>"
|
|
InitializeInterpreted();
|
|
// we should not call Interpret(), which involves parsing <!GTS clauses
|
|
for (vector<CString>::iterator i = m_arrInterpreted.begin(); i < m_arrInterpreted.end(); i++)
|
|
{
|
|
CString command;
|
|
if (GetCommand(*i, command))
|
|
{
|
|
if (command == COMMAND_PROPERTY)
|
|
{
|
|
CString strProperty;
|
|
if (GetVariable(*i,strProperty))
|
|
arr_props.push_back(strProperty);
|
|
}
|
|
}
|
|
}
|
|
}
|
|
catch (...)
|
|
{
|
|
// Catch any other exception thrown.
|
|
CBuildSrcFileLinenoStr SrcLoc( __FILE__, __LINE__ );
|
|
CEvent::ReportWFEvent( SrcLoc.GetSrcFileLineStr(),
|
|
SrcLoc.GetSrcFileLineStr(),
|
|
_T(""), _T(""),
|
|
EV_GTS_GEN_EXCEPTION );
|
|
}
|
|
UNLOCKOBJECT();
|
|
}
|
|
|
|
|
|
void CAPGTSHTIReader::CreatePage( const CHTMLFragments& fragments,
|
|
CString& out,
|
|
const map<CString,CString> & mapStrs,
|
|
CString strHTTPcookies/*= _T("")*/ )
|
|
{
|
|
LOCKOBJECT();
|
|
try
|
|
{
|
|
m_pFragments = &fragments;
|
|
|
|
// V3.2 Cookie related enhancement.
|
|
// Opted to use a member variable rather than modifying class interface by
|
|
// adding a parameter to virtual void method InitializeInterpreted().
|
|
m_strHTTPcookies= strHTTPcookies;
|
|
m_mapCookies= mapStrs;
|
|
|
|
InitializeInterpreted();
|
|
Interpret();
|
|
#ifdef __DEBUG_CUSTOM
|
|
SetOutputToInterpreted();
|
|
FlushOutputStreamToFile("..\\Files\\interpreted.hti");
|
|
#endif
|
|
ParseInterpreted();
|
|
SetOutputToInterpreted();
|
|
#ifdef __DEBUG_CUSTOM
|
|
FlushOutputStreamToFile("..\\Files\\result.htm");
|
|
#endif
|
|
out = m_StreamOutput.rdbuf()->str().c_str();
|
|
}
|
|
catch (...)
|
|
{
|
|
// Catch any other exception thrown.
|
|
CBuildSrcFileLinenoStr SrcLoc( __FILE__, __LINE__ );
|
|
CEvent::ReportWFEvent( SrcLoc.GetSrcFileLineStr(),
|
|
SrcLoc.GetSrcFileLineStr(),
|
|
_T(""), _T(""),
|
|
EV_GTS_GEN_EXCEPTION );
|
|
}
|
|
UNLOCKOBJECT();
|
|
}
|
|
|
|
void CAPGTSHTIReader::InitializeInterpreted()
|
|
{
|
|
long savePos = 0;
|
|
CString str;
|
|
CString command;
|
|
bool bOldFormat = true; // this is an old format (without $Success or $StartForm)
|
|
bool bFoundFirstBlock= false;
|
|
|
|
savePos = GetPos();
|
|
bOldFormat = !Find(CString(COMMAND_STARTVARSTR)+VAR_SUCCESS) &&
|
|
!Find(CString(COMMAND_STARTVARSTR)+VAR_STARTFORM);
|
|
SetPos(0);
|
|
m_arrInterpreted.clear();
|
|
|
|
try
|
|
{
|
|
while (GetLine(str))
|
|
{
|
|
if (bOldFormat && (!bFoundFirstBlock) && (-1 != str.Find( COMMAND_STARTSTR )))
|
|
{
|
|
// Output the $StartForm block only if it is not a resource string command.
|
|
CString strCommand;
|
|
if ((GetCommand( str, strCommand )) && (strCommand != COMMAND_RESOURCESTR))
|
|
{
|
|
/*
|
|
<!GTS if $StartForm>
|
|
<!GTS display $StartForm>
|
|
<!GTS endif>
|
|
*/
|
|
ComposeCommand(COMMAND_IFSTR, VAR_STARTFORM, command);
|
|
m_arrInterpreted.push_back(command);
|
|
ComposeCommand(COMMAND_DISPLAYSTR, VAR_STARTFORM, command);
|
|
m_arrInterpreted.push_back(command);
|
|
ComposeCommand(COMMAND_ENDIFSTR, _T(""), command);
|
|
m_arrInterpreted.push_back(command);
|
|
|
|
bFoundFirstBlock = true;
|
|
}
|
|
}
|
|
|
|
if (bOldFormat && (-1 != str.Find(_T("</FORM>"))))
|
|
{
|
|
/*
|
|
<!GTS if $StartForm>
|
|
*/
|
|
ComposeCommand(COMMAND_IFSTR, VAR_STARTFORM, command);
|
|
m_arrInterpreted.push_back(command);
|
|
|
|
m_arrInterpreted.push_back(str);
|
|
/*
|
|
<!GTS endif>
|
|
*/
|
|
ComposeCommand(COMMAND_ENDIFSTR, _T(""), command);
|
|
m_arrInterpreted.push_back(command);
|
|
}
|
|
else
|
|
{
|
|
// Check if we need to populate any cookie clauses.
|
|
if (-1 != str.Find( COMMAND_COOKIE ))
|
|
SubstituteCookieValues( str );
|
|
|
|
m_arrInterpreted.push_back(str);
|
|
}
|
|
}
|
|
}
|
|
catch (exception& x)
|
|
{
|
|
CString str2;
|
|
// Note STL exception in event log.
|
|
CBuildSrcFileLinenoStr SrcLoc( __FILE__, __LINE__ );
|
|
CEvent::ReportWFEvent( SrcLoc.GetSrcFileLineStr(),
|
|
SrcLoc.GetSrcFileLineStr(),
|
|
CCharConversion::ConvertACharToString(x.what(), str2),
|
|
_T(""),
|
|
EV_GTS_STL_EXCEPTION );
|
|
}
|
|
|
|
SetPos(savePos);
|
|
}
|
|
|
|
void CAPGTSHTIReader::Interpret()
|
|
{
|
|
long curr_index = 0;
|
|
long lLastIndex= -1; // Used to detect a HTI file with incomplete clauses.
|
|
|
|
while(true)
|
|
{
|
|
vector<CString> clause_arr;
|
|
|
|
// tries to extract clause from m_arrInterpreted starting with curr_index
|
|
// and remove it from m_arrInterpreted
|
|
if (ExtractClause(m_arrInterpreted,
|
|
&curr_index, // in - out
|
|
clause_arr))
|
|
{
|
|
// Reset the infinite loop detection counter.
|
|
lLastIndex= -1;
|
|
|
|
// Now curr_index is pointing to next element
|
|
// of m_arrInterpreted (after removed clause)
|
|
// OR OUTSIDE boundary of m_arrInterpreted.
|
|
if (InterpretClause(clause_arr))
|
|
{
|
|
vector<CString>::iterator i = m_arrInterpreted.begin();
|
|
{ // create iterator that points to m_arrInterpreted[curr_index]
|
|
// or is m_arrInterpreted.end()
|
|
long tmp_index = curr_index;
|
|
while(tmp_index--)
|
|
i++;
|
|
}
|
|
|
|
try
|
|
{
|
|
// insert interpreted clause there
|
|
for (vector<CString>::iterator j = clause_arr.begin(); j < clause_arr.end(); j++)
|
|
{
|
|
i = m_arrInterpreted.insert(i, *j); // inserts before "i"
|
|
i++;
|
|
curr_index++;
|
|
}
|
|
}
|
|
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 );
|
|
}
|
|
}
|
|
}
|
|
else
|
|
{
|
|
// If this condition is true, then we are in an infinite loop due to a bad HTI file.
|
|
if (lLastIndex == curr_index)
|
|
{
|
|
// Log that this HTI file does not parse correctly.
|
|
CBuildSrcFileLinenoStr SrcLoc( __FILE__, __LINE__ );
|
|
CEvent::ReportWFEvent( SrcLoc.GetSrcFileLineStr(),
|
|
SrcLoc.GetSrcFileLineStr(),
|
|
GetPathName(), _T(""),
|
|
EV_GTS_BAD_HTI_FILE );
|
|
break;
|
|
}
|
|
|
|
// Update the infinite loop detection counter.
|
|
lLastIndex= curr_index;
|
|
|
|
if (curr_index) {
|
|
// we finished current pass of m_arrInterpreted, start new one
|
|
curr_index = 0;
|
|
continue;
|
|
}
|
|
else {
|
|
// we can not extract clause though we start from beginning -
|
|
// m_arrInterpreted is interpreted now
|
|
break;
|
|
}
|
|
}
|
|
}
|
|
}
|
|
// modified V3.2 JSM
|
|
void CAPGTSHTIReader::ParseInterpreted()
|
|
{
|
|
for (vector<CString>::iterator i = m_arrInterpreted.begin(); i < m_arrInterpreted.end(); i++)
|
|
{
|
|
CString command;
|
|
|
|
if (GetCommand(*i, command))
|
|
{
|
|
if (command == COMMAND_DISPLAYSTR ||
|
|
command == COMMAND_RESOURCESTR ||
|
|
command == COMMAND_INFORMATION
|
|
)
|
|
{
|
|
CString variable;
|
|
|
|
if (GetVariable(*i, variable))
|
|
{
|
|
CString substitution;
|
|
FragmentIDVector arr_fragment;
|
|
|
|
ParseVariable(variable, arr_fragment);
|
|
substitution = const_cast<CHTMLFragments*>(m_pFragments)->GetText(arr_fragment, (command == COMMAND_RESOURCESTR) ? CHTMLFragments::eResource : CHTMLFragments::eNotOfInterest );
|
|
SubstituteCommandBlockWith(substitution, *i);
|
|
}
|
|
else // obvious misbehaviour - "display" command should have variable
|
|
SubstituteCommandBlockWith(_T(""), *i);
|
|
}
|
|
else if (command == COMMAND_VALUE)
|
|
{
|
|
CString variable;
|
|
|
|
if (GetVariable(*i, variable))
|
|
const_cast<CHTMLFragments*>(m_pFragments)->SetValue(variable);
|
|
|
|
SubstituteCommandBlockWith(_T(""), *i);
|
|
}
|
|
// V3.2 JSM
|
|
else if (command == COMMAND_PROPERTY)
|
|
{
|
|
CString strProperty;
|
|
if (GetVariable(*i,strProperty))
|
|
{
|
|
CString substitution;
|
|
substitution = const_cast<CHTMLFragments*>(m_pFragments)->GetNetProp(strProperty);
|
|
SubstituteCommandBlockWith(substitution, *i);
|
|
}
|
|
else // obvious misbehaviour - "property" command should have variable
|
|
SubstituteCommandBlockWith(_T(""), *i);
|
|
} // end V3.2 JSM
|
|
else // obvious misbehaviour - no other commands
|
|
SubstituteCommandBlockWith(_T(""), *i);
|
|
}
|
|
}
|
|
}
|
|
|
|
void CAPGTSHTIReader::SetOutputToInterpreted()
|
|
{
|
|
vector<CString>::iterator j = m_arrInterpreted.end();
|
|
|
|
// Decrement to point to last element.
|
|
j--;
|
|
m_StreamOutput.str(_T(""));
|
|
for (vector<CString>::iterator i = m_arrInterpreted.begin(); i < m_arrInterpreted.end(); i++)
|
|
{
|
|
m_StreamOutput << (LPCTSTR)*i;
|
|
if (i != j) // not last element
|
|
m_StreamOutput << _T('\r') << _T('\n');
|
|
}
|
|
m_StreamOutput << ends;
|
|
}
|
|
|
|
// INPUT: arr_text (with clause)
|
|
// IMPUT: *pstart_index - index in arr_text
|
|
// OUTPUT: arr_text without clause
|
|
// OUTPUT: *pstart_index points to element in arr_text next to where
|
|
// clause used to be or outside arr_text
|
|
// OUTPUT: arr_clause - extracted clause
|
|
bool CAPGTSHTIReader::ExtractClause(vector<CString>& arr_text,
|
|
long* pstart_index,
|
|
vector<CString>& arr_clause)
|
|
{
|
|
if (*pstart_index > arr_text.size() - 1) // quite possible
|
|
return false;
|
|
|
|
for (long i = *pstart_index; i < arr_text.size(); i++)
|
|
{
|
|
CString str_command;
|
|
|
|
if (GetCommand(arr_text[i], str_command))
|
|
{
|
|
if (str_command == COMMAND_FORANYSTR)
|
|
{
|
|
if (ExtractClause(arr_text,
|
|
&i,
|
|
arr_clause,
|
|
COMMAND_FORANYSTR,
|
|
COMMAND_ENDFORSTR))
|
|
{
|
|
*pstart_index = i;
|
|
return true;
|
|
}
|
|
else
|
|
{
|
|
*pstart_index = i;
|
|
return false;
|
|
}
|
|
}
|
|
if (str_command == COMMAND_IFSTR)
|
|
{
|
|
if (ExtractClause(arr_text,
|
|
&i,
|
|
arr_clause,
|
|
COMMAND_IFSTR,
|
|
COMMAND_ENDIFSTR))
|
|
{
|
|
*pstart_index = i;
|
|
return true;
|
|
}
|
|
else
|
|
{
|
|
*pstart_index = i;
|
|
return false;
|
|
}
|
|
}
|
|
}
|
|
}
|
|
return false;
|
|
}
|
|
|
|
bool CAPGTSHTIReader::ExtractClause(vector<CString>& arr_text,
|
|
long* pstart_index,
|
|
vector<CString>& arr_clause,
|
|
const CString& str_start_command,
|
|
const CString& str_end_command)
|
|
{
|
|
CString str_command;
|
|
long start = *pstart_index, end = *pstart_index;
|
|
long nest_level_counter = 1;
|
|
|
|
while (++end < arr_text.size())
|
|
{
|
|
if (GetCommand(arr_text[end], str_command))
|
|
{
|
|
if (str_command == str_start_command)
|
|
{
|
|
nest_level_counter++;
|
|
}
|
|
if (str_command == str_end_command)
|
|
{
|
|
nest_level_counter--;
|
|
if (!nest_level_counter)
|
|
{
|
|
vector<CString>::iterator start_it = arr_text.begin();
|
|
vector<CString>::iterator end_it = arr_text.begin();
|
|
|
|
arr_clause.clear();
|
|
try
|
|
{
|
|
// copy clause to arr_clause
|
|
for (long j = start; j <= end; j++)
|
|
arr_clause.push_back(arr_text[j]);
|
|
}
|
|
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 );
|
|
}
|
|
|
|
// make iterators correspond indexes
|
|
while(start--)
|
|
start_it++;
|
|
while(end--)
|
|
end_it++;
|
|
// and, because we want to delete element pointed
|
|
// at this moment by end_it:
|
|
end_it++;
|
|
// remove clause from arr_text
|
|
arr_text.erase(start_it, end_it);
|
|
return true;
|
|
}
|
|
}
|
|
}
|
|
}
|
|
*pstart_index = --end;;
|
|
return false;
|
|
}
|
|
|
|
bool CAPGTSHTIReader::InterpretClause(vector<CString>& arr_clause)
|
|
{
|
|
CString str_command;
|
|
|
|
if (arr_clause.size() &&
|
|
GetCommand(arr_clause[0], str_command))
|
|
{
|
|
if (str_command == COMMAND_FORANYSTR)
|
|
return InterpretForanyClause(arr_clause);
|
|
if (str_command == COMMAND_IFSTR)
|
|
return InterpretIfClause(arr_clause);
|
|
return false;
|
|
}
|
|
return false;
|
|
}
|
|
|
|
bool CAPGTSHTIReader::InterpretForanyClause(vector<CString>& arr_clause)
|
|
{
|
|
long count = 0;
|
|
CString strVariable; // variable from 1-st line of arr_clause
|
|
vector<CString> arrUnfolded;
|
|
FragmentIDVector arrVariable; // array from strVariable
|
|
|
|
if (arr_clause.size() < 2) // "forany" and "endfor" commands
|
|
return false;
|
|
|
|
if (!GetVariable(arr_clause[0], strVariable))
|
|
return false;
|
|
|
|
ParseVariable(strVariable, arrVariable);
|
|
|
|
count = m_pFragments->GetCount(arrVariable);
|
|
|
|
try
|
|
{
|
|
for (long i = 0; i < count; i++)
|
|
{
|
|
for (long j = 1; j < arr_clause.size() - 1; j++)
|
|
{
|
|
CString command, variable;
|
|
|
|
if (GetCommand(arr_clause[j], command) &&
|
|
GetVariable(arr_clause[j], variable))
|
|
{
|
|
if (command == COMMAND_FORANYSTR && variable == strVariable)
|
|
{
|
|
// if it is clause "forany" with the same variable,
|
|
// there should be neither prefixing nor postfixing
|
|
}
|
|
else
|
|
{
|
|
CString line = arr_clause[j];
|
|
|
|
if (variable == strVariable)
|
|
{
|
|
PostfixVariable(i, variable);
|
|
}
|
|
else
|
|
{
|
|
FragmentIDVector parents, children;
|
|
CString strVariable_postfixed = strVariable;
|
|
PostfixVariable(i, strVariable_postfixed);
|
|
|
|
ParseVariable(strVariable_postfixed, parents);
|
|
ParseVariable(variable, children);
|
|
if (m_pFragments->IsValidSeqOfVars(parents, children))
|
|
PrefixVariable(strVariable_postfixed, variable);
|
|
}
|
|
CString command_block;
|
|
ComposeCommandBlock(command, variable, command_block);
|
|
SubstituteCommandBlockWith(command_block, line);
|
|
arrUnfolded.push_back(line);
|
|
continue;
|
|
}
|
|
}
|
|
arrUnfolded.push_back(arr_clause[j]);
|
|
}
|
|
}
|
|
}
|
|
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 );
|
|
}
|
|
|
|
arr_clause = arrUnfolded;
|
|
return true;
|
|
}
|
|
|
|
bool CAPGTSHTIReader::InterpretIfClause(vector<CString>& arr_clause)
|
|
{
|
|
CString strVariable; // variable from a line of arr_clause
|
|
FragmentIDVector arrVariable;
|
|
|
|
if (arr_clause.size() < 2) // "if" and "endif" commands
|
|
return false;
|
|
|
|
if (!GetVariable( arr_clause[ 0 ], strVariable ))
|
|
return false;
|
|
|
|
ParseVariable( strVariable, arrVariable );
|
|
|
|
// Scan for "if", "elseif", "else", and "endif" commands
|
|
vector<int> arrElseIfIndices;
|
|
int elseIndex = -1; // index of "else" inside arr_clause
|
|
int i = 0;
|
|
int nDepthOfNesting;
|
|
for (i= 1, nDepthOfNesting= 0; i < arr_clause.size() - 1; i++)
|
|
{
|
|
CString command;
|
|
if (GetCommand(arr_clause[i], command))
|
|
{
|
|
if (command == COMMAND_IFSTR)
|
|
{
|
|
nDepthOfNesting++;
|
|
}
|
|
else if (command == COMMAND_ENDIFSTR)
|
|
{
|
|
nDepthOfNesting--;
|
|
}
|
|
else if (command == COMMAND_ELSEIFSTR)
|
|
{
|
|
// V3.2 - Check if this elseif clause is at the level we are looking for.
|
|
if (nDepthOfNesting == 0)
|
|
arrElseIfIndices.push_back( i );
|
|
}
|
|
else if (command == COMMAND_ELSESTR)
|
|
{
|
|
// Check if this else clause is at the level we are looking for.
|
|
if (nDepthOfNesting == 0)
|
|
{
|
|
elseIndex = i;
|
|
break;
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
|
|
vector<CString> arrBody; // intermediate array
|
|
try
|
|
{
|
|
CString strName; // name of strVariable associated through CHTMLFragments
|
|
strName = const_cast<CHTMLFragments*>(m_pFragments)->GetText(arrVariable);
|
|
if (strName.GetLength())
|
|
{
|
|
// Standard processing of what is inside if ... else (or endif)
|
|
int nEndOfClause= (arrElseIfIndices.size()) ? arrElseIfIndices[ 0 ] : elseIndex;
|
|
for (i = 1; i < (nEndOfClause == -1 ? arr_clause.size() - 1 : nEndOfClause); i++)
|
|
arrBody.push_back(arr_clause[i]);
|
|
}
|
|
else
|
|
{
|
|
// Process any elseif or else clauses.
|
|
bool bDoneProcessing= false;
|
|
for (int nElseIf= 0; nElseIf < arrElseIfIndices.size(); nElseIf++)
|
|
{
|
|
if (!GetVariable( arr_clause[ arrElseIfIndices[ nElseIf ] ], strVariable ))
|
|
return false;
|
|
|
|
ParseVariable( strVariable, arrVariable );
|
|
|
|
strName = const_cast<CHTMLFragments*>(m_pFragments)->GetText(arrVariable);
|
|
if (strName.GetLength())
|
|
{
|
|
// Determine the ending point of this elseif clause and extract all clauses within.
|
|
int nEndOfClause= ((nElseIf + 1) < arrElseIfIndices.size())
|
|
? arrElseIfIndices[ nElseIf + 1 ] : elseIndex;
|
|
for (i= arrElseIfIndices[ nElseIf ] + 1; i < nEndOfClause; i++)
|
|
arrBody.push_back( arr_clause[ i ] );
|
|
|
|
bDoneProcessing= true;
|
|
break;
|
|
}
|
|
}
|
|
|
|
if ((!bDoneProcessing) && (elseIndex != -1))
|
|
{
|
|
// All of the clauses failed, output all clauses following the "else".
|
|
for (i = elseIndex + 1; i < arr_clause.size() - 1; i++)
|
|
arrBody.push_back(arr_clause[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 );
|
|
}
|
|
|
|
arr_clause = arrBody;
|
|
return true;
|
|
}
|
|
|
|
bool CAPGTSHTIReader::GetCommand(const CString& line, CString& command)
|
|
{
|
|
CString control_block;
|
|
CString variable;
|
|
|
|
if (GetControlBlockFromLine(line, control_block))
|
|
if (GetCommandVariableFromControlBlock(control_block, command, variable))
|
|
return true;
|
|
|
|
return false;
|
|
}
|
|
|
|
bool CAPGTSHTIReader::ComposeCommand(const CString& oper, const CString& variable, CString& command)
|
|
{
|
|
command = _T("");
|
|
LPCTSTR ws = _T(" ");
|
|
|
|
command += COMMAND_STARTSTR;
|
|
command += ws;
|
|
command += oper;
|
|
if (variable.GetLength()) {
|
|
command += ws;
|
|
command += COMMAND_STARTVARSTR;
|
|
command += variable;
|
|
}
|
|
command += COMMAND_ENDSTR;
|
|
|
|
return true;
|
|
}
|
|
|
|
bool CAPGTSHTIReader::GetVariable(const CString& line, CString& arg_variable)
|
|
{
|
|
CString control_block;
|
|
CString command, variable;
|
|
|
|
if (GetControlBlockFromLine(line, control_block))
|
|
if (GetCommandVariableFromControlBlock(control_block, command, variable))
|
|
if (variable.GetLength()) {
|
|
arg_variable = variable;
|
|
return true;
|
|
}
|
|
return false;
|
|
}
|
|
|
|
void CAPGTSHTIReader::ParseVariable(const CString& variable, FragmentIDVector& out)
|
|
{
|
|
vector<CString> arrStr;
|
|
int start_index = 0;
|
|
int end_index = -1;
|
|
|
|
try
|
|
{
|
|
// arrStr contains strings between delimiter "_"
|
|
while(-1 != (end_index = CString((LPCTSTR)variable + start_index).Find(DELIMITER_PREFIX)))
|
|
{
|
|
// end_index here is from "(LPCTSTR)variable + start_index" string
|
|
// so we can use it as length (2nd argument) in CString::Mid function
|
|
arrStr.push_back(((CString&)variable).Mid(start_index, end_index));
|
|
start_index = start_index + end_index + _tcslen(DELIMITER_PREFIX);
|
|
}
|
|
// pull the "tail" - after last (if any) "_"
|
|
arrStr.push_back(((CString&)variable).Right(variable.GetLength() - start_index));
|
|
|
|
out.clear();
|
|
for (vector<CString>::iterator i = arrStr.begin(); i < arrStr.end(); i++)
|
|
{
|
|
FragmentID fragmentID;
|
|
int curr = (*i).Find(DELIMITER_POSTFIX);
|
|
|
|
if (-1 != curr)
|
|
{
|
|
fragmentID.VarName = (*i).Left(curr);
|
|
|
|
curr += _tcslen(DELIMITER_POSTFIX); // skip delimiter
|
|
|
|
CString strIndex = (LPCTSTR)(*i) + curr;
|
|
strIndex.TrimLeft();
|
|
strIndex.TrimRight();
|
|
|
|
if (strIndex == _T("0"))
|
|
fragmentID.Index = 0;
|
|
else
|
|
fragmentID.Index = _ttol((LPCTSTR)strIndex) == 0
|
|
? fragmentID.Index // error occur
|
|
: _ttol((LPCTSTR)strIndex);
|
|
}
|
|
else
|
|
fragmentID.VarName = *i;
|
|
|
|
out.push_back(fragmentID);
|
|
}
|
|
}
|
|
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 );
|
|
}
|
|
}
|
|
|
|
void CAPGTSHTIReader::ComposeVariable(const FragmentIDVector& arr_fragment, CString& variable)
|
|
{
|
|
variable = _T("");
|
|
|
|
for (FragmentIDVector::const_iterator i = arr_fragment.begin(); i < arr_fragment.end(); i++)
|
|
{
|
|
if (i != arr_fragment.begin())
|
|
variable += DELIMITER_PREFIX;
|
|
|
|
variable += (*i).VarName;
|
|
|
|
if ((*i).Index != -1)
|
|
{
|
|
TCHAR buf[128] = {0};
|
|
|
|
variable += DELIMITER_POSTFIX;
|
|
_stprintf(buf, _T("%d"), (*i).Index);
|
|
variable += buf;
|
|
}
|
|
}
|
|
}
|
|
|
|
bool CAPGTSHTIReader::SubstituteCommandBlockWith(const CString& str_substitution, CString& line)
|
|
{
|
|
int start_index = -1;
|
|
int end_index = -1;
|
|
|
|
if (-1 != (start_index = line.Find(COMMAND_STARTSTR)))
|
|
{
|
|
if (-1 != (end_index = CString((LPCTSTR)line + start_index).Find(COMMAND_ENDSTR)))
|
|
{
|
|
CString tmp;
|
|
|
|
end_index += start_index;
|
|
end_index += _tcslen(COMMAND_ENDSTR); // skip closing bracket
|
|
|
|
tmp += line.Left(start_index);
|
|
tmp += str_substitution;
|
|
tmp += line.Right(line.GetLength() - end_index);
|
|
|
|
line = tmp;
|
|
return true;
|
|
}
|
|
}
|
|
return false;
|
|
}
|
|
|
|
void CAPGTSHTIReader::ComposeCommandBlock(const CString& command, const CString& variable, CString& command_block)
|
|
{
|
|
command_block = COMMAND_STARTSTR;
|
|
command_block += _T(" ");
|
|
command_block += command;
|
|
command_block += _T(" ");
|
|
command_block += COMMAND_STARTVARSTR;
|
|
command_block += variable;
|
|
command_block += _T(" ");
|
|
command_block += COMMAND_ENDSTR;
|
|
}
|
|
|
|
void CAPGTSHTIReader::PostfixVariable(const long postfix, CString& variable)
|
|
{
|
|
TCHAR buf[128] = {0};
|
|
|
|
_stprintf(buf, _T("%ld"), postfix);
|
|
variable += DELIMITER_POSTFIX;
|
|
variable += buf;
|
|
}
|
|
|
|
void CAPGTSHTIReader::PrefixVariable(const CString& prefix, CString& variable)
|
|
{
|
|
CString tmp = variable;
|
|
|
|
variable = prefix;
|
|
variable += DELIMITER_PREFIX;
|
|
variable += tmp;
|
|
}
|
|
// JSM V3.2 --
|
|
// called by GetCommandVariableFromControlBlock to handle
|
|
// decoding the variable part of commands like <!GTS property "fooprop">
|
|
// finds the first string argument in strText, which is either:
|
|
// any text beginning w/ anything other than '"', ending w/ whitespace or COMMAND_ENDSTR
|
|
// all text between doublequote marks "...." where an escape char ('\') escapes the character following.
|
|
//
|
|
CString CAPGTSHTIReader::GetStringArg(const CString & strText)
|
|
{
|
|
CString strArg = strText;
|
|
|
|
// look for quoted text:
|
|
int iStartQuote = strArg.Find(COMMAND_DOUBLEQUOTE);
|
|
if (iStartQuote != -1)
|
|
{
|
|
strArg = strArg.Mid(iStartQuote);
|
|
return GetEscapedText(strArg);
|
|
}
|
|
// o/w, assume that we're dealing w/ ordinary text, which ends
|
|
// with first whitespace or with COMMAND_ENDSTR
|
|
strArg.TrimLeft();
|
|
|
|
int iWhiteSpace(0), iEndCmd(0);
|
|
for(;(iWhiteSpace < strArg.GetLength()) && !(_istspace(strArg[iWhiteSpace])); iWhiteSpace++);
|
|
|
|
iEndCmd = strArg.Find(COMMAND_ENDSTR);
|
|
|
|
strArg = strArg.Left(min(iEndCmd,iWhiteSpace));
|
|
return strArg;
|
|
}
|
|
|
|
// JSM V3.2
|
|
// Called by GetEscapedText
|
|
// recursive function which does the work of removing escapes (backslashes)
|
|
// also checks for non-escaped endquote, which terminates the process
|
|
CString CAPGTSHTIReader::RemoveEscapesFrom(const CString &strIn)
|
|
{
|
|
int iNextESC = strIn.Find(COMMAND_ESCAPECHAR);
|
|
int iNextQuote = strIn.Find(COMMAND_DOUBLEQUOTE);
|
|
|
|
// (iNextQuote == -1) means a bad input, because the string
|
|
// we're looking at must terminate with quote.
|
|
// By default, however, we'll keep running to end of strIn.
|
|
if (iNextQuote == -1)
|
|
iNextQuote = strIn.GetLength();
|
|
|
|
// no more escape chars
|
|
if (iNextESC == -1 || (iNextESC > iNextQuote))
|
|
return strIn.Left(iNextQuote);
|
|
|
|
CString strEscapedChar;
|
|
strEscapedChar = strIn.GetAt(iNextESC + _tcslen(COMMAND_ESCAPECHAR));
|
|
return strIn.Left(iNextESC) +
|
|
strEscapedChar +
|
|
RemoveEscapesFrom(strIn.Mid(iNextESC + _tcslen(COMMAND_ESCAPECHAR) + 1));
|
|
}
|
|
|
|
// Converts a double-quoted string using backslash as an escape character to a correct CString
|
|
CString CAPGTSHTIReader::GetEscapedText(const CString &strText)
|
|
{
|
|
CString strEscaped;
|
|
|
|
// remove leading quote and anything preceding:
|
|
int iLeadQuote = strText.Find(COMMAND_DOUBLEQUOTE);
|
|
if (iLeadQuote != -1)
|
|
{
|
|
strEscaped = RemoveEscapesFrom(strText.Mid(iLeadQuote + _tcslen(COMMAND_DOUBLEQUOTE)));
|
|
}
|
|
return strEscaped;
|
|
}
|
|
|
|
// JSM V3.2 added ability to read string arguments into variable
|
|
// e.g. <!GTS property "FOO">
|
|
//
|
|
bool CAPGTSHTIReader::GetCommandVariableFromControlBlock(const CString& control_block, CString& command, CString& variable)
|
|
{
|
|
int start_command_index = -1;
|
|
int end_command_index = -1;
|
|
int start_variable_index = -1;
|
|
int end_variable_index = -1;
|
|
|
|
|
|
variable.Empty();
|
|
command.Empty();
|
|
|
|
start_command_index = control_block.Find(COMMAND_STARTSTR);
|
|
if (start_command_index == -1) // invalid control block
|
|
return false;
|
|
start_command_index += _tcslen(COMMAND_STARTSTR); // skip prefix
|
|
|
|
// extract the variable block, which can look like:
|
|
// ... $variable_name ...
|
|
// ... "parameter_name\\\"" ... (text in quotes w/ backslash escape)
|
|
// parameter_name (plain text)
|
|
if (-1 != ( end_command_index = (control_block.Mid(start_command_index)).Find(COMMAND_STARTVARSTR) ) )
|
|
{
|
|
// Variable prefixed with '$...'
|
|
end_command_index += start_command_index; // make end_command_index relative to start of control block
|
|
start_variable_index = end_command_index + _tcslen(COMMAND_STARTVARSTR); // skip "$"
|
|
end_variable_index = control_block.Find(COMMAND_ENDSTR);
|
|
|
|
// validation of indexes
|
|
if (-1 == min(start_command_index, end_command_index) ||
|
|
start_command_index > end_command_index)
|
|
return false;
|
|
|
|
command = ((CString&)control_block).Mid(start_command_index, end_command_index - start_command_index);
|
|
command.TrimLeft();
|
|
command.TrimRight();
|
|
|
|
if (start_variable_index > end_variable_index)
|
|
return false;
|
|
if (-1 != start_variable_index)
|
|
{
|
|
// extract variable from "..$varname>"
|
|
variable = ((CString&)control_block).Mid(start_variable_index, end_variable_index - start_variable_index);
|
|
variable.TrimLeft();
|
|
variable.TrimRight();
|
|
}
|
|
}
|
|
else
|
|
{
|
|
// Not prefixed with $.
|
|
// we don't know whether we're looking for a "\"quoted\"" or
|
|
// non-quoted string, or no variable at all. Also, we need
|
|
// to handle special cases like:
|
|
// <!GTS parameter ">">
|
|
// <!GTS endfor >
|
|
// etc.
|
|
command = ((CString&)control_block).Mid(start_command_index);
|
|
command.TrimLeft();
|
|
command.TrimRight();
|
|
// step through looking for whitespace at end of command:
|
|
int iWhiteSpace;
|
|
for(iWhiteSpace = 0;
|
|
(iWhiteSpace < command.GetLength()) && !(_istspace(command[iWhiteSpace]));
|
|
iWhiteSpace++);
|
|
|
|
if (iWhiteSpace != command.GetLength())
|
|
{
|
|
// found whitespace; the rest of the string may be a variable:
|
|
variable = GetStringArg(command.Mid(iWhiteSpace));
|
|
command = command.Left(iWhiteSpace); // truncate command where appropriate
|
|
}
|
|
else
|
|
{
|
|
// If there wasn't a variable after the command, we
|
|
// may still need to truncate to remove the COMMAND_ENDSTR:
|
|
end_command_index = command.Find(COMMAND_ENDSTR);
|
|
if (end_command_index != -1)
|
|
command = command.Left(end_command_index);
|
|
}
|
|
}
|
|
|
|
|
|
return true;
|
|
}
|
|
|
|
bool CAPGTSHTIReader::GetControlBlockFromLine(const CString& line, CString& control_block)
|
|
{
|
|
int start_index = -1;
|
|
int end_index = -1;
|
|
|
|
if (-1 == (start_index = line.Find(COMMAND_STARTSTR)))
|
|
return false;
|
|
if (-1 == (end_index = CString((LPCTSTR)line + start_index).Find(COMMAND_ENDSTR)))
|
|
return false;
|
|
|
|
end_index += _tcslen(COMMAND_ENDSTR); // points beyond closing bracket
|
|
end_index += start_index; // points in "line" string
|
|
|
|
control_block = ((CString&)line).Mid(start_index, end_index - start_index);
|
|
control_block.TrimLeft();
|
|
control_block.TrimRight();
|
|
|
|
return true;
|
|
}
|
|
|
|
bool CAPGTSHTIReader::HasHistoryTable()
|
|
{
|
|
bool bRet;
|
|
|
|
LOCKOBJECT();
|
|
CString indicator = CString(COMMAND_STARTVARSTR) + VAR_RECOMMENDATIONS;
|
|
bRet= Find( indicator );
|
|
UNLOCKOBJECT();
|
|
|
|
return( bRet );
|
|
}
|
|
|
|
#ifdef __DEBUG_CUSTOM
|
|
#include <io.h>
|
|
#include <fcntl.h>
|
|
#include <sys\\stat.h>
|
|
bool CAPGTSHTIReader::FlushOutputStreamToFile(const CString& file_name)
|
|
{
|
|
int hf = 0;
|
|
|
|
hf = _open(
|
|
file_name,
|
|
_O_CREAT | _O_TRUNC | /*_O_TEMPORARY |*/
|
|
_O_BINARY | _O_RDWR | _O_SEQUENTIAL ,
|
|
_S_IREAD | _S_IWRITE
|
|
);
|
|
|
|
if (hf != -1)
|
|
{
|
|
//tstringstream m_StreamOutput
|
|
basic_string<TCHAR> str = m_StreamOutput.rdbuf()->str();
|
|
long size = str.size();
|
|
LPCTSTR buf = str.c_str();
|
|
|
|
int ret = _write(hf, buf, size);
|
|
|
|
_close(hf);
|
|
|
|
if (-1 != ret)
|
|
return true;
|
|
}
|
|
|
|
return false;
|
|
}
|
|
#endif
|
|
|
|
// V3.2 - Enhancement to support cookies.
|
|
// This function handles the substituting of "<!Cookie" clauses with the either
|
|
// values from cookies, "_CK" values passed in via Get/Post, or the default value.
|
|
void CAPGTSHTIReader::SubstituteCookieValues( CString& strText )
|
|
{
|
|
CString strNewText;
|
|
const CString kstr_CommaChar= _T(",");
|
|
const CString kstr_DoubleQuote= _T("\"");
|
|
|
|
// Loop until we have processed all cookie clauses.
|
|
int nNumericCompareStart= strText.Find( kstrCond_NumericCompare );
|
|
int nCookieClauseStart= strText.Find( COMMAND_COOKIE );
|
|
while (CString::FIND_FAILED != nCookieClauseStart)
|
|
{
|
|
CString strCookieClause;
|
|
CString strCookieName, strCookieAttr, strCookieValue;
|
|
int nCookieClauseEnd, nScratchMarker;
|
|
|
|
// Add any text preceding the cookie clause to the return string.
|
|
strNewText+= strText.Left( nCookieClauseStart );
|
|
|
|
// Remove all preceding text.
|
|
strText= strText.Mid( nCookieClauseStart + _tcslen( COMMAND_COOKIE ) );
|
|
|
|
// Look for the ending clause.
|
|
nCookieClauseEnd= strText.Find( COMMAND_ENDSTR );
|
|
if (CString::FIND_FAILED == nCookieClauseEnd)
|
|
{
|
|
CBuildSrcFileLinenoStr SrcLoc( __FILE__, __LINE__ );
|
|
CEvent::ReportWFEvent( SrcLoc.GetSrcFileLineStr(),
|
|
SrcLoc.GetSrcFileLineStr(),
|
|
COMMAND_ENDSTR, _T(""),
|
|
EV_GTS_COOKIE_COMPONENT_NOT_FOUND );
|
|
break;
|
|
}
|
|
|
|
// Pull out the current cookie clause and reset the working string.
|
|
strCookieClause= strText.Left( nCookieClauseEnd );
|
|
strText= strText.Mid( nCookieClauseEnd + 1 );
|
|
|
|
// Extract the cookie name.
|
|
nScratchMarker= strCookieClause.Find( kstr_CommaChar );
|
|
if (CString::FIND_FAILED == nScratchMarker)
|
|
{
|
|
CBuildSrcFileLinenoStr SrcLoc( __FILE__, __LINE__ );
|
|
CEvent::ReportWFEvent( SrcLoc.GetSrcFileLineStr(),
|
|
SrcLoc.GetSrcFileLineStr(),
|
|
kstr_CommaChar, _T(""),
|
|
EV_GTS_COOKIE_COMPONENT_NOT_FOUND );
|
|
break;
|
|
}
|
|
strCookieName= strCookieClause.Left( nScratchMarker );
|
|
strCookieName.TrimLeft();
|
|
strCookieName.TrimRight();
|
|
|
|
// Extract the cookie setting.
|
|
strCookieClause= strCookieClause.Mid( nScratchMarker + 1 );
|
|
nScratchMarker= strCookieClause.Find( kstr_CommaChar );
|
|
if (CString::FIND_FAILED == nScratchMarker)
|
|
{
|
|
CBuildSrcFileLinenoStr SrcLoc( __FILE__, __LINE__ );
|
|
CEvent::ReportWFEvent( SrcLoc.GetSrcFileLineStr(),
|
|
SrcLoc.GetSrcFileLineStr(),
|
|
kstr_CommaChar, _T(""),
|
|
EV_GTS_COOKIE_COMPONENT_NOT_FOUND );
|
|
break;
|
|
}
|
|
strCookieAttr= strCookieClause.Left( nScratchMarker );
|
|
strCookieAttr.TrimLeft();
|
|
strCookieAttr.TrimRight();
|
|
|
|
strCookieClause= strCookieClause.Mid( nScratchMarker + sizeof( TCHAR ) );
|
|
|
|
// Attempt to locate the appropriate attribute/value pair,
|
|
// first checking the command line CK_ values, and
|
|
// then checking the cookies passed in the HTTP header.
|
|
bool bCookieNotFound= true;
|
|
if (!m_mapCookies.empty())
|
|
{
|
|
// Search the command line CK_ values.
|
|
map<CString,CString>::const_iterator iterMap= m_mapCookies.find( strCookieAttr );
|
|
if (iterMap != m_mapCookies.end())
|
|
{
|
|
strCookieValue= iterMap->second;
|
|
bCookieNotFound= false;
|
|
}
|
|
}
|
|
if (bCookieNotFound)
|
|
{
|
|
if (!m_strHTTPcookies.IsEmpty())
|
|
{
|
|
// Attempt to locate the attribute in the HTTP header information.
|
|
if (LocateCookieValue( strCookieName, strCookieAttr, strCookieValue ))
|
|
bCookieNotFound= false;
|
|
}
|
|
}
|
|
if (bCookieNotFound)
|
|
{
|
|
// Extract the default value for this attribute, which should be surrounded
|
|
// by double quotes.
|
|
nScratchMarker= strCookieClause.Find( kstr_DoubleQuote );
|
|
if (CString::FIND_FAILED == nScratchMarker)
|
|
{
|
|
CBuildSrcFileLinenoStr SrcLoc( __FILE__, __LINE__ );
|
|
CEvent::ReportWFEvent( SrcLoc.GetSrcFileLineStr(),
|
|
SrcLoc.GetSrcFileLineStr(),
|
|
kstr_DoubleQuote, _T(""),
|
|
EV_GTS_COOKIE_COMPONENT_NOT_FOUND );
|
|
break;
|
|
}
|
|
strCookieClause= strCookieClause.Mid( nScratchMarker + sizeof( TCHAR ) );
|
|
nScratchMarker= strCookieClause.Find( kstr_DoubleQuote );
|
|
if (CString::FIND_FAILED == nScratchMarker)
|
|
{
|
|
CBuildSrcFileLinenoStr SrcLoc( __FILE__, __LINE__ );
|
|
CEvent::ReportWFEvent( SrcLoc.GetSrcFileLineStr(),
|
|
SrcLoc.GetSrcFileLineStr(),
|
|
kstr_DoubleQuote, _T(""),
|
|
EV_GTS_COOKIE_COMPONENT_NOT_FOUND );
|
|
break;
|
|
}
|
|
strCookieValue= strCookieClause.Left( nScratchMarker );
|
|
}
|
|
|
|
// Add the attribute value to the output string.
|
|
// >>> $MAINT - The determination of whether or not to output quotes should
|
|
// be improved. I currently have no suggestions. RAB-19990918.
|
|
if ((nNumericCompareStart == CString::FIND_FAILED) || (nNumericCompareStart > nCookieClauseStart))
|
|
strNewText+= _T("\"");
|
|
strNewText+= strCookieValue;
|
|
if ((nNumericCompareStart == CString::FIND_FAILED) || (nNumericCompareStart > nCookieClauseStart))
|
|
strNewText+= _T("\"");
|
|
|
|
// Look for another cookie clause.
|
|
nNumericCompareStart= strText.Find( kstrCond_NumericCompare );
|
|
nCookieClauseStart= strText.Find( COMMAND_COOKIE );
|
|
}
|
|
|
|
// Append any remaining text onto the end of the string.
|
|
// If a cookie clause did not contain an ending marker it will be appended as well.
|
|
strNewText+= strText;
|
|
|
|
// Reassign the return string.
|
|
strText= strNewText;
|
|
|
|
return;
|
|
}
|
|
|
|
|
|
// V3.2 - Enhancement to support cookies.
|
|
// This function searches the HTTP cookies for a given cookie name and attribute. If
|
|
// found, this function returns a value of true and the located cookie value.
|
|
bool CAPGTSHTIReader::LocateCookieValue( const CString& strCookieName,
|
|
const CString& strCookieAttr,
|
|
CString& strCookieValue )
|
|
{
|
|
bool bCookieFound= false;
|
|
CString strTmpCookieName= strCookieName + _T("=");
|
|
int nScratch;
|
|
|
|
// URL encode the cookie name to handle underscores.
|
|
APGTS_nmspace::CookieEncodeURL( strTmpCookieName );
|
|
|
|
nScratch= m_strHTTPcookies.Find( strTmpCookieName );
|
|
if (CString::FIND_FAILED != nScratch)
|
|
{
|
|
// Verify that we have not matched on a partial string for the cookie name.
|
|
if ((nScratch == 0) ||
|
|
(m_strHTTPcookies[ nScratch - 1 ] == _T(' ')) ||
|
|
(m_strHTTPcookies[ nScratch - 1 ] == _T(';')))
|
|
{
|
|
// We have found the cookie that we are looking for, now look for the attribute name.
|
|
CString strTmpCookieAttr= strCookieAttr + _T("=");
|
|
|
|
// URL encode the cookie name to handle underscores.
|
|
APGTS_nmspace::CookieEncodeURL( strTmpCookieAttr );
|
|
|
|
|
|
// Jump past the starting point and the original cookie name length.
|
|
CString strScratch = m_strHTTPcookies.Mid( nScratch + strCookieName.GetLength() );
|
|
nScratch= strScratch.Find( _T(";") );
|
|
if (CString::FIND_FAILED != nScratch)
|
|
{
|
|
// Truncate the string at the end of this particular cookie..
|
|
if (nScratch > 0)
|
|
strScratch= strScratch.Left( nScratch );
|
|
}
|
|
nScratch= strScratch.Find( strTmpCookieAttr );
|
|
if (CString::FIND_FAILED != nScratch)
|
|
{
|
|
if (nScratch > 0)
|
|
{
|
|
// Verify that we have not matched on a partial string for the cookie attribute.
|
|
if ((strScratch[ nScratch - 1 ] == _T('=')) ||
|
|
(strScratch[ nScratch - 1 ] == _T('&')))
|
|
{
|
|
strCookieValue= strScratch.Mid( nScratch + strTmpCookieAttr.GetLength() );
|
|
|
|
// Look for and remove any delimiters.
|
|
nScratch= strCookieValue.Find( _T("&") );
|
|
if (CString::FIND_FAILED != nScratch)
|
|
{
|
|
// Truncate the string.
|
|
if (nScratch > 0)
|
|
strCookieValue= strCookieValue.Left( nScratch );
|
|
}
|
|
nScratch= strCookieValue.Find( _T(";") );
|
|
if (CString::FIND_FAILED != nScratch)
|
|
{
|
|
// Truncate the string.
|
|
if (nScratch > 0)
|
|
strCookieValue= strCookieValue.Left( nScratch );
|
|
}
|
|
|
|
// Decode the cookie value.
|
|
if (!strCookieValue.IsEmpty())
|
|
APGTS_nmspace::CookieDecodeURL( strCookieValue );
|
|
bCookieFound= true;
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
return( bCookieFound );
|
|
}
|
|
|