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 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 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 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 391 OslStream::~OslStream() 392 { 393 maFile.close(); 394 } 395 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 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 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 428 void OslStream::FlushData() 429 { 430 } 431 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 495 UCBStream::UCBStream( Reference< XInputStream > & rStm ) 496 : xIS( rStm ) 497 , xSeek( rStm, UNO_QUERY ) 498 { 499 } 500 501 UCBStream::UCBStream( Reference< XOutputStream > & rStm ) 502 : xOS( rStm ) 503 , xSeek( rStm, UNO_QUERY ) 504 { 505 } 506 507 UCBStream::UCBStream( Reference< XStream > & rStm ) 508 : xS( rStm ) 509 , xSeek( rStm, UNO_QUERY ) 510 { 511 } 512 513 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 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 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 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 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 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 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 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 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 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 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 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 829 SbiIoSystem* SbGetIoSystem() 830 { 831 SbiInstance* pInst = pINST; 832 return pInst ? pInst->GetIoSystem() : NULL; 833 } 834 835 ////////////////////////////////////////////////////////////////////////// 836 837 SbiIoSystem::SbiIoSystem() 838 { 839 for( short i = 0; i < CHANNELS; i++ ) 840 pChan[ i ] = NULL; 841 nChan = 0; 842 nError = 0; 843 } 844 845 SbiIoSystem::~SbiIoSystem() 846 { 847 Shutdown(); 848 } 849 850 SbError SbiIoSystem::GetError() 851 { 852 SbError n = nError; nError = 0; 853 return n; 854 } 855 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 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 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 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 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 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 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 976 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 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 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 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