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& ); 90 const String& GetInput() { return aText; } 91 }; 92 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 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 } 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 } 138 IMPL_LINK_INLINE_END( SbiInputDialog, Cancel, Window *, pWindow ) 139 140 ////////////////////////////////////////////////////////////////////////// 141 142 SbiStream::SbiStream() 143 : pStrm( 0 ) 144 { 145 } 146 147 SbiStream::~SbiStream() 148 { 149 delete pStrm; 150 } 151 152 // Ummappen eines SvStream-Fehlers auf einen StarBASIC-Code 153 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 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 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 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 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 390 OslStream::~OslStream() 391 { 392 maFile.close(); 393 } 394 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 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 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 427 void OslStream::FlushData() 428 { 429 } 430 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 494 UCBStream::UCBStream( Reference< XInputStream > & rStm ) 495 : xIS( rStm ) 496 , xSeek( rStm, UNO_QUERY ) 497 { 498 } 499 500 UCBStream::UCBStream( Reference< XOutputStream > & rStm ) 501 : xOS( rStm ) 502 , xSeek( rStm, UNO_QUERY ) 503 { 504 } 505 506 UCBStream::UCBStream( Reference< XStream > & rStm ) 507 : xS( rStm ) 508 , xSeek( rStm, UNO_QUERY ) 509 { 510 } 511 512 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 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 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 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 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 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 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() && !IsRandom() && 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 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 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 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 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 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 828 SbiIoSystem* SbGetIoSystem() 829 { 830 SbiInstance* pInst = pINST; 831 return pInst ? pInst->GetIoSystem() : NULL; 832 } 833 834 ////////////////////////////////////////////////////////////////////////// 835 836 SbiIoSystem::SbiIoSystem() 837 { 838 for( short i = 0; i < CHANNELS; i++ ) 839 pChan[ i ] = NULL; 840 nChan = 0; 841 nError = 0; 842 } 843 844 SbiIoSystem::~SbiIoSystem() 845 { 846 Shutdown(); 847 } 848 849 SbError SbiIoSystem::GetError() 850 { 851 SbError n = nError; nError = 0; 852 return n; 853 } 854 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 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 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 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 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 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 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 975 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 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 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 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