5 #include <boost/unordered_map.hpp> 6 #include <boost/unordered_set.hpp> 7 #include <boost/thread/mutex.hpp> 8 #include <boost/make_shared.hpp> 9 #include <boost/function.hpp> 17 const std::type_info& (*get_type)();
22 static const std::type_info&
id() {
return typeid(T); }
27 template<
typename T>
bool is_type()
const {
41 class String:
public std::vector<char>{
44 String(
const std::string &str) : std::vector<char>(str.begin(), str.end()) {}
45 operator const char * ()
const {
48 operator const std::string ()
const {
49 return std::string(begin(), end());
63 buffer.resize(
sizeof(T));
64 *(T*)&(buffer.front()) = t;
67 if(!type_guard.
is_type<std::string>()){
68 BOOST_THROW_EXCEPTION(std::bad_cast());
78 BOOST_THROW_EXCEPTION(std::length_error(
"buffer empty"));
83 template<
typename T>
const T &
get()
const{
85 BOOST_THROW_EXCEPTION(std::bad_cast());
87 BOOST_THROW_EXCEPTION(std::length_error(
"buffer empty"));
89 return *(T*)&(buffer.front());
114 #define THROW_WITH_KEY(e,k) BOOST_THROW_EXCEPTION(boost::enable_error_info(e) << ObjectDict::key_info(k)) 120 static size_t fromString(
const std::string &str);
123 Key(
const uint16_t i) : hash((i<<16)| 0xFFFF) {}
124 Key(
const uint16_t i,
const uint8_t s): hash((i<<16)| s) {}
125 Key(
const std::string &str): hash(fromString(str)) {}
126 bool hasSub()
const {
return (hash & 0xFFFF) != 0xFFFF; }
128 uint16_t
index()
const {
return hash >> 16;}
130 operator std::string()
const;
146 DEFTYPE_INTEGER8 = 0x0002,
147 DEFTYPE_INTEGER16 = 0x0003,
148 DEFTYPE_INTEGER32 = 0x0004,
149 DEFTYPE_UNSIGNED8 = 0x0005,
150 DEFTYPE_UNSIGNED16 = 0x0006,
151 DEFTYPE_UNSIGNED32 = 0x0007,
152 DEFTYPE_REAL32 = 0x0008,
153 DEFTYPE_VISIBLE_STRING = 0x0009,
154 DEFTYPE_OCTET_STRING = 0x000A,
155 DEFTYPE_UNICODE_STRING = 0x000B,
156 DEFTYPE_DOMAIN = 0x000F,
157 DEFTYPE_REAL64 = 0x0010,
158 DEFTYPE_INTEGER64 = 0x0015,
159 DEFTYPE_UNSIGNED64 = 0x001B
176 Entry(
const Code c,
const uint16_t i,
const uint16_t t,
const std::string & d,
const bool r =
true,
const bool w =
true,
bool m =
false,
const HoldAny def =
HoldAny(),
const HoldAny init =
HoldAny()):
177 obj_code(c), index(i), sub_index(0),data_type(t),readable(r), writable(w), mappable(m), desc(d), def_val(def), init_val(init) {}
179 Entry(
const uint16_t i,
const uint8_t s,
const uint16_t t,
const std::string & d,
const bool r =
true,
const bool w =
true,
bool m =
false,
const HoldAny def =
HoldAny(),
const HoldAny init =
HoldAny()):
180 obj_code(VAR), index(i), sub_index(s),data_type(t),readable(r), writable(w), mappable(m), desc(d), def_val(def), init_val(init) {}
182 operator Key()
const {
return Key(index, sub_index); }
192 return *at(
Key(i,s));
194 const EntryConstSharedPtr&
get(
const Key &k)
const{
197 bool has(uint16_t i, uint8_t s)
const{
198 return dict_.find(
Key(i,s)) != dict_.end();
200 bool has(uint16_t i)
const{
201 return dict_.find(
Key(i)) != dict_.end();
204 return dict_.find(k) != dict_.end();
206 bool insert(
bool is_sub, EntryConstSharedPtr e){
207 std::pair<boost::unordered_map<Key, EntryConstSharedPtr>::iterator,
bool> res = dict_.insert(std::make_pair(is_sub?
Key(e->index,e->sub_index):
Key(e->index),e));
210 bool iterate(boost::unordered_map<Key, EntryConstSharedPtr>::const_iterator &it)
const;
211 typedef std::list<std::pair<std::string, std::string> >
Overlay;
213 static ObjectDictSharedPtr fromFile(
const std::string &path,
const Overlay &overlay = Overlay());
217 typedef boost::error_info<struct tag_objectdict_key, ObjectDict::Key>
key_info;
219 const EntryConstSharedPtr&
at(
const Key &key)
const{
221 return dict_.at(key);
223 catch(
const std::out_of_range &e){
228 boost::unordered_map<Key, EntryConstSharedPtr >
dict_;
237 T (*adder)(
const uint8_t &,
const T &);
239 static T
add(
const uint8_t &u,
const T &t) {
247 if(TypeGuard::create<T>() == val.
type() ){
254 BOOST_THROW_EXCEPTION(std::bad_cast());
260 template<
typename T> std::ostream& operator<<(std::ostream& stream, const NodeIdOffset<T> &n) {
279 class Data: boost::noncopyable{
291 return *(T*)&(buffer.front());
295 buffer.resize(
sizeof(T));
304 size_t size() { boost::mutex::scoped_lock lock(mutex);
return buffer.size(); }
307 : valid(false), read_delegate(r), write_delegate(w), type_guard(
TypeGuard::
create<T>()), entry(e), key(k){
314 : valid(false), read_delegate(r), write_delegate(w), type_guard(t), entry(e), key(k){
322 boost::mutex::scoped_lock lock(mutex);
323 if(r) read_delegate = r;
324 if(w) write_delegate = w;
326 template<
typename T>
const T
get(
bool cached) {
327 boost::mutex::scoped_lock lock(mutex);
329 if(!entry->readable){
334 if(entry->constant) cached =
true;
336 if(!valid || !cached){
338 read_delegate(*entry, buffer);
342 template<
typename T>
void set(
const T &val) {
343 boost::mutex::scoped_lock lock(mutex);
345 if(!entry->writable){
346 if(access<T>() != val){
351 write_delegate(*entry, buffer);
355 boost::mutex::scoped_lock lock(mutex);
356 if(!valid || val != access<T>() ){
357 if(!entry->writable){
361 write_delegate(*entry, buffer);
380 bool valid()
const {
return data != 0; }
382 if(!data) BOOST_THROW_EXCEPTION(
PointerInvalid(
"ObjectStorage::Entry::get()") );
384 return data->get<T>(
false);
395 if(!data) BOOST_THROW_EXCEPTION(
PointerInvalid(
"ObjectStorage::Entry::get_cached()") );
397 return data->get<T>(
true);
407 void set(
const T &val) {
408 if(!data) BOOST_THROW_EXCEPTION(
PointerInvalid(
"ObjectStorage::Entry::set(val)") );
412 if(!data)
return false;
414 data->set_cached(val);
426 Entry(ObjectStorageSharedPtr storage, uint16_t index)
427 : data(storage->entry<type>(index).data) {
430 Entry(ObjectStorageSharedPtr storage, uint16_t index, uint8_t sub_index)
431 : data(storage->entry<type>(index, sub_index).data) {
435 : data(storage->entry<type>(k).data) {
439 return *(data->entry);
446 boost::unordered_map<ObjectDict::Key, DataSharedPtr >
storage_;
456 boost::mutex::scoped_lock lock(mutex_);
458 boost::unordered_map<ObjectDict::Key, DataSharedPtr >::iterator it = storage_.find(key);
460 if(it == storage_.end()){
466 if(!e->def_val.is_empty()){
468 data = boost::make_shared<Data>(key, e,val, read_delegate_, write_delegate_);
470 if(!e->def_val.type().valid() || e->def_val.type() == type) {
471 data = boost::make_shared<Data>(key,e,type, read_delegate_, write_delegate_);
477 std::pair<boost::unordered_map<ObjectDict::Key, DataSharedPtr >::iterator,
bool> ok = storage_.insert(std::make_pair(key, data));
481 if(!it->second->type_guard.is_type<T>()){
487 size_t map(uint16_t index, uint8_t sub_index,
const ReadDelegate & read_delegate,
const WriteDelegate & write_delegate);
499 template<
typename T>
void entry(
Entry<T> &e, uint16_t index, uint8_t sub_index){
511 ReadStringFuncType getStringReader(
const ObjectDict::Key &key,
bool cached =
false);
513 WriteStringFuncType getStringWriter(
const ObjectDict::Key &key,
bool cached =
false);
515 const ObjectDictConstSharedPtr
dict_;
518 ObjectStorage(ObjectDictConstSharedPtr dict, uint8_t node_id, ReadDelegate read_delegate, WriteDelegate write_delegate);
546 template<
typename T,
typename R>
static R *
branch_type(
const uint16_t data_type){
567 throw std::bad_cast();
bool has(const Key &k) const
static T add(const uint8_t &u, const T &t)
const ObjectDictConstSharedPtr dict_
const ObjectDict::EntryConstSharedPtr entry
const std::type_info &(* get_type)()
std::list< std::pair< std::string, std::string > > Overlay
boost::shared_ptr< ObjectDict > ObjectDictSharedPtr
uint8_t sub_index() const
boost::shared_ptr< Data > DataSharedPtr
boost::unordered_map< Key, EntryConstSharedPtr > dict_
const TypeGuard type_guard
Entry< T > entry(uint16_t index)
bool has(uint16_t i) const
Entry(ObjectStorageSharedPtr storage, uint16_t index, uint8_t sub_index)
Data(const ObjectDict::Key &k, const ObjectDict::EntryConstSharedPtr &e, const T &val, const ReadDelegate &r, const WriteDelegate &w)
const ObjectDict::Entry & desc() const
boost::function< void(const std::string &)> WriteStringFuncType
Entry< T > entry(const ObjectDict::Key &key)
const String & data() const
static const T apply(const HoldAny &val, const uint8_t &u)
const TypeGuard & type() const
bool dynamic_channels_supported
boost::unordered_set< uint16_t > dummy_usage
bool simple_boot_up_slave
Key(const std::string &str)
String(const std::string &str)
const Entry & operator()(uint16_t i) const
boost::function< std::string()> ReadStringFuncType
boost::shared_ptr< const ObjectDict > ObjectDictConstSharedPtr
void set_cached(const T &val)
Entry(const Code c, const uint16_t i, const uint16_t t, const std::string &d, const bool r=true, const bool w=true, bool m=false, const HoldAny def=HoldAny(), const HoldAny init=HoldAny())
fastdelegate::FastDelegate2< const ObjectDict::Entry &, const String & > WriteDelegate
boost::unordered_set< uint32_t > baudrates
bool has(uint16_t i, uint8_t s) const
bool operator==(const Key &other) const
ObjectDict::ObjectDictSharedPtr ObjectDictSharedPtr
Key(const uint16_t i, const uint8_t s)
std::size_t operator()(const Key &k) const
ReadDelegate read_delegate_
static R * branch_type(const uint16_t data_type)
boost::unordered_map< ObjectDict::Key, DataSharedPtr > storage_
ObjectDict(const DeviceInfo &info)
const EntryConstSharedPtr & at(const Key &key) const
void set_delegates(const ReadDelegate &r, const WriteDelegate &w)
bool simple_boot_up_master
bool set_cached(const T &val)
static const std::type_info & id()
Entry(ObjectStorageSharedPtr storage, const ObjectDict::Key &k)
std::size_t hash_value(ObjectDict::Key const &k)
ReadDelegate read_delegate
Entry< T > entry(uint16_t index, uint8_t sub_index)
void entry(Entry< T > &e, uint16_t index)
const Entry & operator()(uint16_t i, uint8_t s) const
boost::shared_ptr< const Entry > EntryConstSharedPtr
const DeviceInfo device_info
fastdelegate::FastDelegate2< const ObjectDict::Entry &, String & > ReadDelegate
bool insert(bool is_sub, EntryConstSharedPtr e)
void entry(Entry< T > &e, uint16_t index, uint8_t sub_index)
WriteDelegate write_delegate_
TypeGuard(const std::type_info &(*ti)(), const size_t s)
HoldAny(const std::string &t)
const ObjectDict::Key key
#define THROW_WITH_KEY(e, k)
std::ostream & operator<<(std::ostream &stream, const NodeIdOffset< T > &n)
AccessException(const std::string &w)
HoldAny(const TypeGuard &t)
static TypeGuard create()
bool operator==(const TypeGuard &other) const
Entry(ObjectStorageSharedPtr storage, uint16_t index)
ObjectStorage::ObjectStorageSharedPtr ObjectStorageSharedPtr
const HoldAny & value() const
boost::error_info< struct tag_objectdict_key, ObjectDict::Key > key_info
T(* adder)(const uint8_t &, const T &)
boost::shared_ptr< ObjectStorage > ObjectStorageSharedPtr
Data(const ObjectDict::Key &k, const ObjectDict::EntryConstSharedPtr &e, const TypeGuard &t, const ReadDelegate &r, const WriteDelegate &w)
bool entry(Entry< T > &e, const ObjectDict::Key &k)
WriteDelegate write_delegate
Entry(const uint16_t i, const uint8_t s, const uint16_t t, const std::string &d, const bool r=true, const bool w=true, bool m=false, const HoldAny def=HoldAny(), const HoldAny init=HoldAny())