00001 
00002 
00003 
00004 
00005 
00006 
00007 
00008 
00009 
00010 
00011 
00012 
00013 
00014 
00015 
00016 
00017 
00018 
00019 
00020 
00021 
00022 
00023 
00033 #ifndef S3_STREAMABLE_H
00034 #define S3_STREAMABLE_H
00035 
00036 #include <s3fc/s3_macros.h>
00037 
00038 #include <cstring>
00039 #include <vector>
00040 #include <string>
00041 #include <complex>
00042 
00080 class s3_pack_buffer
00081 {
00082   protected:
00086    size_t capacity;
00091    
00095    size_t pos;
00099    unsigned char* buf;
00103    bool own_storage;
00104   public:
00114    s3_pack_buffer(size_t n_capacity = 0);
00125    s3_pack_buffer(void* n_buf,
00126         size_t n_size);
00130    ~s3_pack_buffer();
00138    void reset();
00142    const s3_pack_buffer& operator+=(int n) const;
00149    s3_pack_buffer& operator+=(int n);
00153    const void* get_buffer() const;
00159    void* get_buffer();
00163    const void* get_current() const;
00169    void* get_current();
00183    void set_capacity(size_t n);
00193    size_t get_size() const;
00200    void copy_in(const void* src, size_t n);
00207    void copy_out(void* dst, size_t n) const;
00208   protected:
00225    void enlarge(size_t n);
00226 };
00227 
00231 class s3_typegroup_pod { };
00232 
00251 template<typename T> 
00252 struct s3_streamable_helper_pod
00253 {
00262    static void pack(const T &t, s3_pack_buffer& b);
00268    static void unpack(T &t, const s3_pack_buffer& b);
00275    static void pack_array(const T* const &t, 
00276            s3_pack_buffer& b, 
00277            const size_t& n);
00290    static void unpack_array(T* &t, 
00291              const s3_pack_buffer& b,
00292              bool inplace);
00293 };
00294 
00295 
00299 class s3_typegroup_streamable { };
00300 
00309 template<typename T> 
00310 struct s3_streamable_helper_streamable
00311 {
00318    static void pack(const T &t,
00319           s3_pack_buffer& b);
00326    static void unpack(T &t, 
00327             const s3_pack_buffer& b);
00328 };
00329 
00334 class s3_typegroup_stl { };
00335 
00344 template<typename T> 
00345 struct s3_streamable_helper_stl
00346 {
00347    
00348    static void pack(const T& t,
00349           s3_pack_buffer& b);
00350    
00351    static void unpack(T& t,
00352             const s3_pack_buffer& b);
00353 };
00354 
00359 class s3_typegroup_other { };
00360 
00372 template<typename T> struct s3_streamable_helper_other;
00373  
00374 #ifdef S3_STREAMABLE_USE_PTS
00375 
00392 template<typename T> struct s3_typegroup_traits
00393 {
00394    typedef s3_typegroup_streamable typegroup;
00395 };
00396 
00400 #define S3_TYPEGROUP_TRAITS_POD(T) template<> \
00401 struct s3_typegroup_traits<T > \
00402    { typedef s3_typegroup_pod typegroup; };
00403 
00406 #define S3_TYPEGROUP_TRAITS_STREAMABLE(T) template<> \
00407 struct s3_typegroup_traits<T > \
00408    { typedef s3_typegroup_streamable typegroup; };
00409 
00414 #define S3_TYPEGROUP_TRAITS_STREAMABLE_1(T) \
00415 template<typename T1> \
00416 struct s3_typegroup_traits<T<T1> > \
00417    { typedef s3_typegroup_streamable typegroup; };
00418 
00422 #define S3_TYPEGROUP_TRAITS_OTHER(T)\
00423 template<> \
00424 struct s3_typegroup_traits<T > \
00425    { typedef s3_typegroup_other typegroup; };
00426 
00431 #define S3_TYPEGROUP_TRAITS_STL_1(T) \
00432 template<typename T1> \
00433 struct s3_typegroup_traits<T<T1> > \
00434    { typedef s3_typegroup_stl typegroup; };
00435 
00447 template<typename T, typename typegroup = typename s3_typegroup_traits<T>::typegroup > struct s3_streamable_dispatcher;
00448 
00449 
00450 
00451 template<typename T>
00452 struct s3_streamable_dispatcher<T, s3_typegroup_pod>
00453 {
00454    
00455    static void pack(const T &t, s3_pack_buffer& b)
00456    {
00457       s3_streamable_helper_pod<T>::pack(t, b);
00458    }
00459    
00460    static void unpack(T& t, const s3_pack_buffer& b)
00461    {
00462       s3_streamable_helper_pod<T>::unpack(t, b);
00463    }
00464    
00465    static void pack_array(const T* const &t, 
00466            s3_pack_buffer& b, 
00467            const size_t& n)
00468    {
00469       s3_streamable_helper_pod<T>::pack_array(t, b, n);
00470    }
00471    
00472    static void unpack_array(T* &t, 
00473              const s3_pack_buffer& b,
00474              bool inplace)
00475    {
00476       s3_streamable_helper_pod<T>::unpack_array(t, b, inplace);
00477    }
00478 };
00479 
00480 
00481 
00482 template<typename T>
00483 struct s3_streamable_dispatcher<T, s3_typegroup_streamable>
00484 {
00485    
00486    static void pack(const T &t, 
00487           s3_pack_buffer& b)
00488    {
00489       s3_streamable_helper_streamable<T>::pack(t, b);
00490    }
00491    
00492    static void unpack(T& t, 
00493             const s3_pack_buffer& b)
00494    {
00495       s3_streamable_helper_streamable<T>::unpack(t, b);
00496    }
00497 };
00498 
00499 
00500 
00501 template<typename T>
00502 struct s3_streamable_dispatcher<T, s3_typegroup_other>
00503 {
00504    
00505    static void pack(const T &t, s3_pack_buffer& b)
00506    {
00507       s3_streamable_helper_other<T>::pack(t, b);
00508    }
00509    
00510    static void unpack(T& t, const s3_pack_buffer& b)
00511    {
00512       s3_streamable_helper_other<T>::unpack(t, b);
00513    }
00514 };
00515 
00516 
00517 
00518 template<typename T>
00519 struct s3_streamable_dispatcher<T, s3_typegroup_stl>
00520 {
00521    
00522    static void pack(const T &t, s3_pack_buffer& b)
00523    {
00524       s3_streamable_helper_stl<T>::pack(t, b);
00525    }
00526    
00527    static void unpack(T& t, const s3_pack_buffer& b)
00528    {
00529       s3_streamable_helper_stl<T>::unpack(t, b);
00530    }
00531 };
00532 
00533 #else
00534 
00552 template<typename T> struct s3_typegroup_traits
00553 {
00554    static inline s3_typegroup_streamable typegroup() 
00555    {
00556       return s3_typegroup_streamable();
00557    }
00558 };
00559 
00563 #define S3_TYPEGROUP_TRAITS_POD(T) template<> \
00564 struct s3_typegroup_traits<T > { \
00565    static inline s3_typegroup_pod typegroup() { \
00566    return s3_typegroup_pod(); \
00567    } \
00568  };
00569 
00572 #define S3_TYPEGROUP_TRAITS_STREAMABLE(T) template<> \
00573 struct s3_typegroup_traits<T > { \
00574    static inline s3_typegroup_streamable typegroup() { \
00575    return s3_typegroup_streamable(); \
00576    } \
00577  };
00578 
00583 #define S3_TYPEGROUP_TRAITS_STREAMABLE_1(T) \
00584 template<typename T1> \
00585 struct s3_typegroup_traits<T<T1> > { \
00586    static inline s3_typegroup_streamable typegroup() { \
00587    return s3_typegroup_streamable(); \
00588    } \
00589  };
00590 
00594 #define S3_TYPEGROUP_TRAITS_OTHER(T)\
00595 template<> \
00596 struct s3_typegroup_traits<T > { \
00597    static inline s3_typegroup_other typegroup() { \
00598    return s3_typegroup_other(); \
00599    } \
00600  };
00601 
00606 #define S3_TYPEGROUP_TRAITS_STL_1(T) \
00607 template<typename T1> \
00608 struct s3_typegroup_traits<T<T1> > { \
00609    static inline s3_typegroup_stl typegroup() { \
00610    return s3_typegroup_stl(); \
00611    } \
00612  };
00613 
00614 
00615 
00616 template<typename T>
00617 struct s3_streamable_dispatcher
00618 {
00619    
00620 
00621 
00622 
00623    
00624    static void pack(const T& t, s3_pack_buffer& b)
00625    {
00626       pack(t, b, s3_typegroup_traits<T>::typegroup());
00627    }
00628    
00629    static void unpack(T& t, const s3_pack_buffer& b)
00630    {
00631       unpack(t, b, s3_typegroup_traits<T>::typegroup());
00632    }
00633    
00634    static void pack_array(const T* const &t, 
00635            s3_pack_buffer& b, 
00636            const size_t& n)
00637    {
00638       pack_array(t, b, n, s3_typegroup_traits<T>::typegroup());
00639    }
00640    
00641    static void unpack_array(T* &t, 
00642              const s3_pack_buffer& b,
00643              bool inplace)
00644    {
00645       unpack_array(t, b, inplace, s3_typegroup_traits<T>::typegroup());
00646    }
00647 
00648    
00649    
00650    static void pack(const T &t, s3_pack_buffer& b,
00651           const s3_typegroup_pod&)
00652    {
00653       s3_streamable_helper_pod<T>::pack(t, b);
00654    }
00655    
00656    static void unpack(T& t, const s3_pack_buffer& b,
00657             const s3_typegroup_pod&)
00658    {
00659       s3_streamable_helper_pod<T>::unpack(t, b);
00660    }
00661    
00662    static void pack_array(const T* const &t, 
00663            s3_pack_buffer& b, 
00664            const size_t& n,
00665            const s3_typegroup_pod&)
00666    {
00667       s3_streamable_helper_pod<T>::pack_array(t, b, n);
00668    }
00669    
00670    static void unpack_array(T* &t, 
00671              const s3_pack_buffer& b,
00672              bool inplace,
00673              const s3_typegroup_pod&)
00674    {
00675       s3_streamable_helper_pod<T>::unpack_array(t, b, inplace);
00676    }
00677 
00678       
00679    
00680    static void pack(const T &t, s3_pack_buffer& b,
00681           const s3_typegroup_streamable&)
00682    {
00683       s3_streamable_helper_streamable<T>::pack(t, b);
00684    }
00685    
00686    static void unpack(T& t, const s3_pack_buffer& b,
00687             const s3_typegroup_streamable&)
00688    {
00689       s3_streamable_helper_streamable<T>::unpack(t, b);
00690    }
00691 
00692    
00693    
00694    static void pack(const T &t, s3_pack_buffer& b,
00695           const s3_typegroup_other&)
00696    {
00697       s3_streamable_helper_other<T>::pack(t, b);
00698    }
00699    
00700    static void unpack(T& t, const s3_pack_buffer& b,
00701             const s3_typegroup_other&)
00702    {
00703       s3_streamable_helper_other<T>::unpack(t, b);
00704    }
00705 
00706    
00707    
00708    static void pack(const T &t, s3_pack_buffer& b,
00709           const s3_typegroup_stl&)
00710    {
00711       s3_streamable_helper_stl<T>::pack(t, b);
00712    }
00713    
00714    static void unpack(T& t, const s3_pack_buffer& b,
00715             const s3_typegroup_stl&)
00716    {
00717       s3_streamable_helper_stl<T>::unpack(t, b);
00718    }
00719 };
00720 
00721 #endif
00722 
00726 template<>
00727 struct s3_streamable_helper_other<std::string>
00728 {
00732    static void pack(const std::string &s, 
00733           s3_pack_buffer& b);
00737    static void unpack(std::string &s, 
00738             const s3_pack_buffer& b);
00739 };
00740 
00741 
00742 S3_TYPEGROUP_TRAITS_OTHER(std::string);
00743 
00744 
00745 S3_TYPEGROUP_TRAITS_POD(bool);
00746 S3_TYPEGROUP_TRAITS_POD(char);
00747 S3_TYPEGROUP_TRAITS_POD(unsigned char);
00748 S3_TYPEGROUP_TRAITS_POD(short);
00749 S3_TYPEGROUP_TRAITS_POD(unsigned short);
00750 S3_TYPEGROUP_TRAITS_POD(int);
00751 S3_TYPEGROUP_TRAITS_POD(unsigned int);
00752 S3_TYPEGROUP_TRAITS_POD(long int);
00753 S3_TYPEGROUP_TRAITS_POD(unsigned long int);
00754 S3_TYPEGROUP_TRAITS_POD(float);
00755 S3_TYPEGROUP_TRAITS_POD(double);
00756 S3_TYPEGROUP_TRAITS_POD(std::complex<float>);
00757 S3_TYPEGROUP_TRAITS_POD(std::complex<double>);
00758 
00759 S3_TYPEGROUP_TRAITS_STL_1(std::vector);
00760 
00765 #define S3_DECLARE_MAGIC_STRING virtual const char* get_magic_string() const
00766 
00771 #define S3_DEFINE_MAGIC_STRING(C)              \
00772      const char* C::get_magic_string() const   \
00773      { return  #C; }
00774  
00775 #define S3_DEFINE_MAGIC_STRING_T(C,T)           \
00776      template <typename T>                      \
00777      const char* C<T>::get_magic_string() const \
00778      { return  #C; }
00779 
00780 class s3_streamable
00781 {
00782   public:
00786    virtual const char* get_magic_string() const = 0;
00791    virtual void pack(s3_pack_buffer &v) const = 0;
00796    virtual void unpack(const s3_pack_buffer &v) = 0;
00802    template<typename T>
00803    static void pack(T const &t, 
00804           s3_pack_buffer &b);
00811    template<typename T>
00812    static void unpack(T const &t,
00813             const s3_pack_buffer &b);
00821    template<typename T>
00822    static void pack_array(T* const &t, 
00823            s3_pack_buffer& b, 
00824            size_t n);
00851    template<typename T>
00852    static void unpack_array(T* const &t, 
00853              const s3_pack_buffer& b,
00854              bool inplace);
00858    template<typename T>
00859    static void pack_array(const T* const &t, 
00860            s3_pack_buffer& b, 
00861            size_t n);
00865    template<typename T>
00866    static void unpack_array(const T* const &t, 
00867              const s3_pack_buffer& b,
00868              bool inplace);
00869   public:
00870 #ifdef S3_VERBOSE_PACKING
00871 
00875    static void pack_string(const std::string& str,
00876             s3_pack_buffer& b);
00881    static std::string unpack_string(const s3_pack_buffer& b);
00882 #endif
00883   private:
00884    
00885    
00886    template<typename T>
00887    static void pack(const T* t, s3_pack_buffer& b, size_t n);
00888    template<typename T>
00889    static void unpack(const T* &t, const s3_pack_buffer& b);
00890    template<typename T>
00891    static void unpack(T* &t, const s3_pack_buffer& b);
00892    template<typename T>
00893    static void unpack(T* const &t, const s3_pack_buffer& b);
00894    template<typename T>
00895    static void unpack(const T* const &t, const s3_pack_buffer& b);
00896 };
00897 
00898 #include <s3fc/s3_streamable.tcc>
00899 
00900 #endif