1 /*************************************************************************
3 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
5 * Copyright 2008 by Sun Microsystems, Inc.
7 * OpenOffice.org - a multi-platform office productivity suite
9 * $RCSfile: strmos2.cxx,v $
12 * This file is part of OpenOffice.org.
14 * OpenOffice.org is free software: you can redistribute it and/or modify
15 * it under the terms of the GNU Lesser General Public License version 3
16 * only, as published by the Free Software Foundation.
18 * OpenOffice.org is distributed in the hope that it will be useful,
19 * but WITHOUT ANY WARRANTY; without even the implied warranty of
20 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
21 * GNU Lesser General Public License version 3 for more details
22 * (a copy is included in the LICENSE file that accompanied this code).
24 * You should have received a copy of the GNU Lesser General Public License
25 * version 3 along with OpenOffice.org. If not, see
26 * <http://www.openoffice.org/license.html>
27 * for a copy of the LGPLv3 License.
29 ************************************************************************/
36 #define INCL_DOSERRORS
39 #include <tools/debug.hxx>
40 #include <tools/fsys.hxx>
41 #include <tools/stream.hxx>
44 #include <osl/file.hxx>
49 #ifndef _OSL_FILE_HXX_
50 #include <osl/file.hxx>
55 // -----------------------------------------------------------------------
74 // -----------------------------------------------------------------------
76 ULONG
GetSvError( APIRET nPMError
)
78 static struct { APIRET pm
; ULONG sv
; } errArr
[] =
80 { ERROR_FILE_NOT_FOUND
, SVSTREAM_FILE_NOT_FOUND
},
81 { ERROR_PATH_NOT_FOUND
, SVSTREAM_PATH_NOT_FOUND
},
82 { ERROR_TOO_MANY_OPEN_FILES
, SVSTREAM_TOO_MANY_OPEN_FILES
},
83 { ERROR_ACCESS_DENIED
, SVSTREAM_ACCESS_DENIED
},
84 { ERROR_INVALID_ACCESS
, SVSTREAM_INVALID_ACCESS
},
85 { ERROR_SHARING_VIOLATION
, SVSTREAM_SHARING_VIOLATION
},
86 { ERROR_SHARING_BUFFER_EXCEEDED
,SVSTREAM_SHARE_BUFF_EXCEEDED
},
87 { ERROR_CANNOT_MAKE
, SVSTREAM_CANNOT_MAKE
},
88 { ERROR_INVALID_PARAMETER
, SVSTREAM_INVALID_PARAMETER
},
89 { ERROR_DRIVE_LOCKED
, SVSTREAM_LOCKING_VIOLATION
},
90 { ERROR_LOCK_VIOLATION
, SVSTREAM_LOCKING_VIOLATION
},
91 { ERROR_FILENAME_EXCED_RANGE
, SVSTREAM_INVALID_PARAMETER
},
92 { ERROR_ATOMIC_LOCK_NOT_SUPPORTED
, SVSTREAM_INVALID_PARAMETER
},
93 { ERROR_READ_LOCKS_NOT_SUPPORTED
, SVSTREAM_INVALID_PARAMETER
},
96 { 0xFFFF, SVSTREAM_GENERALERROR
}
99 ULONG nRetVal
= SVSTREAM_GENERALERROR
; // Standardfehler
103 if( errArr
[i
].pm
== nPMError
)
105 nRetVal
= errArr
[i
].sv
;
110 while( errArr
[i
].pm
!= 0xFFFF );
114 /*************************************************************************
116 |* SvFileStream::SvFileStream()
118 |* Beschreibung STREAM.SDW
119 |* Ersterstellung OV 15.06.94
120 |* Letzte Aenderung OV 15.06.94
122 *************************************************************************/
124 SvFileStream::SvFileStream( const String
& rFileName
, StreamMode nOpenMode
)
129 pInstanceData
= new StreamData
;
131 SetBufferSize( 8192 );
132 // convert URL to SystemPath, if necessary
133 ::rtl::OUString aFileName
, aNormPath
;
135 if ( FileBase::getSystemPathFromFileURL( rFileName
, aFileName
) != FileBase::E_None
)
136 aFileName
= rFileName
;
137 Open( aFileName
, nOpenMode
);
140 /*************************************************************************
142 |* SvFileStream::SvFileStream()
144 |* Beschreibung STREAM.SDW
145 |* Ersterstellung OV 22.11.94
146 |* Letzte Aenderung OV 22.11.94
148 *************************************************************************/
150 SvFileStream::SvFileStream()
155 pInstanceData
= new StreamData
;
156 SetBufferSize( 8192 );
159 /*************************************************************************
161 |* SvFileStream::~SvFileStream()
163 |* Beschreibung STREAM.SDW
164 |* Ersterstellung OV 14.06.94
165 |* Letzte Aenderung OV 14.06.94
167 *************************************************************************/
169 SvFileStream::~SvFileStream()
173 delete pInstanceData
;
176 /*************************************************************************
178 |* SvFileStream::GetFileHandle()
180 |* Beschreibung STREAM.SDW
181 |* Ersterstellung OV 14.06.94
182 |* Letzte Aenderung OV 14.06.94
184 *************************************************************************/
186 ULONG
SvFileStream::GetFileHandle() const
188 return (ULONG
)pInstanceData
->hFile
;
191 /*************************************************************************
193 |* SvFileStream::IsA()
195 |* Beschreibung STREAM.SDW
196 |* Ersterstellung OV 14.06.94
197 |* Letzte Aenderung OV 14.06.94
199 *************************************************************************/
201 USHORT
SvFileStream::IsA() const
203 return ID_FILESTREAM
;
206 /*************************************************************************
208 |* SvFileStream::GetData()
210 |* Beschreibung STREAM.SDW, Prueft nicht Eof; IsEof danach rufbar
211 |* Ersterstellung OV 15.06.94
212 |* Letzte Aenderung OV 15.06.94
214 *************************************************************************/
216 ULONG
SvFileStream::GetData( void* pData
, ULONG nSize
)
219 ByteString
aTraceStr( "SvFileStream::GetData(): " );
220 aTraceStr
+= ByteString::CreateFromInt64(nSize
);
221 aTraceStr
+= " Bytes from ";
222 aTraceStr
+= ByteString(aFilename
, osl_getThreadTextEncoding());
223 DBG_TRACE( aTraceStr
.GetBuffer() );
230 nResult
= DosRead( pInstanceData
->hFile
,(PVOID
)pData
,nSize
,&nCount
);
232 SetError(::GetSvError(nResult
) );
237 /*************************************************************************
239 |* SvFileStream::PutData()
241 |* Beschreibung STREAM.SDW
242 |* Ersterstellung OV 15.06.94
243 |* Letzte Aenderung OV 15.06.94
245 *************************************************************************/
247 ULONG
SvFileStream::PutData( const void* pData
, ULONG nSize
)
250 ByteString
aTraceStr( "SvFileStrean::PutData: " );
251 aTraceStr
+= ByteString::CreateFromInt64(nSize
);
252 aTraceStr
+= " Bytes to ";
253 aTraceStr
+= ByteString(aFilename
, osl_getThreadTextEncoding());
254 DBG_TRACE( aTraceStr
.GetBuffer() );
261 nResult
= DosWrite( pInstanceData
->hFile
,(PVOID
)pData
,nSize
,&nCount
);
263 SetError(::GetSvError(nResult
) );
265 SetError( SVSTREAM_DISK_FULL
);
270 /*************************************************************************
272 |* SvFileStream::SeekPos()
274 |* Beschreibung STREAM.SDW
275 |* Ersterstellung OV 15.06.94
276 |* Letzte Aenderung OV 15.06.94
278 *************************************************************************/
280 ULONG
SvFileStream::SeekPos( ULONG nPos
)
287 if( nPos
!= STREAM_SEEK_TO_END
)
288 nResult
= DosSetFilePtr( pInstanceData
->hFile
,(long)nPos
,
289 FILE_BEGIN
, &nNewPos
);
291 nResult
= DosSetFilePtr( pInstanceData
->hFile
,0L,
292 FILE_END
, &nNewPos
);
295 SetError(::GetSvError(nResult
) );
298 SetError( SVSTREAM_GENERALERROR
);
302 /*************************************************************************
304 |* SvFileStream::Tell()
306 |* Beschreibung STREAM.SDW
307 |* Ersterstellung OV 15.06.94
308 |* Letzte Aenderung OV 15.06.94
310 *************************************************************************/
312 ULONG SvFileStream::Tell()
319 nResult = DosSetFilePtr(pInstanceData->hFile,0L,FILE_CURRENT,&nPos);
321 SetError(::GetSvError(nResult) );
327 /*************************************************************************
329 |* SvFileStream::FlushData()
331 |* Beschreibung STREAM.SDW
332 |* Ersterstellung OV 15.06.94
333 |* Letzte Aenderung OV 15.06.94
335 *************************************************************************/
337 void SvFileStream::FlushData()
342 nResult
= DosResetBuffer(pInstanceData
->hFile
);
344 SetError(::GetSvError(nResult
) );
348 /*************************************************************************
350 |* SvFileStream::LockRange()
352 |* Beschreibung STREAM.SDW
353 |* Ersterstellung OV 15.06.94
354 |* Letzte Aenderung OV 15.06.94
356 *************************************************************************/
358 sal_Bool
SvFileStream::LockRange( ULONG nByteOffset
, ULONG nBytes
)
360 sal_Bool bRetVal
= FALSE
;
364 FILELOCK aLockArea
, aUnlockArea
;
365 aUnlockArea
.lOffset
= 0L;
366 aUnlockArea
.lRange
= 0L;
367 aLockArea
.lOffset
= (long)nByteOffset
;
368 aLockArea
.lRange
= (long)nBytes
;
370 nResult
= DosSetFileLocks(pInstanceData
->hFile
,
371 &aUnlockArea
, &aLockArea
,
372 1000UL, // Zeit in ms bis Abbruch
373 0L // kein Atomic-Lock
377 SetError(::GetSvError(nResult
) );
384 /*************************************************************************
386 |* SvFileStream::UnlockRange()
388 |* Beschreibung STREAM.SDW
389 |* Ersterstellung OV 15.06.94
390 |* Letzte Aenderung OV 15.06.94
392 *************************************************************************/
394 sal_Bool
SvFileStream::UnlockRange( ULONG nByteOffset
, ULONG nBytes
)
396 sal_Bool bRetVal
= FALSE
;
400 FILELOCK aLockArea
, aUnlockArea
;
401 aLockArea
.lOffset
= 0L;
402 aLockArea
.lRange
= 0L;
403 aUnlockArea
.lOffset
= (long)nByteOffset
;
404 aUnlockArea
.lRange
= (long)nBytes
;
406 nResult
= DosSetFileLocks(pInstanceData
->hFile
,
407 &aUnlockArea
, &aLockArea
,
408 1000UL, // Zeit in ms bis Abbruch
409 0L // kein Atomic-Lock
413 SetError(::GetSvError(nResult
) );
420 /*************************************************************************
422 |* SvFileStream::LockFile()
424 |* Beschreibung STREAM.SDW
425 |* Ersterstellung OV 15.06.94
426 |* Letzte Aenderung OV 15.06.94
428 *************************************************************************/
430 sal_Bool
SvFileStream::LockFile()
432 sal_Bool bRetVal
= FALSE
;
435 if( LockRange( 0L, LONG_MAX
) )
449 /*************************************************************************
451 |* SvFileStream::UnlockFile()
453 |* Beschreibung STREAM.SDW
454 |* Ersterstellung OV 15.06.94
455 |* Letzte Aenderung OV 15.06.94
457 *************************************************************************/
459 sal_Bool
SvFileStream::UnlockFile()
461 sal_Bool bRetVal
= FALSE
;
462 if( nLockCounter
> 0)
464 if( nLockCounter
== 1)
466 if( UnlockRange( 0L, LONG_MAX
) )
481 /*************************************************************************
483 |* SvFileStream::Open()
485 |* Beschreibung STREAM.SDW
486 |* Ersterstellung OV 15.06.94
487 |* Letzte Aenderung OV 15.06.94
489 *************************************************************************/
492 BOOL
createLongNameEA ( const PCSZ pszPath
, ULONG ulAttributes
, const String
& aLongName
);
495 void SvFileStream::Open( const String
& rFilename
, StreamMode nOpenMode
)
497 String aParsedFilename
;
500 if ( Folder::IsAvailable() && (rFilename
.Search('{') < 9) )
505 ItemIDPath aVirtualURL
;
508 String
aVirtualString(rFilename
);
510 for (int x
=aVirtualString
.Len(); x
>0; x
--)
512 if (aVirtualString
.Copy(x
,1).Compare("}")==COMPARE_EQUAL
)
519 aVirtualPart
= aVirtualString
.Copy(0,nDivider
+1);
520 aRealPart
= aVirtualString
.Copy(nDivider
+2);
522 aVirtualURL
= aVirtualPart
;
523 aVirtualPath
= aVirtualURL
.GetHostNotationPath();
525 DirEntry
aTempDirEntry(aVirtualPath
);
527 aTempDirEntry
+= aRealPart
;
529 aParsedFilename
= aTempDirEntry
.GetFull();
534 aParsedFilename
= rFilename
;
538 SvStream::ClearBuffer();
541 ULONG nOpenAction
= 0L;
542 ULONG nShareBits
= 0L;
543 ULONG nReadWriteBits
= 0L;
545 eStreamMode
= nOpenMode
;
546 eStreamMode
&= ~STREAM_TRUNC
; // beim ReOpen nicht cutten
548 nOpenMode
|= STREAM_SHARE_DENYNONE
; // definierten Zustand garantieren
550 // ********* Zugriffsflags ***********
551 if( nOpenMode
& STREAM_SHARE_DENYNONE
)
552 nShareBits
= OPEN_SHARE_DENYNONE
;
554 if( nOpenMode
& STREAM_SHARE_DENYREAD
)
555 nShareBits
= OPEN_SHARE_DENYREAD
;
557 if( nOpenMode
& STREAM_SHARE_DENYWRITE
)
558 nShareBits
= OPEN_SHARE_DENYWRITE
;
560 if( nOpenMode
& STREAM_SHARE_DENYALL
)
561 nShareBits
= OPEN_SHARE_DENYREADWRITE
;
563 if( (nOpenMode
& STREAM_READ
) )
565 if( nOpenMode
& STREAM_WRITE
)
566 nReadWriteBits
|= OPEN_ACCESS_READWRITE
;
569 nReadWriteBits
|= OPEN_ACCESS_READONLY
;
570 nOpenMode
|= STREAM_NOCREATE
;
574 nReadWriteBits
|= OPEN_ACCESS_WRITEONLY
;
577 if( nOpenMode
& STREAM_NOCREATE
)
579 // Datei nicht erzeugen
580 nOpenAction
= OPEN_ACTION_FAIL_IF_NEW
| OPEN_ACTION_OPEN_IF_EXISTS
;
584 // Datei erzeugen, wenn nicht vorhanden
585 nOpenAction
= OPEN_ACTION_CREATE_IF_NEW
;
586 if( nOpenMode
& STREAM_TRUNC
)
587 // Auf Nullaenge kuerzen, wenn existiert
588 nOpenAction
|= OPEN_ACTION_REPLACE_IF_EXISTS
;
590 // Inhalt der Datei nicht wegwerfen
591 nOpenAction
|= OPEN_ACTION_OPEN_IF_EXISTS
;
596 // resolves long FAT names used by OS2
598 BOOL bIsLongOS2
=FALSE
;
599 if (Folder::IsAvailable())
601 DirEntry
aDirEntry(rFilename
);
602 if (aDirEntry
.IsLongNameOnFAT())
604 // in kurzen Pfad wandeln
605 ItemIDPath
aItemIDPath(rFilename
);
606 aParsedFilename
= aItemIDPath
.GetHostNotationPath();
612 aFilename
= aParsedFilename
;
613 ByteString
aFileNameA( aFilename
, gsl_getSystemTextEncoding());
614 FSysRedirector::DoRedirect( aFilename
);
617 ByteString
aTraceStr( "SvFileStream::Open(): " );
618 aTraceStr
+= aFileNameA
;
619 DBG_TRACE( aTraceStr
.GetBuffer() );
622 APIRET nRet
= DosOpen( aFileNameA
.GetBuffer(), &pInstanceData
->hFile
,
623 &nActionTaken
, 0L, FILE_NORMAL
, nOpenAction
,
624 nReadWriteBits
| nShareBits
| OPEN_FLAGS_NOINHERIT
, 0L);
626 if( nRet
== ERROR_TOO_MANY_OPEN_FILES
)
630 nRet
= DosSetRelMaxFH( &nToAdd
, &nCurMaxFH
);
631 nRet
= DosOpen( aFileNameA
.GetBuffer(), &pInstanceData
->hFile
,
632 &nActionTaken
, 0L, FILE_NORMAL
, nOpenAction
,
633 nReadWriteBits
| nShareBits
| OPEN_FLAGS_NOINHERIT
, 0L);
636 // Bei Fehler pruefen, ob wir lesen duerfen
637 if( nRet
==ERROR_ACCESS_DENIED
|| nRet
==ERROR_SHARING_VIOLATION
)
639 nReadWriteBits
= OPEN_ACCESS_READONLY
;
640 nRet
= DosOpen( aFileNameA
.GetBuffer(), &pInstanceData
->hFile
,
641 &nActionTaken
, 0L, FILE_NORMAL
, nOpenAction
,
642 nReadWriteBits
| nShareBits
| OPEN_FLAGS_NOINHERIT
, 0L);
648 SetError(::GetSvError(nRet
) );
653 pInstanceData
->bIsEof
= FALSE
;
654 if( nReadWriteBits
!= OPEN_ACCESS_READONLY
)
659 if (bIsOpen
&& bIsLongOS2
)
661 //file schließen, da sonst createLongName u.U. nicht möglich
664 // erzeugtem File langen Namen geben
665 DirEntry
aDirEntry(rFilename
);
666 createLongNameEA(aFileNameA
.GetBuffer(), FILE_NORMAL
, aDirEntry
.GetName());
668 // und wieder oeffnen
675 /*************************************************************************
677 |* SvFileStream::ReOpen()
679 |* Beschreibung STREAM.SDW
680 |* Ersterstellung OV 15.06.94
681 |* Letzte Aenderung OV 15.06.94
683 *************************************************************************/
685 void SvFileStream::ReOpen()
687 if( !bIsOpen
&& aFilename
.Len() )
688 Open( aFilename
, eStreamMode
);
691 /*************************************************************************
693 |* SvFileStream::Close()
695 |* Beschreibung STREAM.SDW
696 |* Ersterstellung OV 15.06.94
697 |* Letzte Aenderung OV 15.06.94
699 *************************************************************************/
701 void SvFileStream::Close()
706 ByteString
aTraceStr( "SvFileStream::Close(): " );
707 aTraceStr
+= ByteString(aFilename
, osl_getThreadTextEncoding());
708 DBG_TRACE( aTraceStr
.GetBuffer() );
717 DosClose( pInstanceData
->hFile
);
723 pInstanceData
->bIsEof
= TRUE
;
724 SvStream::ClearBuffer();
725 SvStream::ClearError();
728 /*************************************************************************
730 |* SvFileStream::ResetError()
732 |* Beschreibung STREAM.SDW; Setzt Filepointer auf Dateianfang
733 |* Ersterstellung OV 15.06.94
734 |* Letzte Aenderung OV 15.06.94
736 *************************************************************************/
738 void SvFileStream::ResetError()
740 SvStream::ClearError();
743 /*************************************************************************
745 |* SvFileStream::SetSize()
748 |* Ersterstellung OV 19.10.95
749 |* Letzte Aenderung OV 19.10.95
751 *************************************************************************/
753 void SvFileStream::SetSize( ULONG nSize
)
757 APIRET nRet
= DosSetFileSize( pInstanceData
->hFile
, nSize
);
759 SetError( ::GetSvError( nRet
) );
764 /*************************************************************************
766 |* SvSharedMemoryStream::AllocateMemory()
768 |* Beschreibung STREAM.SDW
769 |* Ersterstellung CL 05.05.95
770 |* Letzte Aenderung CL 05.05.95
772 *************************************************************************/
774 sal_Bool
SvSharedMemoryStream::AllocateMemory( ULONG nNewSize
)
776 DBG_ASSERT(aHandle
==0,"Keine Handles unter OS/2");
777 DBG_ASSERT(nNewSize
,"Cannot allocate zero Bytes");
778 APIRET nRet
= DosAllocSharedMem( (void**)&pBuf
, (PSZ
)NULL
, nNewSize
,
779 PAG_READ
| PAG_WRITE
| PAG_COMMIT
|
780 OBJ_GIVEABLE
| OBJ_GETTABLE
| OBJ_ANY
);
784 /*************************************************************************
786 |* SvSharedMemoryStream::ReAllocateMemory() (Bozo-Algorithmus)
788 |* Beschreibung STREAM.SDW
789 |* Ersterstellung CL 05.05.95
790 |* Letzte Aenderung CL 05.05.95
792 *************************************************************************/
794 sal_Bool
SvSharedMemoryStream::ReAllocateMemory( long nDiff
)
796 DBG_ASSERT(aHandle
==0,"Keine Handles unter OS/2");
797 sal_Bool bRetVal
= FALSE
;
798 ULONG nNewSize
= nSize
+ nDiff
;
801 // neuen Speicher nicht ueber AllocateMemory holen, da wir den
802 // alten Speicher behalten wollen, falls nicht genuegend Platz
803 // fuer den neuen Block da ist
805 APIRET nRet
= DosAllocSharedMem( (void**)&pNewBuf
,(PSZ
)NULL
,nNewSize
,
806 PAG_READ
| PAG_WRITE
| PAG_COMMIT
|
807 OBJ_GIVEABLE
| OBJ_GETTABLE
| OBJ_ANY
);
808 DBG_ASSERT(!nRet
,"DosAllocSharedMem failed");
812 bRetVal
= TRUE
; // Success!
813 if( nNewSize
< nSize
) // Verkleinern ?
815 memcpy( pNewBuf
, pBuf
, (size_t)nNewSize
);
816 if( nPos
> nNewSize
)
818 if( nEndOfData
>= nNewSize
)
819 nEndOfData
= nNewSize
-1L;
822 memcpy( pNewBuf
, pBuf
, (size_t)nSize
);
824 FreeMemory(); // den alten Block loeschen ...
826 // und den neuen Block in Dienst stellen
827 pBuf
= (sal_uInt8
*)pNewBuf
;
842 void SvSharedMemoryStream::FreeMemory()
844 DBG_ASSERT(aHandle
==0,"Keine Handles unter OS/2");
848 /*************************************************************************
850 |* SvSharedMemoryStream::SetHandle()
852 |* Beschreibung STREAM.SDW
853 |* Ersterstellung OV 05.10.95
854 |* Letzte Aenderung OV 05.10.95
856 *************************************************************************/
858 void* SvSharedMemoryStream::SetHandle( void* aNewHandle
, sal_Size nSize
,
859 sal_Bool bOwnsData
, sal_Size nEOF
)
861 DBG_ERROR("OS/2 does not support memory handles");
862 // return SetBuffer(aNewHandle, nSize, bOwnsData, nEOF );