Line data Source code
1 : /** 2 : Copyright (c) 2016-2022 Roman Katuntsev <sbkarr@stappler.org> 3 : Copyright (c) 2023 Stappler LLC <admin@stappler.dev> 4 : 5 : Permission is hereby granted, free of charge, to any person obtaining a copy 6 : of this software and associated documentation files (the "Software"), to deal 7 : in the Software without restriction, including without limitation the rights 8 : to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 : copies of the Software, and to permit persons to whom the Software is 10 : furnished to do so, subject to the following conditions: 11 : 12 : The above copyright notice and this permission notice shall be included in 13 : all copies or substantial portions of the Software. 14 : 15 : THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 : IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 : FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 : AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 : LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 : OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN 21 : THE SOFTWARE. 22 : **/ 23 : 24 : #ifndef STAPPLER_DATA_SPDATAWRAPPER_H_ 25 : #define STAPPLER_DATA_SPDATAWRAPPER_H_ 26 : 27 : #include "SPDataValue.h" 28 : 29 : namespace STAPPLER_VERSIONIZED stappler::data { 30 : 31 : template <typename Interface> 32 : class WrapperTemplate : public Interface::AllocBaseType { 33 : public: 34 : using Value = typename data::ValueTemplate<Interface>; 35 : using Array = typename Value::ArrayType; 36 : using Dictionary = typename Value::DictionaryType; 37 : 38 : using String = typename data::ValueTemplate<Interface>::StringType; 39 : using Bytes = typename data::ValueTemplate<Interface>::BytesType; 40 : using Type = typename Value::Type; 41 : 42 : template <class Scheme> 43 : class Iterator { 44 : public: 45 : using value_type = typename Dictionary::iterator::value_type; 46 : using reference = typename Dictionary::iterator::reference; 47 : using pointer = typename Dictionary::iterator::pointer; 48 : 49 : Iterator() noexcept { } 50 75 : Iterator(Scheme *scheme) noexcept : scheme(scheme), iter(scheme->_data.asDict().begin()) { skipProtected(); } 51 75 : Iterator(Scheme *scheme, typename Dictionary::iterator iter) noexcept : scheme(scheme), iter(iter) { } 52 : 53 : Iterator(const Iterator &it) noexcept : scheme(it.scheme), iter(it.iter) { } 54 : Iterator &operator= (const Iterator &it) noexcept { scheme = it.scheme; iter = it.iter; return *this; } 55 : 56 300 : reference operator*() const noexcept {return iter.operator*();} 57 : pointer operator->() const noexcept {return iter.operator->();} 58 : 59 300 : Iterator & operator++() noexcept { increment(); return *this; } 60 : Iterator operator++(int) noexcept { Iterator ret = *this; increment(); return ret;} 61 : 62 : bool operator==(const Iterator & other) const noexcept { return iter == other.iter; } 63 375 : bool operator!=(const Iterator & other) const noexcept { return iter != other.iter; } 64 : 65 : protected: 66 300 : void increment() noexcept { iter++; skipProtected(); } 67 375 : void skipProtected() noexcept { 68 375 : if (!scheme->isProtected()) { 69 0 : while(iter != scheme->_data.asDict().end() || scheme->isFieldProtected(iter->first)) { 70 0 : iter++; 71 : } 72 : } 73 375 : } 74 : 75 : Scheme *scheme = nullptr; 76 : typename Dictionary::iterator iter; 77 : }; 78 : 79 : template <class Scheme> 80 : class ConstIterator { 81 : public: 82 : using value_type = typename Dictionary::const_iterator::value_type; 83 : using reference = typename Dictionary::const_iterator::reference; 84 : using pointer = typename Dictionary::const_iterator::pointer; 85 : 86 : ConstIterator() noexcept { } 87 : ConstIterator(const Scheme *scheme) noexcept : scheme(scheme), iter(scheme->_data.asDict().begin()) { skipProtected(); } 88 : ConstIterator(const Scheme *scheme, typename Dictionary::const_iterator iter) noexcept : scheme(scheme), iter(iter) { } 89 : 90 : ConstIterator(const ConstIterator &it) noexcept : scheme(it.scheme), iter(it.iter) { } 91 : ConstIterator &operator= (const ConstIterator &it) noexcept { scheme = it.scheme; iter = it.iter; return *this; } 92 : 93 : reference operator*() const noexcept { return iter.operator*(); } 94 : pointer operator->() const noexcept { return iter.operator->(); } 95 : 96 : ConstIterator & operator++() noexcept { increment(); return *this; } 97 : ConstIterator operator++(int) noexcept { ConstIterator ret = *this; increment(); return ret; } 98 : 99 : bool operator==(const ConstIterator & other) const noexcept { return iter == other.iter; } 100 : bool operator!=(const ConstIterator & other) const noexcept { return iter != other.iter; } 101 : 102 : protected: 103 : void increment() { iter++; skipProtected(); } 104 : void skipProtected() noexcept { 105 : if (!scheme->isProtected()) { 106 : while(iter != scheme->_data.asDict().end() || scheme->isFieldProtected(iter->first)) { 107 : iter++; 108 : } 109 : } 110 : } 111 : 112 : const Scheme *scheme = nullptr; 113 : typename Dictionary::const_iterator iter; 114 : }; 115 : 116 75 : template <typename Scheme> static auto begin(Scheme *scheme) noexcept { 117 75 : return Iterator<Scheme>(scheme); 118 : } 119 75 : template <typename Scheme> static auto end(Scheme *scheme) noexcept { 120 75 : return Iterator<Scheme>(scheme, scheme->getData().asDict().end()); 121 : } 122 : 123 : template <typename Scheme> static auto begin(const Scheme *scheme) noexcept { 124 : return ConstIterator<Scheme>(scheme); 125 : } 126 : template <typename Scheme> static auto end(const Scheme *scheme) noexcept { 127 : return ConstIterator<Scheme>(scheme, scheme->getData().asDict().end()); 128 : } 129 : 130 925 : WrapperTemplate(Value &&data) noexcept : _data(std::move(data)) { 131 925 : if (!_data.isDictionary()) { 132 0 : _data = Value(Type::DICTIONARY); 133 : } 134 925 : } 135 : 136 3050 : WrapperTemplate() noexcept : _data(Type::DICTIONARY) { } 137 : 138 600 : Value &getData() noexcept { return _data; } 139 : const Value &getData() const noexcept { return _data; } 140 : 141 2850 : bool isModified() const { return _modified; } 142 75 : void setModified(bool value) { _modified = value; } 143 : 144 : void setProtected(bool value) { _protected = value; } 145 375 : bool isProtected() const { return _protected; } 146 : 147 : public: 148 : template <class Key> Value &emplace(Key &&key) { _modified = true; return _data.template emplace<Key>(std::forward<Key>(key)); } 149 : template <class Key> bool hasValue(Key &&key) const { return _data.template hasValue<Key>(std::forward<Key>(key)); } 150 : 151 : template <class Val, class Key> Value &setValue(Val &&value, Key &&key) { _modified = true; return _data.template setValue<Val>(std::forward<Val>(value), std::forward<Key>(key)); } 152 : template <class Key> const Value &getValue(Key &&key) const { return _data.template getValue<Key>(std::forward<Key>(key)); } 153 : 154 : template <class Key> void setNull(Key && key) { _modified = true; _data.template setNull<Key>(std::forward<Key>(key)); } 155 : template <class Key> void setBool(bool value, Key && key) { _modified = true; _data.template setBool<Key>(value, std::forward<Key>(key)); } 156 100 : template <class Key> void setInteger(int64_t value, Key && key) { _modified = true; _data.template setInteger<Key>(value, std::forward<Key>(key)); } 157 : template <class Key> void setDouble(double value, Key && key) { _modified = true; _data.template setDouble<Key>(value, std::forward<Key>(key)); } 158 : template <class Key> void setString(const String &v, Key &&key) { _modified = true; _data.template setString<Key>(v, std::forward<Key>(key)); } 159 : template <class Key> void setString(String &&v, Key &&key) { _modified = true; _data.template setString<Key>(std::move(v), std::forward<Key>(key)); } 160 75 : template <class Key> void setString(StringView v, Key &&key) { _modified = true; _data.template setString<Key>(v, std::forward<Key>(key)); } 161 : template <class Key> void setBytes(const Bytes &v, Key &&key) { _modified = true; _data.template setBytes<Key>(v, std::forward<Key>(key)); } 162 0 : template <class Key> void setBytes(Bytes &&v, Key &&key) { _modified = true; _data.template setBytes<Key>(std::move(v), std::forward<Key>(key)); } 163 : template <class Key> void setBytes(BytesView v, Key &&key) { _modified = true; _data.template setBytes<Key>(std::move(v), std::forward<Key>(key)); } 164 : template <class Key> void setArray(const Array &v, Key &&key) { _modified = true; _data.template setArray<Key>(v, std::forward<Key>(key)); } 165 : template <class Key> void setArray(Array &&v, Key &&key) { _modified = true; _data.template setArray<Key>(std::move(v), std::forward<Key>(key)); } 166 : template <class Key> void setDict(const Dictionary &v, Key &&key) { _modified = true; _data.template setDict<Key>(v, std::forward<Key>(key)); } 167 : template <class Key> void setDict(Dictionary &&v, Key &&key) { _modified = true; _data.template setDict<Key>(std::move(v), std::forward<Key>(key)); } 168 : 169 1575 : template <class Key> bool getBool(Key &&key) const { return _data.template getBool<Key>(std::forward<Key>(key)); } 170 : template <class Key> int64_t getInteger(Key &&key, int64_t def = 0) const { return _data.template getInteger<Key>(std::forward<Key>(key), def); } 171 : template <class Key> double getDouble(Key &&key, double def = 0) const { return _data.template getDouble<Key>(std::forward<Key>(key), def); } 172 1825 : template <class Key> const String &getString(Key &&key) const { return _data.template getString<Key>(std::forward<Key>(key)); } 173 0 : template <class Key> const Bytes &getBytes(Key &&key) const { return _data.template getBytes<Key>(std::forward<Key>(key)); } 174 : template <class Key> const Array &getArray(Key &&key) const { return _data.template getArray<Key>(std::forward<Key>(key)); } 175 : template <class Key> const Dictionary &getDict(Key &&key) const { return _data.template getDict<Key>(std::forward<Key>(key)); } 176 : 177 : template <class Key> bool erase(Key &&key) { _modified = true; return _data.template erase<Key>(std::forward<Key>(key)); } 178 : 179 25 : template <class Key> Value& newDict(Key &&key) { _modified = true; return _data.template newDict<Key>(std::forward<Key>(key)); } 180 : template <class Key> Value& newArray(Key &&key) { _modified = true; return _data.template newArray<Key>(std::forward<Key>(key)); } 181 : 182 : template <class Key> bool isNull(Key &&key) const { return _data.template isNull<Key>(std::forward<Key>(key)); } 183 : template <class Key> bool isBasicType(Key &&key) const { return _data.template isBasicType<Key>(std::forward<Key>(key)); } 184 : template <class Key> bool isArray(Key &&key) const { return _data.template isArray<Key>(std::forward<Key>(key)); } 185 : template <class Key> bool isDictionary(Key &&key) const { return _data.template isDictionary<Key>(std::forward<Key>(key)); } 186 : template <class Key> bool isBool(Key &&key) const { return _data.template isBool<Key>(std::forward<Key>(key)); } 187 : template <class Key> bool isInteger(Key &&key) const { return _data.template isInteger<Key>(std::forward<Key>(key)); } 188 : template <class Key> bool isDouble(Key &&key) const { return _data.template isDouble<Key>(std::forward<Key>(key)); } 189 : template <class Key> bool isString(Key &&key) const { return _data.template isString<Key>(std::forward<Key>(key)); } 190 : template <class Key> bool isBytes(Key &&key) const { return _data.template isBytes<Key>(std::forward<Key>(key)); } 191 : 192 : template <class Key> Type getType(Key &&key) const { return _data.template getType<Key>(std::forward<Key>(key)); } 193 : 194 : protected: 195 : Value _data; 196 : bool _protected = true; 197 : bool _modified = false; 198 : }; 199 : 200 : } 201 : 202 : #endif /* STAPPLER_DATA_SPDATAWRAPPER_H_ */