2016-09-10 03:28:11 +03:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
								# include  "StdInc.h" 
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								# include  "BinaryDeserializer.h" 
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								# include  "../registerTypes/RegisterTypes.h" 
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								/*
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								 *  BinaryDeserializer . cpp ,  part  of  VCMI  engine 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								 * 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								 *  Authors :  listed  in  file  AUTHORS  in  main  folder 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								 * 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								 *  License :  GNU  General  Public  License  v2 .0  or  later 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								 *  Full  text  of  license  available  in  license . txt  file ,  in  main  folder 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								 * 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								 */ 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								extern  template  void  registerTypes < BinaryDeserializer > ( BinaryDeserializer  &  s ) ;  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2016-10-30 15:14:59 +03:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								CLoadFile : : CLoadFile ( const  boost : : filesystem : : path  &  fname ,  int  minimalVersion  /*= version*/ )  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									:  serializer ( this ) 
							 
						 
					
						
							
								
									
										
										
										
											2016-09-10 03:28:11 +03:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
								{  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									registerTypes ( serializer ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									openNextFile ( fname ,  minimalVersion ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								}  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								CLoadFile : : ~ CLoadFile ( )  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								{  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								}  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								int  CLoadFile : : read ( void  *  data ,  unsigned  size )  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								{  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									sfile - > read ( ( char * ) data , size ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									return  size ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								}  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								void  CLoadFile : : openNextFile ( const  boost : : filesystem : : path  &  fname ,  int  minimalVersion )  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								{  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									assert ( ! serializer . reverseEndianess ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2016-10-29 19:52:19 +03:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									assert ( minimalVersion  < =  SERIALIZATION_VERSION ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2016-09-10 03:28:11 +03:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									try 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									{ 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										fName  =  fname . string ( ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2016-10-30 15:14:59 +03:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										sfile  =  make_unique < FileStream > ( fname ,  std : : ios : : in  |  std : : ios : : binary ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2016-09-10 03:28:11 +03:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
										sfile - > exceptions ( std : : ifstream : : failbit  |  std : : ifstream : : badbit ) ;  //we throw a lot anyway
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										if ( ! ( * sfile ) ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											THROW_FORMAT ( " Error: cannot open to read %s! " ,  fName ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										//we can read
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										char  buffer [ 4 ] ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										sfile - > read ( buffer ,  4 ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										if ( std : : memcmp ( buffer , " VCMI " , 4 ) ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											THROW_FORMAT ( " Error: not a VCMI file(%s)! " ,  fName ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										serializer  &  serializer . fileVersion ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										if ( serializer . fileVersion  <  minimalVersion ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											THROW_FORMAT ( " Error: too old file format (%s)! " ,  fName ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2016-10-30 15:14:59 +03:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										if ( serializer . fileVersion  >  SERIALIZATION_VERSION ) 
							 
						 
					
						
							
								
									
										
										
										
											2016-09-10 03:28:11 +03:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
										{ 
							 
						 
					
						
							
								
									
										
										
										
											2016-10-29 19:52:19 +03:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
											logGlobal - > warnStream ( )  < <  boost : : format ( " Warning format version mismatch: found %d when current is %d! (file %s) \n " )  %  serializer . fileVersion  %  SERIALIZATION_VERSION  %  fName ; 
							 
						 
					
						
							
								
									
										
										
										
											2016-09-10 03:28:11 +03:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											auto  versionptr  =  ( char * ) & serializer . fileVersion ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											std : : reverse ( versionptr ,  versionptr  +  4 ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											logGlobal - > warnStream ( )  < <  " Version number reversed is  "  < <  serializer . fileVersion  < <  " , checking... " ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2016-10-29 19:52:19 +03:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
											if ( serializer . fileVersion  = =  SERIALIZATION_VERSION ) 
							 
						 
					
						
							
								
									
										
										
										
											2016-09-10 03:28:11 +03:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
											{ 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
												logGlobal - > warnStream ( )  < <  fname  < <  "  seems to have different endianness! Entering reversing mode. " ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
												serializer . reverseEndianess  =  true ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											else 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
												THROW_FORMAT ( " Error: too new file format (%s)! " ,  fName ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									catch ( . . . ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									{ 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										clear ( ) ;  //if anything went wrong, we delete file and rethrow
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										throw ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								}  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								void  CLoadFile : : reportState ( CLogger  *  out )  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								{  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									out - > debugStream ( )  < <  " CLoadFile " ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									if ( ! ! sfile  & &  * sfile ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									{ 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										out - > debugStream ( )  < <  " \t Opened  "  < <  fName  < <  " \n \t Position:  "  < <  sfile - > tellg ( ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								}  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								void  CLoadFile : : clear ( )  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								{  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									sfile  =  nullptr ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									fName . clear ( ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									serializer . fileVersion  =  0 ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								}  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2016-10-30 15:14:59 +03:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								void  CLoadFile : : checkMagicBytes ( const  std : : string  & text )  
						 
					
						
							
								
									
										
										
										
											2016-09-10 03:28:11 +03:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
								{  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									std : : string  loaded  =  text ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									read ( ( void * ) loaded . data ( ) ,  text . length ( ) ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									if ( loaded  ! =  text ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										throw  std : : runtime_error ( " Magic bytes doesn't match! " ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								}