summaryrefslogtreecommitdiff
path: root/g_src/files.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'g_src/files.cpp')
-rwxr-xr-xg_src/files.cpp428
1 files changed, 428 insertions, 0 deletions
diff --git a/g_src/files.cpp b/g_src/files.cpp
new file mode 100755
index 0000000..581e024
--- /dev/null
+++ b/g_src/files.cpp
@@ -0,0 +1,428 @@
+#include "platform.h"
+#include <cerrno>
+#include <string>
+#include <cstring>
+#include <cmath>
+#include <iostream>
+#include <sstream>
+#include <fstream>
+#include <algorithm>
+#include <map>
+#include <set>
+#include <stdio.h>
+//#include <unistd.h>
+
+extern "C" {
+#include <zlib.h>
+#ifndef WIN32
+# include <sys/types.h>
+# include <sys/stat.h>
+# include <sys/time.h>
+# include <signal.h>
+#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_size<copy_size)copy_size=write_size;
+
+ //COPY THE NEXT CHUNK INTO THE BUFFER
+ memmove(in_buffer+in_buffer_amount_loaded,write_var,copy_size);
+
+ write_var=((char *)write_var) + copy_size;
+ write_size-=copy_size;
+ in_buffer_amount_loaded+=copy_size;
+ }
+
+ return 1;
+}
+
+char file_compressorst::flush_in_buffer()
+{
+ if (!f.is_open())return 0;
+ if(!compressed)return 1;
+ if(in_buffer_amount_loaded==0)return 1;//EXTRA CALLS TO FLUSH SHOULDN'T KILL YOU
+
+ //TARN: adapted from zlib example files
+
+ //SET UP THE COMPRESSOR
+ z_stream c_stream;
+ int err;
+
+ c_stream.zalloc = (alloc_func)0;
+ c_stream.zfree = (free_func)0;
+ c_stream.opaque = (voidpf)0;
+
+ err = deflateInit(&c_stream, 9);
+ CHECK_ERR(err, "deflateInit");
+
+ c_stream.next_out = (Bytef*)out_buffer;
+ c_stream.avail_out = out_buffersize;
+
+ //SEND IT TO THE COMPRESSOR
+ c_stream.next_in = (Bytef*)in_buffer;
+ c_stream.avail_in = in_buffer_amount_loaded;
+
+ while (c_stream.total_in != in_buffer_amount_loaded && c_stream.total_out < out_buffersize)
+ {
+ err = deflate(&c_stream, Z_NO_FLUSH);
+ CHECK_ERR(err, "deflate");
+ }
+
+ //FINISH UP THE STREAM
+ while(1)
+ {
+ err = deflate(&c_stream, Z_FINISH);
+ if (err == Z_STREAM_END) break;
+ CHECK_ERR(err, "deflate");
+ }
+
+ err = deflateEnd(&c_stream);
+ CHECK_ERR(err, "deflateEnd");
+
+ //SAVE THE COMPRESSED BIT AS A GIANT BLOCK
+ if(c_stream.total_out>0)
+ {
+ 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_size<copy_size)copy_size=read_size;
+
+ //COPY
+ memmove(read_var,in_buffer+in_buffer_position,copy_size);
+
+ read_var=((char *)read_var) + copy_size;
+ read_size-=copy_size;
+ in_buffer_position+=copy_size;
+ }
+
+ return 1;
+}
+
+char file_compressorst::load_new_in_buffer()
+{
+ if (!f.is_open())return 0;
+ if(!compressed)return 1;
+
+ in_buffer_position=0;
+ in_buffer_amount_loaded=0;
+
+ //LOAD THE BLOCK OF COMPRESSED DATA
+ f.read((char*)&out_buffer_amount_written,sizeof(long));
+ out_buffer_amount_written=byteswap(out_buffer_amount_written);
+ f.read(out_buffer,out_buffer_amount_written);
+
+ int err;
+
+ if(out_buffer_amount_written>0)
+ {
+ //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<<in_stream.rdbuf();
+ }
+ in_stream.close();
+ out_stream.close();
+}
+
+void replace_file(const string &src, const string &dst) {
+#ifdef WIN32
+ remove(dst.c_str());
+#endif
+ rename(src.c_str(), dst.c_str());
+}