• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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