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 osl_freeSecurityHandle(aSecurity);
242 if( !bRet )
243 {
244 // No valid security! -> Secure mode!
245 return sal_True;
246 }
247
248 Reference< XMultiServiceFactory > xSMgr = getProcessServiceFactory();
249 if( !xSMgr.is() )
250 return sal_True;
251 Reference< XBridgeFactory > xBridgeFac( xSMgr->createInstance
252 ( ::rtl::OUString::createFromAscii( "com.sun.star.bridge.BridgeFactory" ) ), UNO_QUERY );
253
254 Sequence< Reference< XBridge > > aBridgeSeq;
255 sal_Int32 nBridgeCount = 0;
256 if( xBridgeFac.is() )
257 {
258 aBridgeSeq = xBridgeFac->getExistingBridges();
259 nBridgeCount = aBridgeSeq.getLength();
260 }
261
262 if( nBridgeCount == 0 )
263 {
264 // No bridges -> local
265 bRetVal = sal_False;
266 return bRetVal;
267 }
268
269 // Iterate through all bridges to find (portal) user property
270 const Reference< XBridge >* pBridges = aBridgeSeq.getConstArray();
271 bRetVal = sal_False; // Now only sal_True if user different from portal user is found
272 sal_Int32 i;
273 for( i = 0 ; i < nBridgeCount ; i++ )
274 {
275 const Reference< XBridge >& rxBridge = pBridges[ i ];
276 ::rtl::OUString aDescription = rxBridge->getDescription();
277 ::rtl::OUString aPortalUser = findUserInDescription( aDescription );
278 if( !aPortalUser.isEmpty() )
279 {
280 // User Found, compare to system user
281 if( aPortalUser == aSystemUser )
282 {
283 // Same user -> system security is ok, bRetVal stays FALSE
284 break;
285 }
286 else
287 {
288 // Different user -> Secure mode!
289 bRetVal = sal_True;
290 break;
291 }
292 }
293 }
294 // No user found or PortalUser != SystemUser -> Secure mode! (Keep default value)
295 }
296
297 return bRetVal;
298 #else
299 return sal_False;
300 #endif
301 }
302
303 // Returns sal_True if UNO is available, otherwise the old file
304 // system implementation has to be used
305 // #89378 New semantic: Don't just ask for UNO but for UCB
hasUno(void)306 sal_Bool hasUno( void )
307 {
308 #ifdef _USE_UNO
309 static sal_Bool bNeedInit = sal_True;
310 static sal_Bool bRetVal = sal_True;
311
312 if( bNeedInit )
313 {
314 bNeedInit = sal_False;
315 Reference< XMultiServiceFactory > xSMgr = getProcessServiceFactory();
316 if( !xSMgr.is() )
317 {
318 // No service manager at all
319 bRetVal = sal_False;
320 }
321 else
322 {
323 Reference< XContentProviderManager > xManager( xSMgr->createInstance( ::rtl::OUString::createFromAscii
324 ( "com.sun.star.ucb.UniversalContentBroker" ) ), UNO_QUERY );
325
326 if ( !( xManager.is() && xManager->queryContentProvider( ::rtl::OUString::createFromAscii( "file:///" ) ).is() ) )
327 {
328 // No UCB
329 bRetVal = sal_False;
330 }
331 }
332 }
333 return bRetVal;
334 #else
335 return sal_False;
336 #endif
337 }
338
339
340
341 #ifndef _OLD_FILE_IMPL
342
343 class OslStream : public SvStream
344 {
345 File maFile;
346 short mnStrmMode;
347
348 public:
349 OslStream( const String& rName, short nStrmMode );
350 ~OslStream();
351 virtual sal_uIntPtr GetData( void* pData, sal_uIntPtr nSize );
352 virtual sal_uIntPtr PutData( const void* pData, sal_uIntPtr nSize );
353 virtual sal_uIntPtr SeekPos( sal_uIntPtr nPos );
354 virtual void FlushData();
355 virtual void SetSize( sal_uIntPtr nSize );
356 };
357
OslStream(const String & rName,short nStrmMode)358 OslStream::OslStream( const String& rName, short nStrmMode )
359 : maFile( rName )
360 , mnStrmMode( nStrmMode )
361 {
362 sal_uInt32 nFlags;
363
364 if( (nStrmMode & (STREAM_READ | STREAM_WRITE)) == (STREAM_READ | STREAM_WRITE) )
365 {
366 nFlags = OpenFlag_Read | OpenFlag_Write;
367 }
368 else if( nStrmMode & STREAM_WRITE )
369 {
370 nFlags = OpenFlag_Write;
371 }
372 else //if( nStrmMode & STREAM_READ )
373 {
374 nFlags = OpenFlag_Read;
375 }
376
377 FileBase::RC nRet = maFile.open( nFlags );
378 if( nRet == FileBase::E_NOENT && nFlags != OpenFlag_Read )
379 {
380 nFlags |= OpenFlag_Create;
381 nRet = maFile.open( nFlags );
382 }
383
384 if( nRet != FileBase::E_None )
385 {
386 SetError( ERRCODE_IO_GENERAL );
387 }
388 }
389
390
~OslStream()391 OslStream::~OslStream()
392 {
393 maFile.close();
394 }
395
GetData(void * pData,sal_uIntPtr nSize)396 sal_uIntPtr OslStream::GetData( void* pData, sal_uIntPtr nSize )
397 {
398 sal_uInt64 nBytesRead = nSize;
399 FileBase::RC nRet = FileBase::E_None;
400 nRet = maFile.read( pData, nBytesRead, nBytesRead );
401 return (sal_uIntPtr)nBytesRead;
402 }
403
PutData(const void * pData,sal_uIntPtr nSize)404 sal_uIntPtr OslStream::PutData( const void* pData, sal_uIntPtr nSize )
405 {
406 sal_uInt64 nBytesWritten;
407 FileBase::RC nRet = FileBase::E_None;
408 nRet = maFile.write( pData, (sal_uInt64)nSize, nBytesWritten );
409 return (sal_uIntPtr)nBytesWritten;
410 }
411
SeekPos(sal_uIntPtr nPos)412 sal_uIntPtr OslStream::SeekPos( sal_uIntPtr nPos )
413 {
414 FileBase::RC nRet;
415 if( nPos == STREAM_SEEK_TO_END )
416 {
417 nRet = maFile.setPos( Pos_End, 0 );
418 }
419 else
420 {
421 nRet = maFile.setPos( Pos_Absolut, (sal_uInt64)nPos );
422 }
423 sal_uInt64 nRealPos;
424 nRet = maFile.getPos( nRealPos );
425 return sal::static_int_cast<sal_uIntPtr>(nRealPos);
426 }
427
FlushData()428 void OslStream::FlushData()
429 {
430 }
431
SetSize(sal_uIntPtr nSize)432 void OslStream::SetSize( sal_uIntPtr nSize )
433 {
434 FileBase::RC nRet = FileBase::E_None;
435 nRet = maFile.setSize( (sal_uInt64)nSize );
436 }
437
438 #endif
439
440
441 #ifdef _USE_UNO
442
443 class UCBStream : public SvStream
444 {
445 Reference< XInputStream > xIS;
446 Reference< XOutputStream > xOS;
447 Reference< XStream > xS;
448 Reference< XSeekable > xSeek;
449 public:
450 UCBStream( Reference< XInputStream > & xIS );
451 UCBStream( Reference< XOutputStream > & xOS );
452 UCBStream( Reference< XStream > & xS );
453 ~UCBStream();
454 virtual sal_uIntPtr GetData( void* pData, sal_uIntPtr nSize );
455 virtual sal_uIntPtr PutData( const void* pData, sal_uIntPtr nSize );
456 virtual sal_uIntPtr SeekPos( sal_uIntPtr nPos );
457 virtual void FlushData();
458 virtual void SetSize( sal_uIntPtr nSize );
459 };
460
461 /*
462 sal_uIntPtr UCBErrorToSvStramError( ucb::IOErrorCode nError )
463 {
464 sal_uIntPtr eReturn = ERRCODE_IO_GENERAL;
465 switch( nError )
466 {
467 case ucb::IOErrorCode_ABORT: eReturn = SVSTREAM_GENERALERROR; break;
468 case ucb::IOErrorCode_NOT_EXISTING: eReturn = SVSTREAM_FILE_NOT_FOUND; break;
469 case ucb::IOErrorCode_NOT_EXISTING_PATH: eReturn = SVSTREAM_PATH_NOT_FOUND; break;
470 case ucb::IOErrorCode_OUT_OF_FILE_HANDLES: eReturn = SVSTREAM_TOO_MANY_OPEN_FILES; break;
471 case ucb::IOErrorCode_ACCESS_DENIED: eReturn = SVSTREAM_ACCESS_DENIED; break;
472 case ucb::IOErrorCode_LOCKING_VIOLATION: eReturn = SVSTREAM_SHARING_VIOLATION; break;
473
474 case ucb::IOErrorCode_INVALID_ACCESS: eReturn = SVSTREAM_INVALID_ACCESS; break;
475 case ucb::IOErrorCode_CANT_CREATE: eReturn = SVSTREAM_CANNOT_MAKE; break;
476 case ucb::IOErrorCode_INVALID_PARAMETER: eReturn = SVSTREAM_INVALID_PARAMETER; break;
477
478 case ucb::IOErrorCode_CANT_READ: eReturn = SVSTREAM_READ_ERROR; break;
479 case ucb::IOErrorCode_CANT_WRITE: eReturn = SVSTREAM_WRITE_ERROR; break;
480 case ucb::IOErrorCode_CANT_SEEK: eReturn = SVSTREAM_SEEK_ERROR; break;
481 case ucb::IOErrorCode_CANT_TELL: eReturn = SVSTREAM_TELL_ERROR; break;
482
483 case ucb::IOErrorCode_OUT_OF_MEMORY: eReturn = SVSTREAM_OUTOFMEMORY; break;
484
485 case SVSTREAM_FILEFORMAT_ERROR: eReturn = SVSTREAM_FILEFORMAT_ERROR; break;
486 case ucb::IOErrorCode_WRONG_VERSION: eReturn = SVSTREAM_WRONGVERSION;
487 case ucb::IOErrorCode_OUT_OF_DISK_SPACE: eReturn = SVSTREAM_DISK_FULL; break;
488
489 case ucb::IOErrorCode_BAD_CRC: eReturn = ERRCODE_IO_BADCRC; break;
490 }
491 return eReturn;
492 }
493 */
494
UCBStream(Reference<XInputStream> & rStm)495 UCBStream::UCBStream( Reference< XInputStream > & rStm )
496 : xIS( rStm )
497 , xSeek( rStm, UNO_QUERY )
498 {
499 }
500
UCBStream(Reference<XOutputStream> & rStm)501 UCBStream::UCBStream( Reference< XOutputStream > & rStm )
502 : xOS( rStm )
503 , xSeek( rStm, UNO_QUERY )
504 {
505 }
506
UCBStream(Reference<XStream> & rStm)507 UCBStream::UCBStream( Reference< XStream > & rStm )
508 : xS( rStm )
509 , xSeek( rStm, UNO_QUERY )
510 {
511 }
512
513
~UCBStream()514 UCBStream::~UCBStream()
515 {
516 try
517 {
518 if( xIS.is() )
519 xIS->closeInput();
520 else if( xOS.is() )
521 xOS->closeOutput();
522 else if( xS.is() )
523 {
524 Reference< XInputStream > xIS_ = xS->getInputStream();
525 if( xIS_.is() )
526 xIS_->closeInput();
527 }
528 }
529 catch( Exception & )
530 {
531 SetError( ERRCODE_IO_GENERAL );
532 }
533 }
534
GetData(void * pData,sal_uIntPtr nSize)535 sal_uIntPtr UCBStream::GetData( void* pData, sal_uIntPtr nSize )
536 {
537 try
538 {
539 Reference< XInputStream > xISFromS;
540 if( xIS.is() )
541 {
542 Sequence<sal_Int8> aData;
543 nSize = xIS->readBytes( aData, nSize );
544 rtl_copyMemory( pData, aData.getConstArray(), nSize );
545 return nSize;
546 }
547 else if( xS.is() && (xISFromS = xS->getInputStream()).is() )
548 {
549 Sequence<sal_Int8> aData;
550 nSize = xISFromS->readBytes( aData, nSize );
551 rtl_copyMemory( pData, aData.getConstArray(), nSize );
552 return nSize;
553 }
554 else
555 SetError( ERRCODE_IO_GENERAL );
556 }
557 catch( Exception & )
558 {
559 SetError( ERRCODE_IO_GENERAL );
560 }
561 return 0;
562 }
563
PutData(const void * pData,sal_uIntPtr nSize)564 sal_uIntPtr UCBStream::PutData( const void* pData, sal_uIntPtr nSize )
565 {
566 try
567 {
568 Reference< XOutputStream > xOSFromS;
569 if( xOS.is() )
570 {
571 Sequence<sal_Int8> aData( (const sal_Int8 *)pData, nSize );
572 xOS->writeBytes( aData );
573 return nSize;
574 }
575 else if( xS.is() && (xOSFromS = xS->getOutputStream()).is() )
576 {
577 Sequence<sal_Int8> aData( (const sal_Int8 *)pData, nSize );
578 xOSFromS->writeBytes( aData );
579 return nSize;
580 }
581 else
582 SetError( ERRCODE_IO_GENERAL );
583 }
584 catch( Exception & )
585 {
586 SetError( ERRCODE_IO_GENERAL );
587 }
588 return 0;
589 }
590
SeekPos(sal_uIntPtr nPos)591 sal_uIntPtr UCBStream::SeekPos( sal_uIntPtr nPos )
592 {
593 try
594 {
595 if( xSeek.is() )
596 {
597 sal_uIntPtr nLen = sal::static_int_cast<sal_uIntPtr>( xSeek->getLength() );
598 if( nPos > nLen )
599 nPos = nLen;
600 xSeek->seek( nPos );
601 return nPos;
602 }
603 else
604 SetError( ERRCODE_IO_GENERAL );
605 }
606 catch( Exception & )
607 {
608 SetError( ERRCODE_IO_GENERAL );
609 }
610 return 0;
611 }
612
FlushData()613 void UCBStream::FlushData()
614 {
615 try
616 {
617 Reference< XOutputStream > xOSFromS;
618 if( xOS.is() )
619 xOS->flush();
620 else if( xS.is() && (xOSFromS = xS->getOutputStream()).is() )
621 xOSFromS->flush();
622 else
623 SetError( ERRCODE_IO_GENERAL );
624 }
625 catch( Exception & )
626 {
627 SetError( ERRCODE_IO_GENERAL );
628 }
629 }
630
SetSize(sal_uIntPtr nSize)631 void UCBStream::SetSize( sal_uIntPtr nSize )
632 {
633 (void)nSize;
634
635 DBG_ERROR( "not allowed to call from basic" );
636 SetError( ERRCODE_IO_GENERAL );
637 }
638
639 #endif
640
641 // Oeffnen eines Streams
Open(short nCh,const ByteString & rName,short nStrmMode,short nFlags,short nL)642 SbError SbiStream::Open
643 ( short nCh, const ByteString& rName, short nStrmMode, short nFlags, short nL )
644 {
645 nMode = nFlags;
646 nLen = nL;
647 nChan = nCh;
648 nLine = 0;
649 nExpandOnWriteTo = 0;
650 if( ( nStrmMode & ( STREAM_READ|STREAM_WRITE ) ) == STREAM_READ )
651 nStrmMode |= STREAM_NOCREATE;
652 String aStr( rName, gsl_getSystemTextEncoding() );
653 String aNameStr = getFullPath( aStr );
654
655 #ifdef _USE_UNO
656 if( hasUno() )
657 {
658 Reference< XMultiServiceFactory > xSMgr = getProcessServiceFactory();
659 if( xSMgr.is() )
660 {
661 Reference< XSimpleFileAccess >
662 xSFI( xSMgr->createInstance( ::rtl::OUString::createFromAscii( "com.sun.star.ucb.SimpleFileAccess" ) ), UNO_QUERY );
663 if( xSFI.is() )
664 {
665 try
666 {
667
668 // #??? For write access delete file if it already exists (not for appending)
669 if( (nStrmMode & STREAM_WRITE) != 0 && !IsAppend() && !IsBinary() && !IsRandom() &&
670 xSFI->exists( aNameStr ) && !xSFI->isFolder( aNameStr ) )
671 {
672 xSFI->kill( aNameStr );
673 }
674
675 if( (nStrmMode & (STREAM_READ | STREAM_WRITE)) == (STREAM_READ | STREAM_WRITE) )
676 {
677 Reference< XStream > xIS = xSFI->openFileReadWrite( aNameStr );
678 pStrm = new UCBStream( xIS );
679 }
680 else if( nStrmMode & STREAM_WRITE )
681 {
682 Reference< XStream > xIS = xSFI->openFileReadWrite( aNameStr );
683 pStrm = new UCBStream( xIS );
684 // Open for writing is not implemented in ucb yet!!!
685 //Reference< XOutputStream > xIS = xSFI->openFileWrite( aNameStr );
686 //pStrm = new UCBStream( xIS );
687 }
688 else //if( nStrmMode & STREAM_READ )
689 {
690 Reference< XInputStream > xIS = xSFI->openFileRead( aNameStr );
691 pStrm = new UCBStream( xIS );
692 }
693
694 }
695 catch( Exception & )
696 {
697 nError = ERRCODE_IO_GENERAL;
698 }
699 }
700 }
701 }
702
703 #endif
704 if( !pStrm )
705 {
706 #ifdef _OLD_FILE_IMPL
707 pStrm = new SvFileStream( aNameStr, nStrmMode );
708 #else
709 pStrm = new OslStream( aNameStr, nStrmMode );
710 #endif
711 }
712 if( IsAppend() )
713 pStrm->Seek( STREAM_SEEK_TO_END );
714 MapError();
715 if( nError )
716 delete pStrm, pStrm = NULL;
717 return nError;
718 }
719
Close()720 SbError SbiStream::Close()
721 {
722 if( pStrm )
723 {
724 if( !hasUno() )
725 {
726 #ifdef _OLD_FILE_IMPL
727 ((SvFileStream *)pStrm)->Close();
728 #endif
729 }
730 MapError();
731 delete pStrm;
732 pStrm = NULL;
733 }
734 nChan = 0;
735 return nError;
736 }
737
Read(ByteString & rBuf,sal_uInt16 n,bool bForceReadingPerByte)738 SbError SbiStream::Read( ByteString& rBuf, sal_uInt16 n, bool bForceReadingPerByte )
739 {
740 nExpandOnWriteTo = 0;
741 if( !bForceReadingPerByte && IsText() )
742 {
743 pStrm->ReadLine( rBuf );
744 nLine++;
745 }
746 else
747 {
748 if( !n ) n = nLen;
749 if( !n )
750 return nError = SbERR_BAD_RECORD_LENGTH;
751 rBuf.Fill( n, ' ' );
752 pStrm->Read( (void*)rBuf.GetBuffer(), n );
753 }
754 MapError();
755 if( !nError && pStrm->IsEof() )
756 nError = SbERR_READ_PAST_EOF;
757 return nError;
758 }
759
Read(char & ch)760 SbError SbiStream::Read( char& ch )
761 {
762 nExpandOnWriteTo = 0;
763 if( !aLine.Len() )
764 {
765 Read( aLine, 0 );
766 aLine += '\n';
767 }
768 ch = aLine.GetBuffer()[0];
769 aLine.Erase( 0, 1 );
770 return nError;
771 }
772
ExpandFile()773 void SbiStream::ExpandFile()
774 {
775 if ( nExpandOnWriteTo )
776 {
777 sal_uIntPtr nCur = pStrm->Seek(STREAM_SEEK_TO_END);
778 if( nCur < nExpandOnWriteTo )
779 {
780 sal_uIntPtr nDiff = nExpandOnWriteTo - nCur;
781 char c = 0;
782 while( nDiff-- )
783 *pStrm << c;
784 }
785 else
786 {
787 pStrm->Seek( nExpandOnWriteTo );
788 }
789 nExpandOnWriteTo = 0;
790 }
791 }
792
Write(const ByteString & rBuf,sal_uInt16 n)793 SbError SbiStream::Write( const ByteString& rBuf, sal_uInt16 n )
794 {
795 ExpandFile();
796 if( IsAppend() )
797 pStrm->Seek( STREAM_SEEK_TO_END );
798
799 if( IsText() )
800 {
801 aLine += rBuf;
802 // Raus damit, wenn das Ende ein LF ist, aber CRLF vorher
803 // strippen, da der SvStrm ein CRLF anfuegt!
804 sal_uInt16 nLineLen = aLine.Len();
805 if( nLineLen && aLine.GetBuffer()[ --nLineLen ] == 0x0A )
806 {
807 aLine.Erase( nLineLen );
808 if( nLineLen && aLine.GetBuffer()[ --nLineLen ] == 0x0D )
809 aLine.Erase( nLineLen );
810 pStrm->WriteLines( aLine );
811 aLine.Erase();
812 }
813 }
814 else
815 {
816 if( !n ) n = nLen;
817 if( !n )
818 return nError = SbERR_BAD_RECORD_LENGTH;
819 pStrm->Write( rBuf.GetBuffer(), n );
820 MapError();
821 }
822 return nError;
823 }
824
825 //////////////////////////////////////////////////////////////////////////
826
827 // Zugriff auf das aktuelle I/O-System:
828
SbGetIoSystem()829 SbiIoSystem* SbGetIoSystem()
830 {
831 SbiInstance* pInst = pINST;
832 return pInst ? pInst->GetIoSystem() : NULL;
833 }
834
835 //////////////////////////////////////////////////////////////////////////
836
SbiIoSystem()837 SbiIoSystem::SbiIoSystem()
838 {
839 for( short i = 0; i < CHANNELS; i++ )
840 pChan[ i ] = NULL;
841 nChan = 0;
842 nError = 0;
843 }
844
~SbiIoSystem()845 SbiIoSystem::~SbiIoSystem()
846 {
847 Shutdown();
848 }
849
GetError()850 SbError SbiIoSystem::GetError()
851 {
852 SbError n = nError; nError = 0;
853 return n;
854 }
855
Open(short nCh,const ByteString & rName,short nMode,short nFlags,short nLen)856 void SbiIoSystem::Open
857 ( short nCh, const ByteString& rName, short nMode, short nFlags, short nLen )
858 {
859 nError = 0;
860 if( nCh >= CHANNELS || !nCh )
861 nError = SbERR_BAD_CHANNEL;
862 else if( pChan[ nCh ] )
863 nError = SbERR_FILE_ALREADY_OPEN;
864 else
865 {
866 pChan[ nCh ] = new SbiStream;
867 nError = pChan[ nCh ]->Open( nCh, rName, nMode, nFlags, nLen );
868 if( nError )
869 delete pChan[ nCh ], pChan[ nCh ] = NULL;
870 }
871 nChan = 0;
872 }
873
874 // Aktuellen Kanal schliessen
875
Close()876 void SbiIoSystem::Close()
877 {
878 if( !nChan )
879 nError = SbERR_BAD_CHANNEL;
880 else if( !pChan[ nChan ] )
881 nError = SbERR_BAD_CHANNEL;
882 else
883 {
884 nError = pChan[ nChan ]->Close();
885 delete pChan[ nChan ];
886 pChan[ nChan ] = NULL;
887 }
888 nChan = 0;
889 }
890
891 // Shutdown nach Programmlauf
892
Shutdown()893 void SbiIoSystem::Shutdown()
894 {
895 for( short i = 1; i < CHANNELS; i++ )
896 {
897 if( pChan[ i ] )
898 {
899 SbError n = pChan[ i ]->Close();
900 delete pChan[ i ];
901 pChan[ i ] = NULL;
902 if( n && !nError )
903 nError = n;
904 }
905 }
906 nChan = 0;
907 // Noch was zu PRINTen?
908 if( aOut.Len() )
909 {
910 String aOutStr( aOut, gsl_getSystemTextEncoding() );
911 #if defined GCC
912 Window* pParent = Application::GetDefDialogParent();
913 MessBox( pParent, WinBits( WB_OK ), String(), aOutStr ).Execute();
914 #else
915 MessBox( GetpApp()->GetDefDialogParent(), WinBits( WB_OK ), String(), aOutStr ).Execute();
916 #endif
917 }
918 aOut.Erase();
919 }
920
921 // Aus aktuellem Kanal lesen
922
Read(ByteString & rBuf,short n)923 void SbiIoSystem::Read( ByteString& rBuf, short n )
924 {
925 if( !nChan )
926 ReadCon( rBuf );
927 else if( !pChan[ nChan ] )
928 nError = SbERR_BAD_CHANNEL;
929 else
930 nError = pChan[ nChan ]->Read( rBuf, n );
931 }
932
Read()933 char SbiIoSystem::Read()
934 {
935 char ch = ' ';
936 if( !nChan )
937 {
938 if( !aIn.Len() )
939 {
940 ReadCon( aIn );
941 aIn += '\n';
942 }
943 ch = aIn.GetBuffer()[0];
944 aIn.Erase( 0, 1 );
945 }
946 else if( !pChan[ nChan ] )
947 nError = SbERR_BAD_CHANNEL;
948 else
949 nError = pChan[ nChan ]->Read( ch );
950 return ch;
951 }
952
Write(const ByteString & rBuf,short n)953 void SbiIoSystem::Write( const ByteString& rBuf, short n )
954 {
955 if( !nChan )
956 WriteCon( rBuf );
957 else if( !pChan[ nChan ] )
958 nError = SbERR_BAD_CHANNEL;
959 else
960 nError = pChan[ nChan ]->Write( rBuf, n );
961 }
962
NextChannel()963 short SbiIoSystem::NextChannel()
964 {
965 for( short i = 1; i < CHANNELS; i++ )
966 {
967 if( !pChan[ i ] )
968 return i;
969 }
970 nError = SbERR_TOO_MANY_FILES;
971 return CHANNELS;
972 }
973
974 // nChannel == 0..CHANNELS-1
975
GetStream(short nChannel) const976 SbiStream* SbiIoSystem::GetStream( short nChannel ) const
977 {
978 SbiStream* pRet = 0;
979 if( nChannel >= 0 && nChannel < CHANNELS )
980 pRet = pChan[ nChannel ];
981 return pRet;
982 }
983
CloseAll(void)984 void SbiIoSystem::CloseAll(void)
985 {
986 for( short i = 1; i < CHANNELS; i++ )
987 {
988 if( pChan[ i ] )
989 {
990 SbError n = pChan[ i ]->Close();
991 delete pChan[ i ];
992 pChan[ i ] = NULL;
993 if( n && !nError )
994 nError = n;
995 }
996 }
997 }
998
999 /***************************************************************************
1000 *
1001 * Console Support
1002 *
1003 ***************************************************************************/
1004
1005 // Einlesen einer Zeile von der Console
1006
ReadCon(ByteString & rIn)1007 void SbiIoSystem::ReadCon( ByteString& rIn )
1008 {
1009 String aPromptStr( aPrompt, gsl_getSystemTextEncoding() );
1010 SbiInputDialog aDlg( NULL, aPromptStr );
1011 if( aDlg.Execute() )
1012 rIn = ByteString( aDlg.GetInput(), gsl_getSystemTextEncoding() );
1013 else
1014 nError = SbERR_USER_ABORT;
1015 aPrompt.Erase();
1016 }
1017
1018 // Ausgabe einer MessageBox, wenn im Console-Puffer ein CR ist
1019
WriteCon(const ByteString & rText)1020 void SbiIoSystem::WriteCon( const ByteString& rText )
1021 {
1022 aOut += rText;
1023 sal_uInt16 n1 = aOut.Search( '\n' );
1024 sal_uInt16 n2 = aOut.Search( '\r' );
1025 if( n1 != STRING_NOTFOUND || n2 != STRING_NOTFOUND )
1026 {
1027 if( n1 == STRING_NOTFOUND ) n1 = n2;
1028 else
1029 if( n2 == STRING_NOTFOUND ) n2 = n1;
1030 if( n1 > n2 ) n1 = n2;
1031 ByteString s( aOut.Copy( 0, n1 ) );
1032 aOut.Erase( 0, n1 );
1033 while( aOut.GetBuffer()[0] == '\n' || aOut.GetBuffer()[0] == '\r' )
1034 aOut.Erase( 0, 1 );
1035 String aStr( s, gsl_getSystemTextEncoding() );
1036 {
1037 vos::OGuard aSolarGuard( Application::GetSolarMutex() );
1038 if( !MessBox( GetpApp()->GetDefDialogParent(),
1039 WinBits( WB_OK_CANCEL | WB_DEF_OK ),
1040 String(), aStr ).Execute() )
1041 nError = SbERR_USER_ABORT;
1042 }
1043 }
1044 }
1045
1046