/** * @file file_hdl.h * @brief ファイルハンドルを用いる ファイルapi の薄いラッパー. * @author tenk* (Masashi Kitamura) * @note * - win と linux(unix)系を対象(想定). * - 基本的に unix 系の関数仕様に似せている. * このため成功/失敗は 0/負値 にしているので注意. * - コピペ利用の元ネタとしても想定しているため、型名等はos固有のまま記述. * - winのHANDLEで標準入出力は0,1,2ではないので、マクロ名を使う必要あり. * - Public Domain Software */ #ifndef FILE_HDL_H_INCLUDED #define FILE_HDL_H_INCLUDED #if defined _WIN32 // -------------------------------------------------------- #include <stddef.h> #include <windows.h> #include <stdlib.h> #include <tchar.h> #include <assert.h> #include <malloc.h> #include <stdarg.h> #ifndef __cplusplus #define inline __inline #endif // 使う側が移植性を考慮する場合に利用する型名等. typedef HANDLE FILE_HDL; typedef unsigned __int64 file_size64_t; typedef __int64 file_off_t; typedef unsigned __int64 file_time_t; #define FILE_ERR_HDL INVALID_HANDLE_VALUE // (-1) #define FILE_HDL_STDIN GetStdHandle(STD_INPUT_HANDLE) #define FILE_HDL_STDOUT GetStdHandle(STD_OUTPUT_HANDLE) #define FILE_HDL_STDERR GetStdHandle(STD_ERROR_HANDLE) // ファイルオープン, r,w,rp,wp はfopenの"rb","wb","rb+","wb+"に相応. inline HANDLE file_open_r (const TCHAR* nm) { assert(nm); return CreateFile(nm, GENERIC_READ , FILE_SHARE_READ, 0, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, 0); } inline HANDLE file_open_w (const TCHAR* nm) { assert(nm); return CreateFile(nm, GENERIC_WRITE, FILE_SHARE_READ, 0, CREATE_ALWAYS, FILE_ATTRIBUTE_NORMAL, 0); } inline HANDLE file_open_rp(const TCHAR* nm) { assert(nm); return CreateFile(nm, GENERIC_READ|GENERIC_WRITE, FILE_SHARE_READ, 0, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, 0); } inline HANDLE file_open_wp(const TCHAR* nm) { assert(nm); return CreateFile(nm, GENERIC_READ|GENERIC_WRITE, FILE_SHARE_READ, 0, CREATE_ALWAYS, FILE_ATTRIBUTE_NORMAL, 0); } inline void file_close(HANDLE hdl) { if (hdl != INVALID_HANDLE_VALUE) CloseHandle(hdl); } inline size_t file_read(HANDLE h, void* b, size_t sz) { DWORD r=0; assert(h!=INVALID_HANDLE_VALUE&&b&&sz); if (!ReadFile(h,b,sz,&r,0)) r=0; return r; } inline size_t file_write(HANDLE h, const void* b, size_t sz) { DWORD r=0; assert(h!=INVALID_HANDLE_VALUE&&b&&sz); if (!WriteFile(h,b,sz,&r,0)) r=0; return r; } inline int file_flush(HANDLE h) { assert(h!=INVALID_HANDLE_VALUE); return FlushFileBuffers(h) ? 0 : -1; } //inline int file_seek32(HANDLE h, int ofs, int mode) { assert(h!=INVALID_HANDLE_VALUE); return SetFilePointer(h, (LONG)ofs, 0, mode); } inline __int64 file_seek(HANDLE h, __int64 ofs, int mode) { assert(h!=INVALID_HANDLE_VALUE); return SetFilePointerEx(h, *(LARGE_INTEGER*)&ofs, (LARGE_INTEGER*)&ofs, mode) ? ofs : 0; } inline __int64 file_tell(HANDLE h) { assert(h!=INVALID_HANDLE_VALUE); return file_seek(h, 0, FILE_CURRENT); } inline unsigned __int64 file_getSize(HANDLE h) { assert(h!=INVALID_HANDLE_VALUE); unsigned __int64 l = 0; return GetFileSizeEx(h, (LARGE_INTEGER*)&l) ? l : 0; } // 時間の取得. 成功したら 0, 失態したら負を返す. inline int file_getTime(HANDLE h, unsigned __int64* pCreat, unsigned __int64* pLastAcs, unsigned __int64* pLastWrt) { assert(h != INVALID_HANDLE_VALUE); return GetFileTime(h, (FILETIME*)pCreat, (FILETIME*)pLastAcs, (FILETIME*)pLastWrt) ? 0 : -1; } // 時間の設定. 成功したら 0, 失態したら負を返す. inline int file_setTime(HANDLE h, unsigned __int64 creatTim, unsigned __int64 lastAcs, unsigned __int64 lastWrt) { assert(h != INVALID_HANDLE_VALUE); return SetFileTime(h, (FILETIME*)&creatTim, (FILETIME*)&lastAcs, (FILETIME*)&lastWrt) ? 0 : -1; } #else // linux(unix) //---------------------------------------------------- #define _LARGEFILE64_SOURCE // include順番を気をつけないと乗っ取れない... #define _FILE_OFFSET_BITS 64 // include順番を気をつけないと乗っ取れない... #include <stddef.h> #include <stdlib.h> #include <string.h> #include <unistd.h> #include <assert.h> #include <stdint.h> #include <fcntl.h> #include <sys/stat.h> #include <sys/types.h> #include <sys/time.h> #include <stdarg.h> // 使う側が移植性を考慮する場合に利用する型名等. #define FILE_ERR_HDL (-1) typedef int FILE_HDL; typedef uint64_t file_size64_t; typedef off64_t file_off_t; typedef time_t file_time_t; #define FILE_HDL_STDIN 0 #define FILE_HDL_STDOUT 1 #define FILE_HDL_STDERR 2 // ファイルオープン, r,w,rp,wp はfopenの"rb","wb","rb+","wb+"に相応. inline int file_open_r (const char* nm) { assert(nm); return open(nm, O_RDONLY, 0766); } inline int file_open_w (const char* nm) { assert(nm); return open(nm, O_WRONLY|O_CREAT|O_TRUNC, 0766); } inline int file_open_rp(const char* nm) { assert(nm); return open(nm, O_RDWR, 0766); } inline int file_open_wp(const char* nm) { assert(nm); return open(nm, O_RDWR|O_CREAT, 0766); } inline void file_close(int hdl) { if (hdl != -1) close(hdl); } inline size_t file_read(int h, void* buf, size_t sz) { assert(h!=-1 && buf && sz); return read(h, buf, sz); } inline size_t file_write(int h, const void* buf, size_t sz) { assert(h!=-1 && buf && sz); return write(h, buf, sz); } inline int file_flush(int h) { h; return 0; } // ダミー. // ほんとに 64ビットを有効になっているかは環境の設定しだい. inline int64_t file_seek(int h, int64_t ofs, int mode) { assert(h!=-1); return lseek64(h,ofs,mode); } inline int64_t file_tell(int h) { assert(h!=-1); return file_seek(h, 0, 1/*seek_cur*/); } inline uint64_t file_getSize(int h) { assert(h!=-1); struct stat st; return fstat(h, &st)==0 ? st.st_size : 0; } /// 時間の取得. 値はシステムに依存. inline int file_getTime(int h, time_t* pCreat, time_t* pLastAcs, time_t* pLastWrt) { struct stat st; int rc; assert(h != 0); rc = fstat(h, &st); if (rc == 0) { if (pLastWrt) *pLastWrt = st.st_mtime; if (pLastAcs) *pLastAcs = st.st_atime; if (pCreat ) *pCreat = st.st_ctime; } return rc; } /// 時間の設定. creatTimは無視するので注意. inline int file_setTime(int h, time_t creatTim, time_t lastAcs, time_t lastWrt) { struct timeval tv[2]; assert(h != 0); creatTim; tv[0].tv_sec = lastAcs; tv[0].tv_usec = 0; tv[1].tv_sec = lastWrt; tv[1].tv_usec = 0; return futimes(h, tv); } #endif // _WIN32 // ------------------------------------------------------- // 文字列出力. ※ \n はwinでも生の\nなので注意. inline size_t file_puts(const char* s, FILE_HDL h) { return file_write(h, s, strlen(s)); } #if 1 #include <stdio.h> // printf書式の文字列出力. ※ \n はwinでも生の\nなので注意. inline size_t file_printf(FILE_HDL h, const char* fmt, ...) { char buf[ 2048 ], *s = buf, *p = s; size_t bufSz = 2048 , n; assert(h!=(FILE_HDL)-1 && fmt); do {va_list a; va_start(a,fmt); n = vsnprintf((s=p), bufSz, fmt, a); va_end(a); } while (n >= bufSz-1 && (p = (char*)alloca((bufSz *= 2))) != 0); return file_write(h, s, n); } #endif #endif // FILE_HDL_INCLUDED