334 lines
7.3 KiB
C
334 lines
7.3 KiB
C
|
|
||
|
#ifndef __SECTION_H_
|
||
|
#define __SECTION_H_
|
||
|
|
||
|
#include <windows.h>
|
||
|
#include <vector>
|
||
|
#include <string>
|
||
|
#include <map>
|
||
|
#include <iostream>
|
||
|
|
||
|
extern "C" {
|
||
|
#include <compliance.h>
|
||
|
}
|
||
|
|
||
|
using namespace std;
|
||
|
|
||
|
class ComplianceFile;
|
||
|
|
||
|
//
|
||
|
// This class represents a section in the compliance
|
||
|
// data file
|
||
|
//
|
||
|
class Section {
|
||
|
public:
|
||
|
Section(const string &name, const vector<string>& lines,
|
||
|
const ComplianceFile& file) : m_file(file) {
|
||
|
m_name = name;
|
||
|
m_lines = lines;
|
||
|
}
|
||
|
|
||
|
Section(const Section& rhs) : m_file(rhs.m_file){
|
||
|
*this = rhs;
|
||
|
}
|
||
|
|
||
|
virtual ~Section() {}
|
||
|
|
||
|
//
|
||
|
// accessors
|
||
|
//
|
||
|
const string& name() const { return m_name; }
|
||
|
const vector<string>& lines() const { return m_lines; }
|
||
|
const ComplianceFile& file() const{ return m_file; }
|
||
|
|
||
|
//
|
||
|
// parses the section content
|
||
|
//
|
||
|
virtual void parse() {}
|
||
|
|
||
|
//
|
||
|
// exceptions which methods of this class
|
||
|
// can throw
|
||
|
//
|
||
|
struct SectionException {
|
||
|
SectionException(const string& sectionName) : m_name(sectionName) {}
|
||
|
|
||
|
string m_name;
|
||
|
|
||
|
friend ostream& operator<<(ostream& os, const struct SectionException& rhs) {
|
||
|
os << "Exception : Section Error : " << rhs.m_name;
|
||
|
return os;
|
||
|
}
|
||
|
};
|
||
|
|
||
|
struct InvalidSectionFormat : public SectionException {
|
||
|
InvalidSectionFormat(const string& sectionName) : SectionException(sectionName) {}
|
||
|
|
||
|
friend ostream& operator<<(ostream& os, const struct InvalidSectionFormat& rhs) {
|
||
|
os << "Exception : Invalid Section Format : " << rhs.m_name;
|
||
|
return os;
|
||
|
}
|
||
|
};
|
||
|
|
||
|
struct InvalidSectionName : public SectionException {
|
||
|
InvalidSectionName(const string §ionName) : SectionException(sectionName) {}
|
||
|
|
||
|
friend ostream& operator<<(ostream& os, const struct InvalidSectionName &rhs) {
|
||
|
os << "Exception : Invalid Section Name : " << rhs.m_name;
|
||
|
return os;
|
||
|
}
|
||
|
};
|
||
|
|
||
|
//
|
||
|
// overloaded operators
|
||
|
//
|
||
|
Section& operator=(const Section& rhs) {
|
||
|
m_name = rhs.m_name;
|
||
|
m_lines = rhs.m_lines;
|
||
|
|
||
|
return *this;
|
||
|
}
|
||
|
|
||
|
protected:
|
||
|
//
|
||
|
// data members
|
||
|
//
|
||
|
string m_name;
|
||
|
vector<string> m_lines;
|
||
|
const ComplianceFile& m_file;
|
||
|
};
|
||
|
|
||
|
|
||
|
//
|
||
|
// This class represents a value section in the compliance
|
||
|
// data file
|
||
|
//
|
||
|
class ValueSection : public Section {
|
||
|
public:
|
||
|
ValueSection(const string& name, const vector<string>& lines,
|
||
|
const ComplianceFile& file) : Section(name, lines, file) {
|
||
|
parse();
|
||
|
}
|
||
|
|
||
|
//
|
||
|
// parse the section and create <name, value> pairs
|
||
|
//
|
||
|
virtual void parse();
|
||
|
|
||
|
unsigned long value(const string &key) const{
|
||
|
map<string, unsigned long>::const_iterator iter = m_values.find(key);
|
||
|
|
||
|
if (iter == m_values.end())
|
||
|
throw ValueNotFound(name(), key);
|
||
|
|
||
|
return (*iter).second;
|
||
|
}
|
||
|
|
||
|
//
|
||
|
// exceptions which can be thrown by the methods
|
||
|
// of this class
|
||
|
//
|
||
|
struct ValueNotFound : public Section::SectionException {
|
||
|
ValueNotFound(const string& name, const string &valname) :
|
||
|
SectionException(name), m_valname(valname){}
|
||
|
|
||
|
string m_valname;
|
||
|
|
||
|
friend ostream& operator<<(ostream& os, const struct ValueNotFound& rhs) {
|
||
|
os << "Exception : Value " << rhs.m_valname << " was not found in "
|
||
|
<< rhs.m_name;
|
||
|
return os;
|
||
|
}
|
||
|
};
|
||
|
|
||
|
protected:
|
||
|
//
|
||
|
// data members
|
||
|
//
|
||
|
map<string, unsigned long> m_values;
|
||
|
};
|
||
|
|
||
|
//
|
||
|
// this class represents a single test case in an test
|
||
|
// section
|
||
|
//
|
||
|
class TestCase {
|
||
|
public:
|
||
|
TestCase(const Section& section, const string& line) :
|
||
|
m_section(section), m_line(line) {
|
||
|
}
|
||
|
|
||
|
virtual ~TestCase() {}
|
||
|
|
||
|
//
|
||
|
// accessors
|
||
|
//
|
||
|
const string& line() const { return m_line; }
|
||
|
const Section& section() const { return m_section; }
|
||
|
|
||
|
virtual void parse() = 0;
|
||
|
virtual void execute(ostream &os) = 0;
|
||
|
virtual bool passed() = 0;
|
||
|
virtual void dump(ostream& os) = 0;
|
||
|
|
||
|
//
|
||
|
// exceptions
|
||
|
//
|
||
|
struct InvalidFormat {
|
||
|
InvalidFormat(const string& line, const string& section) {
|
||
|
m_line = line;
|
||
|
m_section = section;
|
||
|
};
|
||
|
|
||
|
string m_section, m_line;
|
||
|
|
||
|
friend ostream& operator<<(ostream& os, const struct InvalidFormat& rhs) {
|
||
|
os << "Exception : Invalid Test Case : " << rhs.m_line << " in section : "
|
||
|
<< rhs.m_section;
|
||
|
return os;
|
||
|
}
|
||
|
};
|
||
|
|
||
|
protected:
|
||
|
//
|
||
|
// data members
|
||
|
//
|
||
|
const Section& m_section;
|
||
|
string m_line;
|
||
|
};
|
||
|
|
||
|
//
|
||
|
// this class represents a test case (single line
|
||
|
// in an test section)
|
||
|
//
|
||
|
class ComplianceTestCase : public TestCase {
|
||
|
public:
|
||
|
ComplianceTestCase(const Section& section, const string& line) :
|
||
|
TestCase(section, line) {
|
||
|
::memset(&m_cd, 0, sizeof(COMPLIANCE_DATA));
|
||
|
m_passed = false;
|
||
|
m_allowUpgrade = false;
|
||
|
parse();
|
||
|
}
|
||
|
|
||
|
virtual void execute(ostream &os);
|
||
|
virtual bool passed();
|
||
|
virtual void parse();
|
||
|
virtual void dump(ostream& os);
|
||
|
|
||
|
protected:
|
||
|
void sourceDetails();
|
||
|
void installationDetails(const vector<string>& tokens);
|
||
|
|
||
|
//
|
||
|
// data members
|
||
|
//
|
||
|
bool m_passed;
|
||
|
COMPLIANCE_DATA m_cd;
|
||
|
unsigned long m_sourceSKU;
|
||
|
unsigned long m_sourceVAR;
|
||
|
unsigned long m_sourceVer;
|
||
|
unsigned long m_sourceBuild;
|
||
|
bool m_expectedResult;
|
||
|
UINT m_reason;
|
||
|
BOOL m_noUpgrade;
|
||
|
bool m_allowUpgrade;
|
||
|
UINT m_errExpected;
|
||
|
};
|
||
|
|
||
|
//
|
||
|
// default factory to create test cases
|
||
|
//
|
||
|
class TestCaseFactory {
|
||
|
public:
|
||
|
virtual TestCase* create(const Section& section, const string& line) const {
|
||
|
TestCase *pTestCase = new ComplianceTestCase(section, line);
|
||
|
return pTestCase;
|
||
|
}
|
||
|
|
||
|
virtual TestCase* create(const TestCase& tc) const {
|
||
|
return create(tc.section(), tc.line());
|
||
|
}
|
||
|
};
|
||
|
|
||
|
|
||
|
//
|
||
|
// this class represents the test section in the compliance
|
||
|
// data file
|
||
|
//
|
||
|
class TestSection : public Section {
|
||
|
public:
|
||
|
TestSection(const string& name, const vector<string>& lines,
|
||
|
const ComplianceFile& file) : Section(name, lines, file){
|
||
|
bindFactory();
|
||
|
parse();
|
||
|
}
|
||
|
|
||
|
~TestSection() {
|
||
|
vector<TestCase*>::iterator iter = m_testCases.begin();
|
||
|
|
||
|
while (iter != m_testCases.end())
|
||
|
delete (*iter++);
|
||
|
|
||
|
delete m_tcFactory;
|
||
|
}
|
||
|
|
||
|
TestSection& operator=(const TestSection& rhs);
|
||
|
|
||
|
void executeTestCases(ostream& os);
|
||
|
|
||
|
//
|
||
|
// accessors
|
||
|
//
|
||
|
// const vector<TestCase *> testCases() const{ return m_testCases; }
|
||
|
const TestCaseFactory& testCaseFactory() const{ return *m_tcFactory; }
|
||
|
|
||
|
void parse();
|
||
|
|
||
|
protected:
|
||
|
void bindFactory() {
|
||
|
m_tcFactory = new TestCaseFactory();
|
||
|
}
|
||
|
|
||
|
//
|
||
|
// data members
|
||
|
//
|
||
|
vector<TestCase *> m_testCases;
|
||
|
TestCaseFactory *m_tcFactory;
|
||
|
};
|
||
|
|
||
|
|
||
|
//
|
||
|
// default factory to create sections
|
||
|
//
|
||
|
class SectionFactory {
|
||
|
public:
|
||
|
virtual Section* create(const string& name,
|
||
|
const vector<string>& lines, const ComplianceFile& file) const {
|
||
|
return new Section(name, lines, file);
|
||
|
}
|
||
|
|
||
|
virtual Section* create(const Section& section) const {
|
||
|
return create(section.name(), section.lines(), section.file());
|
||
|
}
|
||
|
};
|
||
|
|
||
|
|
||
|
//
|
||
|
// current factory to create sections
|
||
|
//
|
||
|
class OldFormatSectionFactory : public SectionFactory {
|
||
|
public:
|
||
|
virtual Section* create(const string& name,
|
||
|
const vector<string>& lines, const ComplianceFile& file) const {
|
||
|
if (name.find("[test#") != name.npos)
|
||
|
return new TestSection(name, lines, file);
|
||
|
else if (name.find("#values]") != name.npos)
|
||
|
return new ValueSection(name, lines, file);
|
||
|
else
|
||
|
return new Section(name, lines, file);
|
||
|
}
|
||
|
};
|
||
|
|
||
|
|
||
|
#endif // for __SECTION_H_
|