module.cpp revision c6db1b3396384186aab5b685fe1fd540e17b3a62
15821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)//
25821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Copyright 2012 Francisco Jerez
35821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)//
45821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Permission is hereby granted, free of charge, to any person obtaining a
5bbcdd45c55eb7c4641ab97aef9889b0fc828e7d3Ben Murdoch// copy of this software and associated documentation files (the "Software"),
65821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// to deal in the Software without restriction, including without limitation
75821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// the rights to use, copy, modify, merge, publish, distribute, sublicense,
8bbcdd45c55eb7c4641ab97aef9889b0fc828e7d3Ben Murdoch// and/or sell copies of the Software, and to permit persons to whom the
91320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci// Software is furnished to do so, subject to the following conditions:
1068043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)//
1158e6fbe4ee35d65e14b626c557d37565bf8ad179Ben Murdoch// The above copyright notice and this permission notice shall be included in
121320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci// all copies or substantial portions of the Software.
135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)//
145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
161320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL
175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// THE AUTHORS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
1858e6fbe4ee35d65e14b626c557d37565bf8ad179Ben Murdoch// WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF
195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
201320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci// SOFTWARE.
211320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci//
221320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci
231320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci#include <type_traits>
241320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci#include <algorithm>
251320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci
261320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci#include "core/module.hpp"
271320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci
281320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucciusing namespace clover;
291320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci
301320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tuccinamespace {
311320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci   template<typename T, typename = void>
321320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci   struct __serializer;
331320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci
341320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci   /// Serialize the specified object.
351320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci   template<typename T>
361320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci   void
371320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci   __proc(compat::ostream &os, const T &x) {
381320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci      __serializer<T>::proc(os, x);
391320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci   }
40c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
41a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch   /// Deserialize the specified object.
425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)   template<typename T>
43a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch   void
445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)   __proc(compat::istream &is, T &x) {
455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      __serializer<T>::proc(is, x);
465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)   }
475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)   template<typename T>
492a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)   T
502a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)   __proc(compat::istream &is) {
512a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      T x;
522a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      __serializer<T>::proc(is, x);
532a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      return x;
542a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)   }
551320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci
56c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)   /// (De)serialize a scalar value.
571320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci   template<typename T>
581320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci   struct __serializer<T, typename std::enable_if<
591320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci                             std::is_scalar<T>::value>::type> {
601320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci      static void
615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      proc(compat::ostream &os, const T &x) {
625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)         os.write(reinterpret_cast<const char *>(&x), sizeof(x));
631320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci      }
64c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
651320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci      static void
661320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci      proc(compat::istream &is, T &x) {
671320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci         is.read(reinterpret_cast<char *>(&x), sizeof(x));
681320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci      }
691320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci   };
705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)   /// (De)serialize a vector.
721320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci   template<typename T>
731320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci   struct __serializer<compat::vector<T>> {
74c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)      static void
751320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci      proc(compat::ostream &os, const compat::vector<T> &v) {
761320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci         __proc<uint32_t>(os, v.size());
771320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci
781320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci         for (size_t i = 0; i < v.size(); i++)
795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)            __proc<T>(os, v[i]);
805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      }
811320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci
82c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)      static void
831320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci      proc(compat::istream &is, compat::vector<T> &v) {
841320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci         v.reserve(__proc<uint32_t>(is));
851320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci
861320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci         for (size_t i = 0; i < v.size(); i++)
871320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci            new(&v[i]) T(__proc<T>(is));
881320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci      }
891320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci   };
901320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci
911320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci   /// (De)serialize a module::section.
921320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci   template<>
935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)   struct __serializer<module::section> {
945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      template<typename S, typename QT>
950f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles)      static void
960f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles)      proc(S &s, QT &x) {
970f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles)         __proc(s, x.type);
980f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles)         __proc(s, x.size);
990f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles)         __proc(s, x.data);
1000f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles)      }
1010f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles)   };
1020f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles)
1030f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles)   /// (De)serialize a module::argument.
1040f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles)   template<>
1050f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles)   struct __serializer<module::argument> {
10668043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)      template<typename S, typename QT>
10768043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)      static void
10868043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)      proc(S &s, QT &x) {
10968043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)         __proc(s, x.type);
1101320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci         __proc(s, x.size);
111c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)      }
1125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)   };
1131320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci
1141320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci   /// (De)serialize a module::symbol.
1151320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci   template<>
1161320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci   struct __serializer<module::symbol> {
1172a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      template<typename S, typename QT>
1181320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci      static void
1191320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci      proc(S &s, QT &x) {
1201320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci         __proc(s, x.section);
1211320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci         __proc(s, x.offset);
1221320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci         __proc(s, x.args);
1231320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci      }
1241320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci   };
1251320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci
1261320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci   /// (De)serialize a module.
1275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)   template<>
1285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)   struct __serializer<module> {
1295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      template<typename S, typename QT>
1301320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci      static void
1312a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      proc(S &s, QT &x) {
1322a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)         __proc(s, x.syms);
1335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)         __proc(s, x.secs);
1345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      }
1355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)   };
1365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)};
1375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)namespace clover {
1395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)   void
1405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)   module::serialize(compat::ostream &os) const {
1415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      __proc(os, *this);
1421320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci   }
1431320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci
1441320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci   module
1451320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci   module::deserialize(compat::istream &is) {
1461320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci      return __proc<module>(is);
1471320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci   }
1481320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci
1491320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci   const module::symbol &
1501320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci   module::sym(compat::string name) const {
1511320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci      auto it = std::find_if(syms.begin(), syms.end(), [&](const symbol &x) {
1521320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci            return compat::string(x.name) == name;
1531320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci         });
1541320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci
1552a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      if (it == syms.end())
1562a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)         throw noent_error();
1572a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
1582a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      return *it;
1592a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)   }
1602a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
1612a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)   const module::section &
1622a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)   module::sec(typename section::type type) const {
1632a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      auto it = std::find_if(secs.begin(), secs.end(), [&](const section &x) {
1642a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)            return x.type == type;
1652a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)         });
1662a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
1672a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      if (it == secs.end())
1682a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)         throw noent_error();
1692a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
1702a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      return *it;
1712a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)   }
1722a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)}
1732a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)