michael@0: // FileStreams.cpp michael@0: michael@0: #include "StdAfx.h" michael@0: michael@0: #ifndef _WIN32 michael@0: #include michael@0: #include michael@0: #include michael@0: #endif michael@0: michael@0: #include "FileStreams.h" michael@0: michael@0: static inline HRESULT ConvertBoolToHRESULT(bool result) michael@0: { michael@0: // return result ? S_OK: E_FAIL; michael@0: #ifdef _WIN32 michael@0: return result ? S_OK: (::GetLastError()); michael@0: #else michael@0: return result ? S_OK: E_FAIL; michael@0: #endif michael@0: } michael@0: michael@0: bool CInFileStream::Open(LPCTSTR fileName) michael@0: { michael@0: return File.Open(fileName); michael@0: } michael@0: michael@0: #ifdef _WIN32 michael@0: #ifndef _UNICODE michael@0: bool CInFileStream::Open(LPCWSTR fileName) michael@0: { michael@0: return File.Open(fileName); michael@0: } michael@0: #endif michael@0: #endif michael@0: michael@0: STDMETHODIMP CInFileStream::Read(void *data, UInt32 size, UInt32 *processedSize) michael@0: { michael@0: #ifdef _WIN32 michael@0: michael@0: UInt32 realProcessedSize; michael@0: bool result = File.ReadPart(data, size, realProcessedSize); michael@0: if(processedSize != NULL) michael@0: *processedSize = realProcessedSize; michael@0: return ConvertBoolToHRESULT(result); michael@0: michael@0: #else michael@0: michael@0: if(processedSize != NULL) michael@0: *processedSize = 0; michael@0: ssize_t res = File.Read(data, (size_t)size); michael@0: if (res == -1) michael@0: return E_FAIL; michael@0: if(processedSize != NULL) michael@0: *processedSize = (UInt32)res; michael@0: return S_OK; michael@0: michael@0: #endif michael@0: } michael@0: michael@0: #ifndef _WIN32_WCE michael@0: STDMETHODIMP CStdInFileStream::Read(void *data, UInt32 size, UInt32 *processedSize) michael@0: { michael@0: #ifdef _WIN32 michael@0: UInt32 realProcessedSize; michael@0: BOOL res = ::ReadFile(GetStdHandle(STD_INPUT_HANDLE), michael@0: data, size, (DWORD *)&realProcessedSize, NULL); michael@0: if(processedSize != NULL) michael@0: *processedSize = realProcessedSize; michael@0: if (res == FALSE && GetLastError() == ERROR_BROKEN_PIPE) michael@0: return S_OK; michael@0: return ConvertBoolToHRESULT(res != FALSE); michael@0: michael@0: #else michael@0: michael@0: if(processedSize != NULL) michael@0: *processedSize = 0; michael@0: ssize_t res; michael@0: do michael@0: { michael@0: res = read(0, data, (size_t)size); michael@0: } michael@0: while (res < 0 && (errno == EINTR)); michael@0: if (res == -1) michael@0: return E_FAIL; michael@0: if(processedSize != NULL) michael@0: *processedSize = (UInt32)res; michael@0: return S_OK; michael@0: michael@0: #endif michael@0: } michael@0: michael@0: #endif michael@0: michael@0: STDMETHODIMP CInFileStream::Seek(Int64 offset, UInt32 seekOrigin, michael@0: UInt64 *newPosition) michael@0: { michael@0: if(seekOrigin >= 3) michael@0: return STG_E_INVALIDFUNCTION; michael@0: michael@0: #ifdef _WIN32 michael@0: michael@0: UInt64 realNewPosition; michael@0: bool result = File.Seek(offset, seekOrigin, realNewPosition); michael@0: if(newPosition != NULL) michael@0: *newPosition = realNewPosition; michael@0: return ConvertBoolToHRESULT(result); michael@0: michael@0: #else michael@0: michael@0: off_t res = File.Seek(offset, seekOrigin); michael@0: if (res == -1) michael@0: return E_FAIL; michael@0: if(newPosition != NULL) michael@0: *newPosition = (UInt64)res; michael@0: return S_OK; michael@0: michael@0: #endif michael@0: } michael@0: michael@0: STDMETHODIMP CInFileStream::GetSize(UInt64 *size) michael@0: { michael@0: return ConvertBoolToHRESULT(File.GetLength(*size)); michael@0: } michael@0: michael@0: michael@0: ////////////////////////// michael@0: // COutFileStream michael@0: michael@0: bool COutFileStream::Create(LPCTSTR fileName, bool createAlways) michael@0: { michael@0: return File.Create(fileName, createAlways); michael@0: } michael@0: michael@0: #ifdef _WIN32 michael@0: #ifndef _UNICODE michael@0: bool COutFileStream::Create(LPCWSTR fileName, bool createAlways) michael@0: { michael@0: return File.Create(fileName, createAlways); michael@0: } michael@0: #endif michael@0: #endif michael@0: michael@0: STDMETHODIMP COutFileStream::Write(const void *data, UInt32 size, UInt32 *processedSize) michael@0: { michael@0: #ifdef _WIN32 michael@0: michael@0: UInt32 realProcessedSize; michael@0: bool result = File.WritePart(data, size, realProcessedSize); michael@0: if(processedSize != NULL) michael@0: *processedSize = realProcessedSize; michael@0: return ConvertBoolToHRESULT(result); michael@0: michael@0: #else michael@0: michael@0: if(processedSize != NULL) michael@0: *processedSize = 0; michael@0: ssize_t res = File.Write(data, (size_t)size); michael@0: if (res == -1) michael@0: return E_FAIL; michael@0: if(processedSize != NULL) michael@0: *processedSize = (UInt32)res; michael@0: return S_OK; michael@0: michael@0: #endif michael@0: } michael@0: michael@0: STDMETHODIMP COutFileStream::Seek(Int64 offset, UInt32 seekOrigin, michael@0: UInt64 *newPosition) michael@0: { michael@0: if(seekOrigin >= 3) michael@0: return STG_E_INVALIDFUNCTION; michael@0: #ifdef _WIN32 michael@0: michael@0: UInt64 realNewPosition; michael@0: bool result = File.Seek(offset, seekOrigin, realNewPosition); michael@0: if(newPosition != NULL) michael@0: *newPosition = realNewPosition; michael@0: return ConvertBoolToHRESULT(result); michael@0: michael@0: #else michael@0: michael@0: off_t res = File.Seek(offset, seekOrigin); michael@0: if (res == -1) michael@0: return E_FAIL; michael@0: if(newPosition != NULL) michael@0: *newPosition = (UInt64)res; michael@0: return S_OK; michael@0: michael@0: #endif michael@0: } michael@0: michael@0: STDMETHODIMP COutFileStream::SetSize(Int64 newSize) michael@0: { michael@0: #ifdef _WIN32 michael@0: UInt64 currentPos; michael@0: if(!File.Seek(0, FILE_CURRENT, currentPos)) michael@0: return E_FAIL; michael@0: bool result = File.SetLength(newSize); michael@0: UInt64 currentPos2; michael@0: result = result && File.Seek(currentPos, currentPos2); michael@0: return result ? S_OK : E_FAIL; michael@0: #else michael@0: return E_FAIL; michael@0: #endif michael@0: } michael@0: michael@0: #ifndef _WIN32_WCE michael@0: STDMETHODIMP CStdOutFileStream::Write(const void *data, UInt32 size, UInt32 *processedSize) michael@0: { michael@0: if(processedSize != NULL) michael@0: *processedSize = 0; michael@0: michael@0: #ifdef _WIN32 michael@0: UInt32 realProcessedSize; michael@0: BOOL res = TRUE; michael@0: if (size > 0) michael@0: { michael@0: // Seems that Windows doesn't like big amounts writing to stdout. michael@0: // So we limit portions by 32KB. michael@0: UInt32 sizeTemp = (1 << 15); michael@0: if (sizeTemp > size) michael@0: sizeTemp = size; michael@0: res = ::WriteFile(GetStdHandle(STD_OUTPUT_HANDLE), michael@0: data, sizeTemp, (DWORD *)&realProcessedSize, NULL); michael@0: size -= realProcessedSize; michael@0: data = (const void *)((const Byte *)data + realProcessedSize); michael@0: if(processedSize != NULL) michael@0: *processedSize += realProcessedSize; michael@0: } michael@0: return ConvertBoolToHRESULT(res != FALSE); michael@0: michael@0: #else michael@0: michael@0: ssize_t res; michael@0: do michael@0: { michael@0: res = write(1, data, (size_t)size); michael@0: } michael@0: while (res < 0 && (errno == EINTR)); michael@0: if (res == -1) michael@0: return E_FAIL; michael@0: if(processedSize != NULL) michael@0: *processedSize = (UInt32)res; michael@0: return S_OK; michael@0: michael@0: return S_OK; michael@0: #endif michael@0: } michael@0: michael@0: #endif