diff options
| -rw-r--r-- | host/include/uhd/property_tree.hpp | 16 | ||||
| -rw-r--r-- | host/include/uhd/property_tree.ipp | 142 | ||||
| -rw-r--r-- | host/lib/property_tree.cpp | 140 | ||||
| -rw-r--r-- | host/tests/property_test.cpp | 1 | 
4 files changed, 184 insertions, 115 deletions
| diff --git a/host/include/uhd/property_tree.hpp b/host/include/uhd/property_tree.hpp index 18091511e..42e73458f 100644 --- a/host/include/uhd/property_tree.hpp +++ b/host/include/uhd/property_tree.hpp @@ -1,6 +1,7 @@  //  // Copyright 2011,2014-2016 Ettus Research  // Copyright 2018 Ettus Research, a National Instruments Company +// Copyright 2019 Ettus Research, a National Instruments Brand  //  // SPDX-License-Identifier: GPL-3.0-or-later  // @@ -34,8 +35,8 @@ namespace uhd {   *    in a desired value and produces a coerced value.   *    A property must have *exactly one* coercer.   * 2. Manual coercion: Manually calling the set_coerced - *    API fnction to coerce the value of the propery. In - *    order to use manual coercion, the propery must be + *    API function to coerce the value of the property. In + *    order to use manual coercion, the property must be   *    created with the MANUAL_COERCE mode.   * If the coerce mode for a property is AUTO_COERCE then   * it always has a coercer. If the set_coercer API is @@ -53,7 +54,7 @@ namespace uhd {   * callback to get the value of the property. Calling   * get on the property will always call the publisher and   * the cached desired and coerced values are updated only - * using set* calls. A preprty must have *at most one* + * using set* calls. A property must have *at most one*   * publisher. It is legal to have both a coercer   * and publisher for a property but the only way to access   * the desired and coerced values in that case would be by @@ -64,7 +65,8 @@ namespace uhd {   * - T must have a copy constructor   * - T must have an assignment operator   */ -template <typename T> class property : uhd::noncopyable +template <typename T> +class property : uhd::noncopyable  {  public:      typedef boost::function<void(const T&)> subscriber_type; @@ -181,7 +183,8 @@ public:      virtual bool empty(void) const = 0;  }; -template <typename T> property<T>::~property(void) +template <typename T> +property<T>::~property(void)  {      /* NOP */  } @@ -237,7 +240,8 @@ public:      property<T>& create(const fs_path& path, coerce_mode_t coerce_mode = AUTO_COERCE);      //! Get access to a property in the tree -    template <typename T> property<T>& access(const fs_path& path); +    template <typename T> +    property<T>& access(const fs_path& path);  private:      //! Internal create property with wild-card type diff --git a/host/include/uhd/property_tree.ipp b/host/include/uhd/property_tree.ipp index c3203a63b..de1ac28c0 100644 --- a/host/include/uhd/property_tree.ipp +++ b/host/include/uhd/property_tree.ipp @@ -1,6 +1,7 @@  //  // Copyright 2011,2014-2016 Ettus Research  // Copyright 2018 Ettus Research, a National Instruments Company +// Copyright 2019 Ettus Research, a National Instruments Brand  //  // SPDX-License-Identifier: GPL-3.0-or-later  // @@ -16,105 +17,137 @@  /***********************************************************************   * Implement templated property impl   **********************************************************************/ -namespace uhd{ namespace /*anon*/{ +namespace uhd { namespace /*anon*/ { -template <typename T> class property_impl : public property<T>{ +template <typename T> +class property_impl : public property<T> +{  public: -    property_impl<T>(property_tree::coerce_mode_t mode) : _coerce_mode(mode){ +    property_impl<T>(property_tree::coerce_mode_t mode) : _coerce_mode(mode) +    {          if (_coerce_mode == property_tree::AUTO_COERCE) {              _coercer = DEFAULT_COERCER;          }      } -    ~property_impl<T>(void){ +    ~property_impl<T>(void) +    {          /* NOP */      } -    property<T> &set_coercer(const typename property<T>::coercer_type &coercer){ -        if (not _coercer.empty()) uhd::assertion_error("cannot register more than one coercer for a property"); -        if (_coerce_mode == property_tree::MANUAL_COERCE) uhd::assertion_error("cannot register coercer for a manually coerced property"); +    property<T>& set_coercer(const typename property<T>::coercer_type& coercer) +    { +        if (not _coercer.empty()) +            uhd::assertion_error("cannot register more than one coercer for a property"); +        if (_coerce_mode == property_tree::MANUAL_COERCE) +            uhd::assertion_error( +                "cannot register coercer for a manually coerced property");          _coercer = coercer;          return *this;      } -    property<T> &set_publisher(const typename property<T>::publisher_type &publisher){ -        if (not _publisher.empty()) uhd::assertion_error("cannot register more than one publisher for a property"); +    property<T>& set_publisher(const typename property<T>::publisher_type& publisher) +    { +        if (not _publisher.empty()) +            uhd::assertion_error( +                "cannot register more than one publisher for a property");          _publisher = publisher;          return *this;      } -    property<T> &add_desired_subscriber(const typename property<T>::subscriber_type &subscriber){ +    property<T>& add_desired_subscriber( +        const typename property<T>::subscriber_type& subscriber) +    {          _desired_subscribers.push_back(subscriber);          return *this;      } -    property<T> &add_coerced_subscriber(const typename property<T>::subscriber_type &subscriber){ +    property<T>& add_coerced_subscriber( +        const typename property<T>::subscriber_type& subscriber) +    {          _coerced_subscribers.push_back(subscriber);          return *this;      } -    property<T> &update(void){ +    property<T>& update(void) +    {          this->set(this->get());          return *this;      } -    void _set_coerced(const T &value){ +    void _set_coerced(const T& value) +    {          init_or_set_value(_coerced_value, value); -        BOOST_FOREACH(typename property<T>::subscriber_type &csub, _coerced_subscribers){ -            csub(get_value_ref(_coerced_value)); //let errors propagate +        BOOST_FOREACH ( +            typename property<T>::subscriber_type& csub, _coerced_subscribers) { +            csub(get_value_ref(_coerced_value)); // let errors propagate          }      } -    property<T> &set(const T &value){ +    property<T>& set(const T& value) +    {          init_or_set_value(_value, value); -        BOOST_FOREACH(typename property<T>::subscriber_type &dsub, _desired_subscribers){ -            dsub(get_value_ref(_value)); //let errors propagate +        BOOST_FOREACH ( +            typename property<T>::subscriber_type& dsub, _desired_subscribers) { +            dsub(get_value_ref(_value)); // let errors propagate          }          if (not _coercer.empty()) {              _set_coerced(_coercer(get_value_ref(_value)));          } else { -            if (_coerce_mode == property_tree::AUTO_COERCE) uhd::assertion_error("coercer missing for an auto coerced property"); +            if (_coerce_mode == property_tree::AUTO_COERCE) +                uhd::assertion_error("coercer missing for an auto coerced property");          }          return *this;      } -    property<T> &set_coerced(const T &value){ -        if (_coerce_mode == property_tree::AUTO_COERCE) uhd::assertion_error("cannot set coerced value an auto coerced property"); +    property<T>& set_coerced(const T& value) +    { +        if (_coerce_mode == property_tree::AUTO_COERCE) +            uhd::assertion_error("cannot set coerced value an auto coerced property");          _set_coerced(value);          return *this;      } -    const T get(void) const{ +    const T get(void) const +    {          if (empty()) {              throw uhd::runtime_error("Cannot get() on an uninitialized (empty) property");          }          if (not _publisher.empty()) {              return _publisher();          } else { -            if (_coerced_value.get() == NULL and _coerce_mode == property_tree::MANUAL_COERCE) -                throw uhd::runtime_error("uninitialized coerced value for manually coerced attribute"); +            if (_coerced_value.get() == NULL +                and _coerce_mode == property_tree::MANUAL_COERCE) +                throw uhd::runtime_error( +                    "uninitialized coerced value for manually coerced attribute");              return get_value_ref(_coerced_value);          }      } -    const T get_desired(void) const{ -        if (_value.get() == NULL) throw uhd::runtime_error("Cannot get_desired() on an uninitialized (empty) property"); +    const T get_desired(void) const +    { +        if (_value.get() == NULL) +            throw uhd::runtime_error( +                "Cannot get_desired() on an uninitialized (empty) property");          return get_value_ref(_value);      } -    bool empty(void) const{ +    bool empty(void) const +    {          return _publisher.empty() and _value.get() == NULL;      }  private: -    static T DEFAULT_COERCER(const T& value) { +    static T DEFAULT_COERCER(const T& value) +    {          return value;      } -    static void init_or_set_value(boost::scoped_ptr<T>& scoped_value, const T& init_val) { +    static void init_or_set_value(boost::scoped_ptr<T>& scoped_value, const T& init_val) +    {          if (scoped_value.get() == NULL) {              scoped_value.reset(new T(init_val));          } else { @@ -122,36 +155,43 @@ private:          }      } -    static const T& get_value_ref(const boost::scoped_ptr<T>& scoped_value) { -        if (scoped_value.get() == NULL) throw uhd::assertion_error("Cannot use uninitialized property data"); +    static const T& get_value_ref(const boost::scoped_ptr<T>& scoped_value) +    { +        if (scoped_value.get() == NULL) +            throw uhd::assertion_error("Cannot use uninitialized property data");          return *scoped_value.get();      } -    const property_tree::coerce_mode_t                  _coerce_mode; -    std::vector<typename property<T>::subscriber_type>  _desired_subscribers; -    std::vector<typename property<T>::subscriber_type>  _coerced_subscribers; -    typename property<T>::publisher_type                _publisher; -    typename property<T>::coercer_type                  _coercer; -    boost::scoped_ptr<T>                                _value; -    boost::scoped_ptr<T>                                _coerced_value; +    const property_tree::coerce_mode_t _coerce_mode; +    std::vector<typename property<T>::subscriber_type> _desired_subscribers; +    std::vector<typename property<T>::subscriber_type> _coerced_subscribers; +    typename property<T>::publisher_type _publisher; +    typename property<T>::coercer_type _coercer; +    boost::scoped_ptr<T> _value; +    boost::scoped_ptr<T> _coerced_value;  }; -}} //namespace uhd::/*anon*/ +}} // namespace uhd::  /***********************************************************************   * Implement templated methods for the property tree   **********************************************************************/ -namespace uhd{ - -    template <typename T> property<T> &property_tree::create(const fs_path &path, coerce_mode_t coerce_mode){ -        this->_create(path, typename boost::shared_ptr<property<T> >(new property_impl<T>(coerce_mode))); -        return this->access<T>(path); -    } - -    template <typename T> property<T> &property_tree::access(const fs_path &path){ -        return *boost::static_pointer_cast<property<T> >(this->_access(path)); -    } - -} //namespace uhd +namespace uhd { + +template <typename T> +property<T>& property_tree::create(const fs_path& path, coerce_mode_t coerce_mode) +{ +    this->_create(path, +        typename boost::shared_ptr<property<T> >(new property_impl<T>(coerce_mode))); +    return this->access<T>(path); +} + +template <typename T> +property<T>& property_tree::access(const fs_path& path) +{ +    return *boost::static_pointer_cast<property<T> >(this->_access(path)); +} + +} // namespace uhd  #endif /* INCLUDED_UHD_PROPERTY_TREE_IPP */ diff --git a/host/lib/property_tree.cpp b/host/lib/property_tree.cpp index 4d5c53949..07da0cf59 100644 --- a/host/lib/property_tree.cpp +++ b/host/lib/property_tree.cpp @@ -1,14 +1,15 @@  //  // Copyright 2011,2014-2016 Ettus Research  // Copyright 2018 Ettus Research, a National Instruments Company +// Copyright 2019 Ettus Research, a National Instruments Brand  //  // SPDX-License-Identifier: GPL-3.0-or-later  //  #include <uhd/property_tree.hpp>  #include <uhd/types/dict.hpp> -#include <boost/thread/mutex.hpp>  #include <boost/make_shared.hpp> +#include <boost/thread/mutex.hpp>  #include <iostream>  using namespace uhd; @@ -18,43 +19,47 @@ using namespace uhd;   **********************************************************************/  #include <boost/tokenizer.hpp>  #define path_tokenizer(path) \ -    boost::tokenizer<boost::char_separator<char> > \ -    (path, boost::char_separator<char>("/")) +    boost::tokenizer<boost::char_separator<char>>(path, boost::char_separator<char>("/"))  /***********************************************************************   * Property path implementation wrapper   **********************************************************************/ -fs_path::fs_path(void): std::string(){} -fs_path::fs_path(const char *p): std::string(p){} -fs_path::fs_path(const std::string &p): std::string(p){} +fs_path::fs_path(void) : std::string() {} +fs_path::fs_path(const char* p) : std::string(p) {} +fs_path::fs_path(const std::string& p) : std::string(p) {} -std::string fs_path::leaf(void) const{ +std::string fs_path::leaf(void) const +{      const size_t pos = this->rfind("/"); -    if (pos == std::string::npos) return *this; -    return this->substr(pos+1); +    if (pos == std::string::npos) +        return *this; +    return this->substr(pos + 1);  } -fs_path fs_path::branch_path(void) const{ +fs_path fs_path::branch_path(void) const +{      const size_t pos = this->rfind("/"); -    if (pos == std::string::npos) return *this; +    if (pos == std::string::npos) +        return *this;      return fs_path(this->substr(0, pos));  } -fs_path uhd::operator/(const fs_path &lhs, const fs_path &rhs){ -    //strip trailing slash on left-hand-side -    if (not lhs.empty() and *lhs.rbegin() == '/'){ -        return fs_path(lhs.substr(0, lhs.size()-1)) / rhs; +fs_path uhd::operator/(const fs_path& lhs, const fs_path& rhs) +{ +    // strip trailing slash on left-hand-side +    if (not lhs.empty() and *lhs.rbegin() == '/') { +        return fs_path(lhs.substr(0, lhs.size() - 1)) / rhs;      } -    //strip leading slash on right-hand-side -    if (not rhs.empty() and *rhs.begin() == '/'){ +    // strip leading slash on right-hand-side +    if (not rhs.empty() and *rhs.begin() == '/') {          return lhs / fs_path(rhs.substr(1));      }      return fs_path(lhs + "/" + rhs);  } -fs_path uhd::operator/(const fs_path &lhs, size_t rhs) +fs_path uhd::operator/(const fs_path& lhs, size_t rhs)  {      fs_path rhs_str = std::to_string(rhs);      return lhs / rhs_str; @@ -63,118 +68,137 @@ fs_path uhd::operator/(const fs_path &lhs, size_t rhs)  /***********************************************************************   * Property tree implementation   **********************************************************************/ -class property_tree_impl : public uhd::property_tree{ +class property_tree_impl : public uhd::property_tree +{  public: - -    property_tree_impl(const fs_path &root = fs_path()): -        _root(root) +    property_tree_impl(const fs_path& root = fs_path()) : _root(root)      {          _guts = boost::make_shared<tree_guts_type>();      } -    sptr subtree(const fs_path &path_) const{ +    sptr subtree(const fs_path& path_) const +    {          const fs_path 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 +        property_tree_impl* subtree = new property_tree_impl(path); +        subtree->_guts              = this->_guts; // copy the guts sptr          return sptr(subtree);      } -    void remove(const fs_path &path_){ +    void remove(const fs_path& path_) +    {          const fs_path path = _root / path_;          boost::mutex::scoped_lock lock(_guts->mutex); -        node_type *parent = NULL; -        node_type *node = &_guts->root; -        for(const std::string &name:  path_tokenizer(path)){ -            if (not node->has_key(name)) throw_path_not_found(path); +        node_type* parent = NULL; +        node_type* node   = &_guts->root; +        for (const std::string& name : path_tokenizer(path)) { +            if (not node->has_key(name)) +                throw_path_not_found(path);              parent = node; -            node = &(*node)[name]; +            node   = &(*node)[name];          } -        if (parent == NULL) throw uhd::runtime_error("Cannot uproot"); +        if (parent == NULL) +            throw uhd::runtime_error("Cannot uproot");          parent->pop(fs_path(path.leaf()));      } -    bool exists(const fs_path &path_) const{ +    bool exists(const fs_path& path_) const +    {          const fs_path path = _root / path_;          boost::mutex::scoped_lock lock(_guts->mutex); -        node_type *node = &_guts->root; -        for(const std::string &name:  path_tokenizer(path)){ -            if (not node->has_key(name)) return false; +        node_type* node = &_guts->root; +        for (const std::string& name : path_tokenizer(path)) { +            if (not node->has_key(name)) +                return false;              node = &(*node)[name];          }          return true;      } -    std::vector<std::string> list(const fs_path &path_) const{ +    std::vector<std::string> list(const fs_path& path_) const +    {          const fs_path path = _root / path_;          boost::mutex::scoped_lock lock(_guts->mutex); -        node_type *node = &_guts->root; -        for(const std::string &name:  path_tokenizer(path)){ -            if (not node->has_key(name)) throw_path_not_found(path); +        node_type* node = &_guts->root; +        for (const std::string& name : path_tokenizer(path)) { +            if (not node->has_key(name)) +                throw_path_not_found(path);              node = &(*node)[name];          }          return node->keys();      } -    void _create(const fs_path &path_, const boost::shared_ptr<void> &prop){ +    void _create(const fs_path& path_, const boost::shared_ptr<void>& prop) +    {          const fs_path path = _root / path_;          boost::mutex::scoped_lock lock(_guts->mutex); -        node_type *node = &_guts->root; -        for(const std::string &name:  path_tokenizer(path)){ -            if (not node->has_key(name)) (*node)[name] = node_type(); +        node_type* node = &_guts->root; +        for (const std::string& name : path_tokenizer(path)) { +            if (not node->has_key(name)) +                (*node)[name] = node_type();              node = &(*node)[name];          } -        if (node->prop.get() != NULL) throw uhd::runtime_error("Cannot create! Property already exists at: " + path); +        if (node->prop.get() != NULL) +            throw uhd::runtime_error( +                "Cannot create! Property already exists at: " + path);          node->prop = prop;      } -    boost::shared_ptr<void> &_access(const fs_path &path_) const{ +    boost::shared_ptr<void>& _access(const fs_path& path_) const +    {          const fs_path path = _root / path_;          boost::mutex::scoped_lock lock(_guts->mutex); -        node_type *node = &_guts->root; -        for(const std::string &name:  path_tokenizer(path)){ -            if (not node->has_key(name)) throw_path_not_found(path); +        node_type* node = &_guts->root; +        for (const std::string& name : path_tokenizer(path)) { +            if (not node->has_key(name)) +                throw_path_not_found(path);              node = &(*node)[name];          } -        if (node->prop.get() == NULL) throw uhd::runtime_error("Cannot access! Property uninitialized at: " + path); +        if (node->prop.get() == NULL) +            throw uhd::runtime_error("Cannot access! Property uninitialized at: " + path);          return node->prop;      }  private: -    void throw_path_not_found(const fs_path &path) const{ +    void throw_path_not_found(const fs_path& path) const +    {          throw uhd::lookup_error("Path not found in tree: " + path);      } -    //basic structural node element -    struct node_type : uhd::dict<std::string, node_type>{ +    // basic structural node element +    struct node_type : uhd::dict<std::string, node_type> +    {          boost::shared_ptr<void> prop;      }; -    //tree guts which may be referenced in a subtree -    struct tree_guts_type{ +    // 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 +    // members, the tree and root prefix      boost::shared_ptr<tree_guts_type> _guts;      const fs_path _root;  }; -property_tree::~property_tree(void){ +property_tree::~property_tree(void) +{      /* NOP */  }  /***********************************************************************   * Property tree factory   **********************************************************************/ -uhd::property_tree::sptr uhd::property_tree::make(void){ +uhd::property_tree::sptr uhd::property_tree::make(void) +{      return sptr(new property_tree_impl());  } diff --git a/host/tests/property_test.cpp b/host/tests/property_test.cpp index b2086f288..f0e67e14c 100644 --- a/host/tests/property_test.cpp +++ b/host/tests/property_test.cpp @@ -1,6 +1,7 @@  //  // Copyright 2011 Ettus Research LLC  // Copyright 2018 Ettus Research, a National Instruments Company +// Copyright 2019 Ettus Research, a National Instruments Brand  //  // SPDX-License-Identifier: GPL-3.0-or-later  // | 
