S3FC project page S3FC home page

Main Page   Class Hierarchy   Alphabetical List   Compound List   File List   Compound Members   File Members   Related Pages  

s3_streamable.h

Go to the documentation of this file.
00001 /*
00002  * Stone Three Foundation Class (s3fc) provides a number of utility classes.
00003  * Copyright (C) 2001 by Stone Three Signal Processing (Pty) Ltd.
00004  *
00005  * Authored by Stone Three Signal Processing (Pty) Ltd.
00006  *
00007  * This library is free software; you can redistribute it and/or
00008  * modify it under the terms of the GNU Lesser General Public
00009  * License as published by the Free Software Foundation; either
00010  * version 2.1 of the License, or (at your option) any later version.
00011  * 
00012  * This library is distributed in the hope that it will be useful,
00013  * but WITHOUT ANY WARRANTY; without even the implied warranty of
00014  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
00015  * Lesser General Public License for more details.
00016  * 
00017  * You should have received a copy of the GNU Lesser General Public
00018  * License along with this library; if not, write to the Free Software
00019  * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
00020  * 
00021  * Please see the file 'COPYING' in the source root directory.
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    //   size_t size;
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 // dispatcher specialisation for s3_typegroup_pod - forward all calls
00450 //  to s3_streamable_helper_pod
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 // dispatcher specialisation for s3_typegroup_streamable - forward
00481 // to *member* functions of s3_streamable
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 // dispatcher specialisation for s3_typegroup_other - forward
00500 // to specialised s3_streamable_helper_other<T>
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 // dispatcher specialisation for s3_typegroup_stl - forward 
00517 // to s3_streamable_helper_stl
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 // dispatcher specialisation for s3_typegroup_pod - forward all calls
00615 //  to s3_streamable_helper_pod
00616 template<typename T>
00617 struct s3_streamable_dispatcher
00618 {
00619    /*
00620     * Dispatchers invoked by s3_streamable: resolve typegroup from type and
00621     * forward to typegroup-specific dispatcher.
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    /* Dispatchers for s3_typegroup_pod */
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    /* Dispatchers for s3_typegroup_streamable   */   
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    /* Dispatchers for s3_typegroup_other  */
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    /* Dispatchers for s3_typegroup_stl */
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 // string is in typegroup other
00742 S3_TYPEGROUP_TRAITS_OTHER(std::string);
00743 
00744 // some POD types
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    // these should NEVER succeed when called - pointers may 
00885    // *not* be packed (yes, really).
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

Send comments to: s3fc@stonethree.com SourceForge Logo