// // Copyright 2011 Ettus Research LLC // // This program is free software: you can redistribute it and/or modify // it under the terms of the GNU General Public License as published by // the Free Software Foundation, either version 3 of the License, or // (at your option) any later version. // // This program is distributed in the hope that it will be useful, // but WITHOUT ANY WARRANTY; without even the implied warranty of // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the // GNU General Public License for more details. // // You should have received a copy of the GNU General Public License // along with this program. If not, see . // #include #include #include #include #include #include class property_tree_impl : public uhd::property_tree{ public: property_tree_impl(const path_type &root = path_type()): _root(root) { _guts = boost::make_shared(); } sptr subtree(const path_type &path_) const{ const path_type path = _root / path_; boost::mutex::scoped_lock lock(_guts->mutex); property_tree_impl *subtree = new property_tree_impl(path); subtree->_guts = this->_guts; //copy the guts sptr return sptr(subtree); } void remove(const path_type &path_){ const path_type path = _root / path_; boost::mutex::scoped_lock lock(_guts->mutex); node_type *parent = NULL; node_type *node = &_guts->root; BOOST_FOREACH(const std::string &branch, path){ if (not node->has_key(branch)) throw_path_not_found(path); parent = node; node = &(*node)[branch]; } if (parent == NULL) throw uhd::runtime_error("Cannot uproot"); parent->pop(path.leaf()); } bool exists(const path_type &path_) const{ const path_type path = _root / path_; boost::mutex::scoped_lock lock(_guts->mutex); node_type *node = &_guts->root; BOOST_FOREACH(const std::string &branch, path){ if (not node->has_key(branch)) return false; node = &(*node)[branch]; } return true; } std::vector list(const path_type &path_) const{ const path_type path = _root / path_; boost::mutex::scoped_lock lock(_guts->mutex); node_type *node = &_guts->root; BOOST_FOREACH(const std::string &branch, path){ if (not node->has_key(branch)) throw_path_not_found(path); node = &(*node)[branch]; } return node->keys(); } void _create(const path_type &path_, const boost::shared_ptr &prop){ const path_type path = _root / path_; boost::mutex::scoped_lock lock(_guts->mutex); node_type *node = &_guts->root; BOOST_FOREACH(const std::string &branch, path){ if (not node->has_key(branch)) (*node)[branch] = node_type(); node = &(*node)[branch]; } if (node->prop.get() != NULL) throw uhd::runtime_error("Cannot create! Property already exists at: " + path.string()); node->prop = prop; } boost::shared_ptr &_access(const path_type &path_) const{ const path_type path = _root / path_; boost::mutex::scoped_lock lock(_guts->mutex); node_type *node = &_guts->root; BOOST_FOREACH(const std::string &branch, path){ if (not node->has_key(branch)) throw_path_not_found(path); node = &(*node)[branch]; } if (node->prop.get() == NULL) throw uhd::runtime_error("Cannot access! Property uninitialized at: " + path.string()); return node->prop; } private: void throw_path_not_found(const path_type &path) const{ throw uhd::lookup_error("Path not found in tree: " + path.string()); } //basic structural node element struct node_type : uhd::dict{ boost::shared_ptr prop; }; //tree guts which may be referenced in a subtree struct tree_guts_type{ node_type root; boost::mutex mutex; }; //members, the tree and root prefix boost::shared_ptr _guts; const path_type _root; }; uhd::property_tree::sptr uhd::property_tree::make(void){ return sptr(new property_tree_impl()); }