/* vim: set sw=4 sts=4 et foldmethod=syntax : */ /* * Copyright (c) 2009, 2010 Ciaran McCreesh * * This file is part of the Paludis package manager. Paludis is free software; * you can redistribute it and/or modify it under the terms of the GNU General * Public License version 2, as published by the Free Software Foundation. * * Paludis is distributed in the hope that it will be useful, but WITHOUT ANY * WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS * FOR A PARTICULAR PURPOSE. See the GNU General Public License for more * details. * * You should have received a copy of the GNU General Public License along with * this program; if not, write to the Free Software Foundation, Inc., 59 Temple * Place, Suite 330, Boston, MA 02111-1307 USA */ #ifndef PALUDIS_GUARD_PALUDIS_SERIALISE_IMPL_HH #define PALUDIS_GUARD_PALUDIS_SERIALISE_IMPL_HH 1 #include #include #include #include #include #include #include #include #include #include #include #include #include #include namespace paludis { template < typename Flags_, typename Flag_> struct SerialiserFlagsInclude { static const bool value = std::is_same::value || std::is_same::value || std::is_same::value; }; template < bool is_container_, bool might_be_null_, typename T_> struct SerialiserObjectWriterHandler; template <> struct PALUDIS_VISIBLE SerialiserObjectWriterHandler { static void write(Serialiser & s, const bool t); }; template <> struct PALUDIS_VISIBLE SerialiserObjectWriterHandler { static void write(Serialiser & s, const int t); }; template <> struct PALUDIS_VISIBLE SerialiserObjectWriterHandler { static void write(Serialiser & s, const std::string & t); }; template <> struct PALUDIS_VISIBLE SerialiserObjectWriterHandler { static void write(Serialiser & s, const PackageID & t); }; template < typename T_> struct SerialiserObjectWriterHandler > { static void write(Serialiser & s, const Options & t) { std::stringstream ss; for (T_ i(static_cast(0)), i_end(t.highest_bit()) ; i != i_end ; i = static_cast(static_cast(i) + 1)) { if (! t[i]) continue; if (! ss.str().empty()) ss << ","; ss << i; } s.raw_stream() << "\""; s.escape_write(ss.str()); s.raw_stream() << "\";"; } }; template < typename T_> struct SerialiserObjectWriterHandler { static void write(Serialiser & s, const T_ & t) { SerialiserObjectWriterHandler::write(s, t); } }; template < typename T_> struct SerialiserObjectWriterHandler { static void write(Serialiser & s, const T_ & t) { t.serialise(s); } }; template < bool is_container_, typename T_> struct SerialiserObjectWriterHandler { static void write(Serialiser & s, const T_ & t) { if (t) SerialiserObjectWriterHandler::Type>::write( s, *t); else s.raw_stream() << "null;"; } }; template struct SerialiserConstIteratorType { typedef typename T_::ConstIterator Type; }; template struct SerialiserConstIteratorType > { typedef typename std::list::const_iterator Type; }; template struct SerialiserConstIteratorType > { typedef typename std::vector::const_iterator Type; }; template struct SerialiserConstIteratorType > { typedef typename std::unordered_set::const_iterator Type; }; template < typename T_> struct SerialiserObjectWriterHandler { static void write(Serialiser & s, const T_ & t) { s.raw_stream() << "c("; unsigned n(0); for (typename SerialiserConstIteratorType::Type i(t.begin()), i_end(t.end()) ; i != i_end ; ++i) { typedef typename std::iterator_traits< typename SerialiserConstIteratorType::Type>::value_type ItemValueType; typedef typename std::remove_reference::type ItemType; s.raw_stream() << ++n << "="; SerialiserObjectWriterHandler< false, ! std::is_same::Type>::value, ItemType >::write(s, *i); } s.raw_stream() << "count="; SerialiserObjectWriterHandler::write(s, n); s.raw_stream() << ");"; } }; template < typename Flags_, typename T_> SerialiserObjectWriter & SerialiserObjectWriter::member( const Flags_ &, const std::string & item_name, const T_ & t) { _serialiser.raw_stream() << item_name << "="; SerialiserObjectWriterHandler< SerialiserFlagsInclude::value, SerialiserFlagsInclude::value, T_ >::write(_serialiser, t); return *this; } template struct DeserialisatorHandler; template <> struct DeserialisatorHandler { static bool handle(Deserialisation & v) { return destringify(v.string_value()); } }; template <> struct DeserialisatorHandler { static int handle(Deserialisation & v) { return destringify(v.string_value()); } }; template <> struct DeserialisatorHandler { static std::string handle(Deserialisation & v) { return v.string_value(); } }; template <> struct PALUDIS_VISIBLE DeserialisatorHandler > { static std::shared_ptr handle(Deserialisation & v); }; template struct PALUDIS_VISIBLE DeserialisatorHandler > { static std::shared_ptr handle(Deserialisation & v) { if (v.null()) return make_null_shared_ptr(); else return T_::deserialise(v); } }; template struct DeserialisatorHandler > { static Options handle(Deserialisation & v) { Options result; std::list tokens; tokenise(v.string_value(), ",", "", std::back_inserter(tokens)); for (std::list::const_iterator t(tokens.begin()), t_end(tokens.end()) ; t != t_end ; ++t) result += destringify(*t); return result; } }; template struct DeserialisatorHandler { static T_ handle(Deserialisation & v) { return T_::deserialise(v); } }; template T_ Deserialisator::member(const std::string & key_name) { return DeserialisatorHandler::handle(*find_remove_member(key_name)); } template std::shared_ptr deserialise( const Environment * const env, const std::string & str, const std::string & class_name) { Deserialiser d(env, str); Deserialisation dd(class_name, d); return T_::deserialise(dd); } } #endif