@ -11,8 +11,11 @@
typedef char sbyte ;
class SHNFile {
SHNFile ( const SHNFile & ) = delete ;
SHNFile ( const SHNFile & & ) = delete ;
std : : vector < std : : byte > ReadBytes ( std : : ifstream & file ) ;
std : : vector < std : : byte > ReadBytes ( std : : ifstream & file , int bytes ) ;
void WriteBytes ( std : : ofstream & file , char * data , int length ) ;
void WriteBytes ( std : : ofstream & file , std : : vector < std : : byte > & data ) ;
int ReadInt32 ( std : : ifstream & file ) ;
void Encrypt ( ) ;
@ -76,14 +79,15 @@ private:
int length = 0 ;
} ;
int marker = 0 ;
std : : vector < std : : byte > cryptHeade r;
std : : vector < std : : byte > data , rawData ;
char * cryptHeader = nullpt r;
char * data = nullptr , * rawData = nullptr ;
uint32_t header = 0 , recordCount = 0 , defaultRecordLength = 0 , columnCount = 0 ;
std : : vector < Column > columns ;
std : : vector < std : : vector < Data > > contents ;
std : : string filename ;
std : : vector < std : : byte > readArr ;
std : : byte * fileMarker = 0 ;
int readAmt = 0 ;
void Cleanup ( ) ;
public :
void Load ( std : : string file ) ;
void Save ( ) ;
@ -97,6 +101,7 @@ public:
void Write ( int row , int col , std : : string val ) ;
const SHNFile : : Data Get ( int row , int col ) const ;
SHNFile ( ) ;
~ SHNFile ( ) ;
} ;
# ifdef OLC_PGEX_SHNFile
std : : vector < std : : byte > SHNFile : : ReadBytes ( std : : ifstream & file ) {
@ -117,6 +122,11 @@ std::vector<std::byte>SHNFile::ReadBytes(std::ifstream&file,int bytes){
}
return byteArr ;
}
void SHNFile : : WriteBytes ( std : : ofstream & file , char * data , int length ) {
for ( int i = 0 ; i < length ; i + + ) {
file < < unsigned char ( data [ i ] ) ;
}
}
void SHNFile : : WriteBytes ( std : : ofstream & file , std : : vector < std : : byte > & data ) {
for ( int i = 0 ; i < data . size ( ) ; i + + ) {
file < < unsigned char ( data [ i ] ) ;
@ -131,9 +141,9 @@ void SHNFile::Encrypt(){
Decrypt ( ) ;
}
void SHNFile : : Decrypt ( ) {
std : : byte num = std : : byte ( data . size ( ) ) ;
for ( int i = data . size ( ) - 1 ; i > = 0 ; i - - ) {
data [ i ] = std : : byte ( data [ i ] ^ num ) ;
std : : byte num = std : : byte ( readAmt - 0x24 ) ;
for ( int i = readAmt - 0x24 - 1 ; i > = 0 ; i - - ) {
data [ i ] = char ( std : : byte ( data [ i ] ) ^ num ) ;
std : : byte num3 = std : : byte ( i ) ;
num3 = std : : byte ( num3 & std : : byte ( 15 ) ) ;
num3 = std : : byte ( int ( num3 ) + 0x55 ) ;
@ -145,7 +155,9 @@ void SHNFile::Decrypt(){
}
std : : vector < std : : byte > & SHNFile : : ReadBytes ( int bytes ) {
readArr . clear ( ) ;
std : : copy ( data . begin ( ) + marker , data . begin ( ) + marker + bytes , std : : back_inserter ( readArr ) ) ;
for ( int i = 0 ; i < bytes ; i + + ) {
readArr . push_back ( std : : byte ( * ( data + i + marker ) ) ) ;
}
marker + = bytes ;
return readArr ;
}
@ -339,23 +351,29 @@ void SHNFile::Load(std::string file){
header = recordCount = defaultRecordLength = columnCount = 0 ;
columns . clear ( ) ;
contents . clear ( ) ;
rawData . clear ( ) ;
marker = 0 ;
std : : chrono : : time_point < std : : chrono : : high_resolution_clock > timer = std : : chrono : : high_resolution_clock : : now ( ) ;
filename = file ;
Cleanup ( ) ;
//FILE OPERATIONS!
std : : ifstream f ( filename , std : : ios : : binary ) ;
//Since we don't just read in the entire file raw, we have to do some additional work here as the header provides us with some basic info on how to decrypt this file.
//The backup itself needs all the data from the original file, so we're appending it to rawData as we continue reading it.
cryptHeader = ReadBytes ( f , 0x20 ) ;
int readAmt = ReadInt32 ( f ) ;
rawData . push_back ( std : : byte ( readAmt & 0xFF ) ) ;
rawData . push_back ( std : : byte ( ( readAmt > > 8 ) & 0xFF ) ) ;
rawData . push_back ( std : : byte ( ( readAmt > > 16 ) & 0xFF ) ) ;
rawData . push_back ( std : : byte ( ( readAmt > > 24 ) & 0xFF ) ) ;
data = ReadBytes ( f , readAmt - 0x24 ) ;
std : : copy ( data . begin ( ) , data . end ( ) , std : : back_inserter ( rawData ) ) ;
cryptHeader = new char [ 0x20 ] ;
f . read ( cryptHeader , 0x20 ) ;
readAmt = ReadInt32 ( f ) ;
rawData = new char [ readAmt - 0x20 ] ;
rawData [ 0 ] = char ( readAmt & 0xFF ) ;
rawData [ 1 ] = char ( ( readAmt > > 8 ) & 0xFF ) ;
rawData [ 2 ] = char ( ( readAmt > > 16 ) & 0xFF ) ;
rawData [ 3 ] = char ( ( readAmt > > 24 ) & 0xFF ) ;
data = new char [ readAmt - 0x24 ] ;
f . read ( data , readAmt - 0x24 ) ;
for ( int i = 0 ; i < readAmt - 0x24 ; i + + ) {
rawData [ i + 4 ] = data [ i ] ;
}
Decrypt ( ) ;
header = ReadUInt32 ( ) ;
@ -422,7 +440,10 @@ void SHNFile::Load(std::string file){
void SHNFile : : Save ( ) {
std : : ofstream fBackup ( filename + " .bak " , std : : ios : : binary ) ;
std : : cout < < " Saving a backup to " < < filename + " .bak " < < std : : endl ;
for ( int i = 0 ; i < rawData . size ( ) ; i + + ) {
for ( int i = 0 ; i < 0x20 ; i + + ) {
fBackup < < unsigned char ( cryptHeader [ i ] ) ;
}
for ( int i = 0 ; i < readAmt - 0x20 ; i + + ) {
fBackup < < unsigned char ( rawData [ i ] ) ;
}
/*//Decoded version only required for debugging.
@ -493,13 +514,13 @@ void SHNFile::Save(){
}
f . close ( ) ;
std : : ifstream finishedFile ( filename , std : : ios : : binary ) ;
data = ReadBytes ( finishedFile ) ;
finishedFile . read ( data , readAmt - 0x24 ) ;
std : : ofstream encryptedFile ( filename , std : : ios : : binary ) ;
std : : cout < < " Encrypting... " < < std : : endl ;
Encrypt ( ) ;
WriteBytes ( encryptedFile , cryptHeader ) ;
WriteInt32 ( encryptedFile , int32_t ( data . size ( ) + 0x24 ) ) ;
WriteBytes ( encryptedFile , data ) ;
WriteBytes ( encryptedFile , cryptHeader , 0x20 ) ;
WriteInt32 ( encryptedFile , int32_t ( readAmt ) ) ;
WriteBytes ( encryptedFile , data , readAmt - 0x24 ) ;
std : : cout < < " File " < < filename < < " Saved! " < < std : : endl ;
}
const SHNFile : : Data SHNFile : : Get ( int row , int col ) const {
@ -532,4 +553,21 @@ void SHNFile::Write(int row,int col,std::string val){
SHNFile : : SHNFile ( ) {
readArr . reserve ( 64000 ) ;
}
SHNFile : : ~ SHNFile ( ) {
Cleanup ( ) ;
}
void SHNFile : : Cleanup ( ) {
if ( cryptHeader ! = nullptr ) {
delete [ ] cryptHeader ;
cryptHeader = nullptr ;
}
if ( data ! = nullptr ) {
delete [ ] data ;
data = nullptr ;
}
if ( rawData ! = nullptr ) {
delete [ ] rawData ;
rawData = nullptr ;
}
}
# endif