#define _GNU_SOURCE
#define _XOPEN_SOURCE 600

#define _LARGEFILE64_SOURCE 1
#include <errno.h>

#include <unistd.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <stdlib.h>
#include <stdlib.h>
#include <string.h>
#include <pthread.h>
//#include <sys/uio.h>

#ifndef _RAW_IO_H_INCLUDE_
#define _RAW_IO_H_INCLUDE_
#ifdef __cplusplus
extern "C" {
#endif

// 分散バッファ長.
#define BUF_SIZE 32

// セクタに対するバッファ長.
#define MHDL_BUF 384

// バッファ寿命カウント.
#define EXPIRE_BUF 24

// バッファ範囲.
#define BUFFER_RANGE 2

// Writeフラグ.
#define NOT_WRITE 0
#define USE_WRITE 1

// 書込みExpire値.
#define WRITE_EXPIRE 2

// 読み込みExpire値.
#define READ_EXPIRE 1

// バッファ可能範囲初期化カウント値.
#define MAX_NOT_RANGE 16

// Booleanフラグ.
#define TRUE 1
#define FALSE 0

// int64型定義.
typedef off64_t LONG64,*PLONG64 ;

// Boolean.
typedef unsigned int BOOL,*LPBOOL ;

// １つのバッファ情報.
typedef struct {
    LONG64 usePos ;                     // 利用中ポジション.
    LONG64 useLen ;                     // 利用中バッファ長.
    int useWriteFlag ;                  // 書込みフラグ.
    char sectorWriteFlag[ MHDL_BUF ] ;  // セクタ書込みフラグ.
    unsigned int expire ;               // バッファ寿命.
    char* buf ;                         // バッファ.
} MBUF,*LPMBUF ;

// ハンドル格納オブジェクト.
typedef struct {
    int handle ;                        // ファイルハンドル.
    unsigned int len ;                  // バッファ長.
    int sector ;                        // セクタ長.
    LONG64 fileLen ;                    // オープン中ファイル長.
    pthread_mutex_t section ;           // クリティカルセクション(同期).
    LONG64 average ;                    // 平均値.
    LONG64 bufRange ;                   // バッファ可能範囲.
    int maxNotRangeCount ;              // 連続範囲外カウント.
    MBUF bufs[ BUF_SIZE ] ;             // バッファ情報群.
} MHDL,*LPMHDL ;


// rawioオープン.
LPMHDL OpenRawIO( int* result,const char* path,const char* drv ) ;

// rawioクローズ.
void CloseRawIO( LPMHDL mh ) ;

// 指定位置のセクタを書き込む.
int WriteRawIO( LPMHDL mh,const char* data,int pos ) ;

// 指定位置のセクタを読み込む.
int ReadRawIO( LPMHDL mh,char* data,int pos ) ;

// 現在のファイルサイズを取得.
BOOL GetLengthRawIO( LONG64* out,LPMHDL mh ) ;

// ファイルサイズをセット.
BOOL SetLengthRawIO( LPMHDL mh,LONG64 len ) ;

// セクタ数を取得.
int GetSector( LPMHDL mh ) ;

// セクタ数を取得.
int GetSectorByPath( const char* path ) ;

#ifdef __cplusplus
}
#endif
#endif
