1c6db1b3396384186aab5b685fe1fd540e17b3a62Francisco Jerez// 2c6db1b3396384186aab5b685fe1fd540e17b3a62Francisco Jerez// Copyright 2012 Francisco Jerez 3c6db1b3396384186aab5b685fe1fd540e17b3a62Francisco Jerez// 4c6db1b3396384186aab5b685fe1fd540e17b3a62Francisco Jerez// Permission is hereby granted, free of charge, to any person obtaining a 5c6db1b3396384186aab5b685fe1fd540e17b3a62Francisco Jerez// copy of this software and associated documentation files (the "Software"), 6c6db1b3396384186aab5b685fe1fd540e17b3a62Francisco Jerez// to deal in the Software without restriction, including without limitation 7c6db1b3396384186aab5b685fe1fd540e17b3a62Francisco Jerez// the rights to use, copy, modify, merge, publish, distribute, sublicense, 8c6db1b3396384186aab5b685fe1fd540e17b3a62Francisco Jerez// and/or sell copies of the Software, and to permit persons to whom the 9c6db1b3396384186aab5b685fe1fd540e17b3a62Francisco Jerez// Software is furnished to do so, subject to the following conditions: 10c6db1b3396384186aab5b685fe1fd540e17b3a62Francisco Jerez// 11c6db1b3396384186aab5b685fe1fd540e17b3a62Francisco Jerez// The above copyright notice and this permission notice shall be included in 12c6db1b3396384186aab5b685fe1fd540e17b3a62Francisco Jerez// all copies or substantial portions of the Software. 13c6db1b3396384186aab5b685fe1fd540e17b3a62Francisco Jerez// 14c6db1b3396384186aab5b685fe1fd540e17b3a62Francisco Jerez// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 15c6db1b3396384186aab5b685fe1fd540e17b3a62Francisco Jerez// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 16c6db1b3396384186aab5b685fe1fd540e17b3a62Francisco Jerez// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL 17c6db1b3396384186aab5b685fe1fd540e17b3a62Francisco Jerez// THE AUTHORS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, 18c6db1b3396384186aab5b685fe1fd540e17b3a62Francisco Jerez// WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF 19c6db1b3396384186aab5b685fe1fd540e17b3a62Francisco Jerez// OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 20c6db1b3396384186aab5b685fe1fd540e17b3a62Francisco Jerez// SOFTWARE. 21c6db1b3396384186aab5b685fe1fd540e17b3a62Francisco Jerez// 22c6db1b3396384186aab5b685fe1fd540e17b3a62Francisco Jerez 23c6db1b3396384186aab5b685fe1fd540e17b3a62Francisco Jerez#include <type_traits> 24c6db1b3396384186aab5b685fe1fd540e17b3a62Francisco Jerez#include <algorithm> 25c6db1b3396384186aab5b685fe1fd540e17b3a62Francisco Jerez 26c6db1b3396384186aab5b685fe1fd540e17b3a62Francisco Jerez#include "core/module.hpp" 27c6db1b3396384186aab5b685fe1fd540e17b3a62Francisco Jerez 28c6db1b3396384186aab5b685fe1fd540e17b3a62Francisco Jerezusing namespace clover; 29c6db1b3396384186aab5b685fe1fd540e17b3a62Francisco Jerez 30c6db1b3396384186aab5b685fe1fd540e17b3a62Francisco Jereznamespace { 31c6db1b3396384186aab5b685fe1fd540e17b3a62Francisco Jerez template<typename T, typename = void> 32c6db1b3396384186aab5b685fe1fd540e17b3a62Francisco Jerez struct __serializer; 33c6db1b3396384186aab5b685fe1fd540e17b3a62Francisco Jerez 34c6db1b3396384186aab5b685fe1fd540e17b3a62Francisco Jerez /// Serialize the specified object. 35c6db1b3396384186aab5b685fe1fd540e17b3a62Francisco Jerez template<typename T> 36c6db1b3396384186aab5b685fe1fd540e17b3a62Francisco Jerez void 37c6db1b3396384186aab5b685fe1fd540e17b3a62Francisco Jerez __proc(compat::ostream &os, const T &x) { 38c6db1b3396384186aab5b685fe1fd540e17b3a62Francisco Jerez __serializer<T>::proc(os, x); 39c6db1b3396384186aab5b685fe1fd540e17b3a62Francisco Jerez } 40c6db1b3396384186aab5b685fe1fd540e17b3a62Francisco Jerez 41c6db1b3396384186aab5b685fe1fd540e17b3a62Francisco Jerez /// Deserialize the specified object. 42c6db1b3396384186aab5b685fe1fd540e17b3a62Francisco Jerez template<typename T> 43c6db1b3396384186aab5b685fe1fd540e17b3a62Francisco Jerez void 44c6db1b3396384186aab5b685fe1fd540e17b3a62Francisco Jerez __proc(compat::istream &is, T &x) { 45c6db1b3396384186aab5b685fe1fd540e17b3a62Francisco Jerez __serializer<T>::proc(is, x); 46c6db1b3396384186aab5b685fe1fd540e17b3a62Francisco Jerez } 47c6db1b3396384186aab5b685fe1fd540e17b3a62Francisco Jerez 48c6db1b3396384186aab5b685fe1fd540e17b3a62Francisco Jerez template<typename T> 49c6db1b3396384186aab5b685fe1fd540e17b3a62Francisco Jerez T 50c6db1b3396384186aab5b685fe1fd540e17b3a62Francisco Jerez __proc(compat::istream &is) { 51c6db1b3396384186aab5b685fe1fd540e17b3a62Francisco Jerez T x; 52c6db1b3396384186aab5b685fe1fd540e17b3a62Francisco Jerez __serializer<T>::proc(is, x); 53c6db1b3396384186aab5b685fe1fd540e17b3a62Francisco Jerez return x; 54c6db1b3396384186aab5b685fe1fd540e17b3a62Francisco Jerez } 55c6db1b3396384186aab5b685fe1fd540e17b3a62Francisco Jerez 56c6db1b3396384186aab5b685fe1fd540e17b3a62Francisco Jerez /// (De)serialize a scalar value. 57c6db1b3396384186aab5b685fe1fd540e17b3a62Francisco Jerez template<typename T> 58c6db1b3396384186aab5b685fe1fd540e17b3a62Francisco Jerez struct __serializer<T, typename std::enable_if< 59c6db1b3396384186aab5b685fe1fd540e17b3a62Francisco Jerez std::is_scalar<T>::value>::type> { 60c6db1b3396384186aab5b685fe1fd540e17b3a62Francisco Jerez static void 61c6db1b3396384186aab5b685fe1fd540e17b3a62Francisco Jerez proc(compat::ostream &os, const T &x) { 62c6db1b3396384186aab5b685fe1fd540e17b3a62Francisco Jerez os.write(reinterpret_cast<const char *>(&x), sizeof(x)); 63c6db1b3396384186aab5b685fe1fd540e17b3a62Francisco Jerez } 64c6db1b3396384186aab5b685fe1fd540e17b3a62Francisco Jerez 65c6db1b3396384186aab5b685fe1fd540e17b3a62Francisco Jerez static void 66c6db1b3396384186aab5b685fe1fd540e17b3a62Francisco Jerez proc(compat::istream &is, T &x) { 67c6db1b3396384186aab5b685fe1fd540e17b3a62Francisco Jerez is.read(reinterpret_cast<char *>(&x), sizeof(x)); 68c6db1b3396384186aab5b685fe1fd540e17b3a62Francisco Jerez } 69c6db1b3396384186aab5b685fe1fd540e17b3a62Francisco Jerez }; 70c6db1b3396384186aab5b685fe1fd540e17b3a62Francisco Jerez 71c6db1b3396384186aab5b685fe1fd540e17b3a62Francisco Jerez /// (De)serialize a vector. 72c6db1b3396384186aab5b685fe1fd540e17b3a62Francisco Jerez template<typename T> 73c6db1b3396384186aab5b685fe1fd540e17b3a62Francisco Jerez struct __serializer<compat::vector<T>> { 74c6db1b3396384186aab5b685fe1fd540e17b3a62Francisco Jerez static void 75c6db1b3396384186aab5b685fe1fd540e17b3a62Francisco Jerez proc(compat::ostream &os, const compat::vector<T> &v) { 76c6db1b3396384186aab5b685fe1fd540e17b3a62Francisco Jerez __proc<uint32_t>(os, v.size()); 77c6db1b3396384186aab5b685fe1fd540e17b3a62Francisco Jerez 78c6db1b3396384186aab5b685fe1fd540e17b3a62Francisco Jerez for (size_t i = 0; i < v.size(); i++) 79c6db1b3396384186aab5b685fe1fd540e17b3a62Francisco Jerez __proc<T>(os, v[i]); 80c6db1b3396384186aab5b685fe1fd540e17b3a62Francisco Jerez } 81c6db1b3396384186aab5b685fe1fd540e17b3a62Francisco Jerez 82c6db1b3396384186aab5b685fe1fd540e17b3a62Francisco Jerez static void 83c6db1b3396384186aab5b685fe1fd540e17b3a62Francisco Jerez proc(compat::istream &is, compat::vector<T> &v) { 84c6db1b3396384186aab5b685fe1fd540e17b3a62Francisco Jerez v.reserve(__proc<uint32_t>(is)); 85c6db1b3396384186aab5b685fe1fd540e17b3a62Francisco Jerez 86c6db1b3396384186aab5b685fe1fd540e17b3a62Francisco Jerez for (size_t i = 0; i < v.size(); i++) 87c6db1b3396384186aab5b685fe1fd540e17b3a62Francisco Jerez new(&v[i]) T(__proc<T>(is)); 88c6db1b3396384186aab5b685fe1fd540e17b3a62Francisco Jerez } 89c6db1b3396384186aab5b685fe1fd540e17b3a62Francisco Jerez }; 90c6db1b3396384186aab5b685fe1fd540e17b3a62Francisco Jerez 91c6db1b3396384186aab5b685fe1fd540e17b3a62Francisco Jerez /// (De)serialize a module::section. 92c6db1b3396384186aab5b685fe1fd540e17b3a62Francisco Jerez template<> 93c6db1b3396384186aab5b685fe1fd540e17b3a62Francisco Jerez struct __serializer<module::section> { 94c6db1b3396384186aab5b685fe1fd540e17b3a62Francisco Jerez template<typename S, typename QT> 95c6db1b3396384186aab5b685fe1fd540e17b3a62Francisco Jerez static void 96c6db1b3396384186aab5b685fe1fd540e17b3a62Francisco Jerez proc(S &s, QT &x) { 97c6db1b3396384186aab5b685fe1fd540e17b3a62Francisco Jerez __proc(s, x.type); 98c6db1b3396384186aab5b685fe1fd540e17b3a62Francisco Jerez __proc(s, x.size); 99c6db1b3396384186aab5b685fe1fd540e17b3a62Francisco Jerez __proc(s, x.data); 100c6db1b3396384186aab5b685fe1fd540e17b3a62Francisco Jerez } 101c6db1b3396384186aab5b685fe1fd540e17b3a62Francisco Jerez }; 102c6db1b3396384186aab5b685fe1fd540e17b3a62Francisco Jerez 103c6db1b3396384186aab5b685fe1fd540e17b3a62Francisco Jerez /// (De)serialize a module::argument. 104c6db1b3396384186aab5b685fe1fd540e17b3a62Francisco Jerez template<> 105c6db1b3396384186aab5b685fe1fd540e17b3a62Francisco Jerez struct __serializer<module::argument> { 106c6db1b3396384186aab5b685fe1fd540e17b3a62Francisco Jerez template<typename S, typename QT> 107c6db1b3396384186aab5b685fe1fd540e17b3a62Francisco Jerez static void 108c6db1b3396384186aab5b685fe1fd540e17b3a62Francisco Jerez proc(S &s, QT &x) { 109c6db1b3396384186aab5b685fe1fd540e17b3a62Francisco Jerez __proc(s, x.type); 110c6db1b3396384186aab5b685fe1fd540e17b3a62Francisco Jerez __proc(s, x.size); 111c6db1b3396384186aab5b685fe1fd540e17b3a62Francisco Jerez } 112c6db1b3396384186aab5b685fe1fd540e17b3a62Francisco Jerez }; 113c6db1b3396384186aab5b685fe1fd540e17b3a62Francisco Jerez 114c6db1b3396384186aab5b685fe1fd540e17b3a62Francisco Jerez /// (De)serialize a module::symbol. 115c6db1b3396384186aab5b685fe1fd540e17b3a62Francisco Jerez template<> 116c6db1b3396384186aab5b685fe1fd540e17b3a62Francisco Jerez struct __serializer<module::symbol> { 117c6db1b3396384186aab5b685fe1fd540e17b3a62Francisco Jerez template<typename S, typename QT> 118c6db1b3396384186aab5b685fe1fd540e17b3a62Francisco Jerez static void 119c6db1b3396384186aab5b685fe1fd540e17b3a62Francisco Jerez proc(S &s, QT &x) { 120c6db1b3396384186aab5b685fe1fd540e17b3a62Francisco Jerez __proc(s, x.section); 121c6db1b3396384186aab5b685fe1fd540e17b3a62Francisco Jerez __proc(s, x.offset); 122c6db1b3396384186aab5b685fe1fd540e17b3a62Francisco Jerez __proc(s, x.args); 123c6db1b3396384186aab5b685fe1fd540e17b3a62Francisco Jerez } 124c6db1b3396384186aab5b685fe1fd540e17b3a62Francisco Jerez }; 125c6db1b3396384186aab5b685fe1fd540e17b3a62Francisco Jerez 126c6db1b3396384186aab5b685fe1fd540e17b3a62Francisco Jerez /// (De)serialize a module. 127c6db1b3396384186aab5b685fe1fd540e17b3a62Francisco Jerez template<> 128c6db1b3396384186aab5b685fe1fd540e17b3a62Francisco Jerez struct __serializer<module> { 129c6db1b3396384186aab5b685fe1fd540e17b3a62Francisco Jerez template<typename S, typename QT> 130c6db1b3396384186aab5b685fe1fd540e17b3a62Francisco Jerez static void 131c6db1b3396384186aab5b685fe1fd540e17b3a62Francisco Jerez proc(S &s, QT &x) { 132c6db1b3396384186aab5b685fe1fd540e17b3a62Francisco Jerez __proc(s, x.syms); 133c6db1b3396384186aab5b685fe1fd540e17b3a62Francisco Jerez __proc(s, x.secs); 134c6db1b3396384186aab5b685fe1fd540e17b3a62Francisco Jerez } 135c6db1b3396384186aab5b685fe1fd540e17b3a62Francisco Jerez }; 136c6db1b3396384186aab5b685fe1fd540e17b3a62Francisco Jerez}; 137c6db1b3396384186aab5b685fe1fd540e17b3a62Francisco Jerez 138c6db1b3396384186aab5b685fe1fd540e17b3a62Francisco Jereznamespace clover { 139c6db1b3396384186aab5b685fe1fd540e17b3a62Francisco Jerez void 140c6db1b3396384186aab5b685fe1fd540e17b3a62Francisco Jerez module::serialize(compat::ostream &os) const { 141c6db1b3396384186aab5b685fe1fd540e17b3a62Francisco Jerez __proc(os, *this); 142c6db1b3396384186aab5b685fe1fd540e17b3a62Francisco Jerez } 143c6db1b3396384186aab5b685fe1fd540e17b3a62Francisco Jerez 144c6db1b3396384186aab5b685fe1fd540e17b3a62Francisco Jerez module 145c6db1b3396384186aab5b685fe1fd540e17b3a62Francisco Jerez module::deserialize(compat::istream &is) { 146c6db1b3396384186aab5b685fe1fd540e17b3a62Francisco Jerez return __proc<module>(is); 147c6db1b3396384186aab5b685fe1fd540e17b3a62Francisco Jerez } 148c6db1b3396384186aab5b685fe1fd540e17b3a62Francisco Jerez 149c6db1b3396384186aab5b685fe1fd540e17b3a62Francisco Jerez const module::symbol & 150c6db1b3396384186aab5b685fe1fd540e17b3a62Francisco Jerez module::sym(compat::string name) const { 151c6db1b3396384186aab5b685fe1fd540e17b3a62Francisco Jerez auto it = std::find_if(syms.begin(), syms.end(), [&](const symbol &x) { 152c6db1b3396384186aab5b685fe1fd540e17b3a62Francisco Jerez return compat::string(x.name) == name; 153c6db1b3396384186aab5b685fe1fd540e17b3a62Francisco Jerez }); 154c6db1b3396384186aab5b685fe1fd540e17b3a62Francisco Jerez 155c6db1b3396384186aab5b685fe1fd540e17b3a62Francisco Jerez if (it == syms.end()) 156c6db1b3396384186aab5b685fe1fd540e17b3a62Francisco Jerez throw noent_error(); 157c6db1b3396384186aab5b685fe1fd540e17b3a62Francisco Jerez 158c6db1b3396384186aab5b685fe1fd540e17b3a62Francisco Jerez return *it; 159c6db1b3396384186aab5b685fe1fd540e17b3a62Francisco Jerez } 160c6db1b3396384186aab5b685fe1fd540e17b3a62Francisco Jerez 161c6db1b3396384186aab5b685fe1fd540e17b3a62Francisco Jerez const module::section & 162c6db1b3396384186aab5b685fe1fd540e17b3a62Francisco Jerez module::sec(typename section::type type) const { 163c6db1b3396384186aab5b685fe1fd540e17b3a62Francisco Jerez auto it = std::find_if(secs.begin(), secs.end(), [&](const section &x) { 164c6db1b3396384186aab5b685fe1fd540e17b3a62Francisco Jerez return x.type == type; 165c6db1b3396384186aab5b685fe1fd540e17b3a62Francisco Jerez }); 166c6db1b3396384186aab5b685fe1fd540e17b3a62Francisco Jerez 167c6db1b3396384186aab5b685fe1fd540e17b3a62Francisco Jerez if (it == secs.end()) 168c6db1b3396384186aab5b685fe1fd540e17b3a62Francisco Jerez throw noent_error(); 169c6db1b3396384186aab5b685fe1fd540e17b3a62Francisco Jerez 170c6db1b3396384186aab5b685fe1fd540e17b3a62Francisco Jerez return *it; 171c6db1b3396384186aab5b685fe1fd540e17b3a62Francisco Jerez } 172c6db1b3396384186aab5b685fe1fd540e17b3a62Francisco Jerez} 173