Initial community commit
This commit is contained in:
99
Src/Wasabi/bfc/parse/hierarchyparser.cpp
Normal file
99
Src/Wasabi/bfc/parse/hierarchyparser.cpp
Normal file
@ -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);
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user