module.cpp revision 4a39e5073a7d0cd8243c6f963567a9945265490c
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 /// Calculate the size of the specified object. 56 template<typename T> 57 void 58 _proc(module::size_t &sz, const T &x) { 59 _serializer<T>::proc(sz, x); 60 } 61 62 /// (De)serialize a scalar value. 63 template<typename T> 64 struct _serializer<T, typename std::enable_if< 65 std::is_scalar<T>::value>::type> { 66 static void 67 proc(compat::ostream &os, const T &x) { 68 os.write(reinterpret_cast<const char *>(&x), sizeof(x)); 69 } 70 71 static void 72 proc(compat::istream &is, T &x) { 73 is.read(reinterpret_cast<char *>(&x), sizeof(x)); 74 } 75 76 static void 77 proc(module::size_t &sz, const T &x) { 78 sz += sizeof(x); 79 } 80 }; 81 82 /// (De)serialize a vector. 83 template<typename T> 84 struct _serializer<compat::vector<T>, 85 typename std::enable_if< 86 !std::is_scalar<T>::value>::type> { 87 static void 88 proc(compat::ostream &os, const compat::vector<T> &v) { 89 _proc<uint32_t>(os, v.size()); 90 91 for (size_t i = 0; i < v.size(); i++) 92 _proc<T>(os, v[i]); 93 } 94 95 static void 96 proc(compat::istream &is, compat::vector<T> &v) { 97 v.reserve(_proc<uint32_t>(is)); 98 99 for (size_t i = 0; i < v.size(); i++) 100 new(&v[i]) T(_proc<T>(is)); 101 } 102 103 static void 104 proc(module::size_t &sz, const compat::vector<T> &v) { 105 sz += sizeof(uint32_t); 106 107 for (size_t i = 0; i < v.size(); i++) 108 _proc<T>(sz, v[i]); 109 } 110 }; 111 112 template<typename T> 113 struct _serializer<compat::vector<T>, 114 typename std::enable_if< 115 std::is_scalar<T>::value>::type> { 116 static void 117 proc(compat::ostream &os, const compat::vector<T> &v) { 118 _proc<uint32_t>(os, v.size()); 119 os.write(reinterpret_cast<const char *>(v.begin()), 120 v.size() * sizeof(T)); 121 } 122 123 static void 124 proc(compat::istream &is, compat::vector<T> &v) { 125 v.reserve(_proc<uint32_t>(is)); 126 is.read(reinterpret_cast<char *>(v.begin()), 127 v.size() * sizeof(T)); 128 } 129 130 static void 131 proc(module::size_t &sz, const compat::vector<T> &v) { 132 sz += sizeof(uint32_t) + sizeof(T) * v.size(); 133 } 134 }; 135 136 /// (De)serialize a module::section. 137 template<> 138 struct _serializer<module::section> { 139 template<typename S, typename QT> 140 static void 141 proc(S &s, QT &x) { 142 _proc(s, x.id); 143 _proc(s, x.type); 144 _proc(s, x.size); 145 _proc(s, x.data); 146 } 147 }; 148 149 /// (De)serialize a module::argument. 150 template<> 151 struct _serializer<module::argument> { 152 template<typename S, typename QT> 153 static void 154 proc(S &s, QT &x) { 155 _proc(s, x.type); 156 _proc(s, x.size); 157 _proc(s, x.target_size); 158 _proc(s, x.target_align); 159 _proc(s, x.ext_type); 160 } 161 }; 162 163 /// (De)serialize a module::symbol. 164 template<> 165 struct _serializer<module::symbol> { 166 template<typename S, typename QT> 167 static void 168 proc(S &s, QT &x) { 169 _proc(s, x.name); 170 _proc(s, x.section); 171 _proc(s, x.offset); 172 _proc(s, x.args); 173 } 174 }; 175 176 /// (De)serialize a module. 177 template<> 178 struct _serializer<module> { 179 template<typename S, typename QT> 180 static void 181 proc(S &s, QT &x) { 182 _proc(s, x.syms); 183 _proc(s, x.secs); 184 } 185 }; 186}; 187 188namespace clover { 189 void 190 module::serialize(compat::ostream &os) const { 191 _proc(os, *this); 192 } 193 194 module 195 module::deserialize(compat::istream &is) { 196 return _proc<module>(is); 197 } 198 199 module::size_t 200 module::size() const { 201 size_t sz = 0; 202 _proc(sz, *this); 203 return sz; 204 } 205} 206