• 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/binary.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(binary::size_t & sz,const T & x)59    _proc(binary::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__anonbe5c190a0111::_serializer68       proc(std::ostream &os, const T &x) {
69          os.write(reinterpret_cast<const char *>(&x), sizeof(x));
70       }
71 
72       static void
proc__anonbe5c190a0111::_serializer73       proc(std::istream &is, T &x) {
74          is.read(reinterpret_cast<char *>(&x), sizeof(x));
75       }
76 
77       static void
proc__anonbe5c190a0111::_serializer78       proc(binary::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__anonbe5c190a0111::_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__anonbe5c190a0111::_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__anonbe5c190a0111::_serializer105       proc(binary::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__anonbe5c190a0111::_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__anonbe5c190a0111::_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__anonbe5c190a0111::_serializer132       proc(binary::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__anonbe5c190a0111::_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__anonbe5c190a0111::_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__anonbe5c190a0111::_serializer153       proc(binary::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 printf format
159    template<>
160    struct _serializer<binary::printf_info> {
161       template<typename S, typename QT>
162       static void
proc__anonbe5c190a0111::_serializer163       proc(S & s, QT &x) {
164          _proc(s, x.arg_sizes);
165          _proc(s, x.strings);
166       }
167    };
168 
169    /// (De)serialize a binary::section.
170    template<>
171    struct _serializer<binary::section> {
172       template<typename S, typename QT>
173       static void
proc__anonbe5c190a0111::_serializer174       proc(S &s, QT &x) {
175          _proc(s, x.id);
176          _proc(s, x.type);
177          _proc(s, x.size);
178          _proc(s, x.data);
179       }
180    };
181 
182    /// (De)serialize a binary::argument.
183    template<>
184    struct _serializer<binary::argument> {
185       template<typename S, typename QT>
186       static void
proc__anonbe5c190a0111::_serializer187       proc(S &s, QT &x) {
188          _proc(s, x.type);
189          _proc(s, x.size);
190          _proc(s, x.target_size);
191          _proc(s, x.target_align);
192          _proc(s, x.ext_type);
193          _proc(s, x.semantic);
194       }
195    };
196 
197    /// (De)serialize a binary::symbol.
198    template<>
199    struct _serializer<binary::symbol> {
200       template<typename S, typename QT>
201       static void
proc__anonbe5c190a0111::_serializer202       proc(S &s, QT &x) {
203          _proc(s, x.name);
204          _proc(s, x.attributes);
205          _proc(s, x.reqd_work_group_size);
206          _proc(s, x.section);
207          _proc(s, x.offset);
208          _proc(s, x.args);
209       }
210    };
211 
212    /// (De)serialize a binary.
213    template<>
214    struct _serializer<binary> {
215       template<typename S, typename QT>
216       static void
proc__anonbe5c190a0111::_serializer217       proc(S &s, QT &x) {
218          _proc(s, x.syms);
219          _proc(s, x.secs);
220          _proc(s, x.printf_infos);
221          _proc(s, x.printf_strings_in_buffer);
222       }
223    };
224 };
225 
226 namespace clover {
227    void
serialize(std::ostream & os) const228    binary::serialize(std::ostream &os) const {
229       _proc(os, *this);
230    }
231 
232    binary
deserialize(std::istream & is)233    binary::deserialize(std::istream &is) {
234       return _proc<binary>(is);
235    }
236 
237    binary::size_t
size() const238    binary::size() const {
239       size_t sz = 0;
240       _proc(sz, *this);
241       return sz;
242    }
243 }
244