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