# Home    # nevrax.com   
Nevrax
Nevrax.org
#News
#Mailing-list
#Documentation
#CVS
#Bugs
#License
Docs
 
Documentation  
Main Page   Namespace List   Class Hierarchy   Alphabetical List   Compound List   File List   Namespace Members   Compound Members   File Members   Related Pages   Search  

stream.h

Go to the documentation of this file.
00001 
00007 /* Copyright, 2000 Nevrax Ltd.
00008  *
00009  * This file is part of NEVRAX NEL.
00010  * NEVRAX NEL is free software; you can redistribute it and/or modify
00011  * it under the terms of the GNU General Public License as published by
00012  * the Free Software Foundation; either version 2, or (at your option)
00013  * any later version.
00014 
00015  * NEVRAX NEL is distributed in the hope that it will be useful, but
00016  * WITHOUT ANY WARRANTY; without even the implied warranty of
00017  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
00018  * General Public License for more details.
00019 
00020  * You should have received a copy of the GNU General Public License
00021  * along with NEVRAX NEL; see the file COPYING. If not, write to the
00022  * Free Software Foundation, Inc., 59 Temple Place - Suite 330, Boston,
00023  * MA 02111-1307, USA.
00024  */
00025 
00026 #ifndef NL_STREAM_H
00027 #define NL_STREAM_H
00028 
00029 #include        "nel/misc/types_nl.h"
00030 #include        "nel/misc/ucstring.h"
00031 #include        "nel/misc/class_registry.h"
00032 #include        <utility>
00033 #include        <string>
00034 #include        <vector>
00035 #include        <deque>
00036 #include        <list>
00037 #include        <set>
00038 #include        <map>
00039 
00040 namespace       NLMISC
00041 {
00042 
00043 
00044 class   IStream;
00045 
00046 
00047 // ======================================================================================================
00048 // ======================================================================================================
00049 // Stream System.
00050 // ======================================================================================================
00051 // ======================================================================================================
00052 
00053 // For Big/little Endian.
00054 #  define NLMISC_BSWAP16(src)   (src) = (((src)>>8)&0xFF) | (((src)&0xFF)<<8)
00055 #  ifdef NL_OS_WINDOWS
00056 #    define NLMISC_BSWAP32(src) _asm mov eax,(src) _asm bswap eax _asm mov (src),eax
00057 #  else
00058 #    define NLMISC_BSWAP32(src) (src) = (((src)>>24)&0xFF) | ((((src)>>16)&0xFF)<<8) | ((((src)>>8)&0xFF)<<16) | (((src)&0xFF)<<24)
00059 #  endif
00060 #  define NLMISC_BSWAP64(src) (src) = (((src)>>56)&0xFF) | ((((src)>>48)&0xFF)<<8) | ((((src)>>40)&0xFF)<<16) | ((((src)>>32)&0xFF)<<24) | ((((src)>>24)&0xFF)<<32) | ((((src)>>16)&0xFF)<<40) | ((((src)>>8)&0xFF)<<48) | (((src)&0xFF)<<56)
00061 
00062 // ======================================================================================================
00070 struct EStream : public Exception
00071 {
00072         EStream() : Exception( "Stream Error" ) {}
00073 
00074         EStream( const std::string& str ) : Exception( str ) {}
00075 
00076         EStream( const IStream &f );
00077 
00078         EStream( const IStream &f, const std::string& str );
00079 
00080         virtual ~EStream() throw() {}
00081 
00082         // May Not be Filled...
00083         std::string     StreamName;
00084 };
00085 
00086 struct EOlderStream : public EStream
00087 {
00088         EOlderStream() : EStream("The version in stream is older than the class" ) {}
00089         EOlderStream(const IStream &f) : EStream(f, "The version in stream is older than the class" ) {}
00090 };
00091 
00092 struct ENewerStream : public EStream
00093 {
00094         ENewerStream() : EStream("The version in stream is newer than the class" ) {}
00095         ENewerStream(const IStream &f) : EStream(f, "The version in stream is newer than the class" ) {}
00096 };
00097 
00098 struct EInvalidDataStream : public EStream
00099 {
00100         EInvalidDataStream() : EStream("Invalid data format" ) {}
00101         EInvalidDataStream(const IStream &f) : EStream(f, "Invalid data format" ) {}
00102 };
00103 
00104 struct ESeekNotSupported : public EStream
00105 {
00106         ESeekNotSupported() : EStream("Seek fonctionnality is not supported" ) {}
00107         ESeekNotSupported(const IStream &f) : EStream(f, "Seek fonctionnality is not supported" ) {}
00108 };
00109 
00110 
00111 class   IStreamable;
00112 
00113 // ======================================================================================================
00172 class IStream
00173 {
00174 public:
00183         static  void    setVersionException(bool throwOnOlder, bool throwOnNewer);
00188         static  void    getVersionException(bool &throwOnOlder, bool &throwOnNewer);
00189 
00190 
00191 public:
00192 
00198         explicit IStream(bool inputStream);
00199 
00201         virtual ~IStream() {}
00202 
00204         IStream( const IStream& other );
00205 
00207         IStream&                operator=( const IStream& other );
00208         
00210         bool                    isReading() const;
00211 
00212 
00221     template<class T>
00222         void                    serial(T &obj)  { obj.serial(*this); }
00223 
00224 
00229 
00230         virtual void    serial(uint8 &b) ;
00231         virtual void    serial(sint8 &b) ;
00232         virtual void    serial(uint16 &b) ;
00233         virtual void    serial(sint16 &b) ;
00234         virtual void    serial(uint32 &b) ;
00235         virtual void    serial(sint32 &b) ;
00236         virtual void    serial(uint64 &b) ;
00237         virtual void    serial(sint64 &b) ;
00238         virtual void    serial(float &b) ;
00239         virtual void    serial(double &b) ;
00240         virtual void    serial(bool &b) ;
00241 #ifndef NL_OS_CYGWIN
00242         virtual void    serial(char &b) ;
00243 #endif
00244         virtual void    serial(std::string &b) ;
00245         virtual void    serial(ucstring &b) ;
00247 
00248 
00250     template<class T>
00251         void                    serialEnum(T &em) 
00252         {
00253                 sint32  i;
00254                 if(isReading())
00255                 {
00256                         serial(i);
00257                         em = (T)i;
00258                 }
00259                 else
00260                 {
00261                         i = em;
00262                         serial(i);
00263                 }
00264         }
00265 
00266 
00275 
00276         uint8                   serialBitField8(uint8  bf);
00278         uint16                  serialBitField16(uint16  bf);
00280         uint32                  serialBitField32(uint32  bf);
00282 
00283 
00288         template<class T0,class T1>
00289         void                    serial(T0 &a, T1 &b) 
00290         { serial(a); serial(b);}
00291         template<class T0,class T1,class T2>
00292         void                    serial(T0 &a, T1 &b, T2 &c) 
00293         { serial(a); serial(b); serial(c);}
00294         template<class T0,class T1,class T2,class T3>
00295         void                    serial(T0 &a, T1 &b, T2 &c, T3 &d) 
00296         { serial(a); serial(b); serial(c); serial(d);}
00297         template<class T0,class T1,class T2,class T3,class T4>
00298         void                    serial(T0 &a, T1 &b, T2 &c, T3 &d, T4 &e) 
00299         { serial(a); serial(b); serial(c); serial(d); serial(e);}
00300         template<class T0,class T1,class T2,class T3,class T4,class T5>
00301         void                    serial(T0 &a, T1 &b, T2 &c, T3 &d, T4 &e, T5 &f) 
00302         { serial(a); serial(b); serial(c); serial(d); serial(e); serial(f);}
00304 
00305 
00311         template<class T>
00312         void                    serialCont(std::vector<T> &cont)        {serialVector(cont);}
00313         template<class T>
00314         void                    serialCont(std::list<T> &cont)  {serialSTLCont(cont);}
00315         template<class T>
00316         void                    serialCont(std::deque<T> &cont)         {serialSTLCont(cont);}
00317         template<class T>
00318         void                    serialCont(std::set<T> &cont)           {serialSTLCont(cont);}
00319         template<class T>
00320         void                    serialCont(std::multiset<T> &cont)      {serialSTLCont(cont);}
00321         template<class K, class T>
00322         void                    serialCont(std::map<K, T> &cont)                        {serialMap(cont);}
00323         template<class K, class T>
00324         void                    serialCont(std::multimap<K, T> &cont)   {serialMultimap(cont);}
00325 
00326 
00328         virtual void                    serialCont(std::vector<uint8> &cont) ;
00330         virtual void                    serialCont(std::vector<sint8> &cont) ;
00332         virtual void                    serialCont(std::vector<bool> &cont) ;
00333 
00334 
00341         template<class T>
00342         void                    serialContPtr(std::vector<T> &cont)     {serialVectorPtr(cont);}
00343         template<class T>
00344         void                    serialContPtr(std::list<T> &cont)       {serialSTLContPtr(cont);}
00345         template<class T>
00346         void                    serialContPtr(std::deque<T> &cont)      {serialSTLContPtr(cont);}
00347         template<class T>
00348         void                    serialContPtr(std::set<T> &cont)                        {serialSTLContPtr(cont);}
00349         template<class T>
00350         void                    serialContPtr(std::multiset<T> &cont)   {serialSTLContPtr(cont);}
00351 
00352 
00358         template<class T>
00359         void                    serialContPolyPtr(std::vector<T> &cont)         {serialVectorPolyPtr(cont);}
00360         template<class T>
00361         void                    serialContPolyPtr(std::list<T> &cont)   {serialSTLContPolyPtr(cont);}
00362         template<class T>
00363         void                    serialContPolyPtr(std::deque<T> &cont)  {serialSTLContPolyPtr(cont);}
00364         template<class T>
00365         void                    serialContPolyPtr(std::set<T> &cont)                    {serialSTLContPolyPtr(cont);}
00366         template<class T>
00367         void                    serialContPolyPtr(std::multiset<T> &cont)       {serialSTLContPolyPtr(cont);}
00368 
00369 
00377         template<class T>
00378         void                    serialPtr(T* &ptr) 
00379         {
00380                 uint64  node;
00381 
00382                 // Open the node header
00383                 xmlPushBegin ("PTR");
00384 
00385                 xmlSetAttrib ("id");
00386 
00387                 if(isReading())
00388                 {
00389                         serial(node);
00390 
00391                         // Close the header
00392                         xmlPushEnd ();
00393 
00394                         if(node==0)
00395                                 ptr=NULL;
00396                         else
00397                         {
00398                                 ItIdMap it;
00399                                 it= _IdMap.find(node);
00400 
00401                                 // Test if object already created/read.
00402                                 if( it==_IdMap.end() )
00403                                 {
00404                                         // Construct object.
00405                                         ptr= new T;
00406                                         if(ptr==NULL)
00407                                                 throw EStream();
00408 
00409                                         // Insert the node.
00410                                         _IdMap.insert( ValueIdMap(node, ptr) );
00411 
00412                                         // Read the object!
00413                                         serial(*ptr);
00414                                 }
00415                                 else
00416                                         ptr= static_cast<T*>(it->second);
00417                         }
00418                 }
00419                 else
00420                 {
00421                         if(ptr==NULL)
00422                         {
00423                                 node= 0;
00424                                 serial(node);
00425 
00426                                 // Close the header
00427                                 xmlPushEnd ();
00428                         }
00429                         else
00430                         {
00431                                 node= (uint64)(uint)ptr;
00432                                 serial(node);
00433 
00434                                 // Close the header
00435                                 xmlPushEnd ();
00436 
00437                                 // Test if object already written.
00438                                 // If the Id was not yet registered (ie insert works).
00439                                 if( _IdMap.insert( ValueIdMap(node, ptr) ).second==true )
00440                                 {
00441                                         // Write the object!
00442                                         serial(*ptr);
00443                                 }
00444                         }
00445                 }
00446 
00447                 // Close the node
00448                 xmlPop ();
00449         }
00450 
00451         
00459         template<class T>
00460         void                    serialPolyPtr(T* &ptr) 
00461         { IStreamable *p=ptr; serialIStreamable(p); ptr= static_cast<T*>(p);}
00462 
00463 
00474         uint                    serialVersion(uint currentVersion) ;
00475 
00476 
00487         template<class T>
00488         void                    serialCheck(const T& value) 
00489         {
00490                 // Open a node
00491                 xmlPush ("CHECK");
00492 
00493                 if (isReading()) 
00494                 { 
00495                         T read;
00496                         serial (read); 
00497                         if (read!=value) 
00498                                 throw EInvalidDataStream(*this); 
00499                 } 
00500                 else 
00501                 { 
00502                         serial (const_cast<T&>(value)); 
00503                 }
00504 
00505                 // Close the node 
00506                 xmlPop ();
00507         }
00508 
00510 
00517         enum TSeekOrigin { begin, current, end };
00518 
00530         virtual bool            seek (sint32 offset, TSeekOrigin origin) ;
00531 
00532 
00544         virtual sint32          getPos () ;
00545 
00546 
00550         virtual std::string             getStreamName() const;
00551 
00614         template<class T> 
00615         void xmlSerial (T& value0, const char *nodeName)
00616         {
00617                 // Open the node
00618                 xmlPush (nodeName);
00619                 
00620                 // Serial the value
00621                 serial (value0);
00622 
00623                 // Close the node
00624                 xmlPop ();
00625         }
00626         template<class T> 
00627         void xmlSerial (T& value0, T& value1, const char *nodeName)
00628         {
00629                 // Open the node
00630                 xmlPush (nodeName);
00631                 
00632                 // Serial the values
00633                 serial (value0, value1);
00634 
00635                 // Close the node
00636                 xmlPop ();
00637         }
00638         template<class T> 
00639         void xmlSerial (T& value0, T& value1, T& value2, const char *nodeName)
00640         {
00641                 // Open the node
00642                 xmlPush (nodeName);
00643                 
00644                 // Serial the values
00645                 serial (value0, value1, value2);
00646 
00647                 // Close the node
00648                 xmlPop ();
00649         }
00650         template<class T> 
00651         void xmlSerial (T& value0, T& value1, T& value2, T& value3, const char *nodeName)
00652         {
00653                 // Open the node
00654                 xmlPush (nodeName);
00655                 
00656                 // Serial the values
00657                 serial (value0, value1, value2, value3);
00658 
00659                 // Close the node
00660                 xmlPop ();
00661         }
00662 
00669         bool xmlPush (const char *name)
00670         {
00671                 // XML Mode ?
00672                 if (_XML)
00673                 {
00674                         // Open the header
00675                         bool res=xmlPushBeginInternal (name);
00676                         if (res)
00677                                 // close the header
00678                                 xmlPushEndInternal ();
00679                         // Return the result
00680                         return res;
00681                 }
00682 
00683                 // Return ok
00684                 return true;
00685         }
00686 
00693         bool xmlPushBegin (const char *name)
00694         {
00695                 // XML Mode ?
00696                 if (_XML)
00697                 {
00698                         return xmlPushBeginInternal (name);
00699                 }
00700 
00701                 // Return ok
00702                 return true;
00703         }
00704 
00710         bool xmlPushEnd ()
00711         {
00712                 // XML Mode ?
00713                 if (_XML)
00714                 {
00715                         return xmlPushEndInternal ();
00716                 }
00717 
00718                 // Return ok
00719                 return true;
00720         }
00721 
00727         bool xmlPop ()
00728         {
00729                 // XML Mode ?
00730                 if (_XML)
00731                 {
00732                         return xmlPopInternal ();
00733                 }
00734 
00735                 // Return ok
00736                 return true;
00737         }
00738 
00745         bool xmlSetAttrib (const char *name)
00746         {
00747                 // XML Mode ?
00748                 if (_XML)
00749                 {
00750                         return xmlSetAttribInternal (name);
00751                 }
00752 
00753                 // Return ok
00754                 return true;
00755         }
00756 
00762         bool xmlBreakLine ()
00763         {
00764                 // XML Mode ?
00765                 if (_XML)
00766                 {
00767                         return xmlBreakLineInternal ();
00768                 }
00769 
00770                 // Return ok
00771                 return true;
00772         }
00773 
00779         bool xmlComment ()
00780         {
00781                 // XML Mode ?
00782                 if (_XML)
00783                 {
00784                         return xmlCommentInternal ();
00785                 }
00786 
00787                 // Return ok
00788                 return true;
00789         }
00790 
00791 protected:
00792 
00794 
00798         void setXMLMode (bool on);
00799 
00801         virtual bool            xmlPushBeginInternal (const char *name) { return true; };
00802 
00804         virtual bool            xmlPushEndInternal () { return true; };
00805 
00807         virtual bool            xmlPopInternal () { return true; };
00808 
00810         virtual bool            xmlSetAttribInternal (const char *name) { return true; };
00811 
00813         virtual bool            xmlBreakLineInternal () { return true; };
00814 
00816         virtual bool            xmlCommentInternal () { return true; };
00817 
00823         void                            resetPtrTable();
00824 
00830         void                            setInOut(bool inputStream);
00831 
00832 
00833 public:
00835 
00839         virtual void            serialBuffer(uint8 *buf, uint len) =0;
00840         virtual void            serialBit(bool &bit) =0;
00842 
00845         virtual void            serialBufferWithSize(uint8 *buf, uint32 len)
00846         {
00847                 serial (len);
00848                 serialBuffer (buf, len);
00849         }
00850 
00851 private:
00852         bool    _InputStream;
00853         static  bool    _ThrowOnOlder;
00854         static  bool    _ThrowOnNewer;
00855 
00856         // Ptr registry. We store 64 bit Id, to be compatible with futur 64+ bits pointers.
00857         std::map<uint64, void*>                         _IdMap;
00858         typedef std::map<uint64, void*>::iterator       ItIdMap;
00859         typedef std::map<uint64, void*>::value_type     ValueIdMap;
00860 
00861         // Ptr serialisation.
00862         void                    serialIStreamable(IStreamable* &ptr) ;
00863 
00864 
00865 
00866 private:
00871         template<class T>
00872         void                    serialSTLContLen(T &cont, sint32 len) 
00873         {
00874                 typedef typename T::value_type __value_type;
00875                 typedef typename T::iterator __iterator;
00876 
00877                 if(isReading())
00878                 {
00879                         for(sint i=0;i<len;i++)
00880                         {
00881                                 xmlPush ("ELM");
00882 
00883                                 __value_type v;
00884                                 serial(v);
00885                                 (void)cont.insert(cont.end(), v);
00886 
00887                                 xmlPop ();
00888                         }
00889                 }
00890                 else
00891                 {
00892                         __iterator              it= cont.begin();
00893                         for(sint i=0;i<len;i++, it++)
00894                         {
00895                                 xmlPush ("ELM");
00896 
00897                                 serial(const_cast<__value_type&>(*it));
00898 
00899                                 xmlPop ();
00900                         }
00901                 }
00902         }
00903 
00904 
00921         template<class T>
00922         void                    serialSTLCont(T &cont) 
00923         {
00924                 // Open a node header
00925                 xmlPushBegin ("CONTAINER");
00926 
00927                 // Attrib size
00928                 xmlSetAttrib ("size");
00929 
00930                 sint32  len=0;
00931                 if(isReading())
00932                 {
00933                         serial(len);
00934                         cont.clear();
00935                 }
00936                 else
00937                 {
00938                         len= cont.size();
00939                         serial(len);
00940                 }
00941 
00942                 // Close the header
00943                 xmlPushEnd ();
00944 
00945                 serialSTLContLen(cont, len);
00946 
00947                 // Close the node
00948                 xmlPop ();
00949         }
00950 
00951         
00952 protected:
00953 
00958         template<class T>
00959         void                    serialVector(T &cont) 
00960         {
00961                 typedef typename T::value_type __value_type;
00962                 typedef typename T::iterator __iterator;
00963 
00964                 // Open a node header
00965                 xmlPushBegin ("VECTOR");
00966 
00967                 // Attrib size
00968                 xmlSetAttrib ("size");
00969 
00970                 sint32  len=0;
00971                 if(isReading())
00972                 {
00973                         serial(len);
00974 
00975                         // Open a node header
00976                         xmlPushEnd ();
00977 
00978                         // special version for vector: adjut good size.
00979                         contReset(cont);
00980                         cont.resize (len);
00981 
00982                         // Read the vector
00983                         for(sint i=0;i<len;i++)
00984                         {
00985                                 xmlPush ("ELM");
00986 
00987                                 serial(cont[i]);
00988 
00989                                 xmlPop ();
00990                         }
00991                 }
00992                 else
00993                 {
00994                         len= cont.size();
00995                         serial(len);
00996 
00997                         // Close the node header
00998                         xmlPushEnd ();
00999 
01000                         // Write the vector
01001                         __iterator              it= cont.begin();
01002                         for(sint i=0;i<len;i++, it++)
01003                         {
01004                                 xmlPush ("ELM");
01005 
01006                                 serial(const_cast<__value_type&>(*it));
01007 
01008                                 xmlPop ();
01009                         }
01010                 }
01011 
01012                 // Close the node
01013                 xmlPop ();
01014         }
01015 
01016 
01017 private:
01022         template<class T>
01023         void                    serialSTLContLenPtr(T &cont, sint32 len) 
01024         {
01025                 typedef typename T::value_type __value_type;
01026                 typedef typename T::iterator __iterator;
01027 
01028                 if(isReading())
01029                 {
01030                         for(sint i=0;i<len;i++)
01031                         {
01032                                 __value_type    v;
01033                                 serialPtr(v);
01034                                 cont.insert(cont.end(), v);
01035                         }
01036                 }
01037                 else
01038                 {
01039                         __iterator              it= cont.begin();
01040                         for(sint i=0;i<len;i++, it++)
01041                         {
01042                                 serialPtr(const_cast<__value_type&>(*it));
01043                         }
01044                 }
01045         }
01046 
01047 
01052         template<class T>
01053         void                    serialSTLContPtr(T &cont) 
01054         {
01055                 // Open a node header
01056                 xmlPushBegin ("CONTAINER");
01057 
01058                 // Attrib size
01059                 xmlSetAttrib ("size");
01060 
01061                 sint32  len=0;
01062                 if(isReading())
01063                 {
01064                         serial(len);
01065                         cont.clear();
01066                 }
01067                 else
01068                 {
01069                         len= cont.size();
01070                         serial(len);
01071                 }
01072 
01073                 // Close the node header
01074                 xmlPushEnd ();
01075 
01076                 serialSTLContLenPtr(cont, len);
01077 
01078                 // Close the node
01079                 xmlPop ();
01080         }
01081 
01082 
01087         template<class T>
01088         void                    serialVectorPtr(T &cont) 
01089         {
01090                 typedef typename T::value_type __value_type;
01091                 typedef typename T::iterator __iterator;
01092 
01093                 // Open a node header
01094                 xmlPushBegin ("VECTOR");
01095 
01096                 // Attrib size
01097                 xmlSetAttrib ("size");
01098 
01099                 sint32  len=0;
01100                 if(isReading())
01101                 {
01102                         serial(len);
01103                         // special version for vector: adjut good size.
01104                         contReset(cont);
01105                         cont.reserve(len);
01106                 }
01107                 else
01108                 {
01109                         len= cont.size();
01110                         serial(len);
01111                 }
01112 
01113                 // Close the node header
01114                 xmlPushEnd ();
01115 
01116                 serialSTLContLenPtr(cont, len);
01117 
01118                 // Close the node
01119                 xmlPop ();
01120         }
01121 
01122 
01123 private:
01128         template<class T>
01129         void                    serialSTLContLenPolyPtr(T &cont, sint32 len) 
01130         {
01131                 typedef typename T::value_type __value_type;
01132                 typedef typename T::iterator __iterator;
01133 
01134                 if(isReading())
01135                 {
01136                         for(sint i=0;i<len;i++)
01137                         {
01138                                 __value_type    v=NULL;
01139                                 serialPolyPtr(v);
01140                                 cont.insert(cont.end(), v);
01141                         }
01142                 }
01143                 else
01144                 {
01145                         __iterator              it= cont.begin();
01146                         for(sint i=0;i<len;i++, it++)
01147                         {
01148                                 serialPolyPtr(const_cast<__value_type&>(*it));
01149                         }
01150                 }
01151         }
01152 
01153 
01158         template<class T>
01159         void                    serialSTLContPolyPtr(T &cont) 
01160         {
01161                 sint32  len=0;
01162                 if(isReading())
01163                 {
01164                         serial(len);
01165                         cont.clear();
01166                 }
01167                 else
01168                 {
01169                         len= cont.size();
01170                         serial(len);
01171                 }
01172 
01173                 serialSTLContLenPolyPtr(cont, len);
01174         }
01175 
01176 
01181         template<class T>
01182         void                    serialVectorPolyPtr(T &cont) 
01183         {
01184                 typedef typename T::value_type __value_type;
01185                 typedef typename T::iterator __iterator;
01186 
01187                 // Open a node header
01188                 xmlPushBegin ("VECTOR");
01189 
01190                 // Attrib size
01191                 xmlSetAttrib ("size");
01192 
01193                 sint32  len=0;
01194                 if(isReading())
01195                 {
01196                         serial(len);
01197                         // special version for vector: adjut good size.
01198                         contReset(cont);
01199                         cont.reserve(len);
01200                 }
01201                 else
01202                 {
01203                         len= cont.size();
01204                         serial(len);
01205                 }
01206 
01207                 // Close the node header
01208                 xmlPushEnd ();
01209 
01210                 serialSTLContLenPolyPtr(cont, len);
01211 
01212                 // Close the node
01213                 xmlPop ();
01214         }
01215 
01216 
01217 
01218 private:
01219 
01237         template<class T>
01238         void                    serialMultimap(T &cont) 
01239         {
01240                 typedef typename T::value_type __value_type;
01241                 typedef typename T::key_type __key_type;
01242                 typedef typename T::iterator __iterator;
01243 
01244                 // Open a node header
01245                 xmlPushBegin ("MULTIMAP");
01246 
01247                 // Attrib size
01248                 xmlSetAttrib ("size");
01249 
01250                 sint32  len;
01251                 if(isReading())
01252                 {
01253                         cont.clear();
01254                         serial(len);
01255 
01256                         // Close the node header
01257                         xmlPushEnd ();
01258 
01259                         for(sint i=0;i<len;i++)
01260                         {
01261                                 __value_type v;
01262 
01263                                 xmlPush ("KEY");
01264 
01265                                 serial ( const_cast<__key_type&>(v.first) );
01266 
01267                                 xmlPop ();
01268 
01269 
01270                                 xmlPush ("ELM");
01271 
01272                                 serial (v.second);
01273 
01274                                 xmlPop ();
01275 
01276                                 cont.insert(cont.end(), v);
01277                         }
01278                 }
01279                 else
01280                 {
01281                         len= cont.size();
01282                         serial(len);
01283                         __iterator              it= cont.begin();
01284 
01285                         // Close the node header
01286                         xmlPushEnd ();
01287 
01288                         for(sint i=0;i<len;i++, it++)
01289                         {
01290                                 xmlPush ("KEY");
01291 
01292                                 serial( const_cast<__key_type&>((*it).first) );
01293 
01294                                 xmlPop ();
01295 
01296                                 xmlPush ("ELM");
01297                                 
01298                                 serial((*it).second);
01299 
01300                                 xmlPop ();
01301                         }
01302                 }
01303 
01304                 // Close the node
01305                 xmlPop ();
01306         }
01307 
01308 
01326         template<class T>
01327         void                    serialMap(T &cont) 
01328         {
01329                 typedef typename T::value_type __value_type;
01330                 typedef typename T::key_type __key_type;
01331                 typedef typename T::iterator __iterator;
01332 
01333                 // Open a node header
01334                 xmlPushBegin ("MAP");
01335 
01336                 // Attrib size
01337                 xmlSetAttrib ("size");
01338 
01339                 sint32  len;
01340                 if(isReading())
01341                 {
01342                         cont.clear();
01343                         serial(len);
01344 
01345                         // Close the node header
01346                         xmlPushEnd ();
01347 
01348                         for(sint i=0;i<len;i++)
01349                         {
01350 /*                              __value_type v;
01351 
01352                                 xmlPush ("KEY");
01353 
01354                                 serial ( const_cast<__key_type&>(v.first) );
01355 
01356                                 xmlPop ();
01357 
01358 
01359                                 xmlPush ("ELM");
01360 
01361                                 serial (v.second);
01362 
01363                                 xmlPop ();
01364 
01365                                 cont.insert(cont.end(), v);
01366 */
01367                                 // MALKAV 05/07/02 : prevent a copy of the value, copy the key instead
01368                                 __key_type k;
01369 
01370                                 xmlPush ("KEY");
01371                                 serial ( k );
01372                                 xmlPop ();
01373 
01374 
01375                                 xmlPush ("ELM");
01376                                 serial (cont[k]);
01377                                 xmlPop ();
01378                         }
01379                 }
01380                 else
01381                 {
01382                         len= cont.size();
01383                         serial(len);
01384                         __iterator              it= cont.begin();
01385 
01386                         // Close the node header
01387                         xmlPushEnd ();
01388 
01389                         for(sint i=0;i<len;i++, it++)
01390                         {
01391                                 xmlPush ("KEY");
01392 
01393                                 serial( const_cast<__key_type&>((*it).first) );
01394 
01395                                 xmlPop ();
01396 
01397                                 xmlPush ("ELM");
01398                                 
01399                                 serial((*it).second);
01400 
01401                                 xmlPop ();
01402                         }
01403                 }
01404 
01405                 // Close the node
01406                 xmlPop ();
01407         }
01408 
01409         // Mode XML
01410         bool    _XML;
01411 };
01412 
01413 
01414 // ======================================================================================================
01415 // ======================================================================================================
01416 // Handle for streaming Polymorphic classes.
01417 // ======================================================================================================
01418 // ======================================================================================================
01419 
01420 
01421 // ======================================================================================================
01430 class IStreamable : public IClassable
01431 {
01432 public:
01433         virtual void            serial(IStream  &f) =0;
01434 };
01435 
01436 
01437 } // NLMISC.
01438 
01439 
01440 // Inline Implementation.
01441 #include "nel/misc/stream_inline.h"
01442 
01443 
01444 #endif // NL_STREAM_H
01445 
01446 /* End of stream.h */