#include "platform.h" #include #include #include #include #include #include #include #include #include #include #include //#include extern "C" { #include #ifndef WIN32 # include # include # include # include #endif } #include "svector.h" #ifdef WIN32 #ifndef INTEGER_TYPES #define INTEGER_TYPES typedef short int16_t; typedef int int32_t; typedef long long int64_t; typedef unsigned short uint16_t; typedef unsigned int uint32_t; typedef unsigned long long uint64_t; #endif typedef int32_t VIndex; typedef int32_t Ordinal; #endif #include "random.h" using std::string; #include "basics.h" #include "endian.h" #include "files.h" #include "enabler.h" #include "find_files.h" inline void CHECK_ERR(int err, const char* msg) { if (err != Z_OK) { MessageBox(NULL, "One of the compressed files on disk has errors in it. Restore from backup if you are able.", 0, 0); exit(1); } } using std::fstream; char file_compressorst::def_ibuff[FILE_IN_BUFF]; char file_compressorst::def_obuff[FILE_OUT_BUFF]; char file_compressorst::load_posnull_pointer() { char dummy; read_file(dummy); if(!dummy)return 0; else return 1; } char file_compressorst::save_posnull_pointer(void *ptr) { char dummy; if(ptr==NULL) { dummy=0; write_file(dummy); return 0; } else { dummy=1; write_file(dummy); return 1; } } char file_compressorst::write_file(string &str) { short ln=str.length(); if(ln>=10000||ln<0)ln=0; if(!write_file(ln))return 0; if(ln==0)return 1; if(!write_file((void *)str.c_str(),sizeof(char)*ln))return 0; return 1; } char file_compressorst::read_file(string &str) { str.erase(); short ln; if(!read_file(ln))return 0; if(ln==0)return 1; char *strar=new char[ln+1]; if(!read_file(strar,sizeof(char)*ln)) { delete[] strar; return 0; } strar[ln]='\x0'; str=strar; delete[] strar; return 1; } char file_compressorst::write_file(void *write_var,long write_size) { if (!f.is_open())return 0; if(!compressed) { f.write((char *)write_var,write_size); return 1; } //WRITE OUT THE VARIABLE CHUNK BY CHUNK while(write_size>0) { //FLUSH THE BUFFER IF NECESSARY if(in_buffer_amount_loaded>=in_buffersize) { if(!flush_in_buffer())return 0; } //SET THE AMOUNT TO COPY long copy_size=in_buffersize-in_buffer_amount_loaded; if(write_size0) { long compsize=byteswap((long)(c_stream.total_out)); //WRITE IT f.write((char*)&compsize,sizeof(long)); f.write(out_buffer,c_stream.total_out); } in_buffer_position=0; in_buffer_amount_loaded=0; return 1; } char file_compressorst::read_file(void *read_var,long read_size) { if (!f.is_open())return 0; if(!compressed) { f.read((char *)read_var,read_size); return 1; } //NOW LOAD INTO read_var UNTIL DONE while(read_size>0) { //GET A BUFFER IF NECESSARY if(in_buffer_amount_loaded==0|| in_buffer_position>=in_buffer_amount_loaded) { if(!load_new_in_buffer())return 0; } //BAIL IF STILL NO BUFFER LEFT if(in_buffer_amount_loaded==0)return 0; //SET THE AMOUNT TO COPY long copy_size=in_buffer_amount_loaded-in_buffer_position; if(read_size0) { //TARN: adapted from zlib example files //UNCOMPRESS z_stream d_stream; // decompression stream d_stream.zalloc = (alloc_func)0; d_stream.zfree = (free_func)0; d_stream.opaque = (voidpf)0; d_stream.next_in = (Bytef*)out_buffer; d_stream.avail_in = out_buffer_amount_written; err = inflateInit(&d_stream); CHECK_ERR(err, "inflateInit"); d_stream.next_out = (Bytef*)in_buffer; d_stream.avail_out = in_buffersize; while (d_stream.total_out < in_buffersize && d_stream.total_in < out_buffer_amount_written) { //d_stream.avail_in = d_stream.avail_out = 1; // force small buffers err = inflate(&d_stream, Z_NO_FLUSH); if (err == Z_STREAM_END) break; CHECK_ERR(err, "inflate"); } err = inflateEnd(&d_stream); CHECK_ERR(err, "inflateEnd"); in_buffer_amount_loaded=d_stream.total_out; return 1; } else return 0; } void file_compressorst::close_file() { if (f.is_open()) { f.close(); } } char file_compressorst::open_file(const string &filename,char existing_only) { if(filename.empty())return 0; //RESET DATA in_buffer_amount_loaded=0; in_buffer_position=0; out_buffer_amount_written=0; /* //CHECK IF FILE ALREADY EXISTS f.open(filename.c_str(), fstream::in); char file_exists = f.is_open(); if (file_exists)f.close(); //OPEN FILE if(!existing_only || file_exists) f.open(filename.c_str(), fstream::in | fstream::out | fstream::binary); else f.open(filename.c_str(), fstream::in | fstream::out | fstream::binary); */ //if(existing_only)h=CreateFile(filename.c_str(),GENERIC_READ|GENERIC_WRITE,0,NULL,OPEN_EXISTING,FILE_ATTRIBUTE_NORMAL,NULL); //else h=CreateFile(filename.c_str(),GENERIC_READ|GENERIC_WRITE,0,NULL,CREATE_ALWAYS,FILE_ATTRIBUTE_NORMAL,NULL); if(f.is_open())f.close(); f.clear(); if(existing_only) f.open(filename.c_str(), fstream::in | fstream::out | fstream::binary); else f.open(filename.c_str(), fstream::in | fstream::out | fstream::binary | fstream::trunc); if (f.is_open())return 1; else return 0; } file_compressorst::file_compressorst(char *new_in_buffer,long new_in_buffersize, char *new_out_buffer,long new_out_buffersize) { compressed=true; in_buffer=new_in_buffer; in_buffersize=new_in_buffersize; in_buffer_amount_loaded=0; in_buffer_position=0; out_buffer=new_out_buffer; out_buffersize=new_out_buffersize; out_buffer_amount_written=0; f.clear(); } void file_compressorst::set_buffer_info(char *new_in_buffer,long new_in_buffersize, char *new_out_buffer,long new_out_buffersize) { in_buffer=new_in_buffer; in_buffersize=new_in_buffersize; in_buffer_amount_loaded=0; in_buffer_position=0; out_buffer=new_out_buffer; out_buffersize=new_out_buffersize; out_buffer_amount_written=0; f.clear(); } file_compressorst::file_compressorst() { compressed=true; in_buffer=def_ibuff; in_buffersize=FILE_IN_BUFF; in_buffer_amount_loaded=0; in_buffer_position=0; out_buffer=def_obuff; out_buffersize=FILE_OUT_BUFF; out_buffer_amount_written=0; f.clear(); } void copy_file(const string &src,const string &dst) { std::ifstream in_stream(src.c_str(),std::ios_base::binary); std::ofstream out_stream(dst.c_str(),std::ios_base::binary); if(in_stream.is_open()&&out_stream.is_open()) { out_stream<