From b6f57560fb7fae00f0854ca19158bd5512e5405b Mon Sep 17 00:00:00 2001 From: Mike Buland Date: Wed, 1 Oct 2008 21:48:33 +0000 Subject: This commit is sure to break things. This should be a very, very minor change. What changed API-Wise: - I deleted a constructor in Bu::File that shouldn't have been used anyway. - I changed it from using fopen style mode strings to using libbu++ style mode flags. Check the docs for the complete list, but basically instead of "wb" you do Bu::File::Write, and so on, you can or any of the libbu++ flags together. There is no binary/text mode, it just writes whatever you tell it to verbatim (binary mode). Lots of extras are supported. Nothing else should have changed (except now the file stream is unbuffered, like all the other streams). Sorry if this breaks anything, if it's too annoying, use the last revision for a while longer. --- src/file.cpp | 111 ++++++++++++++++++++++++++++++++++++----------------------- 1 file changed, 67 insertions(+), 44 deletions(-) (limited to 'src/file.cpp') diff --git a/src/file.cpp b/src/file.cpp index 3419216..5049bbb 100644 --- a/src/file.cpp +++ b/src/file.cpp @@ -10,30 +10,24 @@ #include #include #include +#include namespace Bu { subExceptionDef( FileException ) } -Bu::File::File( const char *sName, const char *sFlags ) +Bu::File::File( const Bu::FString &sName, int iFlags ) : + fd( -1 ) { - fh = fopen( sName, sFlags ); - if( fh == NULL ) + fd = ::open( sName.getStr(), getPosixFlags( iFlags ) ); + if( fd < 0 ) { - throw Bu::FileException( errno, "%s: %s", strerror(errno), sName ); + throw Bu::FileException( errno, "%s: %s", + strerror(errno), sName.getStr() ); } } -Bu::File::File( const Bu::FString &sName, const char *sFlags ) +Bu::File::File( int fd ) : + fd( fd ) { - fh = fopen( sName.getStr(), sFlags ); - if( fh == NULL ) - { - throw Bu::FileException( errno, "%s: %s", strerror(errno), sName.getStr() ); - } -} - -Bu::File::File( int fd, const char *sFlags ) -{ - fh = fdopen( fd, sFlags ); } Bu::File::~File() @@ -43,69 +37,68 @@ Bu::File::~File() void Bu::File::close() { - if( fh ) + if( fd >= 0 ) { - fclose( fh ); - fh = NULL; + if( ::close( fd ) ) + { + throw Bu::FileException( errno, "%s", + strerror(errno) ); + } + fd = -1; } } size_t Bu::File::read( void *pBuf, size_t nBytes ) { - if( !fh ) + if( fd < 0 ) throw FileException("File not open."); - int nAmnt = fread( pBuf, 1, nBytes, fh ); - - //if( nAmnt == 0 ) - // throw FileException("End of file."); - - return nAmnt; + return ::read( fd, pBuf, nBytes ); } size_t Bu::File::write( const void *pBuf, size_t nBytes ) { - if( !fh ) + if( fd < 0 ) throw FileException("File not open."); - return fwrite( pBuf, 1, nBytes, fh ); + return ::write( fd, pBuf, nBytes ); } long Bu::File::tell() { - if( !fh ) + if( fd < 0 ) throw FileException("File not open."); - return ftell( fh ); + return lseek( fd, 0, SEEK_CUR ); } void Bu::File::seek( long offset ) { - if( !fh ) + if( fd < 0 ) throw FileException("File not open."); - fseek( fh, offset, SEEK_CUR ); + lseek( fd, offset, SEEK_CUR ); } void Bu::File::setPos( long pos ) { - if( !fh ) + if( fd < 0 ) throw FileException("File not open."); - fseek( fh, pos, SEEK_SET ); + lseek( fd, pos, SEEK_SET ); } void Bu::File::setPosEnd( long pos ) { - if( !fh ) + if( fd < 0 ) throw FileException("File not open."); - fseek( fh, pos, SEEK_END ); + lseek( fd, pos, SEEK_END ); } bool Bu::File::isEOS() { - return feof( fh ); + return false; } bool Bu::File::canRead() @@ -145,13 +138,13 @@ void Bu::File::setBlocking( bool bBlocking ) #else if( bBlocking ) fcntl( - fileno( fh ), - F_SETFL, fcntl( fileno( fh ), F_GETFL, 0 )&(~O_NONBLOCK) + fd, + F_SETFL, fcntl( fd, F_GETFL, 0 )&(~O_NONBLOCK) ); else fcntl( - fileno( fh ), - F_SETFL, fcntl( fileno( fh ), F_GETFL, 0 )|O_NONBLOCK + fd, + F_SETFL, fcntl( fd, F_GETFL, 0 )|O_NONBLOCK ); #endif } @@ -159,22 +152,52 @@ void Bu::File::setBlocking( bool bBlocking ) #ifndef WIN32 void Bu::File::truncate( long nSize ) { - ftruncate( fileno( fh ), nSize ); + ftruncate( fd, nSize ); } void Bu::File::chmod( mode_t t ) { - fchmod( fileno( fh ), t ); + fchmod( fd, t ); } #endif void Bu::File::flush() { - fflush( fh ); + // There is no flushing with direct I/O... + //fflush( fh ); } bool Bu::File::isOpen() { - return (fh != NULL); + return (fd > -1); +} + +int Bu::File::getPosixFlags( int iFlags ) +{ + int iRet = 0; + switch( (iFlags&ReadWrite) ) + { + // According to posix, O_RDWR is not necesarilly O_RDONLY|O_WRONLY, so + // lets be proper and use the right value in the right place. + case Read: iRet = O_RDONLY; break; + case Write: iRet = O_WRONLY; break; + case ReadWrite: iRet = O_RDWR; break; + default: + throw FileException( + "You must specify Read, Write, or both when opening a file."); + } + + if( (iFlags&Create) ) + iRet |= O_CREAT; + if( (iFlags&Append) ) + iRet |= O_APPEND; + if( (iFlags&Truncate) ) + iRet |= O_TRUNC; + if( (iFlags&NonBlock) ) + iRet |= O_NONBLOCK; + if( (iFlags&Exclusive) ) + iRet |= O_EXCL; + + return iRet; } -- cgit v1.2.3