1 /**************************************************************
2 *
3 * Licensed to the Apache Software Foundation (ASF) under one
4 * or more contributor license agreements. See the NOTICE file
5 * distributed with this work for additional information
6 * regarding copyright ownership. The ASF licenses this file
7 * to you under the Apache License, Version 2.0 (the
8 * "License"); you may not use this file except in compliance
9 * with the License. You may obtain a copy of the License at
10 *
11 * http://www.apache.org/licenses/LICENSE-2.0
12 *
13 * Unless required by applicable law or agreed to in writing,
14 * software distributed under the License is distributed on an
15 * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
16 * KIND, either express or implied. See the License for the
17 * specific language governing permissions and limitations
18 * under the License.
19 *
20 *************************************************************/
21
22
23
24 // MARKER(update_precomp.py): autogen include statement, do not remove
25 #include "precompiled_basic.hxx"
26 #include <vcl/dialog.hxx>
27 #include <vcl/edit.hxx>
28 #ifndef _SV_BUTTON_HXX //autogen
29 #include <vcl/button.hxx>
30 #endif
31 #include <vcl/msgbox.hxx>
32 #include <vcl/svapp.hxx>
33 #include <osl/security.h>
34 #include <osl/file.hxx>
35 #include <tools/urlobj.hxx>
36 #include <vos/mutex.hxx>
37
38 #include "runtime.hxx"
39
40 #ifdef _USE_UNO
41
42 // <-- encoding
43 #include <sal/alloca.h>
44
45 #include <ctype.h>
46 #include <rtl/byteseq.hxx>
47 #include <rtl/textenc.h>
48 #include <rtl/ustrbuf.hxx>
49 #include <rtl/textenc.h>
50 #include <rtl/ustrbuf.hxx>
51 // encoding -->
52 #include <comphelper/processfactory.hxx>
53
54 #include <com/sun/star/uno/Sequence.hxx>
55 #include <com/sun/star/lang/XMultiServiceFactory.hpp>
56 #include <com/sun/star/ucb/XSimpleFileAccess.hpp>
57 #include <com/sun/star/ucb/XContentProvider.hpp>
58 #include <com/sun/star/ucb/XContentProviderManager.hpp>
59 #include <com/sun/star/io/XInputStream.hpp>
60 #include <com/sun/star/io/XOutputStream.hpp>
61 #include <com/sun/star/io/XStream.hpp>
62 #include <com/sun/star/io/XSeekable.hpp>
63 #include <com/sun/star/bridge/XBridge.hpp>
64 #include <com/sun/star/bridge/XBridgeFactory.hpp>
65
66 using namespace comphelper;
67 using namespace osl;
68 using namespace com::sun::star::uno;
69 using namespace com::sun::star::lang;
70 using namespace com::sun::star::ucb;
71 using namespace com::sun::star::io;
72 using namespace com::sun::star::bridge;
73
74 #endif /* _USE_UNO */
75
76 #include "iosys.hxx"
77 #include "sbintern.hxx"
78
79 // Der Input-Dialog:
80
81 class SbiInputDialog : public ModalDialog {
82 Edit aInput;
83 OKButton aOk;
84 CancelButton aCancel;
85 String aText;
86 DECL_LINK( Ok, Window * );
87 DECL_LINK( Cancel, Window * );
88 public:
89 SbiInputDialog( Window*, const String& );
GetInput()90 const String& GetInput() { return aText; }
91 };
92
SbiInputDialog(Window * pParent,const String & rPrompt)93 SbiInputDialog::SbiInputDialog( Window* pParent, const String& rPrompt )
94 :ModalDialog( pParent, WB_3DLOOK | WB_MOVEABLE | WB_CLOSEABLE ),
95 aInput( this, WB_3DLOOK | WB_LEFT | WB_BORDER ),
96 aOk( this ), aCancel( this )
97 {
98 SetText( rPrompt );
99 aOk.SetClickHdl( LINK( this, SbiInputDialog, Ok ) );
100 aCancel.SetClickHdl( LINK( this, SbiInputDialog, Cancel ) );
101 SetMapMode( MapMode( MAP_APPFONT ) );
102
103 Point aPt = LogicToPixel( Point( 50, 50 ) );
104 Size aSz = LogicToPixel( Size( 145, 65 ) );
105 SetPosSizePixel( aPt, aSz );
106 aPt = LogicToPixel( Point( 10, 10 ) );
107 aSz = LogicToPixel( Size( 120, 12 ) );
108 aInput.SetPosSizePixel( aPt, aSz );
109 aPt = LogicToPixel( Point( 15, 30 ) );
110 aSz = LogicToPixel( Size( 45, 15) );
111 aOk.SetPosSizePixel( aPt, aSz );
112 aPt = LogicToPixel( Point( 80, 30 ) );
113 aSz = LogicToPixel( Size( 45, 15) );
114 aCancel.SetPosSizePixel( aPt, aSz );
115
116 aInput.Show();
117 aOk.Show();
118 aCancel.Show();
119 }
120
IMPL_LINK_INLINE_START(SbiInputDialog,Ok,Window *,pWindow)121 IMPL_LINK_INLINE_START( SbiInputDialog, Ok, Window *, pWindow )
122 {
123 (void)pWindow;
124
125 aText = aInput.GetText();
126 EndDialog( 1 );
127 return 0;
128 }
IMPL_LINK_INLINE_END(SbiInputDialog,Ok,Window *,pWindow)129 IMPL_LINK_INLINE_END( SbiInputDialog, Ok, Window *, pWindow )
130
131 IMPL_LINK_INLINE_START( SbiInputDialog, Cancel, Window *, pWindow )
132 {
133 (void)pWindow;
134
135 EndDialog( 0 );
136 return 0;
137 }
IMPL_LINK_INLINE_END(SbiInputDialog,Cancel,Window *,pWindow)138 IMPL_LINK_INLINE_END( SbiInputDialog, Cancel, Window *, pWindow )
139
140 //////////////////////////////////////////////////////////////////////////
141
142 SbiStream::SbiStream()
143 : pStrm( 0 )
144 {
145 }
146
~SbiStream()147 SbiStream::~SbiStream()
148 {
149 delete pStrm;
150 }
151
152 // Ummappen eines SvStream-Fehlers auf einen StarBASIC-Code
153
MapError()154 void SbiStream::MapError()
155 {
156 if( pStrm )
157 switch( pStrm->GetError() )
158 {
159 case SVSTREAM_OK:
160 nError = 0; break;
161 case SVSTREAM_FILE_NOT_FOUND:
162 nError = SbERR_FILE_NOT_FOUND; break;
163 case SVSTREAM_PATH_NOT_FOUND:
164 nError = SbERR_PATH_NOT_FOUND; break;
165 case SVSTREAM_TOO_MANY_OPEN_FILES:
166 nError = SbERR_TOO_MANY_FILES; break;
167 case SVSTREAM_ACCESS_DENIED:
168 nError = SbERR_ACCESS_DENIED; break;
169 case SVSTREAM_INVALID_PARAMETER:
170 nError = SbERR_BAD_ARGUMENT; break;
171 case SVSTREAM_OUTOFMEMORY:
172 nError = SbERR_NO_MEMORY; break;
173 default:
174 nError = SbERR_IO_ERROR; break;
175 }
176 }
177
178 #ifdef _USE_UNO
179
180 // TODO: Code is copied from daemons2/source/uno/asciiEncoder.cxx
181
findUserInDescription(const::rtl::OUString & aDescription)182 ::rtl::OUString findUserInDescription( const ::rtl::OUString& aDescription )
183 {
184 ::rtl::OUString user;
185
186 sal_Int32 index;
187 sal_Int32 lastIndex = 0;
188
189 do
190 {
191 index = aDescription.indexOf((sal_Unicode) ',', lastIndex);
192 ::rtl::OUString token = (index == -1) ? aDescription.copy(lastIndex) : aDescription.copy(lastIndex, index - lastIndex);
193
194 lastIndex = index + 1;
195
196 sal_Int32 eindex = token.indexOf((sal_Unicode)'=');
197 ::rtl::OUString left = token.copy(0, eindex).toAsciiLowerCase().trim();
198 ::rtl::OUString right = INetURLObject::decode( token.copy(eindex + 1).trim(), '%',
199 INetURLObject::DECODE_WITH_CHARSET );
200
201 if(left.equals(::rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("user"))))
202 {
203 user = right;
204 break;
205 }
206 }
207 while(index != -1);
208
209 return user;
210 }
211
212 #endif
213
214
215 // Hack for #83750
216 sal_Bool runsInSetup( void );
217
needSecurityRestrictions(void)218 sal_Bool needSecurityRestrictions( void )
219 {
220 #ifdef _USE_UNO
221 static sal_Bool bNeedInit = sal_True;
222 static sal_Bool bRetVal = sal_True;
223
224 if( bNeedInit )
225 {
226 // Hack for #83750, use internal flag until
227 // setup provides own service manager
228 if( runsInSetup() )
229 {
230 // Setup is not critical
231 bRetVal = sal_False;
232 return bRetVal;
233 }
234
235 bNeedInit = sal_False;
236
237 // Get system user to compare to portal user
238 oslSecurity aSecurity = osl_getCurrentSecurity();
239 ::rtl::OUString aSystemUser;
240 sal_Bool bRet = osl_getUserName( aSecurity, &aSystemUser.pData );
241 if( !bRet )
242 {
243 // No valid security! -> Secure mode!
244 return sal_True;
245 }
246
247 Reference< XMultiServiceFactory > xSMgr = getProcessServiceFactory();
248 if( !xSMgr.is() )
249 return sal_True;
250 Reference< XBridgeFactory > xBridgeFac( xSMgr->createInstance
251 ( ::rtl::OUString::createFromAscii( "com.sun.star.bridge.BridgeFactory" ) ), UNO_QUERY );
252
253 Sequence< Reference< XBridge > > aBridgeSeq;
254 sal_Int32 nBridgeCount = 0;
255 if( xBridgeFac.is() )
256 {
257 aBridgeSeq = xBridgeFac->getExistingBridges();
258 nBridgeCount = aBridgeSeq.getLength();
259 }
260
261 if( nBridgeCount == 0 )
262 {
263 // No bridges -> local
264 bRetVal = sal_False;
265 return bRetVal;
266 }
267
268 // Iterate through all bridges to find (portal) user property
269 const Reference< XBridge >* pBridges = aBridgeSeq.getConstArray();
270 bRetVal = sal_False; // Now only sal_True if user different from portal user is found
271 sal_Int32 i;
272 for( i = 0 ; i < nBridgeCount ; i++ )
273 {
274 const Reference< XBridge >& rxBridge = pBridges[ i ];
275 ::rtl::OUString aDescription = rxBridge->getDescription();
276 ::rtl::OUString aPortalUser = findUserInDescription( aDescription );
277 if( !aPortalUser.isEmpty() )
278 {
279 // User Found, compare to system user
280 if( aPortalUser == aSystemUser )
281 {
282 // Same user -> system security is ok, bRetVal stays FALSE
283 break;
284 }
285 else
286 {
287 // Different user -> Secure mode!
288 bRetVal = sal_True;
289 break;
290 }
291 }
292 }
293 // No user found or PortalUser != SystemUser -> Secure mode! (Keep default value)
294 }
295
296 return bRetVal;
297 #else
298 return sal_False;
299 #endif
300 }
301
302 // Returns sal_True if UNO is available, otherwise the old file
303 // system implementation has to be used
304 // #89378 New semantic: Don't just ask for UNO but for UCB
hasUno(void)305 sal_Bool hasUno( void )
306 {
307 #ifdef _USE_UNO
308 static sal_Bool bNeedInit = sal_True;
309 static sal_Bool bRetVal = sal_True;
310
311 if( bNeedInit )
312 {
313 bNeedInit = sal_False;
314 Reference< XMultiServiceFactory > xSMgr = getProcessServiceFactory();
315 if( !xSMgr.is() )
316 {
317 // No service manager at all
318 bRetVal = sal_False;
319 }
320 else
321 {
322 Reference< XContentProviderManager > xManager( xSMgr->createInstance( ::rtl::OUString::createFromAscii
323 ( "com.sun.star.ucb.UniversalContentBroker" ) ), UNO_QUERY );
324
325 if ( !( xManager.is() && xManager->queryContentProvider( ::rtl::OUString::createFromAscii( "file:///" ) ).is() ) )
326 {
327 // No UCB
328 bRetVal = sal_False;
329 }
330 }
331 }
332 return bRetVal;
333 #else
334 return sal_False;
335 #endif
336 }
337
338
339
340 #ifndef _OLD_FILE_IMPL
341
342 class OslStream : public SvStream
343 {
344 File maFile;
345 short mnStrmMode;
346
347 public:
348 OslStream( const String& rName, short nStrmMode );
349 ~OslStream();
350 virtual sal_uIntPtr GetData( void* pData, sal_uIntPtr nSize );
351 virtual sal_uIntPtr PutData( const void* pData, sal_uIntPtr nSize );
352 virtual sal_uIntPtr SeekPos( sal_uIntPtr nPos );
353 virtual void FlushData();
354 virtual void SetSize( sal_uIntPtr nSize );
355 };
356
OslStream(const String & rName,short nStrmMode)357 OslStream::OslStream( const String& rName, short nStrmMode )
358 : maFile( rName )
359 , mnStrmMode( nStrmMode )
360 {
361 sal_uInt32 nFlags;
362
363 if( (nStrmMode & (STREAM_READ | STREAM_WRITE)) == (STREAM_READ | STREAM_WRITE) )
364 {
365 nFlags = OpenFlag_Read | OpenFlag_Write;
366 }
367 else if( nStrmMode & STREAM_WRITE )
368 {
369 nFlags = OpenFlag_Write;
370 }
371 else //if( nStrmMode & STREAM_READ )
372 {
373 nFlags = OpenFlag_Read;
374 }
375
376 FileBase::RC nRet = maFile.open( nFlags );
377 if( nRet == FileBase::E_NOENT && nFlags != OpenFlag_Read )
378 {
379 nFlags |= OpenFlag_Create;
380 nRet = maFile.open( nFlags );
381 }
382
383 if( nRet != FileBase::E_None )
384 {
385 SetError( ERRCODE_IO_GENERAL );
386 }
387 }
388
389
~OslStream()390 OslStream::~OslStream()
391 {
392 maFile.close();
393 }
394
GetData(void * pData,sal_uIntPtr nSize)395 sal_uIntPtr OslStream::GetData( void* pData, sal_uIntPtr nSize )
396 {
397 sal_uInt64 nBytesRead = nSize;
398 FileBase::RC nRet = FileBase::E_None;
399 nRet = maFile.read( pData, nBytesRead, nBytesRead );
400 return (sal_uIntPtr)nBytesRead;
401 }
402
PutData(const void * pData,sal_uIntPtr nSize)403 sal_uIntPtr OslStream::PutData( const void* pData, sal_uIntPtr nSize )
404 {
405 sal_uInt64 nBytesWritten;
406 FileBase::RC nRet = FileBase::E_None;
407 nRet = maFile.write( pData, (sal_uInt64)nSize, nBytesWritten );
408 return (sal_uIntPtr)nBytesWritten;
409 }
410
SeekPos(sal_uIntPtr nPos)411 sal_uIntPtr OslStream::SeekPos( sal_uIntPtr nPos )
412 {
413 FileBase::RC nRet;
414 if( nPos == STREAM_SEEK_TO_END )
415 {
416 nRet = maFile.setPos( Pos_End, 0 );
417 }
418 else
419 {
420 nRet = maFile.setPos( Pos_Absolut, (sal_uInt64)nPos );
421 }
422 sal_uInt64 nRealPos;
423 nRet = maFile.getPos( nRealPos );
424 return sal::static_int_cast<sal_uIntPtr>(nRealPos);
425 }
426
FlushData()427 void OslStream::FlushData()
428 {
429 }
430
SetSize(sal_uIntPtr nSize)431 void OslStream::SetSize( sal_uIntPtr nSize )
432 {
433 FileBase::RC nRet = FileBase::E_None;
434 nRet = maFile.setSize( (sal_uInt64)nSize );
435 }
436
437 #endif
438
439
440 #ifdef _USE_UNO
441
442 class UCBStream : public SvStream
443 {
444 Reference< XInputStream > xIS;
445 Reference< XOutputStream > xOS;
446 Reference< XStream > xS;
447 Reference< XSeekable > xSeek;
448 public:
449 UCBStream( Reference< XInputStream > & xIS );
450 UCBStream( Reference< XOutputStream > & xOS );
451 UCBStream( Reference< XStream > & xS );
452 ~UCBStream();
453 virtual sal_uIntPtr GetData( void* pData, sal_uIntPtr nSize );
454 virtual sal_uIntPtr PutData( const void* pData, sal_uIntPtr nSize );
455 virtual sal_uIntPtr SeekPos( sal_uIntPtr nPos );
456 virtual void FlushData();
457 virtual void SetSize( sal_uIntPtr nSize );
458 };
459
460 /*
461 sal_uIntPtr UCBErrorToSvStramError( ucb::IOErrorCode nError )
462 {
463 sal_uIntPtr eReturn = ERRCODE_IO_GENERAL;
464 switch( nError )
465 {
466 case ucb::IOErrorCode_ABORT: eReturn = SVSTREAM_GENERALERROR; break;
467 case ucb::IOErrorCode_NOT_EXISTING: eReturn = SVSTREAM_FILE_NOT_FOUND; break;
468 case ucb::IOErrorCode_NOT_EXISTING_PATH: eReturn = SVSTREAM_PATH_NOT_FOUND; break;
469 case ucb::IOErrorCode_OUT_OF_FILE_HANDLES: eReturn = SVSTREAM_TOO_MANY_OPEN_FILES; break;
470 case ucb::IOErrorCode_ACCESS_DENIED: eReturn = SVSTREAM_ACCESS_DENIED; break;
471 case ucb::IOErrorCode_LOCKING_VIOLATION: eReturn = SVSTREAM_SHARING_VIOLATION; break;
472
473 case ucb::IOErrorCode_INVALID_ACCESS: eReturn = SVSTREAM_INVALID_ACCESS; break;
474 case ucb::IOErrorCode_CANT_CREATE: eReturn = SVSTREAM_CANNOT_MAKE; break;
475 case ucb::IOErrorCode_INVALID_PARAMETER: eReturn = SVSTREAM_INVALID_PARAMETER; break;
476
477 case ucb::IOErrorCode_CANT_READ: eReturn = SVSTREAM_READ_ERROR; break;
478 case ucb::IOErrorCode_CANT_WRITE: eReturn = SVSTREAM_WRITE_ERROR; break;
479 case ucb::IOErrorCode_CANT_SEEK: eReturn = SVSTREAM_SEEK_ERROR; break;
480 case ucb::IOErrorCode_CANT_TELL: eReturn = SVSTREAM_TELL_ERROR; break;
481
482 case ucb::IOErrorCode_OUT_OF_MEMORY: eReturn = SVSTREAM_OUTOFMEMORY; break;
483
484 case SVSTREAM_FILEFORMAT_ERROR: eReturn = SVSTREAM_FILEFORMAT_ERROR; break;
485 case ucb::IOErrorCode_WRONG_VERSION: eReturn = SVSTREAM_WRONGVERSION;
486 case ucb::IOErrorCode_OUT_OF_DISK_SPACE: eReturn = SVSTREAM_DISK_FULL; break;
487
488 case ucb::IOErrorCode_BAD_CRC: eReturn = ERRCODE_IO_BADCRC; break;
489 }
490 return eReturn;
491 }
492 */
493
UCBStream(Reference<XInputStream> & rStm)494 UCBStream::UCBStream( Reference< XInputStream > & rStm )
495 : xIS( rStm )
496 , xSeek( rStm, UNO_QUERY )
497 {
498 }
499
UCBStream(Reference<XOutputStream> & rStm)500 UCBStream::UCBStream( Reference< XOutputStream > & rStm )
501 : xOS( rStm )
502 , xSeek( rStm, UNO_QUERY )
503 {
504 }
505
UCBStream(Reference<XStream> & rStm)506 UCBStream::UCBStream( Reference< XStream > & rStm )
507 : xS( rStm )
508 , xSeek( rStm, UNO_QUERY )
509 {
510 }
511
512
~UCBStream()513 UCBStream::~UCBStream()
514 {
515 try
516 {
517 if( xIS.is() )
518 xIS->closeInput();
519 else if( xOS.is() )
520 xOS->closeOutput();
521 else if( xS.is() )
522 {
523 Reference< XInputStream > xIS_ = xS->getInputStream();
524 if( xIS_.is() )
525 xIS_->closeInput();
526 }
527 }
528 catch( Exception & )
529 {
530 SetError( ERRCODE_IO_GENERAL );
531 }
532 }
533
GetData(void * pData,sal_uIntPtr nSize)534 sal_uIntPtr UCBStream::GetData( void* pData, sal_uIntPtr nSize )
535 {
536 try
537 {
538 Reference< XInputStream > xISFromS;
539 if( xIS.is() )
540 {
541 Sequence<sal_Int8> aData;
542 nSize = xIS->readBytes( aData, nSize );
543 rtl_copyMemory( pData, aData.getConstArray(), nSize );
544 return nSize;
545 }
546 else if( xS.is() && (xISFromS = xS->getInputStream()).is() )
547 {
548 Sequence<sal_Int8> aData;
549 nSize = xISFromS->readBytes( aData, nSize );
550 rtl_copyMemory( pData, aData.getConstArray(), nSize );
551 return nSize;
552 }
553 else
554 SetError( ERRCODE_IO_GENERAL );
555 }
556 catch( Exception & )
557 {
558 SetError( ERRCODE_IO_GENERAL );
559 }
560 return 0;
561 }
562
PutData(const void * pData,sal_uIntPtr nSize)563 sal_uIntPtr UCBStream::PutData( const void* pData, sal_uIntPtr nSize )
564 {
565 try
566 {
567 Reference< XOutputStream > xOSFromS;
568 if( xOS.is() )
569 {
570 Sequence<sal_Int8> aData( (const sal_Int8 *)pData, nSize );
571 xOS->writeBytes( aData );
572 return nSize;
573 }
574 else if( xS.is() && (xOSFromS = xS->getOutputStream()).is() )
575 {
576 Sequence<sal_Int8> aData( (const sal_Int8 *)pData, nSize );
577 xOSFromS->writeBytes( aData );
578 return nSize;
579 }
580 else
581 SetError( ERRCODE_IO_GENERAL );
582 }
583 catch( Exception & )
584 {
585 SetError( ERRCODE_IO_GENERAL );
586 }
587 return 0;
588 }
589
SeekPos(sal_uIntPtr nPos)590 sal_uIntPtr UCBStream::SeekPos( sal_uIntPtr nPos )
591 {
592 try
593 {
594 if( xSeek.is() )
595 {
596 sal_uIntPtr nLen = sal::static_int_cast<sal_uIntPtr>( xSeek->getLength() );
597 if( nPos > nLen )
598 nPos = nLen;
599 xSeek->seek( nPos );
600 return nPos;
601 }
602 else
603 SetError( ERRCODE_IO_GENERAL );
604 }
605 catch( Exception & )
606 {
607 SetError( ERRCODE_IO_GENERAL );
608 }
609 return 0;
610 }
611
FlushData()612 void UCBStream::FlushData()
613 {
614 try
615 {
616 Reference< XOutputStream > xOSFromS;
617 if( xOS.is() )
618 xOS->flush();
619 else if( xS.is() && (xOSFromS = xS->getOutputStream()).is() )
620 xOSFromS->flush();
621 else
622 SetError( ERRCODE_IO_GENERAL );
623 }
624 catch( Exception & )
625 {
626 SetError( ERRCODE_IO_GENERAL );
627 }
628 }
629
SetSize(sal_uIntPtr nSize)630 void UCBStream::SetSize( sal_uIntPtr nSize )
631 {
632 (void)nSize;
633
634 DBG_ERROR( "not allowed to call from basic" );
635 SetError( ERRCODE_IO_GENERAL );
636 }
637
638 #endif
639
640 // Oeffnen eines Streams
Open(short nCh,const ByteString & rName,short nStrmMode,short nFlags,short nL)641 SbError SbiStream::Open
642 ( short nCh, const ByteString& rName, short nStrmMode, short nFlags, short nL )
643 {
644 nMode = nFlags;
645 nLen = nL;
646 nChan = nCh;
647 nLine = 0;
648 nExpandOnWriteTo = 0;
649 if( ( nStrmMode & ( STREAM_READ|STREAM_WRITE ) ) == STREAM_READ )
650 nStrmMode |= STREAM_NOCREATE;
651 String aStr( rName, gsl_getSystemTextEncoding() );
652 String aNameStr = getFullPath( aStr );
653
654 #ifdef _USE_UNO
655 if( hasUno() )
656 {
657 Reference< XMultiServiceFactory > xSMgr = getProcessServiceFactory();
658 if( xSMgr.is() )
659 {
660 Reference< XSimpleFileAccess >
661 xSFI( xSMgr->createInstance( ::rtl::OUString::createFromAscii( "com.sun.star.ucb.SimpleFileAccess" ) ), UNO_QUERY );
662 if( xSFI.is() )
663 {
664 try
665 {
666
667 // #??? For write access delete file if it already exists (not for appending)
668 if( (nStrmMode & STREAM_WRITE) != 0 && !IsAppend() && !IsBinary() &&
669 xSFI->exists( aNameStr ) && !xSFI->isFolder( aNameStr ) )
670 {
671 xSFI->kill( aNameStr );
672 }
673
674 if( (nStrmMode & (STREAM_READ | STREAM_WRITE)) == (STREAM_READ | STREAM_WRITE) )
675 {
676 Reference< XStream > xIS = xSFI->openFileReadWrite( aNameStr );
677 pStrm = new UCBStream( xIS );
678 }
679 else if( nStrmMode & STREAM_WRITE )
680 {
681 Reference< XStream > xIS = xSFI->openFileReadWrite( aNameStr );
682 pStrm = new UCBStream( xIS );
683 // Open for writing is not implemented in ucb yet!!!
684 //Reference< XOutputStream > xIS = xSFI->openFileWrite( aNameStr );
685 //pStrm = new UCBStream( xIS );
686 }
687 else //if( nStrmMode & STREAM_READ )
688 {
689 Reference< XInputStream > xIS = xSFI->openFileRead( aNameStr );
690 pStrm = new UCBStream( xIS );
691 }
692
693 }
694 catch( Exception & )
695 {
696 nError = ERRCODE_IO_GENERAL;
697 }
698 }
699 }
700 }
701
702 #endif
703 if( !pStrm )
704 {
705 #ifdef _OLD_FILE_IMPL
706 pStrm = new SvFileStream( aNameStr, nStrmMode );
707 #else
708 pStrm = new OslStream( aNameStr, nStrmMode );
709 #endif
710 }
711 if( IsAppend() )
712 pStrm->Seek( STREAM_SEEK_TO_END );
713 MapError();
714 if( nError )
715 delete pStrm, pStrm = NULL;
716 return nError;
717 }
718
Close()719 SbError SbiStream::Close()
720 {
721 if( pStrm )
722 {
723 if( !hasUno() )
724 {
725 #ifdef _OLD_FILE_IMPL
726 ((SvFileStream *)pStrm)->Close();
727 #endif
728 }
729 MapError();
730 delete pStrm;
731 pStrm = NULL;
732 }
733 nChan = 0;
734 return nError;
735 }
736
Read(ByteString & rBuf,sal_uInt16 n,bool bForceReadingPerByte)737 SbError SbiStream::Read( ByteString& rBuf, sal_uInt16 n, bool bForceReadingPerByte )
738 {
739 nExpandOnWriteTo = 0;
740 if( !bForceReadingPerByte && IsText() )
741 {
742 pStrm->ReadLine( rBuf );
743 nLine++;
744 }
745 else
746 {
747 if( !n ) n = nLen;
748 if( !n )
749 return nError = SbERR_BAD_RECORD_LENGTH;
750 rBuf.Fill( n, ' ' );
751 pStrm->Read( (void*)rBuf.GetBuffer(), n );
752 }
753 MapError();
754 if( !nError && pStrm->IsEof() )
755 nError = SbERR_READ_PAST_EOF;
756 return nError;
757 }
758
Read(char & ch)759 SbError SbiStream::Read( char& ch )
760 {
761 nExpandOnWriteTo = 0;
762 if( !aLine.Len() )
763 {
764 Read( aLine, 0 );
765 aLine += '\n';
766 }
767 ch = aLine.GetBuffer()[0];
768 aLine.Erase( 0, 1 );
769 return nError;
770 }
771
ExpandFile()772 void SbiStream::ExpandFile()
773 {
774 if ( nExpandOnWriteTo )
775 {
776 sal_uIntPtr nCur = pStrm->Seek(STREAM_SEEK_TO_END);
777 if( nCur < nExpandOnWriteTo )
778 {
779 sal_uIntPtr nDiff = nExpandOnWriteTo - nCur;
780 char c = 0;
781 while( nDiff-- )
782 *pStrm << c;
783 }
784 else
785 {
786 pStrm->Seek( nExpandOnWriteTo );
787 }
788 nExpandOnWriteTo = 0;
789 }
790 }
791
Write(const ByteString & rBuf,sal_uInt16 n)792 SbError SbiStream::Write( const ByteString& rBuf, sal_uInt16 n )
793 {
794 ExpandFile();
795 if( IsAppend() )
796 pStrm->Seek( STREAM_SEEK_TO_END );
797
798 if( IsText() )
799 {
800 aLine += rBuf;
801 // Raus damit, wenn das Ende ein LF ist, aber CRLF vorher
802 // strippen, da der SvStrm ein CRLF anfuegt!
803 sal_uInt16 nLineLen = aLine.Len();
804 if( nLineLen && aLine.GetBuffer()[ --nLineLen ] == 0x0A )
805 {
806 aLine.Erase( nLineLen );
807 if( nLineLen && aLine.GetBuffer()[ --nLineLen ] == 0x0D )
808 aLine.Erase( nLineLen );
809 pStrm->WriteLines( aLine );
810 aLine.Erase();
811 }
812 }
813 else
814 {
815 if( !n ) n = nLen;
816 if( !n )
817 return nError = SbERR_BAD_RECORD_LENGTH;
818 pStrm->Write( rBuf.GetBuffer(), n );
819 MapError();
820 }
821 return nError;
822 }
823
824 //////////////////////////////////////////////////////////////////////////
825
826 // Zugriff auf das aktuelle I/O-System:
827
SbGetIoSystem()828 SbiIoSystem* SbGetIoSystem()
829 {
830 SbiInstance* pInst = pINST;
831 return pInst ? pInst->GetIoSystem() : NULL;
832 }
833
834 //////////////////////////////////////////////////////////////////////////
835
SbiIoSystem()836 SbiIoSystem::SbiIoSystem()
837 {
838 for( short i = 0; i < CHANNELS; i++ )
839 pChan[ i ] = NULL;
840 nChan = 0;
841 nError = 0;
842 }
843
~SbiIoSystem()844 SbiIoSystem::~SbiIoSystem()
845 {
846 Shutdown();
847 }
848
GetError()849 SbError SbiIoSystem::GetError()
850 {
851 SbError n = nError; nError = 0;
852 return n;
853 }
854
Open(short nCh,const ByteString & rName,short nMode,short nFlags,short nLen)855 void SbiIoSystem::Open
856 ( short nCh, const ByteString& rName, short nMode, short nFlags, short nLen )
857 {
858 nError = 0;
859 if( nCh >= CHANNELS || !nCh )
860 nError = SbERR_BAD_CHANNEL;
861 else if( pChan[ nCh ] )
862 nError = SbERR_FILE_ALREADY_OPEN;
863 else
864 {
865 pChan[ nCh ] = new SbiStream;
866 nError = pChan[ nCh ]->Open( nCh, rName, nMode, nFlags, nLen );
867 if( nError )
868 delete pChan[ nCh ], pChan[ nCh ] = NULL;
869 }
870 nChan = 0;
871 }
872
873 // Aktuellen Kanal schliessen
874
Close()875 void SbiIoSystem::Close()
876 {
877 if( !nChan )
878 nError = SbERR_BAD_CHANNEL;
879 else if( !pChan[ nChan ] )
880 nError = SbERR_BAD_CHANNEL;
881 else
882 {
883 nError = pChan[ nChan ]->Close();
884 delete pChan[ nChan ];
885 pChan[ nChan ] = NULL;
886 }
887 nChan = 0;
888 }
889
890 // Shutdown nach Programmlauf
891
Shutdown()892 void SbiIoSystem::Shutdown()
893 {
894 for( short i = 1; i < CHANNELS; i++ )
895 {
896 if( pChan[ i ] )
897 {
898 SbError n = pChan[ i ]->Close();
899 delete pChan[ i ];
900 pChan[ i ] = NULL;
901 if( n && !nError )
902 nError = n;
903 }
904 }
905 nChan = 0;
906 // Noch was zu PRINTen?
907 if( aOut.Len() )
908 {
909 String aOutStr( aOut, gsl_getSystemTextEncoding() );
910 #if defined GCC
911 Window* pParent = Application::GetDefDialogParent();
912 MessBox( pParent, WinBits( WB_OK ), String(), aOutStr ).Execute();
913 #else
914 MessBox( GetpApp()->GetDefDialogParent(), WinBits( WB_OK ), String(), aOutStr ).Execute();
915 #endif
916 }
917 aOut.Erase();
918 }
919
920 // Aus aktuellem Kanal lesen
921
Read(ByteString & rBuf,short n)922 void SbiIoSystem::Read( ByteString& rBuf, short n )
923 {
924 if( !nChan )
925 ReadCon( rBuf );
926 else if( !pChan[ nChan ] )
927 nError = SbERR_BAD_CHANNEL;
928 else
929 nError = pChan[ nChan ]->Read( rBuf, n );
930 }
931
Read()932 char SbiIoSystem::Read()
933 {
934 char ch = ' ';
935 if( !nChan )
936 {
937 if( !aIn.Len() )
938 {
939 ReadCon( aIn );
940 aIn += '\n';
941 }
942 ch = aIn.GetBuffer()[0];
943 aIn.Erase( 0, 1 );
944 }
945 else if( !pChan[ nChan ] )
946 nError = SbERR_BAD_CHANNEL;
947 else
948 nError = pChan[ nChan ]->Read( ch );
949 return ch;
950 }
951
Write(const ByteString & rBuf,short n)952 void SbiIoSystem::Write( const ByteString& rBuf, short n )
953 {
954 if( !nChan )
955 WriteCon( rBuf );
956 else if( !pChan[ nChan ] )
957 nError = SbERR_BAD_CHANNEL;
958 else
959 nError = pChan[ nChan ]->Write( rBuf, n );
960 }
961
NextChannel()962 short SbiIoSystem::NextChannel()
963 {
964 for( short i = 1; i < CHANNELS; i++ )
965 {
966 if( !pChan[ i ] )
967 return i;
968 }
969 nError = SbERR_TOO_MANY_FILES;
970 return CHANNELS;
971 }
972
973 // nChannel == 0..CHANNELS-1
974
GetStream(short nChannel) const975 SbiStream* SbiIoSystem::GetStream( short nChannel ) const
976 {
977 SbiStream* pRet = 0;
978 if( nChannel >= 0 && nChannel < CHANNELS )
979 pRet = pChan[ nChannel ];
980 return pRet;
981 }
982
CloseAll(void)983 void SbiIoSystem::CloseAll(void)
984 {
985 for( short i = 1; i < CHANNELS; i++ )
986 {
987 if( pChan[ i ] )
988 {
989 SbError n = pChan[ i ]->Close();
990 delete pChan[ i ];
991 pChan[ i ] = NULL;
992 if( n && !nError )
993 nError = n;
994 }
995 }
996 }
997
998 /***************************************************************************
999 *
1000 * Console Support
1001 *
1002 ***************************************************************************/
1003
1004 // Einlesen einer Zeile von der Console
1005
ReadCon(ByteString & rIn)1006 void SbiIoSystem::ReadCon( ByteString& rIn )
1007 {
1008 String aPromptStr( aPrompt, gsl_getSystemTextEncoding() );
1009 SbiInputDialog aDlg( NULL, aPromptStr );
1010 if( aDlg.Execute() )
1011 rIn = ByteString( aDlg.GetInput(), gsl_getSystemTextEncoding() );
1012 else
1013 nError = SbERR_USER_ABORT;
1014 aPrompt.Erase();
1015 }
1016
1017 // Ausgabe einer MessageBox, wenn im Console-Puffer ein CR ist
1018
WriteCon(const ByteString & rText)1019 void SbiIoSystem::WriteCon( const ByteString& rText )
1020 {
1021 aOut += rText;
1022 sal_uInt16 n1 = aOut.Search( '\n' );
1023 sal_uInt16 n2 = aOut.Search( '\r' );
1024 if( n1 != STRING_NOTFOUND || n2 != STRING_NOTFOUND )
1025 {
1026 if( n1 == STRING_NOTFOUND ) n1 = n2;
1027 else
1028 if( n2 == STRING_NOTFOUND ) n2 = n1;
1029 if( n1 > n2 ) n1 = n2;
1030 ByteString s( aOut.Copy( 0, n1 ) );
1031 aOut.Erase( 0, n1 );
1032 while( aOut.GetBuffer()[0] == '\n' || aOut.GetBuffer()[0] == '\r' )
1033 aOut.Erase( 0, 1 );
1034 String aStr( s, gsl_getSystemTextEncoding() );
1035 {
1036 vos::OGuard aSolarGuard( Application::GetSolarMutex() );
1037 if( !MessBox( GetpApp()->GetDefDialogParent(),
1038 WinBits( WB_OK_CANCEL | WB_DEF_OK ),
1039 String(), aStr ).Execute() )
1040 nError = SbERR_USER_ABORT;
1041 }
1042 }
1043 }
1044
1045