6 #include <unordered_map> 7 #include <unordered_set> 11 #include <boost/thread/mutex.hpp> 20 const std::type_info& (*get_type)();
25 static const std::type_info&
id() {
return typeid(T); }
30 template<
typename T>
bool is_type()
const {
44 class String:
public std::vector<char>{
47 String(
const std::string &str) : std::vector<char>(str.begin(), str.end()) {}
48 operator const char * ()
const {
51 operator const std::string ()
const {
52 return std::string(begin(), end());
66 buffer.resize(
sizeof(T));
67 *(T*)&(buffer.front()) = t;
70 if(!type_guard.
is_type<std::string>()){
71 BOOST_THROW_EXCEPTION(std::bad_cast());
81 BOOST_THROW_EXCEPTION(std::length_error(
"buffer empty"));
86 template<
typename T>
const T &
get()
const{
88 BOOST_THROW_EXCEPTION(std::bad_cast());
90 BOOST_THROW_EXCEPTION(std::length_error(
"buffer empty"));
92 return *(T*)&(buffer.front());
117 #define THROW_WITH_KEY(e,k) BOOST_THROW_EXCEPTION(boost::enable_error_info(e) << ObjectDict::key_info(k)) 123 static size_t fromString(
const std::string &str);
126 Key(
const uint16_t i) : hash((i<<16)| 0xFFFF) {}
127 Key(
const uint16_t i,
const uint8_t s): hash((i<<16)| s) {}
128 Key(
const std::string &str): hash(fromString(str)) {}
129 bool hasSub()
const {
return (hash & 0xFFFF) != 0xFFFF; }
131 uint16_t
index()
const {
return hash >> 16;}
133 operator std::string()
const;
149 DEFTYPE_INTEGER8 = 0x0002,
150 DEFTYPE_INTEGER16 = 0x0003,
151 DEFTYPE_INTEGER32 = 0x0004,
152 DEFTYPE_UNSIGNED8 = 0x0005,
153 DEFTYPE_UNSIGNED16 = 0x0006,
154 DEFTYPE_UNSIGNED32 = 0x0007,
155 DEFTYPE_REAL32 = 0x0008,
156 DEFTYPE_VISIBLE_STRING = 0x0009,
157 DEFTYPE_OCTET_STRING = 0x000A,
158 DEFTYPE_UNICODE_STRING = 0x000B,
159 DEFTYPE_DOMAIN = 0x000F,
160 DEFTYPE_REAL64 = 0x0010,
161 DEFTYPE_INTEGER64 = 0x0015,
162 DEFTYPE_UNSIGNED64 = 0x001B
179 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()):
180 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) {}
182 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()):
183 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) {}
185 operator Key()
const {
return Key(index, sub_index); }
195 return *at(
Key(i,s));
197 const EntryConstSharedPtr&
get(
const Key &k)
const{
200 bool has(uint16_t i, uint8_t s)
const{
201 return dict_.find(
Key(i,s)) != dict_.end();
203 bool has(uint16_t i)
const{
204 return dict_.find(
Key(i)) != dict_.end();
207 return dict_.find(k) != dict_.end();
210 bool insert(
bool is_sub, EntryConstSharedPtr e){
211 return dict_.insert(std::make_pair(is_sub?
Key(e->index,e->sub_index):
Key(e->index),e)).second;
214 typedef std::unordered_map<Key, EntryConstSharedPtr, KeyHash>
ObjectDictMap;
215 bool iterate(ObjectDictMap::const_iterator &it)
const;
216 typedef std::list<std::pair<std::string, std::string> >
Overlay;
218 static ObjectDictSharedPtr fromFile(
const std::string &path,
const Overlay &overlay = Overlay());
222 typedef boost::error_info<struct tag_objectdict_key, ObjectDict::Key>
key_info;
224 const EntryConstSharedPtr&
at(
const Key &key)
const{
226 return dict_.at(key);
228 catch(
const std::out_of_range &e){
243 T (*adder)(
const uint8_t &,
const T &);
245 static T
add(
const uint8_t &u,
const T &t) {
253 if(TypeGuard::create<T>() == val.
type() ){
260 BOOST_THROW_EXCEPTION(std::bad_cast());
266 template<
typename T> std::ostream& operator<<(std::ostream& stream, const NodeIdOffset<T> &n) {
280 using ReadFunc = std::function<void(const ObjectDict::Entry&, String &)>;
283 using WriteFunc = std::function<void(const ObjectDict::Entry&, const String &)>;
291 Data& operator=(
const Data&) =
delete;
304 return *(T*)&(buffer.front());
308 buffer.resize(
sizeof(T));
317 size_t size() { boost::mutex::scoped_lock lock(mutex);
return buffer.size(); }
320 : valid(false), read_delegate(r), write_delegate(w), type_guard(
TypeGuard::
create<T>()), entry(e), key(k){
327 : valid(false), read_delegate(r), write_delegate(w), type_guard(t), entry(e), key(k){
335 boost::mutex::scoped_lock lock(mutex);
336 if(r) read_delegate = r;
337 if(w) write_delegate = w;
339 template<
typename T>
const T
get(
bool cached) {
340 boost::mutex::scoped_lock lock(mutex);
342 if(!entry->readable){
347 if(entry->constant) cached =
true;
349 if(!valid || !cached){
351 read_delegate(*entry, buffer);
355 template<
typename T>
void set(
const T &val) {
356 boost::mutex::scoped_lock lock(mutex);
358 if(!entry->writable){
359 if(access<T>() != val){
364 write_delegate(*entry, buffer);
368 boost::mutex::scoped_lock lock(mutex);
369 if(!valid || val != access<T>() ){
370 if(!entry->writable){
374 write_delegate(*entry, buffer);
393 bool valid()
const {
return data != 0; }
395 if(!data) BOOST_THROW_EXCEPTION(
PointerInvalid(
"ObjectStorage::Entry::get()") );
397 return data->get<T>(
false);
408 if(!data) BOOST_THROW_EXCEPTION(
PointerInvalid(
"ObjectStorage::Entry::get_cached()") );
410 return data->get<T>(
true);
420 void set(
const T &val) {
421 if(!data) BOOST_THROW_EXCEPTION(
PointerInvalid(
"ObjectStorage::Entry::set(val)") );
425 if(!data)
return false;
427 data->set_cached(val);
439 Entry(ObjectStorageSharedPtr storage, uint16_t index)
440 : data(storage->entry<type>(index).data) {
443 Entry(ObjectStorageSharedPtr storage, uint16_t index, uint8_t sub_index)
444 : data(storage->entry<type>(index, sub_index).data) {
448 : data(storage->entry<type>(k).data) {
452 return *(data->entry);
459 typedef std::unordered_map<ObjectDict::Key, DataSharedPtr, ObjectDict::KeyHash>
ObjectStorageMap;
470 boost::mutex::scoped_lock lock(mutex_);
472 ObjectStorageMap::iterator it = storage_.find(key);
474 if(it == storage_.end()){
480 if(!e->def_val.is_empty()){
482 data = std::make_shared<Data>(key, e,val, read_delegate_, write_delegate_);
484 if(!e->def_val.type().valid() || e->def_val.type() == type) {
485 data = std::make_shared<Data>(key,e,type, read_delegate_, write_delegate_);
491 std::pair<ObjectStorageMap::iterator, bool> ok = storage_.insert(std::make_pair(key, data));
495 if(!it->second->type_guard.is_type<T>()){
501 size_t map(uint16_t index, uint8_t sub_index,
const ReadFunc & read_delegate,
const WriteFunc & write_delegate);
513 template<
typename T>
void entry(
Entry<T> &e, uint16_t index, uint8_t sub_index){
525 ReadStringFuncType getStringReader(
const ObjectDict::Key &key,
bool cached =
false);
527 WriteStringFuncType getStringWriter(
const ObjectDict::Key &key,
bool cached =
false);
529 const ObjectDictConstSharedPtr
dict_;
560 template<
typename T,
typename R>
static R *
branch_type(
const uint16_t data_type){
581 throw std::bad_cast();
std::unordered_map< Key, EntryConstSharedPtr, KeyHash > ObjectDictMap
uint8_t sub_index() const
static T add(const uint8_t &u, const T &t)
const ObjectDictConstSharedPtr dict_
Data(const ObjectDict::Key &k, const ObjectDict::EntryConstSharedPtr &e, const TypeGuard &t, const ReadFunc &r, const WriteFunc &w)
const ObjectDict::EntryConstSharedPtr entry
const std::type_info &(* get_type)()
bool operator==(const TypeGuard &other) const
std::list< std::pair< std::string, std::string > > Overlay
std::unordered_set< uint32_t > baudrates
std::function< std::string()> ReadStringFuncType
const TypeGuard type_guard
std::shared_ptr< const ObjectDict > ObjectDictConstSharedPtr
Entry< T > entry(uint16_t index)
Entry(ObjectStorageSharedPtr storage, uint16_t index, uint8_t sub_index)
void set_delegates(const ReadFunc &r, const WriteFunc &w)
std::shared_ptr< ObjectStorage > ObjectStorageSharedPtr
Entry< T > entry(const ObjectDict::Key &key)
const TypeGuard & type() const
std::shared_ptr< Data > DataSharedPtr
static const T apply(const HoldAny &val, const uint8_t &u)
std::size_t operator()(const Key &k) const
bool dynamic_channels_supported
bool simple_boot_up_slave
Key(const std::string &str)
std::shared_ptr< const Entry > EntryConstSharedPtr
std::unordered_set< uint16_t > dummy_usage
String(const std::string &str)
const HoldAny & value() const
const Entry & operator()(uint16_t i) const
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())
bool has(const Key &k) const
ObjectDict::ObjectDictSharedPtr ObjectDictSharedPtr
bool operator==(const Key &other) const
Key(const uint16_t i, const uint8_t s)
WriteFunc write_delegate_
static R * branch_type(const uint16_t data_type)
ObjectDict(const DeviceInfo &info)
std::unordered_map< ObjectDict::Key, DataSharedPtr, ObjectDict::KeyHash > ObjectStorageMap
ObjectStorageMap storage_
bool simple_boot_up_master
const Entry & operator()(uint16_t i, uint8_t s) const
bool set_cached(const T &val)
bool has(uint16_t i, uint8_t s) const
const EntryConstSharedPtr & at(const Key &key) const
static const std::type_info & id()
Entry(ObjectStorageSharedPtr storage, const ObjectDict::Key &k)
std::size_t hash_value(ObjectDict::Key const &k)
Data(const ObjectDict::Key &k, const ObjectDict::EntryConstSharedPtr &e, const T &val, const ReadFunc &r, const WriteFunc &w)
std::shared_ptr< ObjectDict > ObjectDictSharedPtr
Entry< T > entry(uint16_t index, uint8_t sub_index)
void entry(Entry< T > &e, uint16_t index)
const ObjectDict::Entry & desc() const
const DeviceInfo device_info
bool insert(bool is_sub, EntryConstSharedPtr e)
void entry(Entry< T > &e, uint16_t index, uint8_t sub_index)
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::function< void(const ObjectDict::Entry &, const String &)> WriteFunc
std::ostream & operator<<(std::ostream &stream, const NodeIdOffset< T > &n)
AccessException(const std::string &w)
HoldAny(const TypeGuard &t)
static TypeGuard create()
std::function< void(const std::string &)> WriteStringFuncType
Entry(ObjectStorageSharedPtr storage, uint16_t index)
ObjectStorage::ObjectStorageSharedPtr ObjectStorageSharedPtr
boost::error_info< struct tag_objectdict_key, ObjectDict::Key > key_info
T(* adder)(const uint8_t &, const T &)
bool entry(Entry< T > &e, const ObjectDict::Key &k)
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())
bool has(uint16_t i) const
std::function< void(const ObjectDict::Entry &, String &)> ReadFunc
const String & data() const