hierarchyparser.cpp 2.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899
  1. #include "precomp_wasabi_bfc.h"
  2. #include "hierarchyparser.h"
  3. #include <bfc/nsguid.h>
  4. #include <wchar.h>
  5. // This uses an AMAZINGLY inefficient algorithm! woo hoo!
  6. HierarchyParser::HierarchyParser(const wchar_t *str, const wchar_t *_sibling, const wchar_t *_escape, const wchar_t *_parent_open, const wchar_t *_parent_close) {
  7. // Create a new rootnode.
  8. rootnode = new HPNode(str);
  9. // Parse the rootnode's contents into the rootnode's children.
  10. HierarchyParser downparse(rootnode, _sibling, _escape, _parent_open, _parent_close);
  11. // Set the actual name of the rootnode ("")
  12. (*rootnode)() = L"";
  13. // Mark that this was our allocation
  14. myalloc = 1;
  15. }
  16. HierarchyParser::~HierarchyParser() {
  17. // If we alloc, we must delete.
  18. if (myalloc) {
  19. delete rootnode;
  20. }
  21. }
  22. HPNode *HierarchyParser::findGuid(GUID g) {
  23. return NULL;
  24. }
  25. HPNode *HierarchyParser::findString(const wchar_t *str) {
  26. return NULL;
  27. }
  28. HierarchyParser::HierarchyParser(HPNode *_rootnode, const wchar_t *_sibling, const wchar_t *_escape, const wchar_t *_parent_open, const wchar_t *_parent_close) {
  29. // We did not alloc, we should not delete.
  30. rootnode = _rootnode;
  31. sibling = _sibling;
  32. escape = _escape;
  33. parent_open = _parent_open;
  34. parent_close = _parent_close;
  35. myalloc = 0;
  36. const wchar_t *parsestr = (*rootnode)();
  37. size_t i, length = wcslen(parsestr), depth = 0;
  38. StringW curr_sibling;
  39. for (i = 0; i < length; i++ ) {
  40. wchar_t c = parsestr[i];
  41. if (isEscape(c)) {
  42. // always add the next character
  43. curr_sibling += parsestr[++i];
  44. } else if (isSibling(c)) {
  45. // if we're not inside someone else,
  46. if (!depth) {
  47. // okay, we're done with the current sibling. ship him off.
  48. processSibling(curr_sibling);
  49. // on to the next sibling!
  50. curr_sibling = L"";
  51. } else {
  52. curr_sibling += c;
  53. }
  54. } else if (isParentOpen(c)) {
  55. // increment depth
  56. curr_sibling += c;
  57. depth++;
  58. } else if (isParentClose(c)) {
  59. // decrement depth
  60. curr_sibling += c;
  61. depth--;
  62. } else {
  63. curr_sibling += c;
  64. }
  65. }
  66. // If there is anything left over, process it as a sibling.
  67. if (curr_sibling.len()) {
  68. processSibling(curr_sibling);
  69. }
  70. }
  71. void HierarchyParser::processSibling(const wchar_t *sibstr) {
  72. StringW curr_sibling = sibstr;
  73. // slice the name out of the front of the string.
  74. StringW sibling_name = curr_sibling.lSpliceChar(parent_open);
  75. // curr_sibling will contain the children of this sibling (or nothing).
  76. curr_sibling.rSpliceChar(parent_close);
  77. // create a new child for our root node to contain the sibling's child info
  78. HPNode *child = new HPNode(curr_sibling, rootnode);
  79. // parse the child hierarchically for its children
  80. HierarchyParser childparser(child, sibling, escape, parent_open, parent_close);
  81. // once parsed. set its name to be this sibling
  82. (*child)() = sibling_name;
  83. // and lastly add him as a child to the root node.
  84. rootnode->addChild(child);
  85. }