aboutsummaryrefslogtreecommitdiff
path: root/Src/Wasabi/bfc/parse/hierarchyparser.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'Src/Wasabi/bfc/parse/hierarchyparser.cpp')
-rw-r--r--Src/Wasabi/bfc/parse/hierarchyparser.cpp99
1 files changed, 99 insertions, 0 deletions
diff --git a/Src/Wasabi/bfc/parse/hierarchyparser.cpp b/Src/Wasabi/bfc/parse/hierarchyparser.cpp
new file mode 100644
index 00000000..8d07ed82
--- /dev/null
+++ b/Src/Wasabi/bfc/parse/hierarchyparser.cpp
@@ -0,0 +1,99 @@
+#include "precomp_wasabi_bfc.h"
+#include "hierarchyparser.h"
+#include <bfc/nsguid.h>
+#include <wchar.h>
+// This uses an AMAZINGLY inefficient algorithm! woo hoo!
+
+HierarchyParser::HierarchyParser(const wchar_t *str, const wchar_t *_sibling, const wchar_t *_escape, const wchar_t *_parent_open, const wchar_t *_parent_close) {
+ // Create a new rootnode.
+ rootnode = new HPNode(str);
+ // Parse the rootnode's contents into the rootnode's children.
+ HierarchyParser downparse(rootnode, _sibling, _escape, _parent_open, _parent_close);
+ // Set the actual name of the rootnode ("")
+ (*rootnode)() = L"";
+ // Mark that this was our allocation
+ myalloc = 1;
+}
+
+HierarchyParser::~HierarchyParser() {
+ // If we alloc, we must delete.
+ if (myalloc) {
+ delete rootnode;
+ }
+}
+
+HPNode *HierarchyParser::findGuid(GUID g) {
+ return NULL;
+}
+
+HPNode *HierarchyParser::findString(const wchar_t *str) {
+ return NULL;
+}
+
+HierarchyParser::HierarchyParser(HPNode *_rootnode, const wchar_t *_sibling, const wchar_t *_escape, const wchar_t *_parent_open, const wchar_t *_parent_close) {
+ // We did not alloc, we should not delete.
+ rootnode = _rootnode;
+ sibling = _sibling;
+ escape = _escape;
+ parent_open = _parent_open;
+ parent_close = _parent_close;
+
+ myalloc = 0;
+
+ const wchar_t *parsestr = (*rootnode)();
+
+ size_t i, length = wcslen(parsestr), depth = 0;
+
+ StringW curr_sibling;
+
+ for (i = 0; i < length; i++ ) {
+ wchar_t c = parsestr[i];
+
+ if (isEscape(c)) {
+ // always add the next character
+ curr_sibling += parsestr[++i];
+ } else if (isSibling(c)) {
+ // if we're not inside someone else,
+ if (!depth) {
+ // okay, we're done with the current sibling. ship him off.
+ processSibling(curr_sibling);
+ // on to the next sibling!
+ curr_sibling = L"";
+ } else {
+ curr_sibling += c;
+ }
+ } else if (isParentOpen(c)) {
+ // increment depth
+ curr_sibling += c;
+ depth++;
+ } else if (isParentClose(c)) {
+ // decrement depth
+ curr_sibling += c;
+ depth--;
+ } else {
+ curr_sibling += c;
+ }
+ }
+
+ // If there is anything left over, process it as a sibling.
+ if (curr_sibling.len()) {
+ processSibling(curr_sibling);
+ }
+}
+
+void HierarchyParser::processSibling(const wchar_t *sibstr) {
+ StringW curr_sibling = sibstr;
+ // slice the name out of the front of the string.
+ StringW sibling_name = curr_sibling.lSpliceChar(parent_open);
+ // curr_sibling will contain the children of this sibling (or nothing).
+ curr_sibling.rSpliceChar(parent_close);
+ // create a new child for our root node to contain the sibling's child info
+ HPNode *child = new HPNode(curr_sibling, rootnode);
+ // parse the child hierarchically for its children
+ HierarchyParser childparser(child, sibling, escape, parent_open, parent_close);
+ // once parsed. set its name to be this sibling
+ (*child)() = sibling_name;
+ // and lastly add him as a child to the root node.
+ rootnode->addChild(child);
+}
+