Subversion Repositories Kolibri OS

Rev

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 <iostream>
  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(std::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(std::istream &is, T &x) {
  45.       _serializer<T>::proc(is, x);
  46.    }
  47.  
  48.    template<typename T>
  49.    T
  50.    _proc(std::istream &is) {
  51.       T x;
  52.       _serializer<T>::proc(is, x);
  53.       return x;
  54.    }
  55.  
  56.    /// Calculate the size of the specified object.
  57.    template<typename T>
  58.    void
  59.    _proc(module::size_t &sz, const T &x) {
  60.       _serializer<T>::proc(sz, x);
  61.    }
  62.  
  63.    /// (De)serialize a scalar value.
  64.    template<typename T>
  65.    struct _serializer<T, typename std::enable_if<
  66.                             std::is_scalar<T>::value>::type> {
  67.       static void
  68.       proc(std::ostream &os, const T &x) {
  69.          os.write(reinterpret_cast<const char *>(&x), sizeof(x));
  70.       }
  71.  
  72.       static void
  73.       proc(std::istream &is, T &x) {
  74.          is.read(reinterpret_cast<char *>(&x), sizeof(x));
  75.       }
  76.  
  77.       static void
  78.       proc(module::size_t &sz, const T &x) {
  79.          sz += sizeof(x);
  80.       }
  81.    };
  82.  
  83.    /// (De)serialize a vector.
  84.    template<typename T>
  85.    struct _serializer<std::vector<T>,
  86.                       typename std::enable_if<
  87.                          !std::is_scalar<T>::value>::type> {
  88.       static void
  89.       proc(std::ostream &os, const std::vector<T> &v) {
  90.          _proc<uint32_t>(os, v.size());
  91.  
  92.          for (size_t i = 0; i < v.size(); i++)
  93.             _proc<T>(os, v[i]);
  94.       }
  95.  
  96.       static void
  97.       proc(std::istream &is, std::vector<T> &v) {
  98.          v.resize(_proc<uint32_t>(is));
  99.  
  100.          for (size_t i = 0; i < v.size(); i++)
  101.             new(&v[i]) T(_proc<T>(is));
  102.       }
  103.  
  104.       static void
  105.       proc(module::size_t &sz, const std::vector<T> &v) {
  106.          sz += sizeof(uint32_t);
  107.  
  108.          for (size_t i = 0; i < v.size(); i++)
  109.             _proc<T>(sz, v[i]);
  110.       }
  111.    };
  112.  
  113.    template<typename T>
  114.    struct _serializer<std::vector<T>,
  115.                       typename std::enable_if<
  116.                          std::is_scalar<T>::value>::type> {
  117.       static void
  118.       proc(std::ostream &os, const std::vector<T> &v) {
  119.          _proc<uint32_t>(os, v.size());
  120.          os.write(reinterpret_cast<const char *>(&v[0]),
  121.                   v.size() * sizeof(T));
  122.       }
  123.  
  124.       static void
  125.       proc(std::istream &is, std::vector<T> &v) {
  126.          v.resize(_proc<uint32_t>(is));
  127.          is.read(reinterpret_cast<char *>(&v[0]),
  128.                  v.size() * sizeof(T));
  129.       }
  130.  
  131.       static void
  132.       proc(module::size_t &sz, const std::vector<T> &v) {
  133.          sz += sizeof(uint32_t) + sizeof(T) * v.size();
  134.       }
  135.    };
  136.  
  137.    /// (De)serialize a string.
  138.    template<>
  139.    struct _serializer<std::string> {
  140.       static void
  141.       proc(std::ostream &os, const std::string &s) {
  142.          _proc<uint32_t>(os, s.size());
  143.          os.write(&s[0], s.size() * sizeof(std::string::value_type));
  144.       }
  145.  
  146.       static void
  147.       proc(std::istream &is, std::string &s) {
  148.          s.resize(_proc<uint32_t>(is));
  149.          is.read(&s[0], s.size() * sizeof(std::string::value_type));
  150.       }
  151.  
  152.       static void
  153.       proc(module::size_t &sz, const std::string &s) {
  154.          sz += sizeof(uint32_t) + sizeof(std::string::value_type) * s.size();
  155.       }
  156.    };
  157.  
  158.    /// (De)serialize a module::section.
  159.    template<>
  160.    struct _serializer<module::section> {
  161.       template<typename S, typename QT>
  162.       static void
  163.       proc(S &s, QT &x) {
  164.          _proc(s, x.id);
  165.          _proc(s, x.type);
  166.          _proc(s, x.size);
  167.          _proc(s, x.data);
  168.       }
  169.    };
  170.  
  171.    /// (De)serialize a module::argument.
  172.    template<>
  173.    struct _serializer<module::argument> {
  174.       template<typename S, typename QT>
  175.       static void
  176.       proc(S &s, QT &x) {
  177.          _proc(s, x.type);
  178.          _proc(s, x.size);
  179.          _proc(s, x.target_size);
  180.          _proc(s, x.target_align);
  181.          _proc(s, x.ext_type);
  182.          _proc(s, x.semantic);
  183.       }
  184.    };
  185.  
  186.    /// (De)serialize a module::symbol.
  187.    template<>
  188.    struct _serializer<module::symbol> {
  189.       template<typename S, typename QT>
  190.       static void
  191.       proc(S &s, QT &x) {
  192.          _proc(s, x.name);
  193.          _proc(s, x.section);
  194.          _proc(s, x.offset);
  195.          _proc(s, x.args);
  196.       }
  197.    };
  198.  
  199.    /// (De)serialize a module.
  200.    template<>
  201.    struct _serializer<module> {
  202.       template<typename S, typename QT>
  203.       static void
  204.       proc(S &s, QT &x) {
  205.          _proc(s, x.syms);
  206.          _proc(s, x.secs);
  207.       }
  208.    };
  209. };
  210.  
  211. namespace clover {
  212.    void
  213.    module::serialize(std::ostream &os) const {
  214.       _proc(os, *this);
  215.    }
  216.  
  217.    module
  218.    module::deserialize(std::istream &is) {
  219.       return _proc<module>(is);
  220.    }
  221.  
  222.    module::size_t
  223.    module::size() const {
  224.       size_t sz = 0;
  225.       _proc(sz, *this);
  226.       return sz;
  227.    }
  228. }
  229.