2 // Copyright 2012 Francisco Jerez
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:
11 // The above copyright notice and this permission notice shall be included in
12 // all copies or substantial portions of the Software.
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.
23 #include <type_traits>
25 #include "core/module.hpp"
27 using namespace clover
;
30 template<typename T
, typename
= void>
33 /// Serialize the specified object.
36 _proc(compat::ostream
&os
, const T
&x
) {
37 _serializer
<T
>::proc(os
, x
);
40 /// Deserialize the specified object.
43 _proc(compat::istream
&is
, T
&x
) {
44 _serializer
<T
>::proc(is
, x
);
49 _proc(compat::istream
&is
) {
51 _serializer
<T
>::proc(is
, x
);
55 /// Calculate the size of the specified object.
58 _proc(module::size_t &sz
, const T
&x
) {
59 _serializer
<T
>::proc(sz
, x
);
62 /// (De)serialize a scalar value.
64 struct _serializer
<T
, typename
std::enable_if
<
65 std::is_scalar
<T
>::value
>::type
> {
67 proc(compat::ostream
&os
, const T
&x
) {
68 os
.write(reinterpret_cast<const char *>(&x
), sizeof(x
));
72 proc(compat::istream
&is
, T
&x
) {
73 is
.read(reinterpret_cast<char *>(&x
), sizeof(x
));
77 proc(module::size_t &sz
, const T
&x
) {
82 /// (De)serialize a vector.
84 struct _serializer
<compat::vector
<T
>,
85 typename
std::enable_if
<
86 !std::is_scalar
<T
>::value
>::type
> {
88 proc(compat::ostream
&os
, const compat::vector
<T
> &v
) {
89 _proc
<uint32_t>(os
, v
.size());
91 for (size_t i
= 0; i
< v
.size(); i
++)
96 proc(compat::istream
&is
, compat::vector
<T
> &v
) {
97 v
.reserve(_proc
<uint32_t>(is
));
99 for (size_t i
= 0; i
< v
.size(); i
++)
100 new(&v
[i
]) T(_proc
<T
>(is
));
104 proc(module::size_t &sz
, const compat::vector
<T
> &v
) {
105 sz
+= sizeof(uint32_t);
107 for (size_t i
= 0; i
< v
.size(); i
++)
113 struct _serializer
<compat::vector
<T
>,
114 typename
std::enable_if
<
115 std::is_scalar
<T
>::value
>::type
> {
117 proc(compat::ostream
&os
, const compat::vector
<T
> &v
) {
118 _proc
<uint32_t>(os
, v
.size());
119 os
.write(reinterpret_cast<const char *>(v
.begin()),
120 v
.size() * sizeof(T
));
124 proc(compat::istream
&is
, compat::vector
<T
> &v
) {
125 v
.reserve(_proc
<uint32_t>(is
));
126 is
.read(reinterpret_cast<char *>(v
.begin()),
127 v
.size() * sizeof(T
));
131 proc(module::size_t &sz
, const compat::vector
<T
> &v
) {
132 sz
+= sizeof(uint32_t) + sizeof(T
) * v
.size();
136 /// (De)serialize a module::section.
138 struct _serializer
<module::section
> {
139 template<typename S
, typename QT
>
149 /// (De)serialize a module::argument.
151 struct _serializer
<module::argument
> {
152 template<typename S
, typename QT
>
157 _proc(s
, x
.target_size
);
158 _proc(s
, x
.target_align
);
159 _proc(s
, x
.ext_type
);
163 /// (De)serialize a module::symbol.
165 struct _serializer
<module::symbol
> {
166 template<typename S
, typename QT
>
176 /// (De)serialize a module.
178 struct _serializer
<module
> {
179 template<typename S
, typename QT
>
190 module::serialize(compat::ostream
&os
) const {
195 module::deserialize(compat::istream
&is
) {
196 return _proc
<module
>(is
);
200 module::size() const {