fix baseline build (old cairo) - 'cairo_rectangle_int_t' does not name a type
[LibreOffice.git] / tools / source / stream / strmwnt.cxx
blobdd49f6d2702f569b1e0149fc54fdd69f3c13384a
1 /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
2 /*
3 * This file is part of the LibreOffice project.
5 * This Source Code Form is subject to the terms of the Mozilla Public
6 * License, v. 2.0. If a copy of the MPL was not distributed with this
7 * file, You can obtain one at http://mozilla.org/MPL/2.0/.
9 * This file incorporates work covered by the following license notice:
11 * Licensed to the Apache Software Foundation (ASF) under one or more
12 * contributor license agreements. See the NOTICE file distributed
13 * with this work for additional information regarding copyright
14 * ownership. The ASF licenses this file to you under the Apache
15 * License, Version 2.0 (the "License"); you may not use this file
16 * except in compliance with the License. You may obtain a copy of
17 * the License at http://www.apache.org/licenses/LICENSE-2.0 .
20 // TODO: StreamMode <-> AllocateMemory
22 #include <string.h>
23 #include <limits.h>
25 #ifdef WNT
26 #include <windows.h>
27 #endif
29 #include <osl/thread.h>
30 #include <tools/stream.hxx>
32 // class FileBase
33 #include <osl/file.hxx>
34 using namespace osl;
36 class StreamData
38 public:
39 HANDLE hFile;
41 StreamData()
43 hFile = 0;
47 static sal_Size GetSvError( DWORD nWntError )
49 static struct { DWORD wnt; sal_Size sv; } errArr[] =
51 { ERROR_SUCCESS, SVSTREAM_OK },
52 { ERROR_ACCESS_DENIED, SVSTREAM_ACCESS_DENIED },
53 { ERROR_ACCOUNT_DISABLED, SVSTREAM_ACCESS_DENIED },
54 { ERROR_ACCOUNT_EXPIRED, SVSTREAM_ACCESS_DENIED },
55 { ERROR_ACCOUNT_RESTRICTION, SVSTREAM_ACCESS_DENIED },
56 { ERROR_ATOMIC_LOCKS_NOT_SUPPORTED, SVSTREAM_INVALID_PARAMETER },
57 { ERROR_BAD_PATHNAME, SVSTREAM_PATH_NOT_FOUND },
58 // Filename too long
59 { ERROR_BUFFER_OVERFLOW, SVSTREAM_INVALID_PARAMETER },
60 { ERROR_DIRECTORY, SVSTREAM_INVALID_PARAMETER },
61 { ERROR_DRIVE_LOCKED, SVSTREAM_LOCKING_VIOLATION },
62 { ERROR_FILE_NOT_FOUND, SVSTREAM_FILE_NOT_FOUND },
63 { ERROR_FILENAME_EXCED_RANGE, SVSTREAM_INVALID_PARAMETER },
64 { ERROR_INVALID_ACCESS, SVSTREAM_INVALID_ACCESS },
65 { ERROR_INVALID_DRIVE, SVSTREAM_PATH_NOT_FOUND },
66 { ERROR_INVALID_HANDLE, SVSTREAM_INVALID_HANDLE },
67 { ERROR_INVALID_NAME, SVSTREAM_PATH_NOT_FOUND },
68 { ERROR_INVALID_PARAMETER, SVSTREAM_INVALID_PARAMETER },
69 { ERROR_IS_SUBST_PATH, SVSTREAM_INVALID_PARAMETER },
70 { ERROR_IS_SUBST_TARGET, SVSTREAM_INVALID_PARAMETER },
71 { ERROR_LOCK_FAILED, SVSTREAM_LOCKING_VIOLATION },
72 { ERROR_LOCK_VIOLATION, SVSTREAM_LOCKING_VIOLATION },
73 { ERROR_NEGATIVE_SEEK, SVSTREAM_SEEK_ERROR },
74 { ERROR_PATH_NOT_FOUND, SVSTREAM_PATH_NOT_FOUND },
75 { ERROR_READ_FAULT, SVSTREAM_READ_ERROR },
76 { ERROR_SEEK, SVSTREAM_SEEK_ERROR },
77 { ERROR_SEEK_ON_DEVICE, SVSTREAM_SEEK_ERROR },
78 { ERROR_SHARING_BUFFER_EXCEEDED,SVSTREAM_SHARE_BUFF_EXCEEDED },
79 { ERROR_SHARING_PAUSED, SVSTREAM_SHARING_VIOLATION },
80 { ERROR_SHARING_VIOLATION, SVSTREAM_SHARING_VIOLATION },
81 { ERROR_TOO_MANY_OPEN_FILES, SVSTREAM_TOO_MANY_OPEN_FILES },
82 { ERROR_WRITE_FAULT, SVSTREAM_WRITE_ERROR },
83 { ERROR_WRITE_PROTECT, SVSTREAM_ACCESS_DENIED },
84 { ERROR_DISK_FULL, SVSTREAM_DISK_FULL },
86 { (DWORD)0xFFFFFFFF, SVSTREAM_GENERALERROR }
89 sal_Size nRetVal = SVSTREAM_GENERALERROR; // default error
90 int i=0;
93 if( errArr[i].wnt == nWntError )
95 nRetVal = errArr[i].sv;
96 break;
98 i++;
99 } while( errArr[i].wnt != (DWORD)0xFFFFFFFF );
100 return nRetVal;
103 SvFileStream::SvFileStream( const OUString& rFileName, StreamMode nMode )
105 bIsOpen = false;
106 nLockCounter = 0;
107 bIsWritable = false;
108 pInstanceData = new StreamData;
110 SetBufferSize( 8192 );
111 // convert URL to SystemPath, if necessary
112 OUString aFileName, aNormPath;
114 if ( FileBase::getSystemPathFromFileURL( rFileName, aFileName ) != FileBase::E_None )
115 aFileName = rFileName;
116 Open( aFileName, nMode );
119 SvFileStream::SvFileStream()
121 bIsOpen = false;
122 nLockCounter = 0;
123 bIsWritable = false;
124 pInstanceData = new StreamData;
126 SetBufferSize( 8192 );
129 SvFileStream::~SvFileStream()
131 Close();
132 if (pInstanceData)
133 delete pInstanceData;
136 /// Does not check for EOF, makes isEof callable
137 sal_Size SvFileStream::GetData( void* pData, sal_Size nSize )
139 DWORD nCount = 0;
140 if( IsOpen() )
142 bool bResult = ReadFile(pInstanceData->hFile,(LPVOID)pData,nSize,&nCount,NULL);
143 if( !bResult )
145 sal_Size nTestError = GetLastError();
146 SetError(::GetSvError( nTestError ) );
149 return (DWORD)nCount;
152 sal_Size SvFileStream::PutData( const void* pData, sal_Size nSize )
154 DWORD nCount = 0;
155 if( IsOpen() )
157 if(!WriteFile(pInstanceData->hFile,(LPVOID)pData,nSize,&nCount,NULL))
158 SetError(::GetSvError( GetLastError() ) );
160 return nCount;
163 sal_uInt64 SvFileStream::SeekPos(sal_uInt64 const nPos)
165 // check if a truncated STREAM_SEEK_TO_END was passed
166 assert(nPos != SAL_MAX_UINT32);
167 DWORD nNewPos = 0;
168 if( IsOpen() )
170 if( nPos != STREAM_SEEK_TO_END )
171 // 64-Bit files are not supported
172 nNewPos=SetFilePointer(pInstanceData->hFile,nPos,NULL,FILE_BEGIN);
173 else
174 nNewPos=SetFilePointer(pInstanceData->hFile,0L,NULL,FILE_END);
176 if( nNewPos == 0xFFFFFFFF )
178 SetError(::GetSvError( GetLastError() ) );
179 nNewPos = 0L;
182 else
183 SetError( SVSTREAM_GENERALERROR );
184 return static_cast<sal_uInt64>(nNewPos);
187 void SvFileStream::FlushData()
189 if( IsOpen() )
191 if( !FlushFileBuffers(pInstanceData->hFile) )
192 SetError(::GetSvError(GetLastError()));
196 bool SvFileStream::LockRange( sal_Size nByteOffset, sal_Size nBytes )
198 bool bRetVal = false;
199 if( IsOpen() )
201 bRetVal = ::LockFile(pInstanceData->hFile,nByteOffset,0L,nBytes,0L );
202 if( !bRetVal )
203 SetError(::GetSvError(GetLastError()));
205 return bRetVal;
208 bool SvFileStream::UnlockRange( sal_Size nByteOffset, sal_Size nBytes )
210 bool bRetVal = false;
211 if( IsOpen() )
213 bRetVal = ::UnlockFile(pInstanceData->hFile,nByteOffset,0L,nBytes,0L );
214 if( !bRetVal )
215 SetError(::GetSvError(GetLastError()));
217 return bRetVal;
220 bool SvFileStream::LockFile()
222 bool bRetVal = false;
223 if( !nLockCounter )
225 if( LockRange( 0L, LONG_MAX ) )
227 nLockCounter = 1;
228 bRetVal = true;
231 else
233 nLockCounter++;
234 bRetVal = true;
236 return bRetVal;
239 bool SvFileStream::UnlockFile()
241 bool bRetVal = false;
242 if( nLockCounter > 0)
244 if( nLockCounter == 1)
246 if( UnlockRange( 0L, LONG_MAX ) )
248 nLockCounter = 0;
249 bRetVal = true;
252 else
254 nLockCounter--;
255 bRetVal = true;
258 return bRetVal;
262 NOCREATE TRUNC NT-Action
263 ----------------------------------------------
264 0 (Create) 0 OPEN_ALWAYS
265 0 (Create) 1 CREATE_ALWAYS
266 1 0 OPEN_EXISTING
267 1 1 TRUNCATE_EXISTING
269 void SvFileStream::Open( const OUString& rFilename, StreamMode nMode )
271 OUString aParsedFilename(rFilename);
273 SetLastError( ERROR_SUCCESS );
274 Close();
275 SvStream::ClearBuffer();
277 eStreamMode = nMode;
278 eStreamMode &= ~StreamMode::TRUNC; // don't truncate on reopen
280 aFilename = aParsedFilename;
281 OString aFileNameA(OUStringToOString(aFilename, osl_getThreadTextEncoding()));
282 SetLastError( ERROR_SUCCESS ); // might be changed by Redirector
284 DWORD nOpenAction;
285 DWORD nShareMode = FILE_SHARE_READ | FILE_SHARE_WRITE;
286 DWORD nAccessMode = 0L;
287 UINT nOldErrorMode = SetErrorMode( SEM_FAILCRITICALERRORS|SEM_NOOPENFILEERRORBOX );
289 if( nMode & StreamMode::SHARE_DENYREAD)
290 nShareMode &= ~FILE_SHARE_READ;
292 if( nMode & StreamMode::SHARE_DENYWRITE)
293 nShareMode &= ~FILE_SHARE_WRITE;
295 if( nMode & StreamMode::SHARE_DENYALL)
296 nShareMode = 0;
298 if( (nMode & StreamMode::READ) )
299 nAccessMode |= GENERIC_READ;
300 if( (nMode & StreamMode::WRITE) )
301 nAccessMode |= GENERIC_WRITE;
303 if( nAccessMode == GENERIC_READ ) // ReadOnly ?
304 nMode |= StreamMode::NOCREATE; // Don't create if readonly
306 // Assignment based on true/false table above
307 if( !(nMode & StreamMode::NOCREATE) )
309 if( nMode & StreamMode::TRUNC )
310 nOpenAction = CREATE_ALWAYS;
311 else
312 nOpenAction = OPEN_ALWAYS;
314 else
316 if( nMode & StreamMode::TRUNC )
317 nOpenAction = TRUNCATE_EXISTING;
318 else
319 nOpenAction = OPEN_EXISTING;
322 pInstanceData->hFile = CreateFile(
323 aFileNameA.getStr(),
324 nAccessMode,
325 nShareMode,
326 (LPSECURITY_ATTRIBUTES)NULL,
327 nOpenAction,
328 FILE_ATTRIBUTE_NORMAL | FILE_FLAG_RANDOM_ACCESS,
329 (HANDLE) NULL
332 if( pInstanceData->hFile!=INVALID_HANDLE_VALUE && (
333 // Did Create Always overwrite a file?
334 GetLastError() == ERROR_ALREADY_EXISTS ||
335 // Did Create Always open a new file?
336 GetLastError() == ERROR_FILE_NOT_FOUND ))
338 // If so, no error
339 if( nOpenAction == OPEN_ALWAYS || nOpenAction == CREATE_ALWAYS )
340 SetLastError( ERROR_SUCCESS );
343 // Otherwise, determine if we're allowed to read
344 if( (pInstanceData->hFile==INVALID_HANDLE_VALUE) &&
345 (nAccessMode & GENERIC_WRITE))
347 sal_Size nErr = ::GetSvError( GetLastError() );
348 if(nErr==SVSTREAM_ACCESS_DENIED || nErr==SVSTREAM_SHARING_VIOLATION)
350 nMode &= (~StreamMode::WRITE);
351 nAccessMode = GENERIC_READ;
352 // OV, 28.1.97: Win32 sets file to length 0
353 // if Openaction is CREATE_ALWAYS
354 nOpenAction = OPEN_EXISTING;
355 SetLastError( ERROR_SUCCESS );
356 pInstanceData->hFile = CreateFile(
357 aFileNameA.getStr(),
358 GENERIC_READ,
359 nShareMode,
360 (LPSECURITY_ATTRIBUTES)NULL,
361 nOpenAction,
362 FILE_ATTRIBUTE_NORMAL | FILE_FLAG_RANDOM_ACCESS,
363 (HANDLE) NULL
365 if( GetLastError() == ERROR_ALREADY_EXISTS )
366 SetLastError( ERROR_SUCCESS );
370 if( GetLastError() != ERROR_SUCCESS )
372 bIsOpen = false;
373 SetError(::GetSvError( GetLastError() ) );
375 else
377 bIsOpen = true;
378 // pInstanceData->bIsEof = false;
379 if( nAccessMode & GENERIC_WRITE )
380 bIsWritable = true;
382 SetErrorMode( nOldErrorMode );
385 void SvFileStream::Close()
387 if( IsOpen() )
389 if( nLockCounter )
391 nLockCounter = 1;
392 UnlockFile();
394 Flush();
395 CloseHandle( pInstanceData->hFile );
397 bIsOpen = false;
398 nLockCounter= 0;
399 bIsWritable = false;
400 SvStream::ClearBuffer();
401 SvStream::ClearError();
404 /// Reset filepointer to beginning of file
405 void SvFileStream::ResetError()
407 SvStream::ClearError();
410 void SvFileStream::SetSize(sal_uInt64 const nSize)
413 if( IsOpen() )
415 int bError = false;
416 HANDLE hFile = pInstanceData->hFile;
417 sal_Size nOld = SetFilePointer( hFile, 0L, NULL, FILE_CURRENT );
418 if( nOld != 0xffffffff )
420 if( SetFilePointer(hFile,nSize,NULL,FILE_BEGIN ) != 0xffffffff)
422 bool bSucc = SetEndOfFile( hFile );
423 if( !bSucc )
424 bError = true;
426 if( SetFilePointer( hFile,nOld,NULL,FILE_BEGIN ) == 0xffffffff)
427 bError = true;
429 if( bError )
430 SetError(::GetSvError( GetLastError() ) );
434 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */