LCOV - code coverage report
Current view: top level - basic/source/runtime - iosys.cxx (source / functions) Hit Total Coverage
Test: commit c8344322a7af75b84dd3ca8f78b05543a976dfd5 Lines: 156 448 34.8 %
Date: 2015-06-13 12:38:46 Functions: 24 55 43.6 %
Legend: Lines: hit not hit

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

Generated by: LCOV version 1.11