4 * Created on: Mar 14, 2014
8 #include <Config_XMLReader.h>
10 #include <Event_Loop.hxx>
11 #include <libxml\parser.h>
12 #include <libxml\tree.h>
15 //For GetModuleFileNameW
24 Config_XMLReader::Config_XMLReader(const std::string& theXmlFileName)
27 //Get path to *.xml files (typically ./bin/../plugins/)
29 HMODULE hModule = GetModuleHandleW(NULL);
30 WCHAR wchar_path[MAX_PATH];
31 GetModuleFileNameW(hModule, wchar_path, MAX_PATH);
32 char char_path[MAX_PATH];
34 WideCharToMultiByte(CP_ACP, 0, wchar_path, -1, char_path, MAX_PATH, &DefChar, NULL);
35 prefix = std::string(char_path);
37 unsigned found = prefix.rfind("bin");
38 if(found != std::string::npos)
39 prefix.replace(found, prefix.length(), "plugins\\");
41 //TODO(sbh): Find full path to binary on linux
42 prefix = "../plugins/";
45 m_DocumentPath = prefix + theXmlFileName;
49 Config_XMLReader::~Config_XMLReader()
54 * Read all nodes (recursively if processChildren() is true
55 * for a node). For each read node the processNode will be
58 void Config_XMLReader::readAll()
60 xmlNodePtr aRoot = findRoot();
61 readRecursively(aRoot);
65 * Allows to customize reader's behavior for a node. Virtual.
66 * The default implementation does nothing. (In debug mode prints
69 void Config_XMLReader::processNode(xmlNodePtr aNode)
72 std::cout << "Config_XMLReader::processNode: "
73 << aNode->name << " content: "
74 << aNode->content << std::endl;
79 * Defines which nodes should be processed recursively. Virtual.
80 * The default implementation to read all nodes.
82 bool Config_XMLReader::processChildren(xmlNodePtr aNode)
87 xmlNodePtr Config_XMLReader::findRoot()
90 aDoc = xmlParseFile(m_DocumentPath.c_str());
93 std::cout << "Config_XMLReader::import: " << "Document " << m_DocumentPath
94 << " is not parsed successfully." << std::endl;
98 xmlNodePtr aRoot = xmlDocGetRootElement(aDoc);
101 std::cout << "Config_XMLReader::import: " << "Error: empty document";
108 * Calls processNode() for each child (for some - recursively)
112 void Config_XMLReader::readRecursively(xmlNodePtr theParent)
114 static Event_ID aFeatureEvent = Event_Loop::EventByName("Feature");
118 xmlNodePtr aNode = theParent->xmlChildrenNode;
119 for(; aNode; aNode = aNode->next) {
121 if(processChildren(aNode)) {
122 readRecursively(aNode);
123 Config_FeatureMessage aMessage(aFeatureEvent, this);
129 * void* -> xmlNodePtr
131 xmlNodePtr Config_XMLReader::node(void* theNode)
133 return static_cast<xmlNodePtr>(theNode);
137 * Returns named property for a given node as std::string.
139 std::string Config_XMLReader::getProperty(xmlNodePtr theNode, const char* name)
141 std::string result = "";
142 char* aPropChars = (char*) xmlGetProp(theNode, BAD_CAST name);
143 if(!aPropChars || aPropChars[0] == 0)
145 result = std::string(aPropChars);
150 * Returns true if theNode is XML node with a given name.
152 bool Config_XMLReader::isNode(xmlNodePtr theNode, const char* theNodeName, ...)
155 const xmlChar* aName = theNode->name;
156 if(!aName || theNode->type != XML_ELEMENT_NODE)
159 if(!xmlStrcmp(aName, (const xmlChar *) theNodeName))
162 va_list args; // define argument list variable
163 va_start (args, theNodeName); // init list; point to last defined argument
165 char *anArg = va_arg (args, char *); // get next argument
168 if(!xmlStrcmp(aName, (const xmlChar *) anArg)) {
169 va_end (args); // cleanup the system stack
173 va_end (args); // cleanup the system stack