aboutsummaryrefslogtreecommitdiff
path: root/contrib/epee/include/serialization/keyvalue_serialization_overloads.h
diff options
context:
space:
mode:
Diffstat (limited to 'contrib/epee/include/serialization/keyvalue_serialization_overloads.h')
-rw-r--r--contrib/epee/include/serialization/keyvalue_serialization_overloads.h366
1 files changed, 366 insertions, 0 deletions
diff --git a/contrib/epee/include/serialization/keyvalue_serialization_overloads.h b/contrib/epee/include/serialization/keyvalue_serialization_overloads.h
new file mode 100644
index 000000000..2ad9a82a4
--- /dev/null
+++ b/contrib/epee/include/serialization/keyvalue_serialization_overloads.h
@@ -0,0 +1,366 @@
+// Copyright (c) 2006-2013, Andrey N. Sabelnikov, www.sabelnikov.net
+// All rights reserved.
+//
+// Redistribution and use in source and binary forms, with or without
+// modification, are permitted provided that the following conditions are met:
+// * Redistributions of source code must retain the above copyright
+// notice, this list of conditions and the following disclaimer.
+// * Redistributions in binary form must reproduce the above copyright
+// notice, this list of conditions and the following disclaimer in the
+// documentation and/or other materials provided with the distribution.
+// * Neither the name of the Andrey N. Sabelnikov nor the
+// names of its contributors may be used to endorse or promote products
+// derived from this software without specific prior written permission.
+//
+// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
+// ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+// WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+// DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER BE LIABLE FOR ANY
+// DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+// (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+// LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+// ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+// SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+//
+
+#pragma once
+
+namespace epee
+{
+ namespace serialization
+ {
+
+ //-------------------------------------------------------------------------------------------------------------------
+ template<class t_type, class t_storage>
+ static bool serialize_t_val(const t_type& d, t_storage& stg, typename t_storage::hsection hparent_section, const char* pname)
+ {
+ return stg.set_value(pname, d, hparent_section);
+ }
+ //-------------------------------------------------------------------------------------------------------------------
+ template<class t_type, class t_storage>
+ static bool unserialize_t_val(t_type& d, t_storage& stg, typename t_storage::hsection hparent_section, const char* pname)
+ {
+ return stg.get_value(pname, d, hparent_section);
+ }
+ //-------------------------------------------------------------------------------------------------------------------
+ template<class t_type, class t_storage>
+ static bool serialize_t_val_as_blob(const t_type& d, t_storage& stg, typename t_storage::hsection hparent_section, const char* pname)
+ {
+ std::string blob((const char *)&d, sizeof(d));
+ return stg.set_value(pname, blob, hparent_section);
+ }
+ //-------------------------------------------------------------------------------------------------------------------
+ template<class t_type, class t_storage>
+ static bool unserialize_t_val_as_blob(t_type& d, t_storage& stg, typename t_storage::hsection hparent_section, const char* pname)
+ {
+ std::string blob;
+ if(!stg.get_value(pname, blob, hparent_section))
+ return false;
+ CHECK_AND_ASSERT_MES(blob.size() == sizeof(d), false, "unserialize_t_val_as_blob: size of " << typeid(t_type).name() << " = " << sizeof(t_type) << ", but stored blod size = " << blob.size() << ", value name = " << pname);
+ d = *(const t_type*)blob.data();
+ return true;
+ }
+ //-------------------------------------------------------------------------------------------------------------------
+ template<class serializible_type, class t_storage>
+ static bool serialize_t_obj(const serializible_type& obj, t_storage& stg, typename t_storage::hsection hparent_section, const char* pname)
+ {
+ typename t_storage::hsection hchild_section = stg.open_section(pname, hparent_section, true);
+ CHECK_AND_ASSERT_MES(hchild_section, false, "serialize_t_obj: failed to open/create section " << pname);
+ return obj.store(stg, hchild_section);
+ }
+ //-------------------------------------------------------------------------------------------------------------------
+ template<class serializible_type, class t_storage>
+ static bool unserialize_t_obj(serializible_type& obj, t_storage& stg, typename t_storage::hsection hparent_section, const char* pname)
+ {
+ typename t_storage::hsection hchild_section = stg.open_section(pname, hparent_section, true);
+ if(!hchild_section) return false;
+ return obj._load(stg, hchild_section);
+ }
+ //-------------------------------------------------------------------------------------------------------------------
+ template<class serializible_type, class t_storage>
+ static bool serialize_t_obj(enableable<serializible_type>& obj, t_storage& stg, typename t_storage::hsection hparent_section, const char* pname)
+ {
+ if(!obj.enabled)
+ return true;
+ return serialize_t_obj(obj.v, stg, hparent_section, pname);
+ }
+ //-------------------------------------------------------------------------------------------------------------------
+ template<class serializible_type, class t_storage>
+ static bool unserialize_t_obj(enableable<serializible_type>& obj, t_storage& stg, typename t_storage::hsection hparent_section, const char* pname)
+ {
+ obj.enabled = false;
+ typename t_storage::hsection hchild_section = stg.open_section(pname, hparent_section, true);
+ if(!hchild_section) return false;
+ obj.enabled = true;
+ return obj.v._load(stg, hchild_section);
+ }
+ //-------------------------------------------------------------------------------------------------------------------
+ template<class stl_container, class t_storage>
+ static bool serialize_stl_container_t_val (const stl_container& container, t_storage& stg, typename t_storage::hsection hparent_section, const char* pname)
+ {
+ if(!container.size()) return true;
+ typename stl_container::const_iterator it = container.begin();
+ typename t_storage::harray hval_array = stg.insert_first_value(pname, *it, hparent_section);
+ CHECK_AND_ASSERT_MES(hval_array, false, "failed to insert first value to storage");
+ it++;
+ for(;it!= container.end();it++)
+ stg.insert_next_value(hval_array, *it);
+
+ return true;
+ }
+ //--------------------------------------------------------------------------------------------------------------------
+ template<class stl_container, class t_storage>
+ static bool unserialize_stl_container_t_val(stl_container& container, t_storage& stg, typename t_storage::hsection hparent_section, const char* pname)
+ {
+ container.clear();
+ typename stl_container::value_type exchange_val;
+ typename t_storage::harray hval_array = stg.get_first_value(pname, exchange_val, hparent_section);
+ if(!hval_array) return false;
+ container.push_back(std::move(exchange_val));
+ while(stg.get_next_value(hval_array, exchange_val))
+ container.push_back(std::move(exchange_val));
+ return true;
+ }//--------------------------------------------------------------------------------------------------------------------
+ template<class stl_container, class t_storage>
+ static bool serialize_stl_container_pod_val_as_blob(const stl_container& container, t_storage& stg, typename t_storage::hsection hparent_section, const char* pname)
+ {
+ if(!container.size()) return true;
+ typename stl_container::const_iterator it = container.begin();
+ std::string mb;
+ mb.resize(sizeof(typename stl_container::value_type)*container.size());
+ typename stl_container::value_type* p_elem = (typename stl_container::value_type*)mb.data();
+ BOOST_FOREACH(const typename stl_container::value_type& v, container)
+ {
+ *p_elem = v;
+ p_elem++;
+ }
+ return stg.set_value(pname, mb, hparent_section);
+ }
+ //--------------------------------------------------------------------------------------------------------------------
+ template<class stl_container, class t_storage>
+ static bool unserialize_stl_container_pod_val_as_blob(stl_container& container, t_storage& stg, typename t_storage::hsection hparent_section, const char* pname)
+ {
+ container.clear();
+ std::string buff;
+ bool res = stg.get_value(pname, buff, hparent_section);
+ if(res)
+ {
+ size_t loaded_size = buff.size();
+ typename stl_container::value_type* pelem = (typename stl_container::value_type*)buff.data();
+ CHECK_AND_ASSERT_MES(!(loaded_size%sizeof(typename stl_container::value_type)),
+ false,
+ "size in blob " << loaded_size << " not have not zero modulo for sizeof(value_type) = " << sizeof(typename stl_container::value_type));
+ size_t count = (loaded_size/sizeof(typename stl_container::value_type));
+ for(size_t i = 0; i < count; i++)
+ container.push_back(*(pelem++));
+ }
+ return res;
+ }
+ //--------------------------------------------------------------------------------------------------------------------
+ template<class stl_container, class t_storage>
+ static bool serialize_stl_container_t_obj (const stl_container& container, t_storage& stg, typename t_storage::hsection hparent_section, const char* pname)
+ {
+ bool res = false;
+ if(!container.size()) return true;
+ typename stl_container::const_iterator it = container.begin();
+ typename t_storage::hsection hchild_section = nullptr;
+ typename t_storage::harray hsec_array = stg.insert_first_section(pname, hchild_section, hparent_section);
+ CHECK_AND_ASSERT_MES(hsec_array && hchild_section, false, "failed to insert first section with section name " << pname);
+ res = it->store(stg, hchild_section);
+ it++;
+ for(;it!= container.end();it++)
+ {
+ stg.insert_next_section(hsec_array, hchild_section);
+ res |= it->store(stg, hchild_section);
+ }
+ return res;
+ }
+ //--------------------------------------------------------------------------------------------------------------------
+ template<class stl_container, class t_storage>
+ static bool unserialize_stl_container_t_obj(stl_container& container, t_storage& stg, typename t_storage::hsection hparent_section, const char* pname)
+ {
+ bool res = false;
+ container.clear();
+ typename stl_container::value_type val = typename stl_container::value_type();
+ typename t_storage::hsection hchild_section = nullptr;
+ typename t_storage::harray hsec_array = stg.get_first_section(pname, hchild_section, hparent_section);
+ if(!hsec_array || !hchild_section) return false;
+ res = val._load(stg, hchild_section);
+ container.push_back(val);
+ while(stg.get_next_section(hsec_array, hchild_section))
+ {
+ typename stl_container::value_type val_l = typename stl_container::value_type();
+ res |= val_l._load(stg, hchild_section);
+ container.push_back(std::move(val_l));
+ }
+ return res;
+ }
+ //--------------------------------------------------------------------------------------------------------------------
+ template<bool>
+ struct kv_serialization_overloads_impl_is_base_serializable_types;
+
+ template<>
+ struct kv_serialization_overloads_impl_is_base_serializable_types<true>
+ {
+ template<class t_type, class t_storage>
+ static bool kv_serialize(const t_type& d, t_storage& stg, typename t_storage::hsection hparent_section, const char* pname)
+ {
+ return stg.set_value(pname, d, hparent_section);
+ }
+ //-------------------------------------------------------------------------------------------------------------------
+ template<class t_type, class t_storage>
+ static bool kv_unserialize(t_type& d, t_storage& stg, typename t_storage::hsection hparent_section, const char* pname)
+ {
+ return stg.get_value(pname, d, hparent_section);
+ }
+ //-------------------------------------------------------------------------------------------------------------------
+ template<class t_type, class t_storage>
+ static bool kv_serialize(const std::vector<t_type>& d, t_storage& stg, typename t_storage::hsection hparent_section, const char* pname)
+ {
+ return serialize_stl_container_t_val(d, stg, hparent_section, pname);
+ }
+ //-------------------------------------------------------------------------------------------------------------------
+ template<class t_type, class t_storage>
+ static bool kv_unserialize(std::vector<t_type>& d, t_storage& stg, typename t_storage::hsection hparent_section, const char* pname)
+ {
+ return unserialize_stl_container_t_val(d, stg, hparent_section, pname);
+ }
+ //-------------------------------------------------------------------------------------------------------------------
+ template<class t_type, class t_storage>
+ static bool kv_serialize(const std::list<t_type>& d, t_storage& stg, typename t_storage::hsection hparent_section, const char* pname)
+ {
+ return serialize_stl_container_t_val(d, stg, hparent_section, pname);
+ }
+ //-------------------------------------------------------------------------------------------------------------------
+ template<class t_type, class t_storage>
+ static bool kv_unserialize(std::list<t_type>& d, t_storage& stg, typename t_storage::hsection hparent_section, const char* pname)
+ {
+ return unserialize_stl_container_t_val(d, stg, hparent_section, pname);
+ }
+ //-------------------------------------------------------------------------------------------------------------------
+ };
+ template<>
+ struct kv_serialization_overloads_impl_is_base_serializable_types<false>
+ {
+ template<class t_type, class t_storage>
+ static bool kv_serialize(const t_type& d, t_storage& stg, typename t_storage::hsection hparent_section, const char* pname)
+ {
+ return serialize_t_obj(d, stg, hparent_section, pname);
+ }
+ //-------------------------------------------------------------------------------------------------------------------
+ template<class t_type, class t_storage>
+ static bool kv_unserialize(t_type& d, t_storage& stg, typename t_storage::hsection hparent_section, const char* pname)
+ {
+ return unserialize_t_obj(d, stg, hparent_section, pname);
+ }
+
+ //-------------------------------------------------------------------------------------------------------------------
+ template<class t_type, class t_storage>
+ static bool kv_serialize(const std::vector<t_type>& d, t_storage& stg, typename t_storage::hsection hparent_section, const char* pname)
+ {
+ return serialize_stl_container_t_obj(d, stg, hparent_section, pname);
+ }
+ //-------------------------------------------------------------------------------------------------------------------
+ template<class t_type, class t_storage>
+ static bool kv_unserialize(std::vector<t_type>& d, t_storage& stg, typename t_storage::hsection hparent_section, const char* pname)
+ {
+ return unserialize_stl_container_t_obj(d, stg, hparent_section, pname);
+ }
+ //-------------------------------------------------------------------------------------------------------------------
+ template<class t_type, class t_storage>
+ static bool kv_serialize(const std::list<t_type>& d, t_storage& stg, typename t_storage::hsection hparent_section, const char* pname)
+ {
+ return serialize_stl_container_t_obj(d, stg, hparent_section, pname);
+ }
+ //-------------------------------------------------------------------------------------------------------------------
+ template<class t_type, class t_storage>
+ static bool kv_unserialize(std::list<t_type>& d, t_storage& stg, typename t_storage::hsection hparent_section, const char* pname)
+ {
+ return unserialize_stl_container_t_obj(d, stg, hparent_section, pname);
+ }
+ };
+ typedef boost::mpl::vector<uint64_t, uint32_t, uint16_t, uint8_t, int64_t, int32_t, int16_t, int8_t, double, bool, std::string>::type base_serializable_types;
+ //-------------------------------------------------------------------------------------------------------------------
+ template<bool> struct selector;
+ template<>
+ struct selector<true>
+ {
+ template<class t_type, class t_storage>
+ static bool serialize(const t_type& d, t_storage& stg, typename t_storage::hsection hparent_section, const char* pname)
+ {
+ return kv_serialize(d, stg, hparent_section, pname);
+ }
+
+ template<class t_type, class t_storage>
+ static bool serialize_stl_container_pod_val_as_blob(const t_type& d, t_storage& stg, typename t_storage::hsection hparent_section, const char* pname)
+ {
+ return epee::serialization::serialize_stl_container_pod_val_as_blob(d, stg, hparent_section, pname);
+ }
+
+ template<class t_type, class t_storage>
+ static bool serialize_t_val_as_blob(const t_type& d, t_storage& stg, typename t_storage::hsection hparent_section, const char* pname)
+ {
+ return epee::serialization::serialize_t_val_as_blob(d, stg, hparent_section, pname);
+ }
+
+
+ };
+ template<>
+ struct selector<false>
+ {
+ template<class t_type, class t_storage>
+ static bool serialize(t_type& d, t_storage& stg, typename t_storage::hsection hparent_section, const char* pname)
+ {
+ return kv_unserialize(d, stg, hparent_section, pname);
+ }
+ template<class t_type, class t_storage>
+ static bool serialize_stl_container_pod_val_as_blob(t_type& d, t_storage& stg, typename t_storage::hsection hparent_section, const char* pname)
+ {
+ return epee::serialization::unserialize_stl_container_pod_val_as_blob(d, stg, hparent_section, pname);
+ }
+
+ template<class t_type, class t_storage>
+ static bool serialize_t_val_as_blob(t_type& d, t_storage& stg, typename t_storage::hsection hparent_section, const char* pname)
+ {
+ return epee::serialization::unserialize_t_val_as_blob(d, stg, hparent_section, pname);
+ }
+ };
+
+ template<class t_type, class t_storage>
+ bool kv_serialize(const t_type& d, t_storage& stg, typename t_storage::hsection hparent_section, const char* pname)
+ {
+ return kv_serialization_overloads_impl_is_base_serializable_types<boost::mpl::contains<base_serializable_types, typename std::remove_const<t_type>::type>::value>::kv_serialize(d, stg, hparent_section, pname);
+ }
+ //-------------------------------------------------------------------------------------------------------------------
+ template<class t_type, class t_storage>
+ bool kv_unserialize(t_type& d, t_storage& stg, typename t_storage::hsection hparent_section, const char* pname)
+ {
+ return kv_serialization_overloads_impl_is_base_serializable_types<boost::mpl::contains<base_serializable_types, typename std::remove_const<t_type>::type>::value>::kv_unserialize(d, stg, hparent_section, pname);
+ }
+ //-------------------------------------------------------------------------------------------------------------------
+ template<class t_type, class t_storage>
+ bool kv_serialize(const std::vector<t_type>& d, t_storage& stg, typename t_storage::hsection hparent_section, const char* pname)
+ {
+ return kv_serialization_overloads_impl_is_base_serializable_types<boost::mpl::contains<base_serializable_types, typename std::remove_const<t_type>::type>::value>::kv_serialize(d, stg, hparent_section, pname);
+ }
+ //-------------------------------------------------------------------------------------------------------------------
+ template<class t_type, class t_storage>
+ bool kv_unserialize(std::vector<t_type>& d, t_storage& stg, typename t_storage::hsection hparent_section, const char* pname)
+ {
+ return kv_serialization_overloads_impl_is_base_serializable_types<boost::mpl::contains<base_serializable_types, typename std::remove_const<t_type>::type>::value>::kv_unserialize(d, stg, hparent_section, pname);
+ }
+ //-------------------------------------------------------------------------------------------------------------------
+ template<class t_type, class t_storage>
+ bool kv_serialize(const std::list<t_type>& d, t_storage& stg, typename t_storage::hsection hparent_section, const char* pname)
+ {
+ return kv_serialization_overloads_impl_is_base_serializable_types<boost::mpl::contains<base_serializable_types, typename std::remove_const<t_type>::type>::value>::kv_serialize(d, stg, hparent_section, pname);
+ }
+ //-------------------------------------------------------------------------------------------------------------------
+ template<class t_type, class t_storage>
+ bool kv_unserialize(std::list<t_type>& d, t_storage& stg, typename t_storage::hsection hparent_section, const char* pname)
+ {
+ return kv_serialization_overloads_impl_is_base_serializable_types<boost::mpl::contains<base_serializable_types, typename std::remove_const<t_type>::type>::value>::kv_unserialize(d, stg, hparent_section, pname);
+ }
+ }
+} \ No newline at end of file