Source code of Windows XP (NT5)
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.

191 lines
5.0 KiB

  1. //
  2. // MODULE: TEMPLATEREAD.CPP
  3. //
  4. // PURPOSE: template file reading classes
  5. //
  6. // COMPANY: Saltmine Creative, Inc. (206)-284-7511 [email protected]
  7. //
  8. // AUTHOR: Oleg Kalosha
  9. //
  10. // ORIGINAL DATE: 8-12-98
  11. //
  12. // NOTES:
  13. // 1. CTemplateReader has no public methods to apply the template. These must be supplied
  14. // by classes which inherit from CTemplateReader, and these must be supplied in a
  15. // suitably "stateless" manner.
  16. //
  17. // Version Date By Comments
  18. //--------------------------------------------------------------------
  19. // V3.0 08-04-98 OK
  20. //
  21. #include "stdafx.h"
  22. #include <algorithm>
  23. #include "templateread.h"
  24. #include "event.h"
  25. #include "CharConv.h"
  26. ////////////////////////////////////////////////////////////////////////////////////
  27. // CTemplateInfo
  28. // Manages a pair consisting of a key and a string to substitute for each occurrence of
  29. // that key.
  30. ////////////////////////////////////////////////////////////////////////////////////
  31. CTemplateInfo::CTemplateInfo()
  32. {
  33. }
  34. CTemplateInfo::CTemplateInfo(const CString& key, const CString& substitution)
  35. : m_KeyStr(key),
  36. m_SubstitutionStr(substitution)
  37. {
  38. }
  39. CTemplateInfo::~CTemplateInfo()
  40. {
  41. }
  42. // INPUT/OUTPUT target
  43. // Replace all instances of m_KeyStr in target with m_SubstitutionStr
  44. bool CTemplateInfo::Apply(CString& target) const
  45. {
  46. int start =0, end =0;
  47. bool bRet = false;
  48. while (-1 != (start = target.Find(m_KeyStr)))
  49. {
  50. end = start + m_KeyStr.GetLength();
  51. target = target.Left(start) + m_SubstitutionStr + target.Mid(end);
  52. bRet = true;
  53. }
  54. return bRet;
  55. }
  56. ////////////////////////////////////////////////////////////////////////////////////
  57. // CTemplateReader
  58. ////////////////////////////////////////////////////////////////////////////////////
  59. CTemplateReader::CTemplateReader(CPhysicalFileReader * pPhysicalFileReader, LPCTSTR szDefaultContents /*= NULL */)
  60. : CTextFileReader(pPhysicalFileReader, szDefaultContents)
  61. {
  62. }
  63. CTemplateReader::~CTemplateReader()
  64. {
  65. }
  66. // For all instances of a key, substitute the appropriate value
  67. CTemplateReader& CTemplateReader::operator << (CTemplateInfo& info)
  68. {
  69. CString str;
  70. vector<CString> str_arr;
  71. LOCKOBJECT();
  72. SetPos(m_StreamOutput, 0);
  73. try
  74. {
  75. // put whole content of m_StreamOutput, line by line, into str_arr
  76. while (GetLine(m_StreamOutput, str))
  77. str_arr.push_back(str);
  78. }
  79. catch (exception& x)
  80. {
  81. CString str;
  82. // Note STL exception in event log.
  83. CBuildSrcFileLinenoStr SrcLoc( __FILE__, __LINE__ );
  84. CEvent::ReportWFEvent( SrcLoc.GetSrcFileLineStr(),
  85. SrcLoc.GetSrcFileLineStr(),
  86. CCharConversion::ConvertACharToString(x.what(), str),
  87. _T(""),
  88. EV_GTS_STL_EXCEPTION );
  89. }
  90. vector<CString>::iterator i;
  91. // Replace all instances of m_KeyStr in str_arr elements with m_SubstitutionStr
  92. for (i = str_arr.begin(); i < str_arr.end(); i++)
  93. info.Apply(*i);
  94. m_StreamOutput.clear();
  95. vector<CString>::iterator iLastElement = str_arr.end();
  96. iLastElement--;
  97. for (i = str_arr.begin(); i < str_arr.end(); i++)
  98. {
  99. m_StreamOutput << (LPCTSTR)*i;
  100. if (i != iLastElement)
  101. m_StreamOutput << _T('\r') << _T('\n');
  102. }
  103. m_StreamOutput << ends;
  104. SetPos(m_StreamOutput, 0);
  105. UNLOCKOBJECT();
  106. return *this;
  107. }
  108. // undo substitution with this argument
  109. // As of 11/98, not used in Online Troubleshooter, hence totally untested.
  110. CTemplateReader& CTemplateReader::operator >> (CTemplateInfo& info)
  111. {
  112. LOCKOBJECT();
  113. // remove this element from substitution list
  114. vector<CTemplateInfo>::iterator res = find(m_arrTemplateInfo.begin(), m_arrTemplateInfo.end(), info);
  115. if (res != m_arrTemplateInfo.end())
  116. m_arrTemplateInfo.erase(res);
  117. // perform all substitutions all over again
  118. Parse();
  119. UNLOCKOBJECT();
  120. return *this;
  121. }
  122. // Perform all substitutions
  123. void CTemplateReader::Parse()
  124. {
  125. SetOutputToTemplate();
  126. for (vector<CTemplateInfo>::iterator i = m_arrTemplateInfo.begin(); i < m_arrTemplateInfo.end(); i++)
  127. *this << *i;
  128. }
  129. void CTemplateReader::GetOutput(CString& out)
  130. {
  131. out = _T(""); // clear
  132. LOCKOBJECT();
  133. out = m_StreamOutput.rdbuf()->str().c_str();
  134. UNLOCKOBJECT();
  135. }
  136. // In m_StreamData we always have pure template
  137. // This function is discarding all changes in m_StreamOutput
  138. // and setting it back to template
  139. void CTemplateReader::SetOutputToTemplate()
  140. {
  141. LOCKOBJECT();
  142. tstring tstr;
  143. m_StreamOutput.str(GetContent(tstr));
  144. UNLOCKOBJECT();
  145. }
  146. ////////////////////////////////////////////////////////////////////////////////////
  147. // CSimpleTemplate
  148. ////////////////////////////////////////////////////////////////////////////////////
  149. CSimpleTemplate::CSimpleTemplate(CPhysicalFileReader * pPhysicalFileReader, LPCTSTR szDefaultContents /*= NULL*/) :
  150. CTemplateReader(pPhysicalFileReader, szDefaultContents)
  151. {
  152. }
  153. CSimpleTemplate::~CSimpleTemplate()
  154. {
  155. }
  156. // Given a vector of substitutions to make, perform them all (on the template) and return
  157. // the resulting string.
  158. void CSimpleTemplate::CreatePage( const vector<CTemplateInfo> & arrTemplateInfo,
  159. CString& out)
  160. {
  161. LOCKOBJECT();
  162. m_arrTemplateInfo = arrTemplateInfo;
  163. Parse();
  164. out = m_StreamOutput.rdbuf()->str().c_str();
  165. UNLOCKOBJECT();
  166. }