2016-07-11 11:14:58 -04:00
# include "STDInclude.hpp"
namespace Utils
{
2016-11-20 08:09:07 -05:00
std : : string Stream : : Reader : : readString ( )
2016-07-11 11:14:58 -04:00
{
std : : string str ;
2016-11-20 08:09:07 -05:00
while ( char byte = this - > readByte ( ) )
2016-07-11 11:14:58 -04:00
{
str . append ( & byte , 1 ) ;
}
return str ;
}
2016-11-20 08:09:07 -05:00
const char * Stream : : Reader : : readCString ( )
2016-07-11 11:14:58 -04:00
{
2016-11-20 08:09:07 -05:00
return this - > allocator - > duplicateString ( this - > readString ( ) ) ;
2016-07-11 11:14:58 -04:00
}
2016-11-20 08:09:07 -05:00
char Stream : : Reader : : readByte ( )
2016-07-11 11:14:58 -04:00
{
2016-11-20 08:09:07 -05:00
if ( ( this - > position + 1 ) < = this - > buffer . size ( ) )
2016-07-11 11:14:58 -04:00
{
2016-11-20 08:09:07 -05:00
return this - > buffer [ this - > position + + ] ;
2016-07-11 11:14:58 -04:00
}
return 0 ;
}
2016-11-20 08:09:07 -05:00
void * Stream : : Reader : : read ( size_t size , size_t count )
2016-07-11 11:14:58 -04:00
{
size_t bytes = size * count ;
2016-11-20 08:09:07 -05:00
if ( ( this - > position + bytes ) < = this - > buffer . size ( ) )
2016-07-11 11:14:58 -04:00
{
2016-11-20 08:09:07 -05:00
void * _buffer = this - > allocator - > allocate ( bytes ) ;
2016-07-11 11:14:58 -04:00
2016-11-20 08:09:07 -05:00
std : : memcpy ( _buffer , this - > buffer . data ( ) + this - > position , bytes ) ;
this - > position + = bytes ;
2016-07-11 11:14:58 -04:00
2016-11-20 08:09:07 -05:00
return _buffer ;
2016-07-11 11:14:58 -04:00
}
return nullptr ;
}
2016-11-20 08:09:07 -05:00
bool Stream : : Reader : : end ( )
2016-07-11 11:14:58 -04:00
{
2016-11-20 08:09:07 -05:00
return ( this - > buffer . size ( ) = = this - > position ) ;
2016-07-11 11:14:58 -04:00
}
2016-11-20 08:09:07 -05:00
void Stream : : Reader : : seek ( unsigned int _position )
2016-07-11 11:14:58 -04:00
{
2016-11-20 08:09:07 -05:00
if ( this - > buffer . size ( ) > = _position )
2016-07-11 11:14:58 -04:00
{
2016-11-20 08:09:07 -05:00
this - > position = _position ;
2016-07-11 11:14:58 -04:00
}
}
2016-11-20 08:09:07 -05:00
Stream : : Stream ( ) : criticalSectionState ( 0 )
2016-07-11 11:14:58 -04:00
{
2016-11-20 08:09:07 -05:00
memset ( this - > blockSize , 0 , sizeof ( this - > blockSize ) ) ;
2016-12-21 20:58:00 -05:00
# ifdef DEBUG
if ( this - > writeLog ) return ;
if ( fopen_s ( & this - > writeLog , " userraw/logs/zb_writes.log " , " w " ) )
{
Components : : Logger : : Print ( " WARNING: Couldn't open write log. Writes from ZoneBuilder will not be logged. \n " ) ;
}
# endif
2016-07-11 11:14:58 -04:00
}
Stream : : Stream ( size_t size ) : Stream ( )
{
2016-11-20 08:09:07 -05:00
this - > buffer . reserve ( size ) ;
2016-07-11 11:14:58 -04:00
}
Stream : : ~ Stream ( )
{
2016-11-20 08:09:07 -05:00
this - > buffer . clear ( ) ;
2016-07-11 11:14:58 -04:00
2016-11-20 08:09:07 -05:00
if ( this - > criticalSectionState ! = 0 )
2016-07-11 11:14:58 -04:00
{
2016-11-20 08:09:07 -05:00
MessageBoxA ( 0 , Utils : : String : : VA ( " Invalid critical section state '%i' for stream destruction! " , this - > criticalSectionState ) , " WARNING " , MB_ICONEXCLAMATION ) ;
2016-07-11 11:14:58 -04:00
}
2016-12-21 20:58:00 -05:00
# ifdef DEBUG
if ( this - > writeLog )
{
fclose ( this - > writeLog ) ;
}
# endif
2016-07-11 11:14:58 -04:00
} ;
2016-11-20 08:09:07 -05:00
size_t Stream : : length ( )
2016-07-11 11:14:58 -04:00
{
2016-11-20 08:09:07 -05:00
return this - > buffer . length ( ) ;
2016-07-11 11:14:58 -04:00
}
2016-11-20 08:09:07 -05:00
size_t Stream : : capacity ( )
2016-07-11 11:14:58 -04:00
{
2016-11-20 08:09:07 -05:00
return this - > buffer . capacity ( ) ;
2016-07-11 11:14:58 -04:00
}
2016-11-20 08:09:07 -05:00
char * Stream : : save ( const void * _str , size_t size , size_t count )
2016-07-11 11:14:58 -04:00
{
2016-11-20 08:09:07 -05:00
return this - > save ( this - > getCurrentBlock ( ) , _str , size , count ) ;
2016-07-11 11:14:58 -04:00
}
2016-11-20 08:09:07 -05:00
char * Stream : : save ( Game : : XFILE_BLOCK_TYPES stream , const void * _str , size_t size , size_t count )
2016-07-11 11:14:58 -04:00
{
2016-12-21 20:00:09 -05:00
// Only those seem to actually write data.
2016-12-22 00:42:53 -05:00
// everything else is allocated at runtime but XFILE_BLOCK_RUNTIME is the only one that actually allocates anything
// clearly half of this stuff is unused
2016-12-21 21:29:12 -05:00
if ( stream ! = Game : : XFILE_BLOCK_TEMP & & stream ! = Game : : XFILE_BLOCK_VIRTUAL & & stream ! = Game : : XFILE_BLOCK_PHYSICAL & & stream ! = Game : : XFILE_BLOCK_INVALID )
2016-12-21 20:00:09 -05:00
{
this - > increaseBlockSize ( stream , size * count ) ;
return this - > at ( ) ;
}
2016-11-20 08:09:07 -05:00
auto data = this - > data ( ) ;
2016-07-11 11:14:58 -04:00
2016-11-20 08:09:07 -05:00
if ( this - > isCriticalSection ( ) & & this - > length ( ) + ( size * count ) > this - > capacity ( ) )
2016-07-11 11:14:58 -04:00
{
2016-11-20 08:09:07 -05:00
MessageBoxA ( 0 , Utils : : String : : VA ( " Potential stream reallocation during critical operation detected! Writing data of the length 0x%X exceeds the allocated stream size of 0x%X \n " , ( size * count ) , this - > capacity ( ) ) , " ERROR " , MB_ICONERROR ) ;
2016-07-11 11:14:58 -04:00
__debugbreak ( ) ;
}
2016-11-20 08:09:07 -05:00
this - > buffer . append ( static_cast < const char * > ( _str ) , size * count ) ;
2016-07-11 11:14:58 -04:00
2016-12-21 20:58:00 -05:00
// log the write for zonebuilder debugging
SAVE_LOG_WRITE ( size * count ) ;
2016-11-20 08:09:07 -05:00
if ( this - > data ( ) ! = data & & this - > isCriticalSection ( ) )
2016-07-11 11:14:58 -04:00
{
MessageBoxA ( 0 , " Stream reallocation during critical operations not permitted! \n Please increase the initial memory size or reallocate memory during non-critical sections! " , " ERROR " , MB_ICONERROR ) ;
__debugbreak ( ) ;
}
2016-11-20 08:09:07 -05:00
this - > increaseBlockSize ( stream , size * count ) ;
2016-07-11 11:14:58 -04:00
2016-11-20 08:09:07 -05:00
return this - > at ( ) - ( size * count ) ;
2016-07-11 11:14:58 -04:00
}
2016-11-20 08:09:07 -05:00
char * Stream : : save ( Game : : XFILE_BLOCK_TYPES stream , int value , size_t count )
2016-07-11 11:14:58 -04:00
{
2016-11-20 08:09:07 -05:00
auto ret = this - > length ( ) ;
2016-07-11 11:14:58 -04:00
for ( size_t i = 0 ; i < count ; + + i )
{
2016-11-20 08:09:07 -05:00
this - > save ( stream , & value , 4 , 1 ) ;
2016-07-11 11:14:58 -04:00
}
2016-11-20 08:09:07 -05:00
return this - > data ( ) + ret ;
2016-07-11 11:14:58 -04:00
}
2016-11-20 08:09:07 -05:00
char * Stream : : saveString ( std : : string string )
2016-07-11 11:14:58 -04:00
{
2016-11-20 08:09:07 -05:00
return this - > saveString ( string . data ( ) /*, string.size()*/ ) ;
2016-07-11 11:14:58 -04:00
}
2016-11-20 08:09:07 -05:00
char * Stream : : saveString ( const char * string )
2016-07-11 11:14:58 -04:00
{
2016-11-20 08:09:07 -05:00
return this - > saveString ( string , strlen ( string ) ) ;
2016-07-11 11:14:58 -04:00
}
2016-11-20 08:09:07 -05:00
char * Stream : : saveString ( const char * string , size_t len )
2016-07-11 11:14:58 -04:00
{
2016-11-20 08:09:07 -05:00
auto ret = this - > length ( ) ;
2016-07-11 11:14:58 -04:00
if ( string )
{
2016-11-20 08:09:07 -05:00
this - > save ( string , len ) ;
2016-07-11 11:14:58 -04:00
}
2016-11-20 08:09:07 -05:00
this - > saveNull ( ) ;
2016-07-11 11:14:58 -04:00
2016-11-20 08:09:07 -05:00
return this - > data ( ) + ret ;
2016-07-11 11:14:58 -04:00
}
2016-11-20 08:09:07 -05:00
char * Stream : : saveText ( std : : string string )
2016-07-11 11:14:58 -04:00
{
2016-11-20 08:09:07 -05:00
return this - > save ( string . data ( ) , string . length ( ) ) ;
2016-07-11 11:14:58 -04:00
}
2016-11-20 08:09:07 -05:00
char * Stream : : saveByte ( unsigned char byte , size_t count )
2016-07-11 11:14:58 -04:00
{
2016-11-20 08:09:07 -05:00
auto ret = this - > length ( ) ;
2016-07-11 11:14:58 -04:00
for ( size_t i = 0 ; i < count ; + + i )
{
2016-11-20 08:09:07 -05:00
this - > save ( & byte , 1 ) ;
2016-07-11 11:14:58 -04:00
}
2016-11-20 08:09:07 -05:00
return this - > data ( ) + ret ;
2016-07-11 11:14:58 -04:00
}
2016-11-20 08:09:07 -05:00
char * Stream : : saveNull ( size_t count )
2016-07-11 11:14:58 -04:00
{
2016-11-20 08:09:07 -05:00
return this - > saveByte ( 0 , count ) ;
2016-07-11 11:14:58 -04:00
}
2016-11-20 08:09:07 -05:00
char * Stream : : saveMax ( size_t count )
2016-07-11 11:14:58 -04:00
{
2016-11-20 08:09:07 -05:00
return this - > saveByte ( static_cast < unsigned char > ( - 1 ) , count ) ;
2016-07-11 11:14:58 -04:00
}
2016-11-20 08:09:07 -05:00
void Stream : : align ( Stream : : Alignment align )
2016-07-11 11:14:58 -04:00
{
uint32_t size = 2 < < align ;
// Not power of 2!
if ( ! size | | ( size & ( size - 1 ) ) ) return ;
- - size ;
2016-11-20 08:09:07 -05:00
Game : : XFILE_BLOCK_TYPES stream = this - > getCurrentBlock ( ) ;
this - > blockSize [ stream ] = ~ size & ( this - > getBlockSize ( stream ) + size ) ;
2016-07-11 11:14:58 -04:00
}
2016-11-20 08:09:07 -05:00
bool Stream : : pushBlock ( Game : : XFILE_BLOCK_TYPES stream )
2016-07-11 11:14:58 -04:00
{
2016-11-20 08:09:07 -05:00
this - > streamStack . push_back ( stream ) ;
return this - > isValidBlock ( stream ) ;
2016-07-11 11:14:58 -04:00
}
2016-11-20 08:09:07 -05:00
bool Stream : : popBlock ( )
2016-07-11 11:14:58 -04:00
{
2016-11-20 08:09:07 -05:00
if ( ! this - > streamStack . empty ( ) )
2016-07-11 11:14:58 -04:00
{
2016-11-20 08:09:07 -05:00
this - > streamStack . pop_back ( ) ;
2016-07-11 11:14:58 -04:00
return true ;
}
return false ;
}
2016-11-20 08:09:07 -05:00
bool Stream : : isValidBlock ( Game : : XFILE_BLOCK_TYPES stream )
2016-07-11 11:14:58 -04:00
{
return ( stream < Game : : MAX_XFILE_COUNT & & stream > = Game : : XFILE_BLOCK_TEMP ) ;
}
2016-11-20 08:09:07 -05:00
void Stream : : increaseBlockSize ( Game : : XFILE_BLOCK_TYPES stream , unsigned int size )
2016-07-11 11:14:58 -04:00
{
2016-11-20 08:09:07 -05:00
if ( this - > isValidBlock ( stream ) )
2016-07-11 11:14:58 -04:00
{
2016-11-20 08:09:07 -05:00
this - > blockSize [ stream ] + = size ;
2016-07-11 11:14:58 -04:00
}
}
2016-11-20 08:09:07 -05:00
void Stream : : increaseBlockSize ( unsigned int size )
2016-07-11 11:14:58 -04:00
{
2016-11-20 08:09:07 -05:00
return this - > increaseBlockSize ( this - > getCurrentBlock ( ) , size ) ;
2016-07-11 11:14:58 -04:00
}
2016-11-20 08:09:07 -05:00
Game : : XFILE_BLOCK_TYPES Stream : : getCurrentBlock ( )
2016-07-11 11:14:58 -04:00
{
2016-11-20 08:09:07 -05:00
if ( ! this - > streamStack . empty ( ) )
2016-07-11 11:14:58 -04:00
{
2016-11-20 08:09:07 -05:00
return this - > streamStack . back ( ) ;
2016-07-11 11:14:58 -04:00
}
return Game : : XFILE_BLOCK_INVALID ;
}
2016-11-20 08:09:07 -05:00
char * Stream : : at ( )
2016-07-11 11:14:58 -04:00
{
2016-11-20 08:09:07 -05:00
return reinterpret_cast < char * > ( this - > data ( ) + this - > length ( ) ) ;
2016-07-11 11:14:58 -04:00
}
2016-11-20 08:09:07 -05:00
char * Stream : : data ( )
2016-07-11 11:14:58 -04:00
{
2016-11-20 08:09:07 -05:00
return const_cast < char * > ( this - > buffer . data ( ) ) ;
2016-07-11 11:14:58 -04:00
}
2016-11-20 08:09:07 -05:00
unsigned int Stream : : getBlockSize ( Game : : XFILE_BLOCK_TYPES stream )
2016-07-11 11:14:58 -04:00
{
2016-11-20 08:09:07 -05:00
if ( this - > isValidBlock ( stream ) )
2016-07-11 11:14:58 -04:00
{
2016-11-20 08:09:07 -05:00
return this - > blockSize [ stream ] ;
2016-07-11 11:14:58 -04:00
}
return 0 ;
}
2016-11-20 08:09:07 -05:00
DWORD Stream : : getPackedOffset ( )
2016-07-11 11:14:58 -04:00
{
2016-11-20 08:09:07 -05:00
Game : : XFILE_BLOCK_TYPES block = this - > getCurrentBlock ( ) ;
2016-07-11 11:14:58 -04:00
Stream : : Offset offset ;
offset . block = block ;
2016-11-20 08:09:07 -05:00
offset . offset = this - > getBlockSize ( block ) ;
return offset . getPackedOffset ( ) ;
2016-07-11 11:14:58 -04:00
}
2016-11-20 08:09:07 -05:00
void Stream : : toBuffer ( std : : string & outBuffer )
2016-07-11 11:14:58 -04:00
{
outBuffer . clear ( ) ;
2016-11-20 08:09:07 -05:00
outBuffer . append ( this - > data ( ) , this - > length ( ) ) ;
2016-07-11 11:14:58 -04:00
}
2016-11-20 08:09:07 -05:00
std : : string Stream : : toBuffer ( )
2016-07-11 11:14:58 -04:00
{
2016-11-20 08:09:07 -05:00
std : : string _buffer ;
this - > toBuffer ( _buffer ) ;
return _buffer ;
2016-07-11 11:14:58 -04:00
}
2016-11-20 08:09:07 -05:00
void Stream : : enterCriticalSection ( )
2016-07-11 11:14:58 -04:00
{
2016-11-20 08:09:07 -05:00
+ + this - > criticalSectionState ;
2016-07-11 11:14:58 -04:00
}
2016-11-20 08:09:07 -05:00
void Stream : : leaveCriticalSection ( )
2016-07-11 11:14:58 -04:00
{
2016-11-20 08:09:07 -05:00
- - this - > criticalSectionState ;
2016-07-11 11:14:58 -04:00
}
2016-11-20 08:09:07 -05:00
bool Stream : : isCriticalSection ( )
2016-07-11 11:14:58 -04:00
{
2016-11-20 08:09:07 -05:00
if ( this - > criticalSectionState < 0 )
2016-07-11 11:14:58 -04:00
{
MessageBoxA ( 0 , " CriticalSectionState in stream has been overrun! " , " ERROR " , MB_ICONERROR ) ;
__debugbreak ( ) ;
}
2016-11-20 08:09:07 -05:00
return ( this - > criticalSectionState ! = 0 ) ;
2016-07-11 11:14:58 -04:00
}
2016-12-21 20:58:00 -05:00
# ifdef DEBUG
FILE * Stream : : writeLog = nullptr ;
int Stream : : structLevel = 0 ;
void Stream : : enterStruct ( const char * structName )
{
if ( ! this - > writeLog ) return ;
fprintf ( this - > writeLog , " %*s%s \n " , this - > structLevel + + , " " , structName ) ;
}
void Stream : : leaveStruct ( )
{
if ( ! this - > writeLog ) return ;
this - > structLevel - - ;
if ( this - > structLevel < 0 ) {
Components : : Logger : : Print ( " Stream::exitStruct underflow! All following writes will not be logged! \n " ) ;
fclose ( this - > writeLog ) ;
this - > writeLog = nullptr ;
return ;
}
fprintf ( this - > writeLog , " %*s----- \n " , this - > structLevel , " " ) ;
}
void Stream : : logWrite ( int writeLen )
{
if ( ! this - > writeLog ) return ;
fprintf ( this - > writeLog , " %*s%d \n " , this - > structLevel , " " , writeLen ) ;
}
# endif
2016-07-11 11:14:58 -04:00
}