module.cpp revision 7a9bbff7d641b82deae73e043fe1f02b7492993b
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
25#include "core/module.hpp"
26
27using namespace clover;
28
29namespace {
30   template<typename T, typename = void>
31   struct _serializer;
32
33   /// Serialize the specified object.
34   template<typename T>
35   void
36   _proc(compat::ostream &os, const T &x) {
37      _serializer<T>::proc(os, x);
38   }
39
40   /// Deserialize the specified object.
41   template<typename T>
42   void
43   _proc(compat::istream &is, T &x) {
44      _serializer<T>::proc(is, x);
45   }
46
47   template<typename T>
48   T
49   _proc(compat::istream &is) {
50      T x;
51      _serializer<T>::proc(is, x);
52      return x;
53   }
54
55   /// (De)serialize a scalar value.
56   template<typename T>
57   struct _serializer<T, typename std::enable_if<
58                            std::is_scalar<T>::value>::type> {
59      static void
60      proc(compat::ostream &os, const T &x) {
61         os.write(reinterpret_cast<const char *>(&x), sizeof(x));
62      }
63
64      static void
65      proc(compat::istream &is, T &x) {
66         is.read(reinterpret_cast<char *>(&x), sizeof(x));
67      }
68   };
69
70   /// (De)serialize a vector.
71   template<typename T>
72   struct _serializer<compat::vector<T>> {
73      static void
74      proc(compat::ostream &os, const compat::vector<T> &v) {
75         _proc<uint32_t>(os, v.size());
76
77         for (size_t i = 0; i < v.size(); i++)
78            _proc<T>(os, v[i]);
79      }
80
81      static void
82      proc(compat::istream &is, compat::vector<T> &v) {
83         v.reserve(_proc<uint32_t>(is));
84
85         for (size_t i = 0; i < v.size(); i++)
86            new(&v[i]) T(_proc<T>(is));
87      }
88   };
89
90   /// (De)serialize a module::section.
91   template<>
92   struct _serializer<module::section> {
93      template<typename S, typename QT>
94      static void
95      proc(S &s, QT &x) {
96         _proc(s, x.id);
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
108      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
119      proc(S &s, QT &x) {
120         _proc(s, x.name);
121         _proc(s, x.section);
122         _proc(s, x.offset);
123         _proc(s, x.args);
124      }
125   };
126
127   /// (De)serialize a module.
128   template<>
129   struct _serializer<module> {
130      template<typename S, typename QT>
131      static void
132      proc(S &s, QT &x) {
133         _proc(s, x.syms);
134         _proc(s, x.secs);
135      }
136   };
137};
138
139namespace clover {
140   void
141   module::serialize(compat::ostream &os) const {
142      _proc(os, *this);
143   }
144
145   module
146   module::deserialize(compat::istream &is) {
147      return _proc<module>(is);
148   }
149}
150