Statistics
| Branch: | Tag: | Revision:

root / host / lib / wax.cpp @ 8ebe1265

History | View | Annotate | Download (4.53 KB)

1 751c2a85 Josh Blum
//
2
// Copyright 2010 Ettus Research LLC
3
//
4 aa2c904d Josh Blum
// 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 751c2a85 Josh Blum
18 c5480830 Josh Blum
#include <uhd/wax.hpp>
19 751c2a85 Josh Blum
#include <boost/format.hpp>
20 dfd7f99e Josh Blum
#include <stdexcept>
21 751c2a85 Josh Blum
22 89152d1f Josh Blum
/*!
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 dfd7f99e Josh Blum
 *
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 89152d1f Josh Blum
 */
34 dfd7f99e Josh Blum
class link_args_t{
35
public:
36
    link_args_t(const wax::obj *obj_ptr) : _obj_ptr(obj_ptr){
37
        /* NOP */
38
    }
39 daed43a8 Josh Blum
    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 fc40ff2f Josh Blum
            return _obj_ptr->as<link_args_t>()();
43 daed43a8 Josh Blum
        }
44 dfd7f99e Josh Blum
        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 daed43a8 Josh Blum
    wax::obj & operator()(void) const{
64 fc40ff2f Josh Blum
        return _obj_link.as<link_args_t>()();
65 dfd7f99e Josh Blum
    }
66 daed43a8 Josh Blum
    const wax::obj & key(void) const{
67 dfd7f99e Josh Blum
        return _key;
68
    }
69
private:
70
    wax::obj _obj_link;
71
    const wax::obj _key;
72 89152d1f Josh Blum
};
73
74 751c2a85 Josh Blum
/***********************************************************************
75 bff70172 Josh Blum
 * Structors
76 751c2a85 Josh Blum
 **********************************************************************/
77
wax::obj::obj(void){
78
    /* NOP */
79
}
80
81 cc8caeb1 Josh Blum
wax::obj::obj(const obj &o){
82
    _contents = o._contents;
83
}
84
85 751c2a85 Josh Blum
wax::obj::~obj(void){
86
    /* NOP */
87
}
88
89 bff70172 Josh Blum
/***********************************************************************
90
 * Special Operators
91
 **********************************************************************/
92 cc8caeb1 Josh Blum
wax::obj wax::obj::operator[](const obj &key){
93
    if (_contents.type() == typeid(proxy_args_t)){
94
        obj val = resolve();
95 89152d1f Josh Blum
        //check if its a special link and call
96
        if (val.type() == typeid(link_args_t)){
97 fc40ff2f Josh Blum
            return val.as<link_args_t>()()[key];
98 cc8caeb1 Josh Blum
        }
99
        //unknown obj
100 89152d1f Josh Blum
        throw std::runtime_error("cannot use [] on non wax::obj link");
101 cc8caeb1 Josh Blum
    }
102
    else{
103 dfd7f99e Josh Blum
        return proxy_args_t(this, key);
104 cc8caeb1 Josh Blum
    }
105 751c2a85 Josh Blum
}
106
107 cc8caeb1 Josh Blum
wax::obj & wax::obj::operator=(const obj &val){
108
    if (_contents.type() == typeid(proxy_args_t)){
109 dfd7f99e Josh Blum
        proxy_args_t proxy_args = boost::any_cast<proxy_args_t>(_contents);
110
        proxy_args().set(proxy_args.key(), val);
111 cc8caeb1 Josh Blum
    }
112
    else{
113
        _contents = val._contents;
114
    }
115
    return *this;
116 751c2a85 Josh Blum
}
117
118 bff70172 Josh Blum
/***********************************************************************
119
 * Public Methods
120
 **********************************************************************/
121 cc8caeb1 Josh Blum
wax::obj wax::obj::get_link(void) const{
122 dfd7f99e Josh Blum
    return link_args_t(this);
123 cc8caeb1 Josh Blum
}
124
125
const std::type_info & wax::obj::type(void) const{
126 dfd7f99e Josh Blum
    return resolve().type();
127 751c2a85 Josh Blum
}
128
129 bff70172 Josh Blum
/***********************************************************************
130
 * Private Methods
131
 **********************************************************************/
132 cc8caeb1 Josh Blum
boost::any wax::obj::resolve(void) const{
133
    if (_contents.type() == typeid(proxy_args_t)){
134
        obj val;
135 dfd7f99e Josh Blum
        proxy_args_t proxy_args = boost::any_cast<proxy_args_t>(_contents);
136
        proxy_args().get(proxy_args.key(), val);
137 cc8caeb1 Josh Blum
        return val.resolve();
138 751c2a85 Josh Blum
    }
139 cc8caeb1 Josh Blum
    else{
140
        return _contents;
141 751c2a85 Josh Blum
    }
142
}
143
144 cc8caeb1 Josh Blum
void wax::obj::get(const obj &, obj &){
145
    throw std::runtime_error("Cannot call get on wax obj base class");
146 751c2a85 Josh Blum
}
147
148 cc8caeb1 Josh Blum
void wax::obj::set(const obj &, const obj &){
149
    throw std::runtime_error("Cannot call set on wax obj base class");
150 751c2a85 Josh Blum
}