Subversion Repositories Kolibri OS

Rev

Go to most recent revision | Blame | Last modification | View Log | RSS feed

  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 <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
  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
  44.    __proc(compat::istream &is, T &x) {
  45.       __serializer<T>::proc(is, x);
  46.    }
  47.  
  48.    template<typename T>
  49.    T
  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
  61.       proc(compat::ostream &os, const T &x) {
  62.          os.write(reinterpret_cast<const char *>(&x), sizeof(x));
  63.       }
  64.  
  65.       static void
  66.       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
  75.       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
  83.       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
  96.       proc(S &s, QT &x) {
  97.          __proc(s, x.id);
  98.          __proc(s, x.type);
  99.          __proc(s, x.size);
  100.          __proc(s, x.data);
  101.       }
  102.    };
  103.  
  104.    /// (De)serialize a module::argument.
  105.    template<>
  106.    struct __serializer<module::argument> {
  107.       template<typename S, typename QT>
  108.       static void
  109.       proc(S &s, QT &x) {
  110.          __proc(s, x.type);
  111.          __proc(s, x.size);
  112.       }
  113.    };
  114.  
  115.    /// (De)serialize a module::symbol.
  116.    template<>
  117.    struct __serializer<module::symbol> {
  118.       template<typename S, typename QT>
  119.       static void
  120.       proc(S &s, QT &x) {
  121.          __proc(s, x.name);
  122.          __proc(s, x.section);
  123.          __proc(s, x.offset);
  124.          __proc(s, x.args);
  125.       }
  126.    };
  127.  
  128.    /// (De)serialize a module.
  129.    template<>
  130.    struct __serializer<module> {
  131.       template<typename S, typename QT>
  132.       static void
  133.       proc(S &s, QT &x) {
  134.          __proc(s, x.syms);
  135.          __proc(s, x.secs);
  136.       }
  137.    };
  138. };
  139.  
  140. namespace clover {
  141.    void
  142.    module::serialize(compat::ostream &os) const {
  143.       __proc(os, *this);
  144.    }
  145.  
  146.    module
  147.    module::deserialize(compat::istream &is) {
  148.       return __proc<module>(is);
  149.    }
  150.  
  151.    const module::symbol &
  152.    module::sym(compat::string name) const {
  153.       auto it = std::find_if(syms.begin(), syms.end(), [&](const symbol &x) {
  154.             return compat::string(x.name) == name;
  155.          });
  156.  
  157.       if (it == syms.end())
  158.          throw noent_error();
  159.  
  160.       return *it;
  161.    }
  162.  
  163.    const module::section &
  164.    module::sec(typename section::type type) const {
  165.       auto it = std::find_if(secs.begin(), secs.end(), [&](const section &x) {
  166.             return x.type == type;
  167.          });
  168.  
  169.       if (it == secs.end())
  170.          throw noent_error();
  171.  
  172.       return *it;
  173.    }
  174. }
  175.