//JMVC _LargeFile.cpp
#include "H264AVCVideoIoLib.h"
#include "LargeFile.h"
#include <errno.h>
#if defined( MSYS_WIN32 )
# include <io.h>
# include <sys/stat.h>
# include <fcntl.h>
#else
#ifndef _LARGEFILE64_SOURCE
#define _LARGEFILE64_SOURCE
// heiko.schwarz@hhi.fhg.de: support for BSD systems as proposed by Steffen Kamp [kamp@ient.rwth-aachen.de]
#define _FILE_OFFSET_BITS 64
#endif
# include <sys/ioctl.h>
# include <sys/types.h>
# include <fcntl.h>
# include <dlfcn.h>
# include <cerrno>
# include <unistd.h>
# include "../tllog.h"
#endif
LargeFile::LargeFile() :
m_iFileHandle( -1 )
{
}
LargeFile::~LargeFile()
{
if( -1 != m_iFileHandle )
{
::close( m_iFileHandle );
}
}
ErrVal LargeFile::open( const std::string& rcFilename, enum OpenMode eOpenMode, int iPermMode )
{
TL_MSG("LargeFile::open().");
ROT( rcFilename.empty() );
ROF( -1 == m_iFileHandle );
int iOpenMode;
#if defined( MSYS_WIN32 )
if( eOpenMode == OM_READONLY )
{
iOpenMode = _O_RDONLY;
}
else if( eOpenMode == OM_WRITEONLY )
{
iOpenMode = _O_CREAT | _O_TRUNC | _O_WRONLY;
}
else if( eOpenMode == OM_APPEND )
{
//append mode does not imply write access and the create flag
//simplifies the program's logic (in most cases).
iOpenMode = _O_APPEND | _O_CREAT | _O_WRONLY;
}
else if( eOpenMode == OM_READWRITE )
{
iOpenMode = _O_CREAT | _O_RDWR; //zhh_将创建文件的标志位设置为1,这样open函数无法读写这个文件的时候就会创建他。
}
else
{
AF();
return Err::m_nERR;
}
iOpenMode |= _O_SEQUENTIAL | _O_BINARY; //以顺序存取模式打开文件
m_iFileHandle = ::open( rcFilename.c_str(), iOpenMode, iPermMode );
#elif defined( MSYS_UNIX_LARGEFILE )
if( eOpenMode == OM_READONLY )
{
iOpenMode = O_RDONLY;
}
else if( eOpenMode == OM_WRITEONLY )
{
iOpenMode = O_CREAT | O_TRUNC | O_WRONLY;
}
else if( eOpenMode == OM_APPEND )
{
iOpenMode = O_APPEND | O_CREAT | O_WRONLY;
}
else if( eOpenMode == OM_READWRITE )
{
iOpenMode = O_CREAT | O_RDWR;
}
else
{
AOT( 1 );
return Err::m_nERR;
}
// heiko.schwarz@hhi.fhg.de: support for BSD systems as proposed by Steffen Kamp [kamp@ient.rwth-aachen.de]
//m_iFileHandle = open64( rcFilename.c_str(), iOpenMode, iPermMode );
m_iFileHandle = ::open( rcFilename.c_str(), iOpenMode, iPermMode );
#endif
// check if file is really open
ROTS( -1 == m_iFileHandle );
// and return
return Err::m_nOK;
}
ErrVal LargeFile::close()
{
TL_MSG("argeFile::close().");
int iRetv;
ROTS( -1 == m_iFileHandle );
iRetv = ::close( m_iFileHandle );
m_iFileHandle = -1;
return ( iRetv == 0 ) ? Err::m_nOK : Err::m_nERR;
}
//iOffset 偏移量, iOrigin 原始位置
ErrVal LargeFile::seek( Int64 iOffset, int iOrigin )
{
Int64 iNewOffset;
ROT( -1 == m_iFileHandle );
#if defined( MSYS_WIN32 )
iNewOffset = _lseeki64( m_iFileHandle, iOffset, iOrigin );
#elif defined( MSYS_UNIX_LARGEFILE )
// heiko.schwarz@hhi.fhg.de: support for BSD systems as proposed by Steffen Kamp [kamp@ient.rwth-aachen.de]
//iNewOffset = lseek64( m_iFileHandle, iOffset, iOrigin );
iNewOffset = ::lseek( m_iFileHandle, iOffset, iOrigin );
#endif
return ( iNewOffset == -1 ) ? Err::m_nERR : Err::m_nOK;
}
Int64 LargeFile::tell()
{
TL_MSG("LargeFile::tell()");
ROTR( -1 == m_iFileHandle, -1 );
Int64 iOffset;
#if defined( MSYS_WIN32 )
iOffset = _telli64( m_iFileHandle );//读写文件指针位置
#elif defined( MSYS_UNIX_LARGEFILE )
// heiko.schwarz@hhi.fhg.de: support for BSD systems as proposed by Steffen Kamp [kamp@ient.rwth-aachen.de]
//iOffset = lseek64( m_iFileHandle, 0, SEEK_CUR );
iOffset = ::lseek( m_iFileHandle, 0, SEEK_CUR );//移动文件指针的读写位置
#endif
ROT( iOffset == -1 )
// and return
return iOffset;
}
ErrVal LargeFile::read( Void *pvBuffer, UInt32 uiCount, UInt32& ruiBytesRead )
{
TL_MSG("LargeFile::read().");
int iRetv;
ROT( -1 == m_iFileHandle );
ROT( 0 == uiCount );
ruiBytesRead = 0;
iRetv = ::read( m_iFileHandle, pvBuffer, uiCount );
if( iRetv != (Int)uiCount )
{
//need to handle partial reads before hitting EOF
//If the function tries to read at end of file, it returns 0.
//If the handle is invalid, or the file is not open for reading,
//or the file is locked, the function returns -1 and sets errno to EBADF.
if( iRetv > 0 )
{
//partial reads are acceptable and return the standard success code. Anything
//else must be implemented by the caller.
ruiBytesRead = iRetv;
return Err::m_nOK;
}
else if( iRetv == -1 )
{
return errno;
}
else if( iRetv == 0)
{
return Err::m_nEndOfFile;
}
else
{
AOF( ! "fix me, unexpected return code" );
return Err::m_nERR;
}
}
else
{
ruiBytesRead = uiCount;
}
ROF( iRetv == (Int)uiCount );
return Err::m_nOK;
}
//TL_MSG("LargeFile::write().");
ErrVal LargeFile::write( const Void *pvBuffer, UInt32 uiCount )
{
int iRetv;
ROT( -1 == m_iFileHandle );
ROT( 0 == uiCount );
iRetv = ::write( m_iFileHandle, pvBuffer, uiCount );
ROF( iRetv == (Int)uiCount );
return Err::m_nOK;
}
#if !defined(AFX_LARGEFILE_H__7E94650C_CCB2_4248_AEF5_74966C842261__INCLUDED_)
#define AFX_LARGEFILE_H__7E94650C_CCB2_4248_AEF5_74966C842261__INCLUDED_
#if _MSC_VER > 1000
#pragma once
#endif // _MSC_VER > 1000
#if defined( MSYS_LINUX )
# if (!defined( MSYS_UNIX_LARGEFILE )) || (!defined(_LARGEFILE64_SOURCE) )
# error Large file support requires MSYS_UNIX_LARGEFILE and _LARGEFILE64_SOURCE defined
# endif
#endif
class H264AVCVIDEOIOLIB_API LargeFile
{
public:
enum OpenMode
{
OM_READONLY,
OM_WRITEONLY,
OM_APPEND,
OM_READWRITE
};
public:
LargeFile();
~LargeFile();
ErrVal open( const std::string& rcFilename, enum OpenMode eOpenMode, int iPermMode=0777 );
bool is_open() const { return -1 != m_iFileHandle; }
ErrVal close();
ErrVal seek( Int64 iOffset, int iOrigin );
Int64 tell();
ErrVal read( Void *pvBuffer, UInt32 uiCount, UInt32& ruiBytesRead );
ErrVal write( const Void *pvBuffer, UInt32 uiCount );
Int getFileHandle() { return m_iFileHandle; }
private:
Int m_iFileHandle;
};
#endif // !defined(AFX_LARGEFILE_H__7E94650C_CCB2_4248_AEF5_74966C842261__INCLUDED_)