FileStreams.cpp 5.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261
  1. // FileStreams.cpp
  2. #include "StdAfx.h"
  3. #ifndef _WIN32
  4. #include <fcntl.h>
  5. #include <unistd.h>
  6. #include <errno.h>
  7. #endif
  8. #include "FileStreams.h"
  9. static inline HRESULT ConvertBoolToHRESULT(bool result)
  10. {
  11. #ifdef _WIN32
  12. if (result)
  13. return S_OK;
  14. DWORD lastError = ::GetLastError();
  15. if (lastError == 0)
  16. return E_FAIL;
  17. return lastError;
  18. #else
  19. return result ? S_OK: E_FAIL;
  20. #endif
  21. }
  22. bool CInFileStream::Open(LPCTSTR fileName)
  23. {
  24. return File.Open(fileName);
  25. }
  26. #ifdef USE_WIN_FILE
  27. #ifndef _UNICODE
  28. bool CInFileStream::Open(LPCWSTR fileName)
  29. {
  30. return File.Open(fileName);
  31. }
  32. #endif
  33. #endif
  34. bool CInFileStream::OpenShared(LPCTSTR fileName, bool shareForWrite)
  35. {
  36. return File.OpenShared(fileName, shareForWrite);
  37. }
  38. #ifdef USE_WIN_FILE
  39. #ifndef _UNICODE
  40. bool CInFileStream::OpenShared(LPCWSTR fileName, bool shareForWrite)
  41. {
  42. return File.OpenShared(fileName, shareForWrite);
  43. }
  44. #endif
  45. #endif
  46. STDMETHODIMP CInFileStream::Read(void *data, UInt32 size, UInt32 *processedSize)
  47. {
  48. #ifdef USE_WIN_FILE
  49. UInt32 realProcessedSize;
  50. bool result = File.ReadPart(data, size, realProcessedSize);
  51. if(processedSize != NULL)
  52. *processedSize = realProcessedSize;
  53. return ConvertBoolToHRESULT(result);
  54. #else
  55. if(processedSize != NULL)
  56. *processedSize = 0;
  57. ssize_t res = File.Read(data, (size_t)size);
  58. if (res == -1)
  59. return E_FAIL;
  60. if(processedSize != NULL)
  61. *processedSize = (UInt32)res;
  62. return S_OK;
  63. #endif
  64. }
  65. #ifndef _WIN32_WCE
  66. STDMETHODIMP CStdInFileStream::Read(void *data, UInt32 size, UInt32 *processedSize)
  67. {
  68. #ifdef _WIN32
  69. UInt32 realProcessedSize;
  70. BOOL res = ::ReadFile(GetStdHandle(STD_INPUT_HANDLE),
  71. data, size, (DWORD *)&realProcessedSize, NULL);
  72. if(processedSize != NULL)
  73. *processedSize = realProcessedSize;
  74. if (res == FALSE && GetLastError() == ERROR_BROKEN_PIPE)
  75. return S_OK;
  76. return ConvertBoolToHRESULT(res != FALSE);
  77. #else
  78. if(processedSize != NULL)
  79. *processedSize = 0;
  80. ssize_t res;
  81. do
  82. {
  83. res = read(0, data, (size_t)size);
  84. }
  85. while (res < 0 && (errno == EINTR));
  86. if (res == -1)
  87. return E_FAIL;
  88. if(processedSize != NULL)
  89. *processedSize = (UInt32)res;
  90. return S_OK;
  91. #endif
  92. }
  93. #endif
  94. STDMETHODIMP CInFileStream::Seek(Int64 offset, UInt32 seekOrigin,
  95. UInt64 *newPosition)
  96. {
  97. if(seekOrigin >= 3)
  98. return STG_E_INVALIDFUNCTION;
  99. #ifdef USE_WIN_FILE
  100. UInt64 realNewPosition;
  101. bool result = File.Seek(offset, seekOrigin, realNewPosition);
  102. if(newPosition != NULL)
  103. *newPosition = realNewPosition;
  104. return ConvertBoolToHRESULT(result);
  105. #else
  106. off_t res = File.Seek(offset, seekOrigin);
  107. if (res == -1)
  108. return E_FAIL;
  109. if(newPosition != NULL)
  110. *newPosition = (UInt64)res;
  111. return S_OK;
  112. #endif
  113. }
  114. STDMETHODIMP CInFileStream::GetSize(UInt64 *size)
  115. {
  116. return ConvertBoolToHRESULT(File.GetLength(*size));
  117. }
  118. //////////////////////////
  119. // COutFileStream
  120. HRESULT COutFileStream::Close()
  121. {
  122. return ConvertBoolToHRESULT(File.Close());
  123. }
  124. STDMETHODIMP COutFileStream::Write(const void *data, UInt32 size, UInt32 *processedSize)
  125. {
  126. #ifdef USE_WIN_FILE
  127. UInt32 realProcessedSize;
  128. bool result = File.WritePart(data, size, realProcessedSize);
  129. ProcessedSize += realProcessedSize;
  130. if(processedSize != NULL)
  131. *processedSize = realProcessedSize;
  132. return ConvertBoolToHRESULT(result);
  133. #else
  134. if(processedSize != NULL)
  135. *processedSize = 0;
  136. ssize_t res = File.Write(data, (size_t)size);
  137. if (res == -1)
  138. return E_FAIL;
  139. if(processedSize != NULL)
  140. *processedSize = (UInt32)res;
  141. ProcessedSize += res;
  142. return S_OK;
  143. #endif
  144. }
  145. STDMETHODIMP COutFileStream::Seek(Int64 offset, UInt32 seekOrigin, UInt64 *newPosition)
  146. {
  147. if(seekOrigin >= 3)
  148. return STG_E_INVALIDFUNCTION;
  149. #ifdef USE_WIN_FILE
  150. UInt64 realNewPosition;
  151. bool result = File.Seek(offset, seekOrigin, realNewPosition);
  152. if(newPosition != NULL)
  153. *newPosition = realNewPosition;
  154. return ConvertBoolToHRESULT(result);
  155. #else
  156. off_t res = File.Seek(offset, seekOrigin);
  157. if (res == -1)
  158. return E_FAIL;
  159. if(newPosition != NULL)
  160. *newPosition = (UInt64)res;
  161. return S_OK;
  162. #endif
  163. }
  164. STDMETHODIMP COutFileStream::SetSize(Int64 newSize)
  165. {
  166. #ifdef USE_WIN_FILE
  167. UInt64 currentPos;
  168. if(!File.Seek(0, FILE_CURRENT, currentPos))
  169. return E_FAIL;
  170. bool result = File.SetLength(newSize);
  171. UInt64 currentPos2;
  172. result = result && File.Seek(currentPos, currentPos2);
  173. return result ? S_OK : E_FAIL;
  174. #else
  175. return E_FAIL;
  176. #endif
  177. }
  178. #ifndef _WIN32_WCE
  179. STDMETHODIMP CStdOutFileStream::Write(const void *data, UInt32 size, UInt32 *processedSize)
  180. {
  181. if(processedSize != NULL)
  182. *processedSize = 0;
  183. #ifdef _WIN32
  184. UInt32 realProcessedSize;
  185. BOOL res = TRUE;
  186. if (size > 0)
  187. {
  188. // Seems that Windows doesn't like big amounts writing to stdout.
  189. // So we limit portions by 32KB.
  190. UInt32 sizeTemp = (1 << 15);
  191. if (sizeTemp > size)
  192. sizeTemp = size;
  193. res = ::WriteFile(GetStdHandle(STD_OUTPUT_HANDLE),
  194. data, sizeTemp, (DWORD *)&realProcessedSize, NULL);
  195. size -= realProcessedSize;
  196. data = (const void *)((const Byte *)data + realProcessedSize);
  197. if(processedSize != NULL)
  198. *processedSize += realProcessedSize;
  199. }
  200. return ConvertBoolToHRESULT(res != FALSE);
  201. #else
  202. ssize_t res;
  203. do
  204. {
  205. res = write(1, data, (size_t)size);
  206. }
  207. while (res < 0 && (errno == EINTR));
  208. if (res == -1)
  209. return E_FAIL;
  210. if(processedSize != NULL)
  211. *processedSize = (UInt32)res;
  212. return S_OK;
  213. return S_OK;
  214. #endif
  215. }
  216. #endif