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 #include <iostream> 25 26 #include "core/module.hpp" 27 28 using namespace clover; 29 30 namespace { 31 template<typename T, typename = void> 32 struct _serializer; 33 34 /// Serialize the specified object. 35 template<typename T> 36 void _proc(std::ostream & os,const T & x)37 _proc(std::ostream &os, const T &x) { 38 _serializer<T>::proc(os, x); 39 } 40 41 /// Deserialize the specified object. 42 template<typename T> 43 void _proc(std::istream & is,T & x)44 _proc(std::istream &is, T &x) { 45 _serializer<T>::proc(is, x); 46 } 47 48 template<typename T> 49 T _proc(std::istream & is)50 _proc(std::istream &is) { 51 T x; 52 _serializer<T>::proc(is, x); 53 return x; 54 } 55 56 /// Calculate the size of the specified object. 57 template<typename T> 58 void _proc(module::size_t & sz,const T & x)59 _proc(module::size_t &sz, const T &x) { 60 _serializer<T>::proc(sz, x); 61 } 62 63 /// (De)serialize a scalar value. 64 template<typename T> 65 struct _serializer<T, typename std::enable_if< 66 std::is_scalar<T>::value>::type> { 67 static void proc__anon43458fc40111::_serializer68 proc(std::ostream &os, const T &x) { 69 os.write(reinterpret_cast<const char *>(&x), sizeof(x)); 70 } 71 72 static void proc__anon43458fc40111::_serializer73 proc(std::istream &is, T &x) { 74 is.read(reinterpret_cast<char *>(&x), sizeof(x)); 75 } 76 77 static void proc__anon43458fc40111::_serializer78 proc(module::size_t &sz, const T &x) { 79 sz += sizeof(x); 80 } 81 }; 82 83 /// (De)serialize a vector. 84 template<typename T> 85 struct _serializer<std::vector<T>, 86 typename std::enable_if< 87 !std::is_scalar<T>::value>::type> { 88 static void proc__anon43458fc40111::_serializer89 proc(std::ostream &os, const std::vector<T> &v) { 90 _proc<uint32_t>(os, v.size()); 91 92 for (size_t i = 0; i < v.size(); i++) 93 _proc<T>(os, v[i]); 94 } 95 96 static void proc__anon43458fc40111::_serializer97 proc(std::istream &is, std::vector<T> &v) { 98 v.resize(_proc<uint32_t>(is)); 99 100 for (size_t i = 0; i < v.size(); i++) 101 new(&v[i]) T(_proc<T>(is)); 102 } 103 104 static void proc__anon43458fc40111::_serializer105 proc(module::size_t &sz, const std::vector<T> &v) { 106 sz += sizeof(uint32_t); 107 108 for (size_t i = 0; i < v.size(); i++) 109 _proc<T>(sz, v[i]); 110 } 111 }; 112 113 template<typename T> 114 struct _serializer<std::vector<T>, 115 typename std::enable_if< 116 std::is_scalar<T>::value>::type> { 117 static void proc__anon43458fc40111::_serializer118 proc(std::ostream &os, const std::vector<T> &v) { 119 _proc<uint32_t>(os, v.size()); 120 os.write(reinterpret_cast<const char *>(&v[0]), 121 v.size() * sizeof(T)); 122 } 123 124 static void proc__anon43458fc40111::_serializer125 proc(std::istream &is, std::vector<T> &v) { 126 v.resize(_proc<uint32_t>(is)); 127 is.read(reinterpret_cast<char *>(&v[0]), 128 v.size() * sizeof(T)); 129 } 130 131 static void proc__anon43458fc40111::_serializer132 proc(module::size_t &sz, const std::vector<T> &v) { 133 sz += sizeof(uint32_t) + sizeof(T) * v.size(); 134 } 135 }; 136 137 /// (De)serialize a string. 138 template<> 139 struct _serializer<std::string> { 140 static void proc__anon43458fc40111::_serializer141 proc(std::ostream &os, const std::string &s) { 142 _proc<uint32_t>(os, s.size()); 143 os.write(&s[0], s.size() * sizeof(std::string::value_type)); 144 } 145 146 static void proc__anon43458fc40111::_serializer147 proc(std::istream &is, std::string &s) { 148 s.resize(_proc<uint32_t>(is)); 149 is.read(&s[0], s.size() * sizeof(std::string::value_type)); 150 } 151 152 static void proc__anon43458fc40111::_serializer153 proc(module::size_t &sz, const std::string &s) { 154 sz += sizeof(uint32_t) + sizeof(std::string::value_type) * s.size(); 155 } 156 }; 157 158 /// (De)serialize a module::section. 159 template<> 160 struct _serializer<module::section> { 161 template<typename S, typename QT> 162 static void proc__anon43458fc40111::_serializer163 proc(S &s, QT &x) { 164 _proc(s, x.id); 165 _proc(s, x.type); 166 _proc(s, x.size); 167 _proc(s, x.data); 168 } 169 }; 170 171 /// (De)serialize a module::argument. 172 template<> 173 struct _serializer<module::argument> { 174 template<typename S, typename QT> 175 static void proc__anon43458fc40111::_serializer176 proc(S &s, QT &x) { 177 _proc(s, x.type); 178 _proc(s, x.size); 179 _proc(s, x.target_size); 180 _proc(s, x.target_align); 181 _proc(s, x.ext_type); 182 _proc(s, x.semantic); 183 } 184 }; 185 186 /// (De)serialize a module::symbol. 187 template<> 188 struct _serializer<module::symbol> { 189 template<typename S, typename QT> 190 static void proc__anon43458fc40111::_serializer191 proc(S &s, QT &x) { 192 _proc(s, x.name); 193 _proc(s, x.attributes); 194 _proc(s, x.reqd_work_group_size); 195 _proc(s, x.section); 196 _proc(s, x.offset); 197 _proc(s, x.args); 198 } 199 }; 200 201 /// (De)serialize a module. 202 template<> 203 struct _serializer<module> { 204 template<typename S, typename QT> 205 static void proc__anon43458fc40111::_serializer206 proc(S &s, QT &x) { 207 _proc(s, x.syms); 208 _proc(s, x.secs); 209 } 210 }; 211 }; 212 213 namespace clover { 214 void serialize(std::ostream & os) const215 module::serialize(std::ostream &os) const { 216 _proc(os, *this); 217 } 218 219 module deserialize(std::istream & is)220 module::deserialize(std::istream &is) { 221 return _proc<module>(is); 222 } 223 224 module::size_t size() const225 module::size() const { 226 size_t sz = 0; 227 _proc(sz, *this); 228 return sz; 229 } 230 } 231