make it possible to override CXX from the command line
[rofl0r-df-libgraphics.git] / g_src / files.cpp
blobaec88508053780e94fbeb64f36290a5b3dc43320
1 #include "platform.h"
2 #include <cerrno>
3 #include <string>
4 #include <cstring>
5 #include <cmath>
6 #include <iostream>
7 #include <sstream>
8 #include <fstream>
9 #include <algorithm>
10 #include <map>
11 #include <set>
12 #include <stdio.h>
13 //#include <unistd.h>
15 extern "C" {
16 #include <zlib.h>
17 #ifndef WIN32
18 # include <sys/types.h>
19 # include <sys/stat.h>
20 # include <sys/time.h>
21 # include <signal.h>
22 #endif
24 #include "svector.h"
26 #ifdef WIN32
28 #ifndef INTEGER_TYPES
29 #define INTEGER_TYPES
30 typedef short int16_t;
31 typedef int int32_t;
32 typedef long long int64_t;
33 typedef unsigned short uint16_t;
34 typedef unsigned int uint32_t;
35 typedef unsigned long long uint64_t;
36 #endif
38 typedef int32_t VIndex;
39 typedef int32_t Ordinal;
41 #endif
43 #include "random.h"
45 using std::string;
47 #include "basics.h"
48 #include "endian.h"
49 #include "files.h"
50 #include "enabler.h"
51 #include "find_files.h"
53 inline void CHECK_ERR(int err, const char* msg)
55 if (err != Z_OK)
57 MessageBox(NULL, "One of the compressed files on disk has errors in it. Restore from backup if you are able.", 0, 0);
58 exit(1);
62 using std::fstream;
64 char file_compressorst::def_ibuff[FILE_IN_BUFF];
65 char file_compressorst::def_obuff[FILE_OUT_BUFF];
67 char file_compressorst::load_posnull_pointer()
69 char dummy;
70 read_file(dummy);
72 if(!dummy)return 0;
73 else return 1;
76 char file_compressorst::save_posnull_pointer(void *ptr)
78 char dummy;
80 if(ptr==NULL)
82 dummy=0;
83 write_file(dummy);
84 return 0;
86 else
88 dummy=1;
89 write_file(dummy);
90 return 1;
94 char file_compressorst::write_file(string &str)
96 short ln=str.length();
97 if(ln>=10000||ln<0)ln=0;
99 if(!write_file(ln))return 0;
101 if(ln==0)return 1;
103 if(!write_file((void *)str.c_str(),sizeof(char)*ln))return 0;
105 return 1;
108 char file_compressorst::read_file(string &str)
110 str.erase();
112 short ln;
114 if(!read_file(ln))return 0;
116 if(ln==0)return 1;
118 char *strar=new char[ln+1];
120 if(!read_file(strar,sizeof(char)*ln))
122 delete[] strar;
123 return 0;
125 strar[ln]='\x0';
127 str=strar;
129 delete[] strar;
130 return 1;
133 char file_compressorst::write_file(void *write_var,long write_size)
135 if (!f.is_open())return 0;
137 if(!compressed)
139 f.write((char *)write_var,write_size);
140 return 1;
143 //WRITE OUT THE VARIABLE CHUNK BY CHUNK
144 while(write_size>0)
146 //FLUSH THE BUFFER IF NECESSARY
147 if(in_buffer_amount_loaded>=in_buffersize)
149 if(!flush_in_buffer())return 0;
152 //SET THE AMOUNT TO COPY
153 long copy_size=in_buffersize-in_buffer_amount_loaded;
154 if(write_size<copy_size)copy_size=write_size;
156 //COPY THE NEXT CHUNK INTO THE BUFFER
157 memmove(in_buffer+in_buffer_amount_loaded,write_var,copy_size);
159 write_var=((char *)write_var) + copy_size;
160 write_size-=copy_size;
161 in_buffer_amount_loaded+=copy_size;
164 return 1;
167 char file_compressorst::flush_in_buffer()
169 if (!f.is_open())return 0;
170 if(!compressed)return 1;
171 if(in_buffer_amount_loaded==0)return 1;//EXTRA CALLS TO FLUSH SHOULDN'T KILL YOU
173 //TARN: adapted from zlib example files
175 //SET UP THE COMPRESSOR
176 z_stream c_stream;
177 int err;
179 c_stream.zalloc = (alloc_func)0;
180 c_stream.zfree = (free_func)0;
181 c_stream.opaque = (voidpf)0;
183 err = deflateInit(&c_stream, 9);
184 CHECK_ERR(err, "deflateInit");
186 c_stream.next_out = (Bytef*)out_buffer;
187 c_stream.avail_out = out_buffersize;
189 //SEND IT TO THE COMPRESSOR
190 c_stream.next_in = (Bytef*)in_buffer;
191 c_stream.avail_in = in_buffer_amount_loaded;
193 while (c_stream.total_in != in_buffer_amount_loaded && c_stream.total_out < out_buffersize)
195 err = deflate(&c_stream, Z_NO_FLUSH);
196 CHECK_ERR(err, "deflate");
199 //FINISH UP THE STREAM
200 while(1)
202 err = deflate(&c_stream, Z_FINISH);
203 if (err == Z_STREAM_END) break;
204 CHECK_ERR(err, "deflate");
207 err = deflateEnd(&c_stream);
208 CHECK_ERR(err, "deflateEnd");
210 //SAVE THE COMPRESSED BIT AS A GIANT BLOCK
211 if(c_stream.total_out>0)
213 long compsize=byteswap((long)(c_stream.total_out));
215 //WRITE IT
216 f.write((char*)&compsize,sizeof(long));
217 f.write(out_buffer,c_stream.total_out);
220 in_buffer_position=0;
221 in_buffer_amount_loaded=0;
223 return 1;
226 char file_compressorst::read_file(void *read_var,long read_size)
228 if (!f.is_open())return 0;
230 if(!compressed)
232 f.read((char *)read_var,read_size);
233 return 1;
236 //NOW LOAD INTO read_var UNTIL DONE
237 while(read_size>0)
239 //GET A BUFFER IF NECESSARY
240 if(in_buffer_amount_loaded==0||
241 in_buffer_position>=in_buffer_amount_loaded)
243 if(!load_new_in_buffer())return 0;
246 //BAIL IF STILL NO BUFFER LEFT
247 if(in_buffer_amount_loaded==0)return 0;
249 //SET THE AMOUNT TO COPY
250 long copy_size=in_buffer_amount_loaded-in_buffer_position;
251 if(read_size<copy_size)copy_size=read_size;
253 //COPY
254 memmove(read_var,in_buffer+in_buffer_position,copy_size);
256 read_var=((char *)read_var) + copy_size;
257 read_size-=copy_size;
258 in_buffer_position+=copy_size;
261 return 1;
264 char file_compressorst::load_new_in_buffer()
266 if (!f.is_open())return 0;
267 if(!compressed)return 1;
269 in_buffer_position=0;
270 in_buffer_amount_loaded=0;
272 //LOAD THE BLOCK OF COMPRESSED DATA
273 f.read((char*)&out_buffer_amount_written,sizeof(long));
274 out_buffer_amount_written=byteswap(out_buffer_amount_written);
275 f.read(out_buffer,out_buffer_amount_written);
277 int err;
279 if(out_buffer_amount_written>0)
281 //TARN: adapted from zlib example files
283 //UNCOMPRESS
284 z_stream d_stream; // decompression stream
286 d_stream.zalloc = (alloc_func)0;
287 d_stream.zfree = (free_func)0;
288 d_stream.opaque = (voidpf)0;
290 d_stream.next_in = (Bytef*)out_buffer;
291 d_stream.avail_in = out_buffer_amount_written;
293 err = inflateInit(&d_stream);
294 CHECK_ERR(err, "inflateInit");
296 d_stream.next_out = (Bytef*)in_buffer;
297 d_stream.avail_out = in_buffersize;
299 while (d_stream.total_out < in_buffersize && d_stream.total_in < out_buffer_amount_written)
301 //d_stream.avail_in = d_stream.avail_out = 1; // force small buffers
302 err = inflate(&d_stream, Z_NO_FLUSH);
304 if (err == Z_STREAM_END) break;
305 CHECK_ERR(err, "inflate");
308 err = inflateEnd(&d_stream);
309 CHECK_ERR(err, "inflateEnd");
311 in_buffer_amount_loaded=d_stream.total_out;
313 return 1;
315 else return 0;
318 void file_compressorst::close_file()
320 if (f.is_open())
322 f.close();
326 char file_compressorst::open_file(const string &filename,char existing_only)
328 if(filename.empty())return 0;
330 //RESET DATA
331 in_buffer_amount_loaded=0;
332 in_buffer_position=0;
333 out_buffer_amount_written=0;
336 //CHECK IF FILE ALREADY EXISTS
337 f.open(filename.c_str(), fstream::in);
338 char file_exists = f.is_open();
339 if (file_exists)f.close();
341 //OPEN FILE
342 if(!existing_only || file_exists)
343 f.open(filename.c_str(), fstream::in | fstream::out | fstream::binary);
344 else
345 f.open(filename.c_str(), fstream::in | fstream::out | fstream::binary);
347 //if(existing_only)h=CreateFile(filename.c_str(),GENERIC_READ|GENERIC_WRITE,0,NULL,OPEN_EXISTING,FILE_ATTRIBUTE_NORMAL,NULL);
348 //else h=CreateFile(filename.c_str(),GENERIC_READ|GENERIC_WRITE,0,NULL,CREATE_ALWAYS,FILE_ATTRIBUTE_NORMAL,NULL);
350 if(f.is_open())f.close();
351 f.clear();
353 if(existing_only)
354 f.open(filename.c_str(), fstream::in | fstream::out | fstream::binary);
355 else
356 f.open(filename.c_str(), fstream::in | fstream::out | fstream::binary | fstream::trunc);
358 if (f.is_open())return 1;
359 else return 0;
362 file_compressorst::file_compressorst(char *new_in_buffer,long new_in_buffersize,
363 char *new_out_buffer,long new_out_buffersize)
365 compressed=true;
367 in_buffer=new_in_buffer;
368 in_buffersize=new_in_buffersize;
369 in_buffer_amount_loaded=0;
370 in_buffer_position=0;
372 out_buffer=new_out_buffer;
373 out_buffersize=new_out_buffersize;
374 out_buffer_amount_written=0;
376 f.clear();
379 file_compressorst::file_compressorst()
381 compressed=true;
383 in_buffer=def_ibuff;
384 in_buffersize=FILE_IN_BUFF;
385 in_buffer_amount_loaded=0;
386 in_buffer_position=0;
388 out_buffer=def_obuff;
389 out_buffersize=FILE_OUT_BUFF;
390 out_buffer_amount_written=0;
392 f.clear();
395 void copy_file(const string &src,const string &dst)
397 std::ifstream in_stream(src.c_str(),std::ios_base::binary);
398 std::ofstream out_stream(dst.c_str(),std::ios_base::binary);
399 if(in_stream.is_open()&&out_stream.is_open())
401 out_stream<<in_stream.rdbuf();
403 in_stream.close();
404 out_stream.close();
407 void replace_file(const string &src, const string &dst) {
408 #ifdef WIN32
409 remove(dst.c_str());
410 #endif
411 rename(src.c_str(), dst.c_str());