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