OSDN Git Service

[EMU] Enable to Gzip'ed state saving / loading.
[csp-qt/common_source_project-fm7.git] / source / src / fileio.cpp
index 6226570..fd431ae 100644 (file)
-/*\r
-       Skelton for retropc emulator\r
-\r
-       Author : Takeda.Toshiya\r
-       Date   : 2006.08.18 -\r
-\r
-       [ file i/o ]\r
-*/\r
-\r
-#include "fileio.h"\r
-\r
-FILEIO::FILEIO()\r
-{\r
-      fp = NULL;\r
-}\r
-\r
-FILEIO::~FILEIO(void)\r
-{\r
-    Fclose();\r
-#ifdef _USE_QT\r
-    if(fp != NULL) {\r
-       fp->close();\r
-       delete fp;\r
-    }\r
-   \r
-#endif\r
-}\r
-\r
-bool FILEIO::IsFileExists(_TCHAR *filename)\r
-{\r
-#if defined(_USE_AGAR) || defined(_USE_SDL)\r
-       if(AG_FileExists((char *)filename) > 0) return true;\r
-       return false;\r
-#elif defined(_USE_QT)\r
-       QString   fname((const char *)filename);\r
-       QFileInfo f(fname);\r
-   \r
-       bool val = false;\r
-       if(f.exists()) val = true;\r
-   \r
-       return val;\r
-#else   \r
-        DWORD attr = GetFileAttributes(filename);\r
-       if(attr == -1) {\r
-               return false;\r
-       }\r
-       return ((attr & FILE_ATTRIBUTE_DIRECTORY) == 0);\r
-#endif\r
-}\r
-\r
-bool FILEIO::IsProtected(_TCHAR *filename)\r
-{\r
-#if defined(_USE_AGAR) || defined(_USE_SDL)\r
-        AG_FileInfo inf;\r
-        AG_GetFileInfo((char *)filename, &inf);\r
-        return ((inf.perms & AG_FILE_WRITEABLE) == 0);\r
-#elif defined(_USE_QT)\r
-       QString   fname((const char *)filename);\r
-       QFileInfo f(fname);\r
-   \r
-       bool val = false;\r
-       if(f.exists()) {\r
-         if(f.isReadable() && !(f.isWritable())) val = true;\r
-       }\r
-   \r
-       return val;\r
-#else\r
-       return ((GetFileAttributes(filename) & FILE_ATTRIBUTE_READONLY) != 0);\r
-#endif\r
-}\r
-\r
-bool FILEIO::Fopen(_TCHAR *filename, int mode)\r
-{\r
-#if defined(_USE_QT)\r
-        if(fp != NULL) {\r
-          fp->close();\r
-       }\r
-        fp = new QFile((const char *)filename);\r
-        int open_mode;\r
-       switch(mode) {\r
-       case FILEIO_READ_BINARY:\r
-               mode = IO_ReadOnly;\r
-               break;\r
-       case FILEIO_WRITE_BINARY:\r
-               mode = IO_WriteOnly;\r
-               break;\r
-       case FILEIO_READ_WRITE_BINARY:\r
-               mode = IO_ReadWrite;\r
-               break;\r
-       case FILEIO_READ_WRITE_NEW_BINARY:\r
-               mode = IO_ReadWrite;\r
-               break;\r
-       case FILEIO_READ_ASCII:\r
-               mode = IO_ReadOnly | IO_Translate;\r
-               break;\r
-       case FILEIO_WRITE_ASCII:\r
-               mode = IO_WriteOnly | IO_Translate;\r
-               break;\r
-       case FILEIO_READ_WRITE_ASCII:\r
-               mode = IO_ReadWrite | IO_Translate;\r
-               break;\r
-       case FILEIO_READ_WRITE_NEW_ASCII:\r
-               mode = IO_ReadWrite | IO_Translate;\r
-               break;\r
-        default:\r
-               return false;\r
-               break;\r
-       }\r
-        return fp->open(mode);\r
-  \r
-#else   \r
-        Fclose();\r
-       switch(mode) {\r
-       case FILEIO_READ_BINARY:\r
-               return ((fp = _tfopen(filename, _T("rb"))) != NULL);\r
-       case FILEIO_WRITE_BINARY:\r
-               return ((fp = _tfopen(filename, _T("wb"))) != NULL);\r
-       case FILEIO_READ_WRITE_BINARY:\r
-               return ((fp = _tfopen(filename, _T("r+b"))) != NULL);\r
-       case FILEIO_READ_WRITE_NEW_BINARY:\r
-               return ((fp = _tfopen(filename, _T("w+b"))) != NULL);\r
-       case FILEIO_READ_ASCII:\r
-               return ((fp = _tfopen(filename, _T("r"))) != NULL);\r
-       case FILEIO_WRITE_ASCII:\r
-               return ((fp = _tfopen(filename, _T("w"))) != NULL);\r
-       case FILEIO_READ_WRITE_ASCII:\r
-               return ((fp = _tfopen(filename, _T("r+"))) != NULL);\r
-       case FILEIO_READ_WRITE_NEW_ASCII:\r
-               return ((fp = _tfopen(filename, _T("w+"))) != NULL);\r
-       }\r
-       return false;\r
-#endif\r
-}\r
-\r
-void FILEIO::Fclose()\r
-{\r
-#if defined(_USE_QT)\r
-       if(fp) {\r
-         fp->flush();\r
-         fp->close();\r
-         delete fp;\r
-       }\r
-   \r
-#else\r
-        if(fp) {\r
-               fclose(fp);\r
-       }\r
-#endif\r
-       fp = NULL;\r
-}\r
-#if defined(_USE_QT)\r
-\r
-# define GET_VALUE(type) \\r
-       uint8 buffer[sizeof(type)]; \\r
-       fp->readBlock(buffer, sizeof(type)); \n\r
-       return *(type *)buffer\r
-\r
-#define PUT_VALUE(type, v) \\r
-        fp->writeBlock(&v, sizeof(type))\r
-\r
-#else\r
-\r
-# define GET_VALUE(type) \\r
-       uint8 buffer[sizeof(type)]; \\r
-       fread(buffer, sizeof(buffer), 1, fp); \\r
-       return *(type *)buffer\r
-\r
-#define PUT_VALUE(type, v) \\r
-       fwrite(&v, sizeof(type), 1, fp)\r
-\r
-#endif\r
-\r
-bool FILEIO::FgetBool()\r
-{\r
-       GET_VALUE(bool);\r
-}\r
-\r
-void FILEIO::FputBool(bool val)\r
-{\r
-       PUT_VALUE(bool, val);\r
-}\r
-\r
-uint8 FILEIO::FgetUint8()\r
-{\r
-       GET_VALUE(uint8);\r
-}\r
-\r
-void FILEIO::FputUint8(uint8 val)\r
-{\r
-       PUT_VALUE(uint8, val);\r
-}\r
-\r
-uint16 FILEIO::FgetUint16()\r
-{\r
-       GET_VALUE(uint16);\r
-}\r
-\r
-void FILEIO::FputUint16(uint16 val)\r
-{\r
-       PUT_VALUE(uint16, val);\r
-}\r
-\r
-uint32 FILEIO::FgetUint32()\r
-{\r
-       GET_VALUE(uint32);\r
-}\r
-\r
-void FILEIO::FputUint32(uint32 val)\r
-{\r
-       PUT_VALUE(uint32, val);\r
-}\r
-\r
-uint64 FILEIO::FgetUint64()\r
-{\r
-       GET_VALUE(uint64);\r
-}\r
-\r
-void FILEIO::FputUint64(uint64 val)\r
-{\r
-       PUT_VALUE(uint64, val);\r
-}\r
-\r
-int8 FILEIO::FgetInt8()\r
-{\r
-       GET_VALUE(int8);\r
-}\r
-\r
-void FILEIO::FputInt8(int8 val)\r
-{\r
-       PUT_VALUE(int8, val);\r
-}\r
-\r
-int16 FILEIO::FgetInt16()\r
-{\r
-       GET_VALUE(int16);\r
-}\r
-\r
-void FILEIO::FputInt16(int16 val)\r
-{\r
-       PUT_VALUE(int16, val);\r
-}\r
-\r
-int32 FILEIO::FgetInt32()\r
-{\r
-       GET_VALUE(int32);\r
-}\r
-\r
-void FILEIO::FputInt32(int32 val)\r
-{\r
-       PUT_VALUE(int32, val);\r
-}\r
-\r
-int64 FILEIO::FgetInt64()\r
-{\r
-       GET_VALUE(int64);\r
-}\r
-\r
-void FILEIO::FputInt64(int64 val)\r
-{\r
-       PUT_VALUE(int64, val);\r
-}\r
-\r
-float FILEIO::FgetFloat()\r
-{\r
-       GET_VALUE(float);\r
-}\r
-\r
-void FILEIO::FputFloat(float val)\r
-{\r
-       PUT_VALUE(float, val);\r
-}\r
-\r
-double FILEIO::FgetDouble()\r
-{\r
-       GET_VALUE(double);\r
-}\r
-\r
-void FILEIO::FputDouble(double val)\r
-{\r
-       PUT_VALUE(double, val);\r
-}\r
-\r
-int FILEIO::Fgetc()\r
-{\r
-#if defined(_USE_QT)\r
-        return fp->getch();\r
-#else\r
-       return fgetc(fp);\r
-#endif\r
-}\r
-\r
-int FILEIO::Fputc(int c)\r
-{\r
-#if defined(_USE_QT)\r
-        return fp->putch(c);\r
-#else\r
-       return fputc(c, fp);\r
-#endif\r
-}\r
-\r
-uint32 FILEIO::Fread(void* buffer, uint32 size, uint32 count)\r
-{\r
-#if defined(_USE_QT)\r
-        uint64 l = (uint64)size * (uint64)count;\r
-        l = l + fp->readData(buffer, l);\r
-        return (uint32)l;\r
-#else\r
-       return fread(buffer, size, count, fp);\r
-#endif\r
-}\r
-\r
-uint32 FILEIO::Fwrite(void* buffer, uint32 size, uint32 count)\r
-{\r
-#if defined(_USE_QT)\r
-        uint64 l = (uint64)size * (uint64)count;\r
-        l = l + fp->writeData(buffer, l);\r
-        return (uint32)l;\r
-#else\r
-       return fwrite(buffer, size, count, fp);\r
-#endif\r
-}\r
-\r
-uint32 FILEIO::Fseek(long offset, int origin)\r
-{\r
-#if defined(_USE_QT)\r
-        switch(origin) {\r
-       case FILEIO_SEEK_CUR:\r
-               if( fp->seek(offset + fp->pos())) ) return 0;\r
-       case FILEIO_SEEK_END:\r
-               fp->seek(fp->size()); return 0; \r
-        case FILEIO_SEEK_SET:\r
-               if(fp->seek(0)) return 0;\r
-       }\r
-       return 0xFFFFFFFF;\r
-   \r
-#else\r
-        switch(origin) {\r
-       case FILEIO_SEEK_CUR:\r
-               return fseek(fp, offset, SEEK_CUR);\r
-       case FILEIO_SEEK_END:\r
-               return fseek(fp, offset, SEEK_END);\r
-       case FILEIO_SEEK_SET:\r
-               return fseek(fp, offset, SEEK_SET);\r
-       }\r
-       return 0xFFFFFFFF;\r
-#endif\r
-}\r
-\r
-uint32 FILEIO::Ftell()\r
-{\r
-#if defined(_USE_QT)\r
-    return (uint32) fp->pos();\r
-#else\r
-   return ftell(fp);\r
-#endif\r
-}\r
-\r
-void FILEIO::Remove(_TCHAR *filename)\r
-{\r
-#if defined(_USE_QT)\r
-   QString fname = (char *)filename;\r
-   QFile tmpfp;\r
-   tmpfp.remove(fname);\r
-   \r
-#else\r
-   DeleteFile(filename);\r
-#endif\r
-//     _tremove(filename);     // not supported on wince\r
-}\r
+/*
+       Skelton for retropc emulator
+
+       Author : Takeda.Toshiya
+       Date   : 2006.08.18 -
+
+       [ file i/o ]
+*/
+
+#if defined(_USE_QT) || defined(_USE_SDL)
+       #include <stdarg.h>
+       #include <fcntl.h>
+       #include <stdio.h>
+       #include <iostream>
+       #include <fstream>
+       #include <cstdio>
+       #if defined(_USE_QT)
+               #include <sys/types.h>
+               #include <sys/stat.h>
+               #if !defined(Q_OS_WIN)
+                       #include <unistd.h>
+               #endif
+       #endif
+#elif defined(_WIN32)
+       #include <windows.h>
+#endif
+#include "fileio.h"
+#if !defined(_MSC_VER)
+#include <stdarg.h>
+#include <fcntl.h>
+#include <stdio.h>
+#include <iostream>
+#include <fstream>
+#include <cstdio>
+#endif
+
+#ifdef USE_ZLIB
+       #if defined(USE_QT)
+               #include <zlib.h>
+               #include <zconf.h>
+       #else
+               #ifdef _WIN32
+                       #define ZLIB_WINAPI
+               #endif
+               #include "zlib-1.2.11/zlib.h"
+               #include "zlib-1.2.11/zconf.h"
+       #endif
+#endif
+
+#if ZLIB_VERNUM < 0x1290
+inline size_t gzfread(void *buffer, size_t size, size_t count, gzFile file)
+{
+       uint8_t *p = (uint8_t *)buffer;
+       int s = 0;
+       int i = 0;
+       for(i = 0; i < count; i++) {
+               for(int j = 0; j < size; j++) {
+                       s = gzgetc(file);
+                       if(s < 0) return 0; // EOF
+                       *p++ = (uint8_t)s; 
+               }
+       }
+       return i + 1;
+}
+inline size_t gzfwrite(void *buffer, size_t size, size_t count, gzFile file)
+{
+       uint8_t *p = (uint8_t *)buffer;
+       uint8_t n;
+       int s = 0;
+       int i = 0;
+       for(i = 0; i < count; i++) {
+               for(int j = 0; j < size; j++) {
+                       n = *p++; 
+                       s = gzputc(file, n);
+                       if(s < 0) return 0; // EOF
+               }
+       }
+       return i + 1;
+}
+#endif                 
+FILEIO::FILEIO()
+{
+#ifdef USE_ZLIB
+       gz = NULL;
+#endif
+       fp = NULL;
+       path[0] = _T('\0');
+}
+
+FILEIO::~FILEIO(void)
+{
+       Fclose();
+}
+
+bool FILEIO::IsFileExisting(const _TCHAR *file_path)
+{
+#if defined(_USE_QT) || defined(_USE_SDL)
+       FILE *f;
+       f = fopen(file_path, "r");
+       if(f != NULL)  {
+               fclose(f);         
+               return true;
+       }
+       return false;
+#elif defined(_WIN32)
+       DWORD attr = GetFileAttributes(file_path);
+       if(attr == -1) {
+               return false;
+       }
+       return ((attr & FILE_ATTRIBUTE_DIRECTORY) == 0);
+#else
+       return (_taccess(file_path, 0) == 0);
+#endif
+}
+
+#if defined(_USE_QT)
+# include <sys/types.h>
+# include <sys/stat.h>
+# if !defined(Q_OS_WIN)
+#   include <unistd.h>
+# endif
+#endif
+bool FILEIO::IsFileProtected(const _TCHAR *file_path)
+{
+#if defined(_USE_QT) || defined(_USE_SDL)
+       struct stat st;
+       if(stat(file_path, &st) == 0) {
+# if defined(_WIN32)
+               if((st.st_mode & S_IWUSR) == 0) {
+# else
+               if((st.st_mode & (S_IWUSR | S_IWGRP | S_IWOTH)) == 0) {
+# endif
+                       return true;
+               }
+       }
+       return false;
+#elif defined(_WIN32)
+       return ((GetFileAttributes(file_path) & FILE_ATTRIBUTE_READONLY) != 0);
+#else
+       return (_taccess(file_path, 2) != 0);
+#endif
+}
+
+bool FILEIO::RemoveFile(const _TCHAR *file_path)
+{
+#if defined(_USE_QT) || defined(_USE_SDL)
+       return (remove(file_path) == 0);
+#elif defined(_WIN32)
+       return (DeleteFile(file_path) != 0);
+#else
+       return (_tremove(file_path) == 0);      // not supported on wince ???
+#endif
+}
+
+bool FILEIO::RenameFile(const _TCHAR *existing_file_path, const _TCHAR *new_file_path)
+{
+#if defined(_USE_QT) || defined(_USE_SDL)
+       return (rename(existing_file_path, new_file_path) == 0);
+#elif defined(_WIN32)
+       return (MoveFile(existing_file_path, new_file_path) != 0);
+#else
+       return (_trename(existing_file_path, new_file_path) == 0);
+#endif                 
+}
+
+bool FILEIO::Fopen(const _TCHAR *file_path, int mode)
+{
+       Fclose();
+       
+       // store file path
+       my_tcscpy_s(path, _MAX_PATH, file_path);
+       
+#ifdef USE_ZLIB
+       if(check_file_extension(file_path, _T(".gz"))) {
+               return Gzopen(file_path, mode);
+       }
+#endif
+       switch(mode) {
+       case FILEIO_READ_BINARY:
+               return ((fp = _tfopen(file_path, _T("rb"))) != NULL);
+       case FILEIO_WRITE_BINARY:
+               return ((fp = _tfopen(file_path, _T("wb"))) != NULL);
+       case FILEIO_READ_WRITE_BINARY:
+               return ((fp = _tfopen(file_path, _T("r+b"))) != NULL);
+       case FILEIO_READ_WRITE_NEW_BINARY:
+               return ((fp = _tfopen(file_path, _T("w+b"))) != NULL);
+       case FILEIO_READ_ASCII:
+               return ((fp = _tfopen(file_path, _T("r"))) != NULL);
+       case FILEIO_WRITE_ASCII:
+               return ((fp = _tfopen(file_path, _T("w"))) != NULL);
+       case FILEIO_WRITE_APPEND_ASCII:
+               return ((fp = _tfopen(file_path, _T("a"))) != NULL);
+       case FILEIO_READ_WRITE_ASCII:
+               return ((fp = _tfopen(file_path, _T("r+"))) != NULL);
+       case FILEIO_READ_WRITE_NEW_ASCII:
+               return ((fp = _tfopen(file_path, _T("w+"))) != NULL);
+       case FILEIO_READ_WRITE_APPEND_ASCII:
+               return ((fp = _tfopen(file_path, _T("a+"))) != NULL);
+       }
+       return false;
+}
+
+#ifdef USE_ZLIB
+bool FILEIO::Gzopen(const _TCHAR *file_path, int mode)
+{
+       gz_size = 0;
+       
+       switch(mode) {
+       case FILEIO_READ_BINARY:
+//     case FILEIO_READ_WRITE_BINARY:
+       case FILEIO_READ_ASCII:
+//     case FILEIO_READ_WRITE_ASCII:
+//     case FILEIO_READ_WRITE_APPEND_ASCII:
+               if((fp = _tfopen(file_path, _T("rb"))) != NULL) {
+                       // check gzip header
+                       uint8_t data[10], name[_MAX_PATH] = {0};
+                       fread(data, 10, 1, fp);
+                       if(data[0] == 0x1f && data[1] == 0x8b && data[2] == 0x08) {
+                               if(data[3] & 2) {
+                                       // skip part number
+                                       fseek(fp, 2, SEEK_CUR);
+                               }
+                               if(data[3] & 4) {
+                                       // skip extra field
+                                       fread(data + 4, 2, 1, fp);
+                                       fseek(fp, data[4] | (data[5] << 8), SEEK_CUR);
+                               }
+                               if(data[3] & 8) {
+                                       // read original file name
+                                       fread(name, sizeof(name), 1, fp);
+                                       my_stprintf_s(path, _MAX_PATH, _T("%s%s"), get_parent_dir(path), (char *)name);
+                               }
+                               // get uncompressed input size
+                               fseek(fp, -4, SEEK_END);
+                               fread(data, 4, 1, fp);
+                               gz_size = data[0] | (data[1] << 8) | (data[2] << 16) | (data[3] << 24);
+                       }
+                       fclose(fp);
+                       fp = NULL;
+               }
+               if(gz_size == 0) {
+                       return false;
+               }
+               break;
+       }
+       switch(mode) {
+       case FILEIO_READ_BINARY:
+               return ((gz = gzopen(tchar_to_char(file_path), "rb")) != NULL);
+       case FILEIO_WRITE_BINARY:
+               return ((gz = gzopen(tchar_to_char(file_path), "wb")) != NULL);
+//     case FILEIO_READ_WRITE_BINARY:
+//             return ((fp = _tfopen(file_path, _T("r+b"))) != NULL);
+//     case FILEIO_READ_WRITE_NEW_BINARY:
+//             return ((fp = _tfopen(file_path, _T("w+b"))) != NULL);
+       case FILEIO_READ_ASCII:
+               return ((gz = gzopen(tchar_to_char(file_path), "r")) != NULL);
+       case FILEIO_WRITE_ASCII:
+               return ((gz = gzopen(tchar_to_char(file_path), "w")) != NULL);
+//     case FILEIO_WRITE_APPEND_ASCII:
+//             return ((fp = _tfopen(file_path, _T("a"))) != NULL);
+//     case FILEIO_READ_WRITE_ASCII:
+//             return ((fp = _tfopen(file_path, _T("r+"))) != NULL);
+//     case FILEIO_READ_WRITE_NEW_ASCII:
+//             return ((fp = _tfopen(file_path, _T("w+"))) != NULL);
+//     case FILEIO_READ_WRITE_APPEND_ASCII:
+//             return ((fp = _tfopen(file_path, _T("a+"))) != NULL);
+       }
+       return false;
+}
+#endif
+
+void FILEIO::Fclose()
+{
+#ifdef USE_ZLIB
+       if(gz != NULL) {
+               gzclose(gz);
+               gz = NULL;
+       }
+#endif
+       if(fp != NULL) {
+               fclose(fp);
+               fp = NULL;
+       }
+       path[0] = _T('\0');
+}
+
+long FILEIO::FileLength()
+{
+       long pos = Ftell();
+       Fseek(0, FILEIO_SEEK_END);
+       long len = Ftell();
+       Fseek(pos, FILEIO_SEEK_SET);
+       return len;
+}
+
+#define GET_VALUE(type) \
+       uint8_t buffer[sizeof(type)];                           \
+       type *tmpv = (type *)buffer;                            \
+       Fread(buffer, sizeof(buffer), 1);               \
+       return *tmpv;                                           
+
+#define PUT_VALUE(type, v) \
+       Fwrite(&v, sizeof(type), 1)
+
+bool FILEIO::FgetBool()
+{
+       GET_VALUE(bool);
+}
+
+void FILEIO::FputBool(bool val)
+{
+       PUT_VALUE(bool, val);
+}
+
+uint8_t FILEIO::FgetUint8()
+{
+       GET_VALUE(uint8_t);
+}
+
+void FILEIO::FputUint8(uint8_t val)
+{
+       PUT_VALUE(uint8_t, val);
+}
+
+uint16_t FILEIO::FgetUint16()
+{
+       GET_VALUE(uint16_t);
+}
+
+void FILEIO::FputUint16(uint16_t val)
+{
+       PUT_VALUE(uint16_t, val);
+}
+
+uint32_t FILEIO::FgetUint32()
+{
+       GET_VALUE(uint32_t);
+}
+
+void FILEIO::FputUint32(uint32_t val)
+{
+       PUT_VALUE(uint32_t, val);
+}
+
+uint64_t FILEIO::FgetUint64()
+{
+       GET_VALUE(uint64_t);
+}
+
+void FILEIO::FputUint64(uint64_t val)
+{
+       PUT_VALUE(uint64_t, val);
+}
+
+int8_t FILEIO::FgetInt8()
+{
+       GET_VALUE(int8_t);
+}
+
+void FILEIO::FputInt8(int8_t val)
+{
+       PUT_VALUE(int8_t, val);
+}
+
+int16_t FILEIO::FgetInt16()
+{
+       GET_VALUE(int16_t);
+}
+
+void FILEIO::FputInt16(int16_t val)
+{
+       PUT_VALUE(int16_t, val);
+}
+
+int32_t FILEIO::FgetInt32()
+{
+       GET_VALUE(int32_t);
+}
+
+void FILEIO::FputInt32(int32_t val)
+{
+       PUT_VALUE(int32_t, val);
+}
+
+int64_t FILEIO::FgetInt64()
+{
+       GET_VALUE(int64_t);
+}
+
+void FILEIO::FputInt64(int64_t val)
+{
+       PUT_VALUE(int64_t, val);
+}
+
+float FILEIO::FgetFloat()
+{
+       GET_VALUE(float);
+}
+
+void FILEIO::FputFloat(float val)
+{
+       PUT_VALUE(float, val);
+}
+
+double FILEIO::FgetDouble()
+{
+       GET_VALUE(double);
+}
+
+void FILEIO::FputDouble(double val)
+{
+       PUT_VALUE(double, val);
+}
+
+typedef union {
+       struct {
+#ifdef __BIG_ENDIAN__
+               uint8_t h, l;
+#else
+               uint8_t l, h;
+#endif
+       } b;
+       uint16_t u16;
+       int16_t s16;
+} pair16_t;
+
+typedef union {
+       struct {
+#ifdef __BIG_ENDIAN__
+               uint8_t h3, h2, h, l;
+#else
+               uint8_t l, h, h2, h3;
+#endif
+       } b;
+       uint32_t u32;
+       int32_t s32;
+} pair32_t;
+
+typedef union {
+       struct {
+#ifdef __BIG_ENDIAN__
+               uint8_t h7, h6, h5, h4, h3, h2, h, l;
+#else
+               uint8_t l, h, h2, h3, h4, h5, h6, h7;
+#endif
+       } b;
+       uint64_t u64;
+       int64_t s64;
+} pair64_t;
+
+uint16_t FILEIO::FgetUint16_LE()
+{
+       pair16_t tmp;
+       tmp.b.l = FgetUint8();
+       tmp.b.h = FgetUint8();
+       return tmp.u16;
+}
+
+void FILEIO::FputUint16_LE(uint16_t val)
+{
+       pair16_t tmp;
+       tmp.u16 = val;
+       FputUint8(tmp.b.l);
+       FputUint8(tmp.b.h);
+}
+
+uint32_t FILEIO::FgetUint32_LE()
+{
+       pair32_t tmp;
+       tmp.b.l  = FgetUint8();
+       tmp.b.h  = FgetUint8();
+       tmp.b.h2 = FgetUint8();
+       tmp.b.h3 = FgetUint8();
+       return tmp.u32;
+}
+
+void FILEIO::FputUint32_LE(uint32_t val)
+{
+       pair32_t tmp;
+       tmp.u32 = val;
+       FputUint8(tmp.b.l);
+       FputUint8(tmp.b.h);
+       FputUint8(tmp.b.h2);
+       FputUint8(tmp.b.h3);
+}
+
+uint64_t FILEIO::FgetUint64_LE()
+{
+       pair64_t tmp;
+       tmp.b.l  = FgetUint8();
+       tmp.b.h  = FgetUint8();
+       tmp.b.h2 = FgetUint8();
+       tmp.b.h3 = FgetUint8();
+       tmp.b.h4 = FgetUint8();
+       tmp.b.h5 = FgetUint8();
+       tmp.b.h6 = FgetUint8();
+       tmp.b.h7 = FgetUint8();
+       return tmp.u64;
+}
+
+void FILEIO::FputUint64_LE(uint64_t val)
+{
+       pair64_t tmp;
+       tmp.u64 = val;
+       FputUint8(tmp.b.l);
+       FputUint8(tmp.b.h);
+       FputUint8(tmp.b.h2);
+       FputUint8(tmp.b.h3);
+       FputUint8(tmp.b.h4);
+       FputUint8(tmp.b.h5);
+       FputUint8(tmp.b.h6);
+       FputUint8(tmp.b.h7);
+}
+
+int16_t FILEIO::FgetInt16_LE()
+{
+       pair16_t tmp;
+       tmp.b.l = FgetUint8();
+       tmp.b.h = FgetUint8();
+       return tmp.s16;
+}
+
+void FILEIO::FputInt16_LE(int16_t val)
+{
+       pair16_t tmp;
+       tmp.s16 = val;
+       FputUint8(tmp.b.l);
+       FputUint8(tmp.b.h);
+}
+
+int32_t FILEIO::FgetInt32_LE()
+{
+       pair32_t tmp;
+       tmp.b.l  = FgetUint8();
+       tmp.b.h  = FgetUint8();
+       tmp.b.h2 = FgetUint8();
+       tmp.b.h3 = FgetUint8();
+       return tmp.s32;
+}
+
+void FILEIO::FputInt32_LE(int32_t val)
+{
+       pair32_t tmp;
+       tmp.s32 = val;
+       FputUint8(tmp.b.l);
+       FputUint8(tmp.b.h);
+       FputUint8(tmp.b.h2);
+       FputUint8(tmp.b.h3);
+}
+
+int64_t FILEIO::FgetInt64_LE()
+{
+       pair64_t tmp;
+       tmp.b.l  = FgetUint8();
+       tmp.b.h  = FgetUint8();
+       tmp.b.h2 = FgetUint8();
+       tmp.b.h3 = FgetUint8();
+       tmp.b.h4 = FgetUint8();
+       tmp.b.h5 = FgetUint8();
+       tmp.b.h6 = FgetUint8();
+       tmp.b.h7 = FgetUint8();
+       return tmp.s64;
+}
+
+void FILEIO::FputInt64_LE(int64_t val)
+{
+       pair64_t tmp;
+       tmp.s64 = val;
+       FputUint8(tmp.b.l);
+       FputUint8(tmp.b.h);
+       FputUint8(tmp.b.h2);
+       FputUint8(tmp.b.h3);
+       FputUint8(tmp.b.h4);
+       FputUint8(tmp.b.h5);
+       FputUint8(tmp.b.h6);
+       FputUint8(tmp.b.h7);
+}
+
+uint16_t FILEIO::FgetUint16_BE()
+{
+       pair16_t tmp;
+       tmp.b.h = FgetUint8();
+       tmp.b.l = FgetUint8();
+       return tmp.u16;
+}
+
+void FILEIO::FputUint16_BE(uint16_t val)
+{
+       pair16_t tmp;
+       tmp.u16 = val;
+       FputUint8(tmp.b.h);
+       FputUint8(tmp.b.l);
+}
+
+uint32_t FILEIO::FgetUint32_BE()
+{
+       pair32_t tmp;
+       tmp.b.h3 = FgetUint8();
+       tmp.b.h2 = FgetUint8();
+       tmp.b.h  = FgetUint8();
+       tmp.b.l  = FgetUint8();
+       return tmp.u32;
+}
+
+void FILEIO::FputUint32_BE(uint32_t val)
+{
+       pair32_t tmp;
+       tmp.u32 = val;
+       FputUint8(tmp.b.h3);
+       FputUint8(tmp.b.h2);
+       FputUint8(tmp.b.h);
+       FputUint8(tmp.b.l);
+}
+
+uint64_t FILEIO::FgetUint64_BE()
+{
+       pair64_t tmp;
+       tmp.b.h7 = FgetUint8();
+       tmp.b.h6 = FgetUint8();
+       tmp.b.h5 = FgetUint8();
+       tmp.b.h4 = FgetUint8();
+       tmp.b.h3 = FgetUint8();
+       tmp.b.h2 = FgetUint8();
+       tmp.b.h  = FgetUint8();
+       tmp.b.l  = FgetUint8();
+       return tmp.u64;
+}
+
+void FILEIO::FputUint64_BE(uint64_t val)
+{
+       pair64_t tmp;
+       tmp.u64 = val;
+       FputUint8(tmp.b.h7);
+       FputUint8(tmp.b.h6);
+       FputUint8(tmp.b.h5);
+       FputUint8(tmp.b.h4);
+       FputUint8(tmp.b.h3);
+       FputUint8(tmp.b.h2);
+       FputUint8(tmp.b.h);
+       FputUint8(tmp.b.l);
+}
+
+int16_t FILEIO::FgetInt16_BE()
+{
+       pair16_t tmp;
+       tmp.b.h = FgetUint8();
+       tmp.b.l = FgetUint8();
+       return tmp.s16;
+}
+
+void FILEIO::FputInt16_BE(int16_t val)
+{
+       pair16_t tmp;
+       tmp.s16 = val;
+       FputUint8(tmp.b.h);
+       FputUint8(tmp.b.l);
+}
+
+int32_t FILEIO::FgetInt32_BE()
+{
+       pair32_t tmp;
+       tmp.b.h3 = FgetUint8();
+       tmp.b.h2 = FgetUint8();
+       tmp.b.h  = FgetUint8();
+       tmp.b.l  = FgetUint8();
+       return tmp.s32;
+}
+
+void FILEIO::FputInt32_BE(int32_t val)
+{
+       pair32_t tmp;
+       tmp.s32 = val;
+       FputUint8(tmp.b.h3);
+       FputUint8(tmp.b.h2);
+       FputUint8(tmp.b.h);
+       FputUint8(tmp.b.l);
+}
+
+int64_t FILEIO::FgetInt64_BE()
+{
+       pair64_t tmp;
+       tmp.b.h7 = FgetUint8();
+       tmp.b.h6 = FgetUint8();
+       tmp.b.h5 = FgetUint8();
+       tmp.b.h4 = FgetUint8();
+       tmp.b.h3 = FgetUint8();
+       tmp.b.h2 = FgetUint8();
+       tmp.b.h  = FgetUint8();
+       tmp.b.l  = FgetUint8();
+       return tmp.s64;
+}
+
+void FILEIO::FputInt64_BE(int64_t val)
+{
+       pair64_t tmp;
+       tmp.s64 = val;
+       FputUint8(tmp.b.h7);
+       FputUint8(tmp.b.h6);
+       FputUint8(tmp.b.h5);
+       FputUint8(tmp.b.h4);
+       FputUint8(tmp.b.h3);
+       FputUint8(tmp.b.h2);
+       FputUint8(tmp.b.h);
+       FputUint8(tmp.b.l);
+}
+
+int FILEIO::Fgetc()
+{
+#ifdef USE_ZLIB
+       if(gz != NULL) {
+               return gzgetc(gz);
+       } else
+#endif
+       {
+               if(fp != NULL) {
+                       return getc(fp);
+               } else {
+                       return 0;
+               }
+       }
+}
+
+int FILEIO::Fputc(int c)
+{
+#ifdef USE_ZLIB
+       if(gz != NULL) {
+               return gzputc(gz, c);
+       } else
+#endif
+       {
+               if(fp != NULL) {
+                       return fputc(c, fp);
+               } else {
+                       return 0;
+               }
+       }
+}
+
+char *FILEIO::Fgets(char *str, int n)
+{
+#ifdef USE_ZLIB
+       if(gz != NULL) {
+               return gzgets(gz, str, n);
+       } else
+#endif
+       {
+               if(fp != NULL) {
+                       return fgets(str, n, fp);
+               } else {
+                       return 0;
+               }
+       }
+}
+
+_TCHAR *FILEIO::Fgetts(_TCHAR *str, int n)
+{
+#ifdef USE_ZLIB
+       if(gz != NULL) {
+#if defined(_UNICODE) && defined(SUPPORT_TCHAR_TYPE)
+               char *str_mb = (char *)calloc(sizeof(char), n + 1);
+               gzgets(gz, str_mb, n);
+               my_swprintf_s(str, n, L"%s", char_to_wchar(str_mb));
+               free(str_mb);
+               return str;
+#else
+               return gzgets(gz, str, n);
+#endif
+       } else
+#endif
+       return _fgetts(str, n, fp);
+}
+
+int FILEIO::Fprintf(const char* format, ...)
+{
+       va_list ap;
+       char buffer[1024];
+       
+       va_start(ap, format);
+       my_vsprintf_s(buffer, 1024, format, ap);
+       va_end(ap);
+       
+#ifdef USE_ZLIB
+       if(gz != NULL) {
+               return gzprintf(gz, "%s", buffer);
+       } else
+#endif
+       {
+               if(fp != NULL) {
+                       return my_fprintf_s(fp, "%s", buffer);
+               } else {
+                       return 0;
+               }
+       }
+}
+
+int FILEIO::Ftprintf(const _TCHAR* format, ...)
+{
+       va_list ap;
+       _TCHAR buffer[1024];
+       
+       va_start(ap, format);
+       my_vstprintf_s(buffer, 1024, format, ap);
+       va_end(ap);
+       
+#ifdef USE_ZLIB
+       if(gz != NULL) {
+               return gzprintf(gz, "%s", tchar_to_char(buffer));
+       } else
+#endif
+       return my_ftprintf_s(fp, _T("%s"), buffer);
+}
+
+size_t FILEIO::Fread(void* buffer, size_t size, size_t count)
+{
+#ifdef USE_ZLIB
+       if(gz != NULL) {
+               return gzfread(buffer, size, count, gz);
+       } else
+#endif
+       {
+               if(fp != NULL) {
+                       return fread(buffer, size, count, fp);
+               } else {
+                       return 0;
+               }
+       }
+}
+
+size_t FILEIO::Fwrite(const void* buffer, size_t size, size_t count)
+{
+#ifdef USE_ZLIB
+       if(gz != NULL) {
+               return gzfwrite(buffer, size, count, gz);
+       } else
+#endif
+       {
+               if(fp != NULL) {
+                       return fwrite(buffer, size, count, fp);
+               } else {
+                       return 0;
+               }
+       }
+}
+
+int FILEIO::Fseek(long offset, int origin)
+{
+#ifdef USE_ZLIB
+       if(gz != NULL) {
+               switch(origin) {
+               case FILEIO_SEEK_CUR:
+                       return gzseek(gz, offset, SEEK_CUR);
+               case FILEIO_SEEK_END:
+                       return gzseek(gz, offset + gz_size, SEEK_SET);
+               case FILEIO_SEEK_SET:
+                       return gzseek(gz, offset, SEEK_SET);
+               }
+       } else
+#endif
+       {
+               if(fp == NULL) return -1;
+               switch(origin) {
+               case FILEIO_SEEK_CUR:
+                       return fseek(fp, offset, SEEK_CUR);
+               case FILEIO_SEEK_END:
+                       return fseek(fp, offset, SEEK_END);
+               case FILEIO_SEEK_SET:
+                       return fseek(fp, offset, SEEK_SET);
+               }
+       }
+       return -1;
+}
+
+long FILEIO::Ftell()
+{
+#ifdef USE_ZLIB
+       if(gz != NULL) {
+               return gztell(gz);
+       } else
+#endif
+       {
+               if(fp != NULL) {
+                       return ftell(fp);
+               } else {
+                       return 0;
+               }
+       }
+}
+
+
+bool FILEIO::Fcompare(const void* buffer, size_t size)
+{
+       bool result = false;
+       void *tmp = malloc(size);
+       
+       if(Fread(tmp, size, 1) == 1) {
+               result = (memcmp(buffer, tmp, size) == 0);
+       }
+       free(tmp);
+       return result;
+}