Statistics
| Branch: | Tag: | Revision:

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
}