mail[Wesnoth-commits] r44601 - /trunk/src/ana/api/binary_streams.hpp


Others Months | Index by Date | Thread Index
>>   [Date Prev] [Date Next] [Thread Prev] [Thread Next]

Header


Content

Posted by billybiset on July 24, 2010 - 00:21:
Author: billynux
Date: Sat Jul 24 00:21:57 2010
New Revision: 44601

URL: http://svn.gna.org/viewcvs/wesnoth?rev=44601&view=rev
Log:
Improved the ana serializer implementation with helpers for containers.

Modified:
    trunk/src/ana/api/binary_streams.hpp

Modified: trunk/src/ana/api/binary_streams.hpp
URL: 
http://svn.gna.org/viewcvs/wesnoth/trunk/src/ana/api/binary_streams.hpp?rev=44601&r1=44600&r2=44601&view=diff
==============================================================================
--- trunk/src/ana/api/binary_streams.hpp (original)
+++ trunk/src/ana/api/binary_streams.hpp Sat Jul 24 00:21:57 2010
@@ -44,8 +44,38 @@
 {
     namespace serializer
     {
+        template <class T>
+        struct template_is_container { enum {  value = 0   }; };
+
+        // This could/should be done with Template Meta Programming
+        template <class T>
+        struct template_is_container< std::vector<T> > { enum {  value = 1 
}; };
+
+        template <class K, class D>
+        struct template_is_container< std::vector<K,D> > { enum {  value = 1 
}; };
+
+        template <class T>
+        struct template_is_container< std::list<T> > { enum {  value = 1 }; 
};
+
+        template <class K, class D>
+        struct template_is_container< std::list<K,D> > { enum {  value = 1 
}; };
+
+        template <class K, class D, class C>
+        struct template_is_container< std::set<K,D,C> > { enum {  value = 1 
}; };
+
+        template <class K, class D>
+        struct template_is_container< std::map<K,D> > { enum {  value = 1 }; 
};
+
+        template <class K, class D>
+        struct template_is_container< std::multimap<K,D> > { enum {  value = 
1 }; };
+
         class bostream
         {
+            private:
+                template<class T, bool IsContainer> struct _inserter_helper;
+
+                template<class T, bool IsContainer> friend struct 
_inserter_helper;
+
             public:
                 bostream() :
                     _s()
@@ -55,7 +85,7 @@
                 template <class T>
                 bostream& operator<< (T x)
                 {
-                    _s.append(reinterpret_cast<char*>(&x), sizeof(T));
+                    _inserter_helper<T, template_is_container<T>::value 
::call(this, x);
                     return *this;
                 }
 
@@ -100,6 +130,9 @@
 
         class bistream
         {
+            private:
+                template<class T> friend class container_reader;
+
             public:
                 bistream(const std::string& str) :
                     _s(str),
@@ -160,6 +193,112 @@
                 std::string _s;
                 std::size_t _pos;
         };
+
+        template<class T>
+        class container_writer
+        {
+            public:
+                container_writer( size_t size, bostream& bos) :
+                    _elements_left( size ),
+                    _bos( bos )
+                {
+                    _bos << uint32_t( size );
+                }
+
+                container_writer& operator<<(T element)
+                {
+                    assert( _elements_left > 0 );
+                    --_elements_left;
+
+                    _bos << element;
+
+                    return *this;
+                }
+
+                ~container_writer()
+                {
+                    if ( _elements_left != 0 )
+                        throw/* std::runtime_error*/("More elements were 
expected to be written.");
+                }
+            private:
+                size_t    _elements_left;
+                bostream& _bos;
+        };
+
+        template<class T>
+        class container_reader
+        {
+            public:
+                container_reader( bistream& bis) :
+                    _elements_left( 0 ),
+                    _bis( bis )
+                {
+                    _bis >> _elements_left;
+                }
+
+                container_reader& operator>>(T& element)
+                {
+                    assert( _elements_left > 0 );
+                    --_elements_left;
+
+                    _bis >> element;
+
+                    return *this;
+                }
+
+                void skip(size_t elements = 1)
+                {
+                    if ( elements > _elements_left )
+                        throw("Trying to skip too much.");
+
+                    _elements_left -= elements;
+
+                    _bis._pos += sizeof(T) * elements;
+
+                    if ( _bis._pos > _bis._s.size() )
+                        throw("Too much mas skipped.");
+                }
+
+                void finished()
+                {
+                    skip( _elements_left );
+                    _elements_left = 0;
+                }
+
+                ~container_reader()
+                {
+                    if ( _elements_left != 0 )
+                        finished();
+                }
+
+            private:
+                size_t    _elements_left;
+                bistream& _bis;
+        };
+
+        template<class T>
+        struct bostream::_inserter_helper<T, false>
+        {
+            static void call(bostream* bos, const T& x)
+            {
+                bos->_s.append(reinterpret_cast<const char*>(&x), sizeof(T));
+            }
+        };
+
+        template<class T>
+        struct bostream::_inserter_helper<T, true>
+        {
+            static void call(bostream* bos, const T& cont)
+            {
+                const uint32_t size(cont.size());
+                (*bos) << size;
+
+                typename T::const_iterator it( cont.begin() );
+
+                for (; it != cont.end(); ++it)
+                    (*bos) << *it;
+            }
+        };
     } //serializer namespace
 } //ana namespace
 




Related Messages


Powered by MHonArc, Updated Sat Jul 24 04:20:11 2010