diff --git a/src/DOM.cpp b/src/DOM.cpp index 06f770e53..078e00ff1 100644 --- a/src/DOM.cpp +++ b/src/DOM.cpp @@ -476,9 +476,18 @@ bool getDOM (const std::string& name, const Task& task, Variant& value) // // This makes the DOM class a reusible object. +//////////////////////////////////////////////////////////////////////////////// +void DOM::addSource ( + const std::string&, + bool (*provider)(const std::string&, Variant&)) +{ + // TODO Implement. +} + //////////////////////////////////////////////////////////////////////////////// bool DOM::valid (const std::string& reference) const { + // TODO Implement. return false; } @@ -504,3 +513,87 @@ std::vector DOM::decomposeReference (const std::string& reference) } //////////////////////////////////////////////////////////////////////////////// +int DOM::count () const +{ + // This branch. + int total = 1; + + // Recurse and count the branches. + for (auto& i : _branches) + total += i->count (); + + return total; +} + +//////////////////////////////////////////////////////////////////////////////// +std::shared_ptr DOM::find (const std::string& path) +{ + std::vector elements = split (path, '.'); + + // Must start at the trunk. + auto cursor = std::make_shared (*this); + auto it = elements.begin (); + if (cursor->_name != *it) + return nullptr; + + // Perhaps the trunk is what is needed? + if (elements.size () == 1) + return cursor; + + // Now look for the next branch. + for (++it; it != elements.end (); ++it) + { + bool found = false; + + // If the cursor has a branch that matches *it, proceed. + for (auto i = cursor->_branches.begin (); i != cursor->_branches.end (); ++i) + { + if ((*i)->_name == *it) + { + cursor = *i; + found = true; + break; + } + } + + if (! found) + return nullptr; + } + + return cursor; +} + +//////////////////////////////////////////////////////////////////////////////// +std::string DOM::dumpNode ( + const std::shared_ptr t, + int depth) const +{ + std::stringstream out; + + // Dump node + for (int i = 0; i < depth; ++i) + out << " "; + + out + // Useful for debugging tree node new/delete errors. + // << std::hex << t << " " + << "\033[1m" << t->_name << "\033[0m\n"; + + // Recurse for branches. + for (auto& b : t->_branches) + out << dumpNode (b, depth + 1); + + return out.str (); +} + +//////////////////////////////////////////////////////////////////////////////// +std::string DOM::dump () const +{ + std::stringstream out; + out << "DOM (" << count () << " nodes)\n" + << dumpNode (std::make_shared (*this), 1); + + return out.str (); +} + +//////////////////////////////////////////////////////////////////////////////// diff --git a/src/DOM.h b/src/DOM.h index 2f6d0704e..64a9cb403 100644 --- a/src/DOM.h +++ b/src/DOM.h @@ -28,17 +28,13 @@ #define INCLUDED_DOM #include -#include #include #include -// 2017-04-22 Deprecated. +// 2017-04-22 Deprecated, use DOM::get. bool getDOM (const std::string&, Variant&); bool getDOM (const std::string&, const Task&, Variant&); -// DOM Tree -class DOM; - class DOM { public: @@ -46,9 +42,18 @@ public: bool valid (const std::string&) const; Variant get (const Task&, const std::string&) const; Variant get (const std::string&) const; + int count () const; + std::shared_ptr find (const std::string&); + std::string dump () const; private: std::vector decomposeReference (const std::string&) const; + std::string dumpNode (const std::shared_ptr , int) const; + +private: + std::string _name {"Unknown"}; + std::shared_ptr _provider {nullptr}; + std::vector > _branches {}; }; #endif