OSDN Git Service

[VM][General] Merge Upstream 2018-05-06.
[csp-qt/common_source_project-fm7.git] / source / src / fileio.cpp
1 /*
2         Skelton for retropc emulator
3
4         Author : Takeda.Toshiya
5         Date   : 2006.08.18 -
6
7         [ file i/o ]
8 */
9
10 #if defined(_USE_QT) || defined(_USE_SDL)
11         #include <stdarg.h>
12         #include <fcntl.h>
13         #include <stdio.h>
14         #include <iostream>
15         #include <fstream>
16         #include <cstdio>
17         #if defined(_USE_QT)
18                 #include <sys/types.h>
19                 #include <sys/stat.h>
20                 #if !defined(Q_OS_WIN)
21                         #include <unistd.h>
22                 #endif
23         #endif
24 #elif defined(_WIN32)
25         #include <windows.h>
26 #endif
27 #include "fileio.h"
28 #if !defined(_MSC_VER)
29 #include <stdarg.h>
30 #include <fcntl.h>
31 #include <stdio.h>
32 #include <iostream>
33 #include <fstream>
34 #include <cstdio>
35 #endif
36
37 #ifdef USE_ZLIB
38         #if defined(USE_QT)
39                 #include <zlib.h>
40                 #include <zconf.h>
41         #else
42                 #ifdef _WIN32
43                         #define ZLIB_WINAPI
44                 #endif
45                 #include "zlib-1.2.11/zlib.h"
46                 #include "zlib-1.2.11/zconf.h"
47         #endif
48 #endif
49
50 #if ZLIB_VERNUM < 0x1290
51 inline size_t gzfread(void *buffer, size_t size, size_t count, gzFile file)
52 {
53         uint8_t *p = (uint8_t *)buffer;
54         int s = 0;
55         int i = 0;
56         for(i = 0; i < count; i++) {
57                 for(int j = 0; j < size; j++) {
58                         s = gzgetc(file);
59                         if(s < 0) return 0; // EOF
60                         *p++ = (uint8_t)s; 
61                 }
62         }
63         return i + 1;
64 }
65 inline size_t gzfwrite(void *buffer, size_t size, size_t count, gzFile file)
66 {
67         uint8_t *p = (uint8_t *)buffer;
68         uint8_t n;
69         int s = 0;
70         int i = 0;
71         for(i = 0; i < count; i++) {
72                 for(int j = 0; j < size; j++) {
73                         n = *p++; 
74                         s = gzputc(file, n);
75                         if(s < 0) return 0; // EOF
76                 }
77         }
78         return i + 1;
79 }
80 #endif                  
81 FILEIO::FILEIO()
82 {
83 #ifdef USE_ZLIB
84         gz = NULL;
85 #endif
86         fp = NULL;
87         path[0] = _T('\0');
88 }
89
90 FILEIO::~FILEIO(void)
91 {
92         Fclose();
93 }
94
95 bool FILEIO::IsFileExisting(const _TCHAR *file_path)
96 {
97 #if defined(_USE_QT) || defined(_USE_SDL)
98         FILE *f;
99         f = fopen(file_path, "r");
100         if(f != NULL)  {
101                 fclose(f);         
102                 return true;
103         }
104         return false;
105 #elif defined(_WIN32)
106         DWORD attr = GetFileAttributes(file_path);
107         if(attr == -1) {
108                 return false;
109         }
110         return ((attr & FILE_ATTRIBUTE_DIRECTORY) == 0);
111 #else
112         return (_taccess(file_path, 0) == 0);
113 #endif
114 }
115
116 #if defined(_USE_QT)
117 # include <sys/types.h>
118 # include <sys/stat.h>
119 # if !defined(Q_OS_WIN)
120 #   include <unistd.h>
121 # endif
122 #endif
123 bool FILEIO::IsFileProtected(const _TCHAR *file_path)
124 {
125 #if defined(_USE_QT) || defined(_USE_SDL)
126         struct stat st;
127         if(stat(file_path, &st) == 0) {
128 # if defined(_WIN32)
129                 if((st.st_mode & S_IWUSR) == 0) {
130 # else
131                 if((st.st_mode & (S_IWUSR | S_IWGRP | S_IWOTH)) == 0) {
132 # endif
133                         return true;
134                 }
135         }
136         return false;
137 #elif defined(_WIN32)
138         return ((GetFileAttributes(file_path) & FILE_ATTRIBUTE_READONLY) != 0);
139 #else
140         return (_taccess(file_path, 2) != 0);
141 #endif
142 }
143
144 bool FILEIO::RemoveFile(const _TCHAR *file_path)
145 {
146 #if defined(_USE_QT) || defined(_USE_SDL)
147         return (remove(file_path) == 0);
148 #elif defined(_WIN32)
149         return (DeleteFile(file_path) != 0);
150 #else
151         return (_tremove(file_path) == 0);      // not supported on wince ???
152 #endif
153 }
154
155 bool FILEIO::RenameFile(const _TCHAR *existing_file_path, const _TCHAR *new_file_path)
156 {
157 #if defined(_USE_QT) || defined(_USE_SDL)
158         return (rename(existing_file_path, new_file_path) == 0);
159 #elif defined(_WIN32)
160         return (MoveFile(existing_file_path, new_file_path) != 0);
161 #else
162         return (_trename(existing_file_path, new_file_path) == 0);
163 #endif                  
164 }
165
166 bool FILEIO::Fopen(const _TCHAR *file_path, int mode)
167 {
168         Fclose();
169         
170         // store file path
171         my_tcscpy_s(path, _MAX_PATH, file_path);
172         
173 #ifdef USE_ZLIB
174         if(check_file_extension(file_path, _T(".gz"))) {
175                 return Gzopen(file_path, mode);
176         }
177 #endif
178         switch(mode) {
179         case FILEIO_READ_BINARY:
180                 return ((fp = _tfopen(file_path, _T("rb"))) != NULL);
181         case FILEIO_WRITE_BINARY:
182                 return ((fp = _tfopen(file_path, _T("wb"))) != NULL);
183         case FILEIO_READ_WRITE_BINARY:
184                 return ((fp = _tfopen(file_path, _T("r+b"))) != NULL);
185         case FILEIO_READ_WRITE_NEW_BINARY:
186                 return ((fp = _tfopen(file_path, _T("w+b"))) != NULL);
187         case FILEIO_READ_ASCII:
188                 return ((fp = _tfopen(file_path, _T("r"))) != NULL);
189         case FILEIO_WRITE_ASCII:
190                 return ((fp = _tfopen(file_path, _T("w"))) != NULL);
191         case FILEIO_WRITE_APPEND_ASCII:
192                 return ((fp = _tfopen(file_path, _T("a"))) != NULL);
193         case FILEIO_READ_WRITE_ASCII:
194                 return ((fp = _tfopen(file_path, _T("r+"))) != NULL);
195         case FILEIO_READ_WRITE_NEW_ASCII:
196                 return ((fp = _tfopen(file_path, _T("w+"))) != NULL);
197         case FILEIO_READ_WRITE_APPEND_ASCII:
198                 return ((fp = _tfopen(file_path, _T("a+"))) != NULL);
199         }
200         return false;
201 }
202
203 #ifdef USE_ZLIB
204 bool FILEIO::Gzopen(const _TCHAR *file_path, int mode)
205 {
206         gz_size = 0;
207         
208         switch(mode) {
209         case FILEIO_READ_BINARY:
210 //      case FILEIO_READ_WRITE_BINARY:
211         case FILEIO_READ_ASCII:
212 //      case FILEIO_READ_WRITE_ASCII:
213 //      case FILEIO_READ_WRITE_APPEND_ASCII:
214                 if((fp = _tfopen(file_path, _T("rb"))) != NULL) {
215                         // check gzip header
216                         uint8_t data[10], name[_MAX_PATH] = {0};
217                         fread(data, 10, 1, fp);
218                         if(data[0] == 0x1f && data[1] == 0x8b && data[2] == 0x08) {
219                                 if(data[3] & 2) {
220                                         // skip part number
221                                         fseek(fp, 2, SEEK_CUR);
222                                 }
223                                 if(data[3] & 4) {
224                                         // skip extra field
225                                         fread(data + 4, 2, 1, fp);
226                                         fseek(fp, data[4] | (data[5] << 8), SEEK_CUR);
227                                 }
228                                 if(data[3] & 8) {
229                                         // read original file name
230                                         fread(name, sizeof(name), 1, fp);
231                                         my_stprintf_s(path, _MAX_PATH, _T("%s%s"), get_parent_dir(path), (char *)name);
232                                 }
233                                 // get uncompressed input size
234                                 fseek(fp, -4, SEEK_END);
235                                 fread(data, 4, 1, fp);
236                                 gz_size = data[0] | (data[1] << 8) | (data[2] << 16) | (data[3] << 24);
237                         }
238                         fclose(fp);
239                         fp = NULL;
240                 }
241                 if(gz_size == 0) {
242                         return false;
243                 }
244                 break;
245         }
246         switch(mode) {
247         case FILEIO_READ_BINARY:
248                 return ((gz = gzopen(tchar_to_char(file_path), "rb")) != NULL);
249 //      case FILEIO_WRITE_BINARY:
250 //              return ((fp = _tfopen(file_path, _T("wb"))) != NULL);
251 //      case FILEIO_READ_WRITE_BINARY:
252 //              return ((fp = _tfopen(file_path, _T("r+b"))) != NULL);
253 //      case FILEIO_READ_WRITE_NEW_BINARY:
254 //              return ((fp = _tfopen(file_path, _T("w+b"))) != NULL);
255         case FILEIO_READ_ASCII:
256                 return ((gz = gzopen(tchar_to_char(file_path), "r")) != NULL);
257         case FILEIO_WRITE_ASCII:
258                 return ((gz = gzopen(tchar_to_char(file_path), "w")) != NULL);
259 //      case FILEIO_WRITE_APPEND_ASCII:
260 //              return ((fp = _tfopen(file_path, _T("a"))) != NULL);
261 //      case FILEIO_READ_WRITE_ASCII:
262 //              return ((fp = _tfopen(file_path, _T("r+"))) != NULL);
263 //      case FILEIO_READ_WRITE_NEW_ASCII:
264 //              return ((fp = _tfopen(file_path, _T("w+"))) != NULL);
265 //      case FILEIO_READ_WRITE_APPEND_ASCII:
266 //              return ((fp = _tfopen(file_path, _T("a+"))) != NULL);
267         }
268         return false;
269 }
270 #endif
271
272 void FILEIO::Fclose()
273 {
274 #ifdef USE_ZLIB
275         if(gz != NULL) {
276                 gzclose(gz);
277                 gz = NULL;
278         }
279 #endif
280         if(fp != NULL) {
281                 fclose(fp);
282                 fp = NULL;
283         }
284         path[0] = _T('\0');
285 }
286
287 long FILEIO::FileLength()
288 {
289         long pos = Ftell();
290         Fseek(0, FILEIO_SEEK_END);
291         long len = Ftell();
292         Fseek(pos, FILEIO_SEEK_SET);
293         return len;
294 }
295
296 #define GET_VALUE(type) \
297         uint8_t buffer[sizeof(type)];                           \
298         type *tmpv = (type *)buffer;                            \
299         Fread(buffer, sizeof(buffer), 1);               \
300         return *tmpv;                                           
301
302 #define PUT_VALUE(type, v) \
303         Fwrite(&v, sizeof(type), 1)
304
305 bool FILEIO::FgetBool()
306 {
307         GET_VALUE(bool);
308 }
309
310 void FILEIO::FputBool(bool val)
311 {
312         PUT_VALUE(bool, val);
313 }
314
315 uint8_t FILEIO::FgetUint8()
316 {
317         GET_VALUE(uint8_t);
318 }
319
320 void FILEIO::FputUint8(uint8_t val)
321 {
322         PUT_VALUE(uint8_t, val);
323 }
324
325 uint16_t FILEIO::FgetUint16()
326 {
327         GET_VALUE(uint16_t);
328 }
329
330 void FILEIO::FputUint16(uint16_t val)
331 {
332         PUT_VALUE(uint16_t, val);
333 }
334
335 uint32_t FILEIO::FgetUint32()
336 {
337         GET_VALUE(uint32_t);
338 }
339
340 void FILEIO::FputUint32(uint32_t val)
341 {
342         PUT_VALUE(uint32_t, val);
343 }
344
345 uint64_t FILEIO::FgetUint64()
346 {
347         GET_VALUE(uint64_t);
348 }
349
350 void FILEIO::FputUint64(uint64_t val)
351 {
352         PUT_VALUE(uint64_t, val);
353 }
354
355 int8_t FILEIO::FgetInt8()
356 {
357         GET_VALUE(int8_t);
358 }
359
360 void FILEIO::FputInt8(int8_t val)
361 {
362         PUT_VALUE(int8_t, val);
363 }
364
365 int16_t FILEIO::FgetInt16()
366 {
367         GET_VALUE(int16_t);
368 }
369
370 void FILEIO::FputInt16(int16_t val)
371 {
372         PUT_VALUE(int16_t, val);
373 }
374
375 int32_t FILEIO::FgetInt32()
376 {
377         GET_VALUE(int32_t);
378 }
379
380 void FILEIO::FputInt32(int32_t val)
381 {
382         PUT_VALUE(int32_t, val);
383 }
384
385 int64_t FILEIO::FgetInt64()
386 {
387         GET_VALUE(int64_t);
388 }
389
390 void FILEIO::FputInt64(int64_t val)
391 {
392         PUT_VALUE(int64_t, val);
393 }
394
395 float FILEIO::FgetFloat()
396 {
397         GET_VALUE(float);
398 }
399
400 void FILEIO::FputFloat(float val)
401 {
402         PUT_VALUE(float, val);
403 }
404
405 double FILEIO::FgetDouble()
406 {
407         GET_VALUE(double);
408 }
409
410 void FILEIO::FputDouble(double val)
411 {
412         PUT_VALUE(double, val);
413 }
414
415 typedef union {
416         struct {
417 #ifdef __BIG_ENDIAN__
418                 uint8_t h, l;
419 #else
420                 uint8_t l, h;
421 #endif
422         } b;
423         uint16_t u16;
424         int16_t s16;
425 } pair16_t;
426
427 typedef union {
428         struct {
429 #ifdef __BIG_ENDIAN__
430                 uint8_t h3, h2, h, l;
431 #else
432                 uint8_t l, h, h2, h3;
433 #endif
434         } b;
435         uint32_t u32;
436         int32_t s32;
437 } pair32_t;
438
439 typedef union {
440         struct {
441 #ifdef __BIG_ENDIAN__
442                 uint8_t h7, h6, h5, h4, h3, h2, h, l;
443 #else
444                 uint8_t l, h, h2, h3, h4, h5, h6, h7;
445 #endif
446         } b;
447         uint64_t u64;
448         int64_t s64;
449 } pair64_t;
450
451 uint16_t FILEIO::FgetUint16_LE()
452 {
453         pair16_t tmp;
454         tmp.b.l = FgetUint8();
455         tmp.b.h = FgetUint8();
456         return tmp.u16;
457 }
458
459 void FILEIO::FputUint16_LE(uint16_t val)
460 {
461         pair16_t tmp;
462         tmp.u16 = val;
463         FputUint8(tmp.b.l);
464         FputUint8(tmp.b.h);
465 }
466
467 uint32_t FILEIO::FgetUint32_LE()
468 {
469         pair32_t tmp;
470         tmp.b.l  = FgetUint8();
471         tmp.b.h  = FgetUint8();
472         tmp.b.h2 = FgetUint8();
473         tmp.b.h3 = FgetUint8();
474         return tmp.u32;
475 }
476
477 void FILEIO::FputUint32_LE(uint32_t val)
478 {
479         pair32_t tmp;
480         tmp.u32 = val;
481         FputUint8(tmp.b.l);
482         FputUint8(tmp.b.h);
483         FputUint8(tmp.b.h2);
484         FputUint8(tmp.b.h3);
485 }
486
487 uint64_t FILEIO::FgetUint64_LE()
488 {
489         pair64_t tmp;
490         tmp.b.l  = FgetUint8();
491         tmp.b.h  = FgetUint8();
492         tmp.b.h2 = FgetUint8();
493         tmp.b.h3 = FgetUint8();
494         tmp.b.h4 = FgetUint8();
495         tmp.b.h5 = FgetUint8();
496         tmp.b.h6 = FgetUint8();
497         tmp.b.h7 = FgetUint8();
498         return tmp.u64;
499 }
500
501 void FILEIO::FputUint64_LE(uint64_t val)
502 {
503         pair64_t tmp;
504         tmp.u64 = val;
505         FputUint8(tmp.b.l);
506         FputUint8(tmp.b.h);
507         FputUint8(tmp.b.h2);
508         FputUint8(tmp.b.h3);
509         FputUint8(tmp.b.h4);
510         FputUint8(tmp.b.h5);
511         FputUint8(tmp.b.h6);
512         FputUint8(tmp.b.h7);
513 }
514
515 int16_t FILEIO::FgetInt16_LE()
516 {
517         pair16_t tmp;
518         tmp.b.l = FgetUint8();
519         tmp.b.h = FgetUint8();
520         return tmp.s16;
521 }
522
523 void FILEIO::FputInt16_LE(int16_t val)
524 {
525         pair16_t tmp;
526         tmp.s16 = val;
527         FputUint8(tmp.b.l);
528         FputUint8(tmp.b.h);
529 }
530
531 int32_t FILEIO::FgetInt32_LE()
532 {
533         pair32_t tmp;
534         tmp.b.l  = FgetUint8();
535         tmp.b.h  = FgetUint8();
536         tmp.b.h2 = FgetUint8();
537         tmp.b.h3 = FgetUint8();
538         return tmp.s32;
539 }
540
541 void FILEIO::FputInt32_LE(int32_t val)
542 {
543         pair32_t tmp;
544         tmp.s32 = val;
545         FputUint8(tmp.b.l);
546         FputUint8(tmp.b.h);
547         FputUint8(tmp.b.h2);
548         FputUint8(tmp.b.h3);
549 }
550
551 int64_t FILEIO::FgetInt64_LE()
552 {
553         pair64_t tmp;
554         tmp.b.l  = FgetUint8();
555         tmp.b.h  = FgetUint8();
556         tmp.b.h2 = FgetUint8();
557         tmp.b.h3 = FgetUint8();
558         tmp.b.h4 = FgetUint8();
559         tmp.b.h5 = FgetUint8();
560         tmp.b.h6 = FgetUint8();
561         tmp.b.h7 = FgetUint8();
562         return tmp.s64;
563 }
564
565 void FILEIO::FputInt64_LE(int64_t val)
566 {
567         pair64_t tmp;
568         tmp.s64 = val;
569         FputUint8(tmp.b.l);
570         FputUint8(tmp.b.h);
571         FputUint8(tmp.b.h2);
572         FputUint8(tmp.b.h3);
573         FputUint8(tmp.b.h4);
574         FputUint8(tmp.b.h5);
575         FputUint8(tmp.b.h6);
576         FputUint8(tmp.b.h7);
577 }
578
579 uint16_t FILEIO::FgetUint16_BE()
580 {
581         pair16_t tmp;
582         tmp.b.h = FgetUint8();
583         tmp.b.l = FgetUint8();
584         return tmp.u16;
585 }
586
587 void FILEIO::FputUint16_BE(uint16_t val)
588 {
589         pair16_t tmp;
590         tmp.u16 = val;
591         FputUint8(tmp.b.h);
592         FputUint8(tmp.b.l);
593 }
594
595 uint32_t FILEIO::FgetUint32_BE()
596 {
597         pair32_t tmp;
598         tmp.b.h3 = FgetUint8();
599         tmp.b.h2 = FgetUint8();
600         tmp.b.h  = FgetUint8();
601         tmp.b.l  = FgetUint8();
602         return tmp.u32;
603 }
604
605 void FILEIO::FputUint32_BE(uint32_t val)
606 {
607         pair32_t tmp;
608         tmp.u32 = val;
609         FputUint8(tmp.b.h3);
610         FputUint8(tmp.b.h2);
611         FputUint8(tmp.b.h);
612         FputUint8(tmp.b.l);
613 }
614
615 uint64_t FILEIO::FgetUint64_BE()
616 {
617         pair64_t tmp;
618         tmp.b.h7 = FgetUint8();
619         tmp.b.h6 = FgetUint8();
620         tmp.b.h5 = FgetUint8();
621         tmp.b.h4 = FgetUint8();
622         tmp.b.h3 = FgetUint8();
623         tmp.b.h2 = FgetUint8();
624         tmp.b.h  = FgetUint8();
625         tmp.b.l  = FgetUint8();
626         return tmp.u64;
627 }
628
629 void FILEIO::FputUint64_BE(uint64_t val)
630 {
631         pair64_t tmp;
632         tmp.u64 = val;
633         FputUint8(tmp.b.h7);
634         FputUint8(tmp.b.h6);
635         FputUint8(tmp.b.h5);
636         FputUint8(tmp.b.h4);
637         FputUint8(tmp.b.h3);
638         FputUint8(tmp.b.h2);
639         FputUint8(tmp.b.h);
640         FputUint8(tmp.b.l);
641 }
642
643 int16_t FILEIO::FgetInt16_BE()
644 {
645         pair16_t tmp;
646         tmp.b.h = FgetUint8();
647         tmp.b.l = FgetUint8();
648         return tmp.s16;
649 }
650
651 void FILEIO::FputInt16_BE(int16_t val)
652 {
653         pair16_t tmp;
654         tmp.s16 = val;
655         FputUint8(tmp.b.h);
656         FputUint8(tmp.b.l);
657 }
658
659 int32_t FILEIO::FgetInt32_BE()
660 {
661         pair32_t tmp;
662         tmp.b.h3 = FgetUint8();
663         tmp.b.h2 = FgetUint8();
664         tmp.b.h  = FgetUint8();
665         tmp.b.l  = FgetUint8();
666         return tmp.s32;
667 }
668
669 void FILEIO::FputInt32_BE(int32_t val)
670 {
671         pair32_t tmp;
672         tmp.s32 = val;
673         FputUint8(tmp.b.h3);
674         FputUint8(tmp.b.h2);
675         FputUint8(tmp.b.h);
676         FputUint8(tmp.b.l);
677 }
678
679 int64_t FILEIO::FgetInt64_BE()
680 {
681         pair64_t tmp;
682         tmp.b.h7 = FgetUint8();
683         tmp.b.h6 = FgetUint8();
684         tmp.b.h5 = FgetUint8();
685         tmp.b.h4 = FgetUint8();
686         tmp.b.h3 = FgetUint8();
687         tmp.b.h2 = FgetUint8();
688         tmp.b.h  = FgetUint8();
689         tmp.b.l  = FgetUint8();
690         return tmp.s64;
691 }
692
693 void FILEIO::FputInt64_BE(int64_t val)
694 {
695         pair64_t tmp;
696         tmp.s64 = val;
697         FputUint8(tmp.b.h7);
698         FputUint8(tmp.b.h6);
699         FputUint8(tmp.b.h5);
700         FputUint8(tmp.b.h4);
701         FputUint8(tmp.b.h3);
702         FputUint8(tmp.b.h2);
703         FputUint8(tmp.b.h);
704         FputUint8(tmp.b.l);
705 }
706
707 int FILEIO::Fgetc()
708 {
709 #ifdef USE_ZLIB
710         if(gz != NULL) {
711                 return gzgetc(gz);
712         } else
713 #endif
714         {
715                 if(fp != NULL) {
716                         return getc(fp);
717                 } else {
718                         return 0;
719                 }
720         }
721 }
722
723 int FILEIO::Fputc(int c)
724 {
725 #ifdef USE_ZLIB
726         if(gz != NULL) {
727                 return gzputc(gz, c);
728         } else
729 #endif
730         {
731                 if(fp != NULL) {
732                         return fputc(c, fp);
733                 } else {
734                         return 0;
735                 }
736         }
737 }
738
739 char *FILEIO::Fgets(char *str, int n)
740 {
741 #ifdef USE_ZLIB
742         if(gz != NULL) {
743                 return gzgets(gz, str, n);
744         } else
745 #endif
746         {
747                 if(fp != NULL) {
748                         return fgets(str, n, fp);
749                 } else {
750                         return 0;
751                 }
752         }
753 }
754
755 _TCHAR *FILEIO::Fgetts(_TCHAR *str, int n)
756 {
757 #ifdef USE_ZLIB
758         if(gz != NULL) {
759 #if defined(_UNICODE) && defined(SUPPORT_TCHAR_TYPE)
760                 char *str_mb = (char *)calloc(sizeof(char), n + 1);
761                 gzgets(gz, str_mb, n);
762                 my_swprintf_s(str, n, L"%s", char_to_wchar(str_mb));
763                 free(str_mb);
764                 return str;
765 #else
766                 return gzgets(gz, str, n);
767 #endif
768         } else
769 #endif
770         return _fgetts(str, n, fp);
771 }
772
773 int FILEIO::Fprintf(const char* format, ...)
774 {
775         va_list ap;
776         char buffer[1024];
777         
778         va_start(ap, format);
779         my_vsprintf_s(buffer, 1024, format, ap);
780         va_end(ap);
781         
782 #ifdef USE_ZLIB
783         if(gz != NULL) {
784                 return gzprintf(gz, "%s", buffer);
785         } else
786 #endif
787         {
788                 if(fp != NULL) {
789                         return my_fprintf_s(fp, "%s", buffer);
790                 } else {
791                         return 0;
792                 }
793         }
794 }
795
796 int FILEIO::Ftprintf(const _TCHAR* format, ...)
797 {
798         va_list ap;
799         _TCHAR buffer[1024];
800         
801         va_start(ap, format);
802         my_vstprintf_s(buffer, 1024, format, ap);
803         va_end(ap);
804         
805 #ifdef USE_ZLIB
806         if(gz != NULL) {
807                 return gzprintf(gz, "%s", tchar_to_char(buffer));
808         } else
809 #endif
810         return my_ftprintf_s(fp, _T("%s"), buffer);
811 }
812
813 size_t FILEIO::Fread(void* buffer, size_t size, size_t count)
814 {
815 #ifdef USE_ZLIB
816         if(gz != NULL) {
817                 return gzfread(buffer, size, count, gz);
818         } else
819 #endif
820         {
821                 if(fp != NULL) {
822                         return fread(buffer, size, count, fp);
823                 } else {
824                         return 0;
825                 }
826         }
827 }
828
829 size_t FILEIO::Fwrite(const void* buffer, size_t size, size_t count)
830 {
831 #ifdef USE_ZLIB
832         if(gz != NULL) {
833                 return gzfwrite(buffer, size, count, gz);
834         } else
835 #endif
836         {
837                 if(fp != NULL) {
838                         return fwrite(buffer, size, count, fp);
839                 } else {
840                         return 0;
841                 }
842         }
843 }
844
845 int FILEIO::Fseek(long offset, int origin)
846 {
847 #ifdef USE_ZLIB
848         if(gz != NULL) {
849                 switch(origin) {
850                 case FILEIO_SEEK_CUR:
851                         return gzseek(gz, offset, SEEK_CUR);
852                 case FILEIO_SEEK_END:
853                         return gzseek(gz, offset + gz_size, SEEK_SET);
854                 case FILEIO_SEEK_SET:
855                         return gzseek(gz, offset, SEEK_SET);
856                 }
857         } else
858 #endif
859         {
860                 if(fp == NULL) return -1;
861                 switch(origin) {
862                 case FILEIO_SEEK_CUR:
863                         return fseek(fp, offset, SEEK_CUR);
864                 case FILEIO_SEEK_END:
865                         return fseek(fp, offset, SEEK_END);
866                 case FILEIO_SEEK_SET:
867                         return fseek(fp, offset, SEEK_SET);
868                 }
869         }
870         return -1;
871 }
872
873 long FILEIO::Ftell()
874 {
875 #ifdef USE_ZLIB
876         if(gz != NULL) {
877                 return gztell(gz);
878         } else
879 #endif
880         {
881                 if(fp != NULL) {
882                         return ftell(fp);
883                 } else {
884                         return 0;
885                 }
886         }
887 }
888
889
890 bool FILEIO::Fcompare(const void* buffer, size_t size)
891 {
892         bool result = false;
893         void *tmp = malloc(size);
894         
895         if(Fread(tmp, size, 1) == 1) {
896                 result = (memcmp(buffer, tmp, size) == 0);
897         }
898         free(tmp);
899         return result;
900 }