• 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 BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
18 // WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF
19 // OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
20 // SOFTWARE.
21 //
22 
23 #include <type_traits>
24 #include <algorithm>
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(compat::ostream & os,const T & x)37    __proc(compat::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(compat::istream & is,T & x)44    __proc(compat::istream &is, T &x) {
45       __serializer<T>::proc(is, x);
46    }
47 
48    template<typename T>
49    T
__proc(compat::istream & is)50    __proc(compat::istream &is) {
51       T x;
52       __serializer<T>::proc(is, x);
53       return x;
54    }
55 
56    /// (De)serialize a scalar value.
57    template<typename T>
58    struct __serializer<T, typename std::enable_if<
59                              std::is_scalar<T>::value>::type> {
60       static void
proc__anond7e2df640111::__serializer61       proc(compat::ostream &os, const T &x) {
62          os.write(reinterpret_cast<const char *>(&x), sizeof(x));
63       }
64 
65       static void
proc__anond7e2df640111::__serializer66       proc(compat::istream &is, T &x) {
67          is.read(reinterpret_cast<char *>(&x), sizeof(x));
68       }
69    };
70 
71    /// (De)serialize a vector.
72    template<typename T>
73    struct __serializer<compat::vector<T>> {
74       static void
proc__anond7e2df640111::__serializer75       proc(compat::ostream &os, const compat::vector<T> &v) {
76          __proc<uint32_t>(os, v.size());
77 
78          for (size_t i = 0; i < v.size(); i++)
79             __proc<T>(os, v[i]);
80       }
81 
82       static void
proc__anond7e2df640111::__serializer83       proc(compat::istream &is, compat::vector<T> &v) {
84          v.reserve(__proc<uint32_t>(is));
85 
86          for (size_t i = 0; i < v.size(); i++)
87             new(&v[i]) T(__proc<T>(is));
88       }
89    };
90 
91    /// (De)serialize a module::section.
92    template<>
93    struct __serializer<module::section> {
94       template<typename S, typename QT>
95       static void
proc__anond7e2df640111::__serializer96       proc(S &s, QT &x) {
97          __proc(s, x.type);
98          __proc(s, x.size);
99          __proc(s, x.data);
100       }
101    };
102 
103    /// (De)serialize a module::argument.
104    template<>
105    struct __serializer<module::argument> {
106       template<typename S, typename QT>
107       static void
proc__anond7e2df640111::__serializer108       proc(S &s, QT &x) {
109          __proc(s, x.type);
110          __proc(s, x.size);
111       }
112    };
113 
114    /// (De)serialize a module::symbol.
115    template<>
116    struct __serializer<module::symbol> {
117       template<typename S, typename QT>
118       static void
proc__anond7e2df640111::__serializer119       proc(S &s, QT &x) {
120          __proc(s, x.section);
121          __proc(s, x.offset);
122          __proc(s, x.args);
123       }
124    };
125 
126    /// (De)serialize a module.
127    template<>
128    struct __serializer<module> {
129       template<typename S, typename QT>
130       static void
proc__anond7e2df640111::__serializer131       proc(S &s, QT &x) {
132          __proc(s, x.syms);
133          __proc(s, x.secs);
134       }
135    };
136 };
137 
138 namespace clover {
139    void
serialize(compat::ostream & os) const140    module::serialize(compat::ostream &os) const {
141       __proc(os, *this);
142    }
143 
144    module
deserialize(compat::istream & is)145    module::deserialize(compat::istream &is) {
146       return __proc<module>(is);
147    }
148 
149    const module::symbol &
sym(compat::string name) const150    module::sym(compat::string name) const {
151       auto it = std::find_if(syms.begin(), syms.end(), [&](const symbol &x) {
152             return compat::string(x.name) == name;
153          });
154 
155       if (it == syms.end())
156          throw noent_error();
157 
158       return *it;
159    }
160 
161    const module::section &
sec(typename section::type type) const162    module::sec(typename section::type type) const {
163       auto it = std::find_if(secs.begin(), secs.end(), [&](const section &x) {
164             return x.type == type;
165          });
166 
167       if (it == secs.end())
168          throw noent_error();
169 
170       return *it;
171    }
172 }
173