OSDN Git Service

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