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.

333 lines
7.3 KiB

  1. #ifndef __SECTION_H_
  2. #define __SECTION_H_
  3. #include <windows.h>
  4. #include <vector>
  5. #include <string>
  6. #include <map>
  7. #include <iostream>
  8. extern "C" {
  9. #include <compliance.h>
  10. }
  11. using namespace std;
  12. class ComplianceFile;
  13. //
  14. // This class represents a section in the compliance
  15. // data file
  16. //
  17. class Section {
  18. public:
  19. Section(const string &name, const vector<string>& lines,
  20. const ComplianceFile& file) : m_file(file) {
  21. m_name = name;
  22. m_lines = lines;
  23. }
  24. Section(const Section& rhs) : m_file(rhs.m_file){
  25. *this = rhs;
  26. }
  27. virtual ~Section() {}
  28. //
  29. // accessors
  30. //
  31. const string& name() const { return m_name; }
  32. const vector<string>& lines() const { return m_lines; }
  33. const ComplianceFile& file() const{ return m_file; }
  34. //
  35. // parses the section content
  36. //
  37. virtual void parse() {}
  38. //
  39. // exceptions which methods of this class
  40. // can throw
  41. //
  42. struct SectionException {
  43. SectionException(const string& sectionName) : m_name(sectionName) {}
  44. string m_name;
  45. friend ostream& operator<<(ostream& os, const struct SectionException& rhs) {
  46. os << "Exception : Section Error : " << rhs.m_name;
  47. return os;
  48. }
  49. };
  50. struct InvalidSectionFormat : public SectionException {
  51. InvalidSectionFormat(const string& sectionName) : SectionException(sectionName) {}
  52. friend ostream& operator<<(ostream& os, const struct InvalidSectionFormat& rhs) {
  53. os << "Exception : Invalid Section Format : " << rhs.m_name;
  54. return os;
  55. }
  56. };
  57. struct InvalidSectionName : public SectionException {
  58. InvalidSectionName(const string &sectionName) : SectionException(sectionName) {}
  59. friend ostream& operator<<(ostream& os, const struct InvalidSectionName &rhs) {
  60. os << "Exception : Invalid Section Name : " << rhs.m_name;
  61. return os;
  62. }
  63. };
  64. //
  65. // overloaded operators
  66. //
  67. Section& operator=(const Section& rhs) {
  68. m_name = rhs.m_name;
  69. m_lines = rhs.m_lines;
  70. return *this;
  71. }
  72. protected:
  73. //
  74. // data members
  75. //
  76. string m_name;
  77. vector<string> m_lines;
  78. const ComplianceFile& m_file;
  79. };
  80. //
  81. // This class represents a value section in the compliance
  82. // data file
  83. //
  84. class ValueSection : public Section {
  85. public:
  86. ValueSection(const string& name, const vector<string>& lines,
  87. const ComplianceFile& file) : Section(name, lines, file) {
  88. parse();
  89. }
  90. //
  91. // parse the section and create <name, value> pairs
  92. //
  93. virtual void parse();
  94. unsigned long value(const string &key) const{
  95. map<string, unsigned long>::const_iterator iter = m_values.find(key);
  96. if (iter == m_values.end())
  97. throw ValueNotFound(name(), key);
  98. return (*iter).second;
  99. }
  100. //
  101. // exceptions which can be thrown by the methods
  102. // of this class
  103. //
  104. struct ValueNotFound : public Section::SectionException {
  105. ValueNotFound(const string& name, const string &valname) :
  106. SectionException(name), m_valname(valname){}
  107. string m_valname;
  108. friend ostream& operator<<(ostream& os, const struct ValueNotFound& rhs) {
  109. os << "Exception : Value " << rhs.m_valname << " was not found in "
  110. << rhs.m_name;
  111. return os;
  112. }
  113. };
  114. protected:
  115. //
  116. // data members
  117. //
  118. map<string, unsigned long> m_values;
  119. };
  120. //
  121. // this class represents a single test case in an test
  122. // section
  123. //
  124. class TestCase {
  125. public:
  126. TestCase(const Section& section, const string& line) :
  127. m_section(section), m_line(line) {
  128. }
  129. virtual ~TestCase() {}
  130. //
  131. // accessors
  132. //
  133. const string& line() const { return m_line; }
  134. const Section& section() const { return m_section; }
  135. virtual void parse() = 0;
  136. virtual void execute(ostream &os) = 0;
  137. virtual bool passed() = 0;
  138. virtual void dump(ostream& os) = 0;
  139. //
  140. // exceptions
  141. //
  142. struct InvalidFormat {
  143. InvalidFormat(const string& line, const string& section) {
  144. m_line = line;
  145. m_section = section;
  146. };
  147. string m_section, m_line;
  148. friend ostream& operator<<(ostream& os, const struct InvalidFormat& rhs) {
  149. os << "Exception : Invalid Test Case : " << rhs.m_line << " in section : "
  150. << rhs.m_section;
  151. return os;
  152. }
  153. };
  154. protected:
  155. //
  156. // data members
  157. //
  158. const Section& m_section;
  159. string m_line;
  160. };
  161. //
  162. // this class represents a test case (single line
  163. // in an test section)
  164. //
  165. class ComplianceTestCase : public TestCase {
  166. public:
  167. ComplianceTestCase(const Section& section, const string& line) :
  168. TestCase(section, line) {
  169. ::memset(&m_cd, 0, sizeof(COMPLIANCE_DATA));
  170. m_passed = false;
  171. m_allowUpgrade = false;
  172. parse();
  173. }
  174. virtual void execute(ostream &os);
  175. virtual bool passed();
  176. virtual void parse();
  177. virtual void dump(ostream& os);
  178. protected:
  179. void sourceDetails();
  180. void installationDetails(const vector<string>& tokens);
  181. //
  182. // data members
  183. //
  184. bool m_passed;
  185. COMPLIANCE_DATA m_cd;
  186. unsigned long m_sourceSKU;
  187. unsigned long m_sourceVAR;
  188. unsigned long m_sourceVer;
  189. unsigned long m_sourceBuild;
  190. bool m_expectedResult;
  191. UINT m_reason;
  192. BOOL m_noUpgrade;
  193. bool m_allowUpgrade;
  194. UINT m_errExpected;
  195. };
  196. //
  197. // default factory to create test cases
  198. //
  199. class TestCaseFactory {
  200. public:
  201. virtual TestCase* create(const Section& section, const string& line) const {
  202. TestCase *pTestCase = new ComplianceTestCase(section, line);
  203. return pTestCase;
  204. }
  205. virtual TestCase* create(const TestCase& tc) const {
  206. return create(tc.section(), tc.line());
  207. }
  208. };
  209. //
  210. // this class represents the test section in the compliance
  211. // data file
  212. //
  213. class TestSection : public Section {
  214. public:
  215. TestSection(const string& name, const vector<string>& lines,
  216. const ComplianceFile& file) : Section(name, lines, file){
  217. bindFactory();
  218. parse();
  219. }
  220. ~TestSection() {
  221. vector<TestCase*>::iterator iter = m_testCases.begin();
  222. while (iter != m_testCases.end())
  223. delete (*iter++);
  224. delete m_tcFactory;
  225. }
  226. TestSection& operator=(const TestSection& rhs);
  227. void executeTestCases(ostream& os);
  228. //
  229. // accessors
  230. //
  231. // const vector<TestCase *> testCases() const{ return m_testCases; }
  232. const TestCaseFactory& testCaseFactory() const{ return *m_tcFactory; }
  233. void parse();
  234. protected:
  235. void bindFactory() {
  236. m_tcFactory = new TestCaseFactory();
  237. }
  238. //
  239. // data members
  240. //
  241. vector<TestCase *> m_testCases;
  242. TestCaseFactory *m_tcFactory;
  243. };
  244. //
  245. // default factory to create sections
  246. //
  247. class SectionFactory {
  248. public:
  249. virtual Section* create(const string& name,
  250. const vector<string>& lines, const ComplianceFile& file) const {
  251. return new Section(name, lines, file);
  252. }
  253. virtual Section* create(const Section& section) const {
  254. return create(section.name(), section.lines(), section.file());
  255. }
  256. };
  257. //
  258. // current factory to create sections
  259. //
  260. class OldFormatSectionFactory : public SectionFactory {
  261. public:
  262. virtual Section* create(const string& name,
  263. const vector<string>& lines, const ComplianceFile& file) const {
  264. if (name.find("[test#") != name.npos)
  265. return new TestSection(name, lines, file);
  266. else if (name.find("#values]") != name.npos)
  267. return new ValueSection(name, lines, file);
  268. else
  269. return new Section(name, lines, file);
  270. }
  271. };
  272. #endif // for __SECTION_H_