1 /* 2 Copyright (c) 2009 NetAllied Systems GmbH 3 4 This file is part of Common libBuffer. 5 6 Licensed under the MIT Open Source License, 7 for details please see LICENSE file or the website 8 http://www.opensource.org/licenses/mit-license.php 9 */ 10 11 #include "CommonFWriteBufferFlusher.h" 12 13 #include <cerrno> 14 #include <stdio.h> 15 16 namespace Common 17 { 18 //-------------------------------------------------------------------- FWriteBufferFlusher(const char * fileName,size_t bufferSize,const char * mode)19 FWriteBufferFlusher::FWriteBufferFlusher( const char* fileName, size_t bufferSize, const char* mode/*="wb"*/ ) 20 : mBufferSize(bufferSize) 21 , mBuffer( new char[bufferSize] ) 22 #if defined(_WIN32) && !defined(__GNUC__) 23 , mError( (int)fopen_s( &mStream, fileName, mode ) ) 24 #else 25 , mStream(fopen( fileName, mode )) 26 , mError( mStream ? 0 : errno ) 27 #endif 28 , mLastMarkId(END_OF_STREAM) 29 , mMarkIds() 30 { 31 if ( mError == 0 ) 32 { 33 mError = ( setvbuf( mStream , mBuffer, _IOFBF, mBufferSize ) != 0 ); 34 } 35 } 36 //----------------------------------------------------------------------- 37 38 /* note: Unix has no _wfopen_s equivalent if its important we could 39 * impliment our own but most likely this function is only needed 40 * by windows developers - campbell */ 41 #if defined(_WIN32) && !defined(__GNUC__) FWriteBufferFlusher(const wchar_t * fileName,size_t bufferSize,const wchar_t * mode)42 FWriteBufferFlusher::FWriteBufferFlusher( const wchar_t* fileName, size_t bufferSize, const wchar_t* mode/*=L"wb"*/ ) 43 : mBufferSize(bufferSize) 44 , mBuffer( new char[bufferSize] ) 45 , mError( (int)_wfopen_s( &mStream, fileName, mode ) ) 46 , mLastMarkId(END_OF_STREAM) 47 , mMarkIds() 48 { 49 if ( mError == 0 ) 50 { 51 mError = ( setvbuf( mStream , mBuffer, _IOFBF, mBufferSize ) != 0 ); 52 } 53 } 54 #endif 55 //-------------------------------------------------------------------- ~FWriteBufferFlusher()56 FWriteBufferFlusher::~FWriteBufferFlusher() 57 { 58 if ( mStream ) 59 { 60 fclose(mStream); 61 } 62 delete[] mBuffer; 63 } 64 65 //-------------------------------------------------------------------- receiveData(const char * buffer,size_t length)66 bool FWriteBufferFlusher::receiveData( const char* buffer, size_t length ) 67 { 68 if ( !mStream ) 69 { 70 return false; 71 } 72 return fwrite( buffer, 1, length, mStream ) == length; 73 } 74 75 //-------------------------------------------------------------------- flush()76 bool FWriteBufferFlusher::flush() 77 { 78 if ( !mStream ) 79 { 80 return false; 81 } 82 return fflush( mStream ) == 0; 83 } 84 85 //------------------------------ startMark()86 void FWriteBufferFlusher::startMark() 87 { 88 // store the current file position 89 #ifdef __MINGW32__ 90 FilePosType currentPos = ftello64(mStream); 91 #elif defined( _WIN32) 92 FilePosType currentPos = _ftelli64(mStream); 93 #elif defined (__APPLE__) || defined(__FreeBSD__) || defined(__DragonFly__) 94 FilePosType currentPos = ftello(mStream); 95 #else 96 FilePosType currentPos = ftello64(mStream); 97 #endif 98 99 mLastMarkId++; 100 mMarkIds.insert(std::make_pair(mLastMarkId, currentPos)); 101 } 102 103 //------------------------------ endMark()104 IBufferFlusher::MarkId FWriteBufferFlusher::endMark() 105 { 106 return mLastMarkId; 107 } 108 109 //------------------------------ jumpToMark(IBufferFlusher::MarkId markId,bool keepMarkId)110 bool FWriteBufferFlusher::jumpToMark( IBufferFlusher::MarkId markId, bool keepMarkId /*= false*/ ) 111 { 112 if ( markId == END_OF_STREAM ) 113 { 114 #ifdef __MINGW32__ 115 return (fseeko64(mStream,0,SEEK_END) == 0); 116 #elif defined( _WIN32) 117 return (_fseeki64(mStream, 0, SEEK_END) == 0); 118 #elif defined (__APPLE__) || defined(__FreeBSD__) || defined(__DragonFly__) 119 return (fseeko(mStream, 0, SEEK_END) == 0); 120 #else 121 return (fseeko64(mStream, 0, SEEK_END) == 0); 122 #endif 123 } 124 else 125 { 126 MarkIdToFilePos::const_iterator markIdIt = mMarkIds.find(markId); 127 if ( markIdIt == mMarkIds.end() ) 128 { 129 return false; 130 } 131 else 132 { 133 FilePosType pos = markIdIt->second; 134 #ifdef __MINGW32__ 135 bool success = (fseeko64(mStream,pos,SEEK_SET) == 0); 136 #elif defined( _WIN32) 137 bool success = (_fseeki64(mStream, pos, SEEK_SET) == 0); 138 #elif defined (__APPLE__) || defined(__FreeBSD__) || defined(__DragonFly__) 139 bool success = (fseeko(mStream, pos, SEEK_SET) == 0); 140 #else 141 bool success = (fseeko64(mStream, pos, SEEK_SET) == 0); 142 #endif 143 if ( !keepMarkId ) 144 { 145 mMarkIds.erase(markIdIt); 146 } 147 return success; 148 } 149 } 150 } 151 152 } // namespace Common 153 154