root / host / lib / wax.cpp @ 76ebda89
History | View | Annotate | Download (4.53 KB)
| 1 |
//
|
|---|---|
| 2 |
// Copyright 2010 Ettus Research LLC
|
| 3 |
//
|
| 4 |
// This program is free software: you can redistribute it and/or modify
|
| 5 |
// it under the terms of the GNU General Public License as published by
|
| 6 |
// the Free Software Foundation, either version 3 of the License, or
|
| 7 |
// (at your option) any later version.
|
| 8 |
//
|
| 9 |
// This program is distributed in the hope that it will be useful,
|
| 10 |
// but WITHOUT ANY WARRANTY; without even the implied warranty of
|
| 11 |
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
| 12 |
// GNU General Public License for more details.
|
| 13 |
//
|
| 14 |
// You should have received a copy of the GNU General Public License
|
| 15 |
// along with this program. If not, see <http://www.gnu.org/licenses/>.
|
| 16 |
//
|
| 17 |
|
| 18 |
#include <uhd/wax.hpp> |
| 19 |
#include <boost/format.hpp> |
| 20 |
#include <stdexcept> |
| 21 |
|
| 22 |
/*!
|
| 23 |
* The link args for internal use within this cpp file:
|
| 24 |
*
|
| 25 |
* It contains a link (in this case a pointer) to a wax object.
|
| 26 |
* Only the methods in this file may create or parse link args.
|
| 27 |
* The get_link method is the creator of a link args object.
|
| 28 |
* The [] operator will resolve the link and make the [] call.
|
| 29 |
*
|
| 30 |
* TODO: register the link args with the wax obj that it links to.
|
| 31 |
* That way, if the obj destructs, the link can be invalidated.
|
| 32 |
* The operator() will throw, rather than dereferencing bad memory.
|
| 33 |
*/
|
| 34 |
class link_args_t{ |
| 35 |
public:
|
| 36 |
link_args_t(const wax::obj *obj_ptr) : _obj_ptr(obj_ptr){
|
| 37 |
/* NOP */
|
| 38 |
} |
| 39 |
wax::obj & operator()(void) const{ |
| 40 |
//recursively resolve link args to get at original pointer
|
| 41 |
if (_obj_ptr->type() == typeid(link_args_t)){ |
| 42 |
return _obj_ptr->as<link_args_t>()();
|
| 43 |
} |
| 44 |
return *const_cast<wax::obj *>(_obj_ptr); |
| 45 |
} |
| 46 |
private:
|
| 47 |
const wax::obj *_obj_ptr;
|
| 48 |
}; |
| 49 |
|
| 50 |
/*!
|
| 51 |
* The proxy args for internal use within this cpp file:
|
| 52 |
*
|
| 53 |
* It contains a link and a key for setting/getting a property.
|
| 54 |
* Only the methods in this file may create or parse proxy args.
|
| 55 |
* Class methods have special handling for the case when the
|
| 56 |
* wax obj contains an instance of the proxy args.
|
| 57 |
*/
|
| 58 |
class proxy_args_t{ |
| 59 |
public:
|
| 60 |
proxy_args_t(const wax::obj *obj_ptr, const wax::obj &key) : _key(key){ |
| 61 |
_obj_link = obj_ptr->get_link(); |
| 62 |
} |
| 63 |
wax::obj & operator()(void) const{ |
| 64 |
return _obj_link.as<link_args_t>()();
|
| 65 |
} |
| 66 |
const wax::obj & key(void) const{ |
| 67 |
return _key;
|
| 68 |
} |
| 69 |
private:
|
| 70 |
wax::obj _obj_link; |
| 71 |
const wax::obj _key;
|
| 72 |
}; |
| 73 |
|
| 74 |
/***********************************************************************
|
| 75 |
* Structors
|
| 76 |
**********************************************************************/
|
| 77 |
wax::obj::obj(void){
|
| 78 |
/* NOP */
|
| 79 |
} |
| 80 |
|
| 81 |
wax::obj::obj(const obj &o){
|
| 82 |
_contents = o._contents; |
| 83 |
} |
| 84 |
|
| 85 |
wax::obj::~obj(void){
|
| 86 |
/* NOP */
|
| 87 |
} |
| 88 |
|
| 89 |
/***********************************************************************
|
| 90 |
* Special Operators
|
| 91 |
**********************************************************************/
|
| 92 |
wax::obj wax::obj::operator[](const obj &key){ |
| 93 |
if (_contents.type() == typeid(proxy_args_t)){ |
| 94 |
obj val = resolve(); |
| 95 |
//check if its a special link and call
|
| 96 |
if (val.type() == typeid(link_args_t)){ |
| 97 |
return val.as<link_args_t>()()[key];
|
| 98 |
} |
| 99 |
//unknown obj
|
| 100 |
throw std::runtime_error("cannot use [] on non wax::obj link"); |
| 101 |
} |
| 102 |
else{
|
| 103 |
return proxy_args_t(this, key); |
| 104 |
} |
| 105 |
} |
| 106 |
|
| 107 |
wax::obj & wax::obj::operator=(const obj &val){ |
| 108 |
if (_contents.type() == typeid(proxy_args_t)){ |
| 109 |
proxy_args_t proxy_args = boost::any_cast<proxy_args_t>(_contents); |
| 110 |
proxy_args().set(proxy_args.key(), val); |
| 111 |
} |
| 112 |
else{
|
| 113 |
_contents = val._contents; |
| 114 |
} |
| 115 |
return *this; |
| 116 |
} |
| 117 |
|
| 118 |
/***********************************************************************
|
| 119 |
* Public Methods
|
| 120 |
**********************************************************************/
|
| 121 |
wax::obj wax::obj::get_link(void) const{ |
| 122 |
return link_args_t(this); |
| 123 |
} |
| 124 |
|
| 125 |
const std::type_info & wax::obj::type(void) const{ |
| 126 |
return resolve().type();
|
| 127 |
} |
| 128 |
|
| 129 |
/***********************************************************************
|
| 130 |
* Private Methods
|
| 131 |
**********************************************************************/
|
| 132 |
boost::any wax::obj::resolve(void) const{ |
| 133 |
if (_contents.type() == typeid(proxy_args_t)){ |
| 134 |
obj val; |
| 135 |
proxy_args_t proxy_args = boost::any_cast<proxy_args_t>(_contents); |
| 136 |
proxy_args().get(proxy_args.key(), val); |
| 137 |
return val.resolve();
|
| 138 |
} |
| 139 |
else{
|
| 140 |
return _contents;
|
| 141 |
} |
| 142 |
} |
| 143 |
|
| 144 |
void wax::obj::get(const obj &, obj &){ |
| 145 |
throw std::runtime_error("Cannot call get on wax obj base class"); |
| 146 |
} |
| 147 |
|
| 148 |
void wax::obj::set(const obj &, const obj &){ |
| 149 |
throw std::runtime_error("Cannot call set on wax obj base class"); |
| 150 |
} |