# 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.cpp

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 #include "stdmisc.h"
00027 
00028 #include "nel/misc/stream.h"
00029 
00030 using namespace std;
00031 
00032 
00033 namespace NLMISC
00034 {
00035 
00036 
00037 // ======================================================================================================
00038 // ======================================================================================================
00039 // EStream.
00040 // ======================================================================================================
00041 // ======================================================================================================
00042 
00043 
00044 // ======================================================================================================
00045 EStream::EStream( const IStream &f ) : Exception( "In Stream: " + f.getStreamName() + string(": Stream Error") )
00046 {
00047         StreamName= f.getStreamName();
00048 }
00049 
00050 EStream::EStream( const IStream &f, const std::string& str )
00051  : Exception( "In Stream: " + f.getStreamName() + ": " + str )
00052 {
00053         StreamName= f.getStreamName();
00054 }
00055 
00056 
00057 // ======================================================================================================
00058 // ======================================================================================================
00059 // IStream.
00060 // ======================================================================================================
00061 // ======================================================================================================
00062 
00063 
00064 // ======================================================================================================
00065 bool    IStream::_ThrowOnOlder=false;
00066 bool    IStream::_ThrowOnNewer=true;
00067 
00068 
00069 // ======================================================================================================
00070 void    IStream::setVersionException(bool throwOnOlder, bool throwOnNewer)
00071 {
00072         _ThrowOnOlder=throwOnOlder;
00073         _ThrowOnNewer=throwOnNewer;
00074 }
00075 
00076 // ======================================================================================================
00077 void    IStream::getVersionException(bool &throwOnOlder, bool &throwOnNewer)
00078 {
00079         throwOnOlder=_ThrowOnOlder;
00080         throwOnNewer=_ThrowOnNewer;
00081 }
00082 
00083 
00084 
00085 /*
00086  * Copy constructor
00087  */
00088 IStream::IStream( const IStream& other )
00089 {
00090         operator=( other );
00091 
00092         // By default, mode _XML is off
00093         _XML = false;
00094 }
00095 
00096 
00097 /*
00098  * Assignment operator
00099  */
00100 IStream& IStream::operator=( const IStream& other )
00101 {
00102         _InputStream = other._InputStream;
00103         return *this;
00104 }
00105 
00106 
00107 // ======================================================================================================
00108 // ======================================================================================================
00109 // ======================================================================================================
00110 
00111 
00112 // ======================================================================================================
00113 void                    IStream::serialIStreamable(IStreamable* &ptr)
00114 {
00115         uint64  node=0;
00116 
00117         // Open a node
00118         xmlPushBegin ("POLYPTR");
00119 
00120         if(isReading())
00121         {
00122                 // First attribute name
00123                 xmlSetAttrib ("id");
00124 
00125                 serial(node);
00126 
00127                 if(node==0)
00128                 {
00129                         ptr=NULL;
00130 
00131                         // Close the node header
00132                         xmlPushEnd ();
00133                 }
00134                 else
00135                 {
00136                         ItIdMap it;
00137                         it= _IdMap.find(node);
00138 
00139                         // Test if object already created/read.
00140                         if( it==_IdMap.end() )
00141                         {
00142                                 // Read the class name.
00143                                 string  className;
00144 
00145                                 // Second attribute name
00146                                 xmlSetAttrib ("class");
00147 
00148                                 serial(className);
00149 
00150                                 // Close the node header
00151                                 xmlPushEnd ();
00152 
00153                                 // Construct object.
00154                                 ptr= dynamic_cast<IStreamable*> (CClassRegistry::create(className));
00155                                 if(ptr==NULL)
00156                                 #ifdef NL_DEBUG
00157                                         throw EUnregisteredClass(className);
00158                                 #else
00159                                         throw EUnregisteredClass();
00160                                 #endif
00161 
00162 
00163                                 #ifdef NL_DEBUG
00164                                         nlassert(CClassRegistry::checkObject(ptr));
00165                                 #endif
00166 
00167                                 // Insert the node.
00168                                 _IdMap.insert( ValueIdMap(node, ptr) );
00169 
00170                                 // Read the object!
00171                                 ptr->serial(*this);
00172                         }
00173                         else
00174                         {
00175                                 ptr= static_cast<IStreamable*>(it->second);
00176 
00177                                 // Close the node header
00178                                 xmlPushEnd ();
00179                         }
00180                 }
00181         }
00182         else
00183         {
00184                 if(ptr==NULL)
00185                 {
00186                         node= 0;
00187 
00188                         // First attribute name
00189                         xmlSetAttrib ("id");
00190 
00191                         serial(node);
00192 
00193                         // Close the node header
00194                         xmlPushEnd ();
00195                 }
00196                 else
00197                 {
00198                         // Assume that prt size is an int size
00199                         nlassert(sizeof(uint) == sizeof(void *));
00200                         node= (uint64)((uint)ptr);
00201 
00202                         // First attribute name
00203                         xmlSetAttrib ("id");
00204 
00205                         serial(node);
00206 
00207                         // Test if object already written.
00208                         // If the Id was not yet registered (ie insert works).
00209                         if( _IdMap.insert( ValueIdMap(node, ptr) ).second==true )
00210                         {
00211                                 #ifdef NL_DEBUG
00212                                         nlassert(CClassRegistry::checkObject(ptr));
00213                                 #endif
00214 
00215                                 // Write the class name.
00216                                 string  className=ptr->getClassName();
00217 
00218                                 // Second attribute name
00219                                 xmlSetAttrib ("class");
00220 
00221                                 serial(className);
00222 
00223                                 // Close the node header
00224                                 xmlPushEnd ();
00225 
00226                                 // Write the object!
00227                                 ptr->serial(*this);
00228                         }
00229                         else
00230                         {
00231                                 // Close the node header
00232                                 xmlPushEnd ();
00233                         }
00234                 }
00235         }
00236 
00237         // Close the node 
00238         xmlPop ();
00239 }
00240 // ======================================================================================================
00241 void                    IStream::resetPtrTable()
00242 {
00243         _IdMap.clear();
00244 }
00245 
00246 
00247 // ======================================================================================================
00248 // ======================================================================================================
00249 // ======================================================================================================
00250 
00251 
00252 // ======================================================================================================
00253 uint IStream::serialVersion(uint currentVersion) 
00254 {
00255         uint8   b=0;
00256         uint32  v=0;
00257         uint    streamVersion;
00258 
00259         // Open the node
00260         xmlPush ("VERSION");
00261 
00262         if(isReading())
00263         {
00264                 serial(b);
00265                 if(b==0xFF)
00266                         serial(v);
00267                 else
00268                         v=b;
00269                 streamVersion=v;
00270 
00271                 // Exception test.
00272                 if(_ThrowOnOlder && streamVersion < currentVersion)
00273                         throw EOlderStream(*this);
00274                 if(_ThrowOnNewer && streamVersion > currentVersion)
00275                         throw ENewerStream(*this);
00276         }
00277         else
00278         {
00279                 v= streamVersion=currentVersion;
00280                 if(v>=0xFF)
00281                 {
00282                         b=0xFF;
00283                         serial(b);
00284                         serial(v);
00285                 }
00286                 else
00287                 {
00288                         b= (uint8)v;
00289                         serial(b);
00290                 }
00291         }
00292 
00293         // Close the node
00294         xmlPop ();
00295 
00296         return streamVersion;
00297 }
00298 
00299 
00300 // ======================================================================================================
00301 // ======================================================================================================
00302 // ======================================================================================================
00303 
00304 // ======================================================================================================
00305 void                    IStream::serialCont(vector<uint8> &cont) 
00306 {
00307         sint32  len=0;
00308         if(isReading())
00309         {
00310                 serial(len);
00311                 cont.resize(len);
00312                 if (len != 0)
00313                         serialBuffer( (uint8*)&(*cont.begin()) , len);
00314         }
00315         else
00316         {
00317                 len= cont.size();
00318                 serial(len);
00319                 if (len != 0)
00320                         serialBuffer( (uint8*)&(*cont.begin()) ,  len);
00321         }
00322 }
00323 // ======================================================================================================
00324 void                    IStream::serialCont(vector<sint8> &cont) 
00325 {
00326         sint32  len=0;
00327         if(isReading())
00328         {
00329                 serial(len);
00330                 cont.resize(len);
00331                 if (len != 0)
00332                         serialBuffer( (uint8*)&(*cont.begin()) , len);
00333         }
00334         else
00335         {
00336                 len= cont.size();
00337                 serial(len);
00338                 if (len != 0)
00339                         serialBuffer( (uint8*)&(*cont.begin()) ,  len);
00340         }
00341 }
00342 // ======================================================================================================
00343 void                    IStream::serialCont(vector<bool> &cont) 
00344 {
00345         sint32  len=0;
00346         vector<uint8>   vec;
00347 
00348         if(isReading())
00349         {
00350                 serial(len);
00351                 cont.resize(len);
00352 
00353                 if (len != 0)
00354                 {
00355                         // read as uint8*.
00356                         sint    lb= (len+7)/8;
00357                         vec.resize(lb);
00358                         serialBuffer( (uint8*)&(*vec.begin()) ,  lb);
00359                         for(sint i=0;i<len;i++)
00360                         {
00361                                 uint    bit= (vec[i>>3]>>(i&7)) & 1;
00362                                 cont[i]= bit?true:false;
00363                         }
00364                 }
00365         }
00366         else
00367         {
00368                 len= cont.size();
00369                 serial(len);
00370 
00371                 if (len != 0)
00372                 {
00373                         // write as uint8*.
00374                         sint    lb= (len+7)/8;
00375                         vec.resize(lb);
00376                         fill_n(vec.begin(), lb, 0);
00377                         for(sint i=0;i<len;i++)
00378                         {
00379                                 uint    bit= cont[i]?1:0;
00380                                 vec[i>>3]|= bit<<(i&7);
00381                         }
00382                         serialBuffer( (uint8*)&(*vec.begin()) ,  lb);
00383                 }
00384         }
00385 
00386 }
00387 // ======================================================================================================
00388 bool                    IStream::seek (sint32 offset, TSeekOrigin origin) 
00389 {
00390         throw ESeekNotSupported(*this);
00391         return false;
00392 }
00393 // ======================================================================================================
00394 sint32                  IStream::getPos () 
00395 {
00396         throw ESeekNotSupported(*this);
00397 }
00398 
00399 // ======================================================================================================
00400 void                    IStream::setInOut(bool inputStream)
00401 {
00402         _InputStream= inputStream;
00403 }
00404 
00405 
00406 // ======================================================================================================
00407 string                  IStream::getStreamName() const
00408 {
00409         return "";
00410 }
00411 
00412 
00413 // ======================================================================================================
00414 void                    IStream::setXMLMode (bool on)
00415 {
00416         _XML = on;
00417 }
00418 
00419 
00420 }
00421