2018年6月7日木曜日

64bitを考慮した, ファイル操作

LinuxとWindowsでチェックしています。
ftellをサイズ取得のために使うべきではないという説明はこちら
#include <cassert>
#include <cstdint>
#include <stdio.h>
#include <sys/stat.h>

//C++98 199711L
//C++11 201103L
#ifdef __cplusplus
#   if 201103L<=__cplusplus || 1900<=_MSC_VER
#       define CPP_CPP11 1
#   endif
#endif

#ifdef __cplusplus
#   ifdef CPP_CPP11
#       define CPP_NULL nullptr
#   else
#       define CPP_NULL 0
#   endif
#else
#   define CPP_NULL ((void*)0)
#endif

#ifdef _NDEBUG
#define CPP_ASSERT(exp)
#else
#define CPP_ASSERT(exp) assert(exp)
#endif

#ifndef CPP_TYPES
#define CPP_TYPES
typedef int8_t s8;
typedef int16_t s16;
typedef int32_t s32;
typedef int64_t s64;

typedef uint8_t u8;
typedef uint16_t u16;
typedef uint32_t u32;
typedef uint64_t u64;

typedef float f32;
typedef double f64;

typedef char Char;

typedef ::size_t size_t;
#endif

#ifdef _MSC_VER
#ifndef CPP_FSEEK
#define CPP_FSEEK(f,p,o) _fseeki64((f),(p),(o))
#endif

#ifndef CPP_FTELL
#define CPP_FTELL(f) _ftelli64((f))
#endif

#ifndef CPP_SPRINTF
#define CPP_SPRINTF(b,f, ...) sprintf_s(b, f, __VA_ARGS__)
#endif

#ifndef CPP_FSEEK
#define CPP_FSEEK(f,p,o) fseeko64((f),(p),(o))
#endif

#ifndef CPP_FTELL
#define CPP_FTELL(f) ftello64((f))
#endif

#ifndef CPP_SPRINTF
#define CPP_SPRINTF(b,f, ...) sprintf((b), (f), __VA_ARGS__)
#endif

inline s64 CPP_FSIZE(FILE* file)
{
    CPP_ASSERT(CPP_NULL != file);
    struct _stat64 stat;
    return (0 == _fstat64(_fileno(file), &stat))? stat.st_size : 0;
}

inline FILE* CPP_FOPEN(const Char* filepath, const Char* mode)
{
    CPP_ASSERT(CPP_NULL != filepath);
    CPP_ASSERT(CPP_NULL != mode);
    FILE* file = CPP_NULL;
    return 0 == ::fopen_s(&file, filepath, mode) ? file : CPP_NULL;
}

inline void CPP_FCLOSE(FILE*& file)
{
    if(CPP_NULL != file){
        fclose(file);
        file = CPP_NULL;
    }
}

#else
#ifndef CPP_FSEEK
#define CPP_FSEEK(f,p,o) fseeko64((f),(p),(o))
#endif

#ifndef CPP_FTELL
#define CPP_FTELL(f) ftello64((f))
#endif

#ifndef CPP_SPRINTF
#define CPP_SPRINTF(b,f, ...) sprintf((b), (f), __VA_ARGS__)
#endif

inline s64 CPP_FSIZE(FILE* file)
{
    CPP_ASSERT(CPP_NULL != file);
    struct stat64 stat;
    return (0 == fstat64(fileno(file), &stat))? stat.st_size : 0;
}

inline FILE* CPP_FOPEN(const Char* filepath, const Char* mode)
{
    CPP_ASSERT(CPP_NULL != filepath);
    CPP_ASSERT(CPP_NULL != mode);
    return fopen(filepath, mode);
}

inline void CPP_FCLOSE(FILE*& file)
{
    if(CPP_NULL != file){
        fclose(file);
        file = CPP_NULL;
    }
}
#endif

int main(int argc, char** argv)
{
    FILE* file = CPP_FOPEN(argv[0], "rb");
    CPP_FSEEK(file, 0, SEEK_END);
    s64 size = CPP_FTELL(file);
    CPP_FSEEK(file, 0, SEEK_SET);
    s64 statSize = CPP_FSIZE(file);
    printf("size=%ld,%ld\n", size, statSize);
    CPP_FCLOSE(file);
    return 0;
}

0 件のコメント:

コメントを投稿