• 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__anon35cc1d6e0111::_serializer68       proc(std::ostream &os, const T &x) {
69          os.write(reinterpret_cast<const char *>(&x), sizeof(x));
70       }
71 
72       static void
proc__anon35cc1d6e0111::_serializer73       proc(std::istream &is, T &x) {
74          is.read(reinterpret_cast<char *>(&x), sizeof(x));
75       }
76 
77       static void
proc__anon35cc1d6e0111::_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__anon35cc1d6e0111::_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__anon35cc1d6e0111::_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__anon35cc1d6e0111::_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__anon35cc1d6e0111::_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__anon35cc1d6e0111::_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__anon35cc1d6e0111::_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__anon35cc1d6e0111::_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__anon35cc1d6e0111::_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__anon35cc1d6e0111::_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__anon35cc1d6e0111::_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__anon35cc1d6e0111::_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__anon35cc1d6e0111::_serializer191       proc(S &s, QT &x) {
192          _proc(s, x.name);
193          _proc(s, x.section);
194          _proc(s, x.offset);
195          _proc(s, x.args);
196       }
197    };
198 
199    /// (De)serialize a module.
200    template<>
201    struct _serializer<module> {
202       template<typename S, typename QT>
203       static void
proc__anon35cc1d6e0111::_serializer204       proc(S &s, QT &x) {
205          _proc(s, x.syms);
206          _proc(s, x.secs);
207       }
208    };
209 };
210 
211 namespace clover {
212    void
serialize(std::ostream & os) const213    module::serialize(std::ostream &os) const {
214       _proc(os, *this);
215    }
216 
217    module
deserialize(std::istream & is)218    module::deserialize(std::istream &is) {
219       return _proc<module>(is);
220    }
221 
222    module::size_t
size() const223    module::size() const {
224       size_t sz = 0;
225       _proc(sz, *this);
226       return sz;
227    }
228 }
229