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