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