1 // NeL - MMORPG Framework <http://dev.ryzom.com/projects/nel/>
2 // Copyright (C) 2010 Winch Gate Property Limited
4 // This program is free software: you can redistribute it and/or modify
5 // it under the terms of the GNU Affero General Public License as
6 // published by the Free Software Foundation, either version 3 of the
7 // License, or (at your option) any later version.
9 // This program is distributed in the hope that it will be useful,
10 // but WITHOUT ANY WARRANTY; without even the implied warranty of
11 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 // GNU Affero General Public License for more details.
14 // You should have received a copy of the GNU Affero General Public License
15 // along with this program. If not, see <http://www.gnu.org/licenses/>.
19 #include "nel/misc/stream.h"
20 #include "nel/misc/mem_stream.h"
32 // ======================================================================================================
33 // ======================================================================================================
35 // ======================================================================================================
36 // ======================================================================================================
39 // ======================================================================================================
40 EStream::EStream( const IStream
&f
) : Exception( "In Stream: " + f
.getStreamName() + string(": Stream Error") )
42 StreamName
= f
.getStreamName();
45 EStream::EStream( const IStream
&f
, const std::string
& str
)
46 : Exception( "In Stream: " + f
.getStreamName() + ": " + str
)
48 StreamName
= f
.getStreamName();
51 EInvalidDataStream::EInvalidDataStream(const char *msg
, uint size
)
52 : EStream( NLMISC::toString( msg
, size
) )
56 EStreamOverflow::EStreamOverflow( const char *msg
, uint size
)
57 : EStream( NLMISC::toString( msg
, size
) )
61 // ======================================================================================================
62 // ======================================================================================================
64 // ======================================================================================================
65 // ======================================================================================================
68 // ======================================================================================================
69 bool IStream::_ThrowOnOlder
=false;
70 bool IStream::_ThrowOnNewer
=true;
73 // ======================================================================================================
74 void IStream::setVersionException(bool throwOnOlder
, bool throwOnNewer
)
76 _ThrowOnOlder
=throwOnOlder
;
77 _ThrowOnNewer
=throwOnNewer
;
80 // ======================================================================================================
81 void IStream::getVersionException(bool &throwOnOlder
, bool &throwOnNewer
)
83 throwOnOlder
=_ThrowOnOlder
;
84 throwOnNewer
=_ThrowOnNewer
;
92 IStream::IStream( const IStream
& other
)
96 // By default, mode _XML is off
102 * Assignment operator
104 IStream
& IStream::operator=( const IStream
& other
)
106 _InputStream
= other
._InputStream
;
111 void IStream::swap(IStream
&other
)
113 std::swap(_InputStream
, other
._InputStream
);
114 std::swap(_NextSerialPtrId
, other
._NextSerialPtrId
);
115 _IdMap
.swap(other
._IdMap
);
116 std::swap(_XML
, other
._XML
);
120 // ======================================================================================================
121 // ======================================================================================================
122 // ======================================================================================================
125 // ======================================================================================================
126 void IStream::serialIStreamable(IStreamable
* &ptr
)
131 xmlPushBegin ("POLYPTR");
135 // First attribute name
144 // Close the node header
150 it
= _IdMap
.find(node
);
152 // Test if object already created/read.
153 if( it
==_IdMap
.end() )
155 // Read the class name.
158 // Second attribute name
159 xmlSetAttrib ("class");
163 // Close the node header
167 ptr
= dynamic_cast<IStreamable
*> (CClassRegistry::create(className
));
170 throw EUnregisteredClass(className
);
172 throw EUnregisteredClass();
177 nlassert(CClassRegistry::checkObject(ptr
));
181 _IdMap
.insert( ValueIdMap(node
, ptr
) );
188 ptr
= static_cast<IStreamable
*>(it
->second
);
190 // Close the node header
201 // First attribute name
206 // Close the node header
211 // Assume that prt size is an int size
213 // nlassert(sizeof(uint) == sizeof(void *));
217 it
= _IdMap
.find((uint64
)/*(uint)*/ptr
);
219 // Test if object has been already written
220 if( it
==_IdMap
.end() )
224 // Get the next available ID
225 node
= _NextSerialPtrId
++;
231 // Insert the pointer in the map with the id
232 _IdMap
.insert( ValueIdMap((uint64
)/*(uint)*/ptr
, (void*)/*(uint)*/node
) );
235 nlassert(CClassRegistry::checkObject(ptr
));
238 // Write the class name.
239 string className
=ptr
->getClassName();
241 // Second attribute name
242 xmlSetAttrib ("class");
245 // Close the node header
253 // Write only the object id
255 node
= (uint64
)/*(uint)*/(it
->second
);
265 // ======================================================================================================
266 void IStream::resetPtrTable()
269 _NextSerialPtrId
= 1; // Start at 1 because 0 is the NULL pointer
273 // ======================================================================================================
274 // ======================================================================================================
275 // ======================================================================================================
278 // ======================================================================================================
279 uint
IStream::serialVersion(uint currentVersion
)
298 if(_ThrowOnOlder
&& streamVersion
< currentVersion
)
299 throw EOlderStream(*this);
300 if(_ThrowOnNewer
&& streamVersion
> currentVersion
)
301 throw ENewerStream(*this);
305 v
= streamVersion
=currentVersion
;
322 return streamVersion
;
326 // ======================================================================================================
327 // ======================================================================================================
328 // ======================================================================================================
330 // ======================================================================================================
331 void IStream::serialCont(vector
<uint8
> &cont
)
338 // check stream holds enough bytes (avoid STL to crash on resize)
339 checkStreamSize(len
);
344 serialBuffer( (uint8
*)&(*cont
.begin()) , len
);
348 len
= (sint32
)cont
.size();
351 serialBuffer( (uint8
*)&(*cont
.begin()) , len
);
354 // ======================================================================================================
355 void IStream::serialCont(vector
<sint8
> &cont
)
362 // check stream holds enough bytes (avoid STL to crash on resize)
363 checkStreamSize(len
);
368 serialBuffer( (uint8
*)&(*cont
.begin()) , len
);
372 len
= (sint32
)cont
.size();
375 serialBuffer( (uint8
*)&(*cont
.begin()) , len
);
378 // ======================================================================================================
379 void IStream::serialCont(vector
<bool> &cont
)
388 // check stream holds enough bytes (avoid STL to crash on resize)
389 checkStreamSize(len
/8);
399 serialBuffer( (uint8
*)&(*vec
.begin()) , lb
);
400 for(sint i
=0;i
<len
;i
++)
402 uint bit
= (vec
[i
>>3]>>(i
&7)) & 1;
403 cont
[i
]= bit
?true:false;
409 len
= (sint32
)cont
.size();
417 fill_n(vec
.begin(), lb
, 0);
418 for(sint i
=0;i
<len
;i
++)
420 uint bit
= cont
[i
]?1:0;
421 vec
[i
>>3]|= bit
<<(i
&7);
423 serialBuffer( (uint8
*)&(*vec
.begin()) , lb
);
428 // ======================================================================================================
429 bool IStream::seek (sint32 offset
, TSeekOrigin origin
) const
431 throw ESeekNotSupported(*this);
433 // ======================================================================================================
434 sint32
IStream::getPos () const
436 throw ESeekNotSupported(*this);
439 // ======================================================================================================
440 void IStream::setInOut(bool inputStream
)
442 _InputStream
= inputStream
;
446 // ======================================================================================================
447 string
IStream::getStreamName() const
453 // ======================================================================================================
454 void IStream::setXMLMode (bool on
)
461 * Serial memstream, bitmemstream...
463 void IStream::serialMemStream( CMemStream
&b
)
470 // fill b with data from this
472 serialBuffer (b
.bufferToFill (len
), len
);
477 // fill this with data from b
481 serialBuffer( (uint8
*) b
.buffer (), len
);