#ifndef ZNODE_PAYLOAD_H #define ZNODE_PAYLOAD_H #include #include //#include //#include namespace znode { template class zstringmap : public std::map { public: using str_cref = const str_t&; using str_ptr = str_t*; using str_list = std::vector; using zvalue = str_t; // could be any or variant // __fixme: should this be a vector? or a maptor? //using zattributes = std::map; using zattributes = zstringmap; str_cref key_of(str_cref value) const { for( const auto& pair : *this ) { if (pair.second == value) return pair.first; } static str_t s_dummy; return s_dummy; } }; template class zpayload { public: using str_cref = const str_t&; using str_ptr = str_t*; using str_list = std::vector; using zvalue = str_t; // could be any or variant // __fixme: should this be a vector? or a maptor? //using zattributes = std::map; using zattributes = zstringmap; static const str_t cType;// = "Type"; static const str_t cName;// = "Name"; static const str_t cValue;// = "Value"; static const str_t cFriendlyName; protected: str_t _tag_name; str_t _value; zattributes _attributes; static zvalue s_dummy_value; public: zpayload( str_cref tag_name ) : _tag_name{tag_name} {} // ... zpayload( str_cref tag_name, str_cref value ) : _tag_name{tag_name}, _value{value} {} zpayload( str_cref tag_name, const str_list& attriblist ) : zpayload(tag_name) { for( str_cref entry : attriblist ) { str_t key_value, data_value; if( xstr_split_by( entry, "=", key_value, data_value) ) set_attribute( key_value, data_value ); } } str_cref tag_name() const { return _tag_name; } str_ptr tag_name_ptr() { return &_tag_name; } void set_tag_name( str_cref tag_name ) { _tag_name = tag_name; } str_cref tag_value() const { return _value; } str_ptr tag_value_ptr() { return &_value; } void set_tag_value( str_cref value ) { _value = value; } str_cref friendly_name() const { return attribute(cFriendlyName); } str_ptr friendly_name_ptr() { return &attribute(cFriendlyName); } str_cref type() const { return attribute(cType); } str_ptr type_ptr() const { return &attribute(cType); } void set_type( str_cref type ) { set_attribute( cType, type); } str_cref name() const { return attribute(cName); } str_ptr name_ptr() { return &attribute(cName); } void set_name( str_cref name ) { set_attribute( cType, name); } const zattributes& attributes() const { return _attributes; } bool has_attribute(str_cref key ) const { if( xstr_is_empty( key ) ) return false; typename zattributes::const_iterator pos = _attributes.find(key); if( pos == _attributes.end() ) return false; return true; } bool test_attribute(str_cref key, str_cref value ) const { if( xstr_is_empty( key ) ) return false; typename zattributes::const_iterator pos = _attributes.find(key); if( pos == _attributes.end() ) return false; if( !xstr_is_empty( value ) ) return (*pos).second == value; return true; } const zvalue& attribute(str_cref key ) const { if( !xstr_is_empty( key ) ) { typename zattributes::const_iterator pos = _attributes.find(key); if (pos != _attributes.end()) { const zvalue& result = (*pos).second; if (!xstr_is_empty(result) && result[0] == '@') return attribute( xstr_sub_str(result, 1) ); return result; } } return s_dummy_value; } const zvalue* attribute_ptr(str_cref key ) const { if( !xstr_is_empty( key ) ) { typename zattributes::const_iterator pos = _attributes.find(key); if (pos != _attributes.end()) { const zvalue& result = (*pos).second; if (!xstr_is_empty(result) && result[0] == '@') return attribute_ptr( xstr_sub_str(result, 1) ); return &result; } } return &s_dummy_value; } void set_attribute(str_cref key, zvalue value ) { if( !xstr_is_empty( key ) ) _attributes[key] = value; } // dumper str_t to_string() const { str_t result = '<' +_tag_name +'>'; if( !xstr_is_empty(_value) ) result += ": " + _value; if( !_attributes.empty() ) { result += " ["; bool first = true; for (const auto& entry : _attributes) { if(first) { result += entry.first + "=" + entry.second; first = false; continue; } result += ", " + entry.first + "=" + entry.second; } result += "]"; } return result; } // forward helpers bool xstr_split_by(str_cref entry, str_cref sep, str_t& key, str_t& value ); str_t xstr_sub_str(str_cref entry, int pos) const; bool xstr_is_empty(str_cref key ) const; }; // init statics template str_t zpayload::s_dummy_value; } #endif // ZNODE_PAYLOAD_H