Files
libreoffice/basic/source/runtime/methods.cxx

3714 lines
101 KiB
C++
Raw Normal View History

2000-09-18 15:18:56 +00:00
/*************************************************************************
*
* $RCSfile: methods.cxx,v $
*
2001-05-30 09:52:05 +00:00
* $Revision: 1.22 $
2000-09-18 15:18:56 +00:00
*
2001-05-30 09:52:05 +00:00
* last change: $Author: ab $ $Date: 2001-05-30 10:52:05 $
2000-09-18 15:18:56 +00:00
*
* The Contents of this file are made available subject to the terms of
* either of the following licenses
*
* - GNU Lesser General Public License Version 2.1
* - Sun Industry Standards Source License Version 1.1
*
* Sun Microsystems Inc., October, 2000
*
* GNU Lesser General Public License Version 2.1
* =============================================
* Copyright 2000 by Sun Microsystems, Inc.
* 901 San Antonio Road, Palo Alto, CA 94303, USA
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
* License version 2.1, as published by the Free Software Foundation.
*
* This library is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public
* License along with this library; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place, Suite 330, Boston,
* MA 02111-1307 USA
*
*
* Sun Industry Standards Source License Version 1.1
* =================================================
* The contents of this file are subject to the Sun Industry Standards
* Source License Version 1.1 (the "License"); You may not use this file
* except in compliance with the License. You may obtain a copy of the
* License at http://www.openoffice.org/license.html.
*
* Software provided under this License is provided on an "AS IS" basis,
* WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING,
* WITHOUT LIMITATION, WARRANTIES THAT THE SOFTWARE IS FREE OF DEFECTS,
* MERCHANTABLE, FIT FOR A PARTICULAR PURPOSE, OR NON-INFRINGING.
* See the License for the specific provisions governing your rights and
* obligations concerning the Software.
*
* The Initial Developer of the Original Code is: Sun Microsystems, Inc.
*
* Copyright: 2000 by Sun Microsystems, Inc.
*
* All Rights Reserved.
*
* Contributor(s): _______________________________________
*
*
************************************************************************/
#ifndef _DATE_HXX //autogen
#include <tools/date.hxx>
#endif
#ifndef _SBXVAR_HXX
#include <svtools/sbxvar.hxx>
#endif
#ifndef _INTN_HXX //autogen
#include <tools/intn.hxx>
#endif
#ifndef _VOS_PROCESS_HXX
#include <vos/process.hxx>
#endif
#ifndef _SV_SVAPP_HXX //autogen
#include <vcl/svapp.hxx>
#endif
#ifndef _SV_SOUND_HXX //autogen
#include <vcl/sound.hxx>
#endif
#ifndef _SV_WINTYPES_HXX //autogen
#include <vcl/wintypes.hxx>
#endif
#ifndef _SV_MSGBOX_HXX //autogen
#include <vcl/msgbox.hxx>
#endif
#ifndef _SBXCLASS_HXX //autogen
#include <svtools/sbx.hxx>
#endif
#ifndef _ZFORLIST_HXX //autogen
#include <svtools/zforlist.hxx>
#endif
#ifndef _TOOLS_SOLMATH_HXX //autogen wg. SolarMath
#include <tools/solmath.hxx>
#endif
#include <tools/urlobj.hxx>
2000-09-26 08:02:02 +00:00
#include <osl/time.h>
#include <unotools/charclass.hxx>
#include <unotools/ucbstreamhelper.hxx>
#include <tools/isolang.hxx>
2000-09-18 15:18:56 +00:00
#ifdef OS2
#define INCL_WINWINDOWMGR
#define INCL_DOS
#endif
#if defined (WNT)
#ifndef _SVWIN_H
#include <tools/svwin.h>
#endif
#endif
#if defined (OS2)
#ifndef _SVPM_H
#include <tools/svpm.h>
#endif
#endif
#pragma hdrstop
#include "runtime.hxx"
2000-09-26 08:02:02 +00:00
#ifdef _OLD_FILE_IMPL
#ifndef _FSYS_HXX //autogen
#include <tools/fsys.hxx>
#endif
2001-05-30 09:52:05 +00:00
#else
#include <osl/file.hxx>
2000-09-26 08:02:02 +00:00
#endif
2000-09-18 15:18:56 +00:00
#ifdef _USE_UNO
2000-11-02 11:03:49 +00:00
#ifndef _COMPHELPER_PROCESSFACTORY_HXX_
#include <comphelper/processfactory.hxx>
#endif
2000-09-18 15:18:56 +00:00
#include <com/sun/star/uno/Sequence.hxx>
#include <com/sun/star/util/DateTime.hpp>
#include <com/sun/star/lang/XMultiServiceFactory.hpp>
#include <com/sun/star/lang/Locale.hpp>
2000-09-18 15:18:56 +00:00
#include <com/sun/star/ucb/XSimpleFileAccess.hpp>
#include <com/sun/star/io/XInputStream.hpp>
#include <com/sun/star/io/XOutputStream.hpp>
#include <com/sun/star/io/XStream.hpp>
#include <com/sun/star/io/XSeekable.hpp>
2000-11-02 11:03:49 +00:00
using namespace comphelper;
2000-09-18 15:18:56 +00:00
using namespace rtl;
using namespace osl;
using namespace com::sun::star::uno;
using namespace com::sun::star::lang;
using namespace com::sun::star::ucb;
using namespace com::sun::star::io;
#endif /* _USE_UNO */
2000-09-26 08:02:02 +00:00
//#define _ENABLE_CUR_DIR
2000-09-18 15:18:56 +00:00
#include "stdobj.hxx"
#include "stdobj1.hxx"
#include "rtlproto.hxx"
#include "basrid.hxx"
#include "sb.hrc"
#ifndef _SBIOSYS_HXX
#include "iosys.hxx"
#endif
#ifndef _DDECTRL_HXX
#include "ddectrl.hxx"
#endif
#include <sbintern.hxx>
2000-11-22 12:27:25 +00:00
#include <list>
2000-09-18 15:18:56 +00:00
#include <math.h>
#include <stdio.h>
#include <stdlib.h>
#include <ctype.h>
#if defined (WIN) || defined (WNT) || defined (OS2)
#include <direct.h> // _getdcwd get current work directory, _chdrive
#endif
#ifdef WIN
#include <dos.h> // _dos_getfileattr
#include <errno.h>
#endif
#ifdef UNX
#include <errno.h>
#include <unistd.h>
#endif
#ifdef WNT
#include <io.h>
#endif
#ifdef MAC
#include <mac_start.h>
#ifndef __FILES__
#include <Files.h>
#endif
#ifndef __ERRORS__
#include <Errors.h>
#endif
#include <MAC_TOOLS.hxx>
#include <mac_end.h>
#endif
//#include <numbers.hxx>
#include "segmentc.hxx"
#pragma SW_SEGMENT_CLASS( SBRUNTIME, SBRUNTIME_CODE )
#if defined (OS2) && defined (__BORLANDC__)
#pragma option -w-par
#endif
static void FilterWhiteSpace( String& rStr )
{
rStr.EraseAllChars( ' ' );
rStr.EraseAllChars( '\t' );
rStr.EraseAllChars( '\n' );
rStr.EraseAllChars( '\r' );
}
static long GetDayDiff( const Date& rDate )
{
Date aRefDate( 1,1,1900 );
long nDiffDays;
if ( aRefDate > rDate )
{
nDiffDays = (long)(aRefDate - rDate);
nDiffDays *= -1;
}
else
nDiffDays = (long)(rDate - aRefDate);
nDiffDays += 2; // Anpassung VisualBasic: 1.Jan.1900 == 2
return nDiffDays;
}
static CharClass& GetCharClass( void )
{
static sal_Bool bInit = sal_False;
static ::com::sun::star::lang::Locale aLocale;
if( !bInit )
{
const International& rInt = GetpApp()->GetAppInternational();
LanguageType eLang = rInt.GetLanguage();
String aLanguage, aCountry;
ConvertLanguageToIsoNames( (eLang == LANGUAGE_SYSTEM ? International::GetRealLanguage( eLang ) : eLang),
aLanguage, aCountry );
aLocale = ::com::sun::star::lang::Locale( aLanguage, aCountry, OUString() );
}
static CharClass aCharClass( aLocale );
return aCharClass;
}
2000-09-18 15:18:56 +00:00
//*** UCB file access ***
2000-09-26 08:02:02 +00:00
2000-09-18 15:18:56 +00:00
// Converts possibly relative paths to absolute paths
// according to the setting done by ChDir/ChDrive
String getFullPath( const String& aRelPath )
2000-09-26 08:02:02 +00:00
{
OUString aFileURL;
// #80204 Try first if it already is a valid URL
2001-05-30 09:52:05 +00:00
INetURLObject aURLObj( aRelPath );
aFileURL = aURLObj.GetMainURL();
if( !aFileURL.getLength() )
{
2001-05-10 13:02:47 +00:00
File::getFileURLFromSystemPath( aRelPath, aFileURL );
}
2001-05-30 09:52:05 +00:00
2000-09-26 08:02:02 +00:00
return aFileURL;
}
//*** OSL file access ***
// Converts possibly relative paths to absolute paths
// according to the setting done by ChDir/ChDrive
2001-05-30 09:52:05 +00:00
// #87427 OSL need File URLs, so getFullPathUNC
// is mapped to getFullPath (inline in runtime.hxx)
/*
2000-09-26 08:02:02 +00:00
String getFullPathUNC( const String& aRelPath )
2000-09-18 15:18:56 +00:00
{
OUString aNormPath;
2000-09-18 15:18:56 +00:00
// TODO: Use CurDir to build full path
// First step: Return given path unchanged
2000-09-26 08:02:02 +00:00
//static inline RC getAbsolutePath( const ::rtl::OUString& strDirBase, const ::rtl::OUString& strRelative, ::rtl::OUString& strAbsolute )
// #80204 Try first if it already is a file URL
INetURLObject aURLObj( aRelPath );
if( aURLObj.GetProtocol() == INET_PROT_FILE )
{
OUString aFileURL = aURLObj.GetMainURL();
2001-05-10 13:02:47 +00:00
aNormPath = aFileURL;
}
else
{
2001-05-10 13:02:47 +00:00
File::getFileURLFromSystemPath( aRelPath, aNormPath );
}
2000-09-26 08:02:02 +00:00
return aNormPath;
2000-09-18 15:18:56 +00:00
}
2001-05-30 09:52:05 +00:00
*/
2000-09-26 08:02:02 +00:00
2000-09-18 15:18:56 +00:00
// Sets (virtual) current path for UCB file access
void implChDir( const String& aDir )
{
// TODO
}
// Sets (virtual) current drive for UCB file access
void implChDrive( const String& aDrive )
{
// TODO
}
// Returns (virtual) current path for UCB file access
String implGetCurDir( void )
{
String aRetStr;
return aRetStr;
}
// TODO: -> SbiGlobals
static Reference< XSimpleFileAccess > getFileAccess( void )
{
static Reference< XSimpleFileAccess > xSFI;
if( !xSFI.is() )
{
Reference< XMultiServiceFactory > xSMgr = getProcessServiceFactory();
if( xSMgr.is() )
{
xSFI = Reference< XSimpleFileAccess >( xSMgr->createInstance
( OUString::createFromAscii( "com.sun.star.ucb.SimpleFileAccess" ) ), UNO_QUERY );
}
}
return xSFI;
}
// Properties und Methoden legen beim Get (bPut = FALSE) den Returnwert
// im Element 0 des Argv ab; beim Put (bPut = TRUE) wird der Wert aus
// Element 0 gespeichert.
// CreateObject( class )
RTLFUNC(CreateObject)
{
String aClass( rPar.Get( 1 )->GetString() );
SbxObjectRef p = SbxBase::CreateObject( aClass );
if( !p )
StarBASIC::Error( SbERR_CANNOT_LOAD );
else
{
// Convenience: BASIC als Parent eintragen
p->SetParent( pBasic );
rPar.Get( 0 )->PutObject( p );
}
}
// Error( n )
RTLFUNC(Error)
{
if( !pBasic )
StarBASIC::Error( SbERR_INTERNAL_ERROR );
else
{
String aErrorMsg;
SbError nErr = 0L;
if( rPar.Count() == 1 )
{
nErr = StarBASIC::GetErr();
aErrorMsg = StarBASIC::GetErrorMsg();
}
else
{
INT32 nCode = rPar.Get( 1 )->GetLong();
if( nCode > 65535L )
StarBASIC::Error( SbERR_CONVERSION );
else
nErr = StarBASIC::GetSfxFromVBError( (USHORT)nCode );
}
pBasic->MakeErrorText( nErr, aErrorMsg );
rPar.Get( 0 )->PutString( pBasic->GetErrorText() );
}
}
// Sinus
RTLFUNC(Sin)
{
if ( rPar.Count() < 2 )
StarBASIC::Error( SbERR_BAD_ARGUMENT );
else
{
SbxVariableRef pArg = rPar.Get( 1 );
rPar.Get( 0 )->PutDouble( sin( pArg->GetDouble() ) );
}
}
// Cosinus
RTLFUNC(Cos)
{
if ( rPar.Count() < 2 )
StarBASIC::Error( SbERR_BAD_ARGUMENT );
else
{
SbxVariableRef pArg = rPar.Get( 1 );
rPar.Get( 0 )->PutDouble( cos( pArg->GetDouble() ) );
}
}
// Atn
RTLFUNC(Atn)
{
if ( rPar.Count() < 2 )
StarBASIC::Error( SbERR_BAD_ARGUMENT );
else
{
SbxVariableRef pArg = rPar.Get( 1 );
rPar.Get( 0 )->PutDouble( atan( pArg->GetDouble() ) );
}
}
RTLFUNC(Abs)
{
if ( rPar.Count() < 2 )
StarBASIC::Error( SbERR_BAD_ARGUMENT );
else
{
SbxVariableRef pArg = rPar.Get( 1 );
rPar.Get( 0 )->PutDouble( fabs( pArg->GetDouble() ) );
}
}
RTLFUNC(Asc)
{
if ( rPar.Count() < 2 )
StarBASIC::Error( SbERR_BAD_ARGUMENT );
else
{
SbxVariableRef pArg = rPar.Get( 1 );
String aStr( pArg->GetString() );
if ( aStr.Len() == 0 )
{
StarBASIC::Error( SbERR_BAD_ARGUMENT );
rPar.Get(0)->PutEmpty();
}
else
{
sal_Unicode aCh = aStr.GetBuffer()[0];
rPar.Get(0)->PutInteger( (INT16)aCh );
}
}
}
RTLFUNC(Chr)
{
if ( rPar.Count() < 2 )
StarBASIC::Error( SbERR_BAD_ARGUMENT );
else
{
SbxVariableRef pArg = rPar.Get( 1 );
sal_Unicode aCh = (sal_Unicode) pArg->GetInteger();
String aStr( aCh );
2000-09-18 15:18:56 +00:00
rPar.Get(0)->PutString( aStr );
}
}
#ifdef UNX
#define _MAX_PATH 260
#define _PATH_INCR 250
#endif
RTLFUNC(CurDir)
{
// #57064 Obwohl diese Funktion nicht mit DirEntry arbeitet, ist sie von
// der Anpassung an virtuelle URLs nich betroffen, da bei Nutzung der
// DirEntry-Funktionalitaet keine Moeglichkeit besteht, das aktuelle so
// zu ermitteln, dass eine virtuelle URL geliefert werden koennte.
// rPar.Get(0)->PutEmpty();
#if defined (WIN) || defined (WNT) || (defined (OS2) && !defined( WTC ))
int nCurDir = 0; // Current dir // JSM
if ( rPar.Count() == 2 )
{
String aDrive = rPar.Get(1)->GetString();
if ( aDrive.Len() != 1 )
{
StarBASIC::Error( SbERR_BAD_ARGUMENT );
return;
}
else
{
nCurDir = (int)aDrive.GetBuffer()[0];
if ( !isalpha( nCurDir ) )
{
StarBASIC::Error( SbERR_BAD_ARGUMENT );
return;
}
else
nCurDir -= ( 'A' - 1 );
}
}
char* pBuffer = new char[ _MAX_PATH ];
#ifdef MTW
int old = _getdrive();
_chdrive(nCurDir);
if ( getcwd( pBuffer, _MAX_PATH ) != 0 )
rPar.Get(0)->PutString( String::CreateFromAscii( pBuffer ) );
else
StarBASIC::Error( SbERR_NO_DEVICE );
delete pBuffer;
_chdrive(old);
#else
#ifdef OS2
if( !nCurDir )
nCurDir = _getdrive();
#endif
if ( _getdcwd( nCurDir, pBuffer, _MAX_PATH ) != 0 )
rPar.Get(0)->PutString( String::CreateFromAscii( pBuffer ) );
else
StarBASIC::Error( SbERR_NO_DEVICE );
delete pBuffer;
#endif
#elif defined MAC
Str255 aBuffer;
FSSpec aFileSpec; // Pseudofile
String aPar1;
OSErr nErr;
// Erstmal aktuelle Pfad bestimmen
nErr = FSMakeFSSpec(0,0,"\p:X",&aFileSpec);
PathNameFromDirID( aFileSpec.parID,aFileSpec.vRefNum, (char*) aBuffer);
String aPath((char*) &aBuffer[1],aBuffer[0]);
if ( rPar.Count() == 2 )
{
aPar1 = rPar.Get(1)->GetString();
// Wen kein ':' drin ist dann haengen wir (netterweise) einen an
if (aPar1.Search(':') == STRING_NOTFOUND)
aPar1 += ':';
USHORT nFirstColon = aPar1.Search(':');
if (!aPar1.Len() ||
nFirstColon != (aPar1.Len() - 1))
// Kein ':' am Ende oder mehr als ein ':' oder leerer String
{
StarBASIC::Error( SbERR_BAD_ARGUMENT );
return;
}
// Is Param1 eventuelle das Volume des aktuellen Pfades ?
USHORT nMatchPoint = aPath.Match(aPar1);
if (nMatchPoint != (nFirstColon + 1))
{
String aPseudoFile(aPar1);
aPseudoFile += 'X'; // Pseudodatei
nErr = FSMakeFSSpec(0,0,aPseudoFile.GetPascalStr(),&aFileSpec);
if(nErr == nsvErr)
{
StarBASIC::Error( SbERR_NO_DEVICE );
return;
}
aPath = aPar1;
}
}
rPar.Get(0)->PutString(aPath);
#elif defined( UNX )
int nSize = _PATH_INCR;
char* pMem;
while( TRUE )
{
pMem = new char[nSize];
if( !pMem )
{
StarBASIC::Error( SbERR_NO_MEMORY );
return;
}
if( getcwd( pMem, nSize-1 ) != NULL )
{
rPar.Get(0)->PutString( String::CreateFromAscii(pMem) );
delete pMem;
return;
}
if( errno != ERANGE )
{
StarBASIC::Error( SbERR_INTERNAL_ERROR );
delete pMem;
return;
}
delete pMem;
nSize += _PATH_INCR;
};
#endif
}
RTLFUNC(ChDir) // JSM
{
rPar.Get(0)->PutEmpty();
if (rPar.Count() == 2)
{
2000-09-26 08:02:02 +00:00
#ifdef _ENABLE_CUR_DIR
2000-09-18 15:18:56 +00:00
String aPath = rPar.Get(1)->GetString();
BOOL bError = FALSE;
#ifdef WNT
// #55997 Laut MI hilft es bei File-URLs einen DirEntry zwischenzuschalten
// #40996 Harmoniert bei Verwendung der WIN32-Funktion nicht mit getdir
DirEntry aEntry( aPath );
ByteString aFullPath( aEntry.GetFull(), gsl_getSystemTextEncoding() );
if( chdir( aFullPath.GetBuffer()) )
bError = TRUE;
#else
if (!DirEntry(aPath).SetCWD())
bError = TRUE;
#endif
if( bError )
StarBASIC::Error( SbERR_PATH_NOT_FOUND );
2000-09-26 08:02:02 +00:00
#endif
2000-09-18 15:18:56 +00:00
}
else
StarBASIC::Error( SbERR_BAD_ARGUMENT );
}
RTLFUNC(ChDrive) // JSM
{
rPar.Get(0)->PutEmpty();
if (rPar.Count() == 2)
{
2000-09-26 08:02:02 +00:00
#ifdef _ENABLE_CUR_DIR
2000-09-18 15:18:56 +00:00
// Keine Laufwerke in Unix
#ifndef UNX
String aPar1 = rPar.Get(1)->GetString();
#if defined (WIN) || defined (WNT) || (defined (OS2) && !defined (WTC))
if (aPar1.Len() > 0)
{
int nCurDrive = (int)aPar1.GetBuffer()[0]; ;
if ( !isalpha( nCurDrive ) )
{
StarBASIC::Error( SbERR_BAD_ARGUMENT );
return;
}
else
nCurDrive -= ( 'A' - 1 );
if (_chdrive(nCurDrive))
StarBASIC::Error( SbERR_NO_DEVICE );
}
#elif defined MAC
// Wen kein ':' drin ist dann haengen wir (netterweise) einen an
if (aPar1.Search(':') == STRING_NOTFOUND)
aPar1 += ':';
if (!aPar1.Len() ||
aPar1.Search(':') != (aPar1.Len() - 1))
// Kein ':' am Ende oder mehr als ein ':' oder leerer String
{
StarBASIC::Error( SbERR_BAD_ARGUMENT );
return;
}
DirEntry aDrive(aPar1);
if (aDrive.SetCWD())
return;
else
StarBASIC::Error( SbERR_NO_DEVICE );
#endif
#endif
// #ifndef UNX
2000-09-26 08:02:02 +00:00
#endif
2000-09-18 15:18:56 +00:00
}
else
StarBASIC::Error( SbERR_BAD_ARGUMENT );
}
// Implementation of StepRENAME with UCB
void implStepRenameUCB( const String& aSource, const String& aDest )
{
Reference< XSimpleFileAccess > xSFI = getFileAccess();
if( xSFI.is() )
{
try
{
xSFI->move( getFullPath( aSource ), getFullPath( aDest ) );
}
catch( Exception & )
{
StarBASIC::Error( ERRCODE_IO_GENERAL );
}
}
}
2000-09-26 08:02:02 +00:00
// Implementation of StepRENAME with OSL
void implStepRenameOSL( const String& aSource, const String& aDest )
{
FileBase::RC nRet = File::move( getFullPathUNC( aSource ), getFullPathUNC( aDest ) );
if( nRet != FileBase::E_None )
2000-09-26 08:02:02 +00:00
{
StarBASIC::Error( SbERR_PATH_NOT_FOUND );
}
}
2000-09-18 15:18:56 +00:00
RTLFUNC(FileCopy) // JSM
{
rPar.Get(0)->PutEmpty();
if (rPar.Count() == 3)
{
String aSource = rPar.Get(1)->GetString();
String aDest = rPar.Get(2)->GetString();
// <-- UCB
if( hasUno() )
{
Reference< XSimpleFileAccess > xSFI = getFileAccess();
if( xSFI.is() )
{
try
{
xSFI->copy( getFullPath( aSource ), getFullPath( aDest ) );
}
catch( Exception & )
{
StarBASIC::Error( ERRCODE_IO_GENERAL );
}
}
}
else
// --> UCB
{
2000-09-26 08:02:02 +00:00
#ifdef _OLD_FILE_IMPL
2000-09-18 15:18:56 +00:00
DirEntry aSourceDirEntry(aSource);
if (aSourceDirEntry.Exists())
{
if (aSourceDirEntry.CopyTo(DirEntry(aDest),FSYS_ACTION_COPYFILE) != FSYS_ERR_OK)
StarBASIC::Error( SbERR_PATH_NOT_FOUND );
}
else
StarBASIC::Error( SbERR_PATH_NOT_FOUND );
2000-09-26 08:02:02 +00:00
#else
FileBase::RC nRet = File::copy( getFullPathUNC( aSource ), getFullPathUNC( aDest ) );
if( nRet != FileBase::RC::E_None )
{
StarBASIC::Error( SbERR_PATH_NOT_FOUND );
}
#endif
2000-09-18 15:18:56 +00:00
}
}
else
StarBASIC::Error( SbERR_BAD_ARGUMENT );
}
RTLFUNC(Kill) // JSM
{
rPar.Get(0)->PutEmpty();
if (rPar.Count() == 2)
{
String aFileSpec = rPar.Get(1)->GetString();
// <-- UCB
if( hasUno() )
{
Reference< XSimpleFileAccess > xSFI = getFileAccess();
if( xSFI.is() )
{
try
{
xSFI->kill( getFullPath( aFileSpec ) );
}
catch( Exception & )
{
StarBASIC::Error( ERRCODE_IO_GENERAL );
}
}
}
else
// --> UCB
{
2000-09-26 08:02:02 +00:00
#ifdef _OLD_FILE_IMPL
2000-09-18 15:18:56 +00:00
if(DirEntry(aFileSpec).Kill() != FSYS_ERR_OK)
StarBASIC::Error( SbERR_PATH_NOT_FOUND );
2000-09-26 08:02:02 +00:00
#else
File::remove( getFullPathUNC( aFileSpec ) );
#endif
2000-09-18 15:18:56 +00:00
}
}
else
StarBASIC::Error( SbERR_BAD_ARGUMENT );
}
RTLFUNC(MkDir) // JSM
{
rPar.Get(0)->PutEmpty();
if (rPar.Count() == 2)
{
String aPath = rPar.Get(1)->GetString();
// <-- UCB
if( hasUno() )
{
Reference< XSimpleFileAccess > xSFI = getFileAccess();
if( xSFI.is() )
{
try
{
xSFI->createFolder( getFullPath( aPath ) );
}
catch( Exception & )
{
StarBASIC::Error( ERRCODE_IO_GENERAL );
}
}
}
else
// --> UCB
{
2000-09-26 08:02:02 +00:00
#ifdef _OLD_FILE_IMPL
2000-09-18 15:18:56 +00:00
if (!DirEntry(aPath).MakeDir())
StarBASIC::Error( SbERR_PATH_NOT_FOUND );
2000-09-26 08:02:02 +00:00
#else
Directory::create( getFullPathUNC( aPath ) );
#endif
2000-09-18 15:18:56 +00:00
}
}
else
StarBASIC::Error( SbERR_BAD_ARGUMENT );
}
2000-09-26 08:02:02 +00:00
#ifndef _OLD_FILE_IMPL
// In OSL only empty directories can be deleted
// so we have to delete all files recursively
void implRemoveDirRecursive( const String& aDirPath )
{
DirectoryItem aItem;
FileBase::RC nRet = DirectoryItem::get( aDirPath, aItem );
sal_Bool bExists = (nRet == FileBase::RC::E_None);
FileStatus aFileStatus( FileStatusMask_Type );
nRet = aItem.getFileStatus( aFileStatus );
FileStatus::Type aType = aFileStatus.getFileType();
sal_Bool bFolder = (aType == FileStatus::Type::Directory);
if( !bExists || !bFolder )
{
StarBASIC::Error( SbERR_PATH_NOT_FOUND );
return;
}
Directory aDir( aDirPath );
nRet = aDir.open();
if( nRet != FileBase::RC::E_None )
{
StarBASIC::Error( SbERR_PATH_NOT_FOUND );
return;
}
for( ;; )
{
DirectoryItem aItem;
nRet = aDir.getNextItem( aItem );
if( nRet != FileBase::RC::E_None )
break;
// Handle flags
2001-05-30 09:52:05 +00:00
FileStatus aFileStatus( FileStatusMask_Type | FileStatusMask_FileURL );
2000-09-26 08:02:02 +00:00
nRet = aItem.getFileStatus( aFileStatus );
2001-05-30 09:52:05 +00:00
OUString aPath = aFileStatus.getFileURL();
2000-09-26 08:02:02 +00:00
// Directory?
FileStatus::Type aType = aFileStatus.getFileType();
sal_Bool bFolder = (aType == FileStatus::Type::Directory);
if( bFolder )
{
implRemoveDirRecursive( aPath );
}
else
{
File::remove( aPath );
}
}
nRet = Directory::remove( aDirPath );
}
#endif
2000-09-18 15:18:56 +00:00
RTLFUNC(RmDir) // JSM
{
rPar.Get(0)->PutEmpty();
if (rPar.Count() == 2)
{
String aPath = rPar.Get(1)->GetString();
// <-- UCB
if( hasUno() )
{
Reference< XSimpleFileAccess > xSFI = getFileAccess();
if( xSFI.is() )
{
try
{
xSFI->kill( getFullPath( aPath ) );
}
catch( Exception & )
{
StarBASIC::Error( ERRCODE_IO_GENERAL );
}
}
}
else
// --> UCB
{
2000-09-26 08:02:02 +00:00
#ifdef _OLD_FILE_IMPL
2000-09-18 15:18:56 +00:00
DirEntry aDirEntry(aPath);
if (aDirEntry.Kill() != FSYS_ERR_OK)
StarBASIC::Error( SbERR_PATH_NOT_FOUND );
2000-09-26 08:02:02 +00:00
#else
implRemoveDirRecursive( getFullPathUNC( aPath ) );
#endif
2000-09-18 15:18:56 +00:00
}
}
else
StarBASIC::Error( SbERR_BAD_ARGUMENT );
}
RTLFUNC(SendKeys) // JSM
{
rPar.Get(0)->PutEmpty();
StarBASIC::Error(SbERR_NOT_IMPLEMENTED);
}
RTLFUNC(Exp)
{
ULONG nArgCount = rPar.Count();
if ( rPar.Count() < 2 )
StarBASIC::Error( SbERR_BAD_ARGUMENT );
else
{
double aDouble = rPar.Get( 1 )->GetDouble();
aDouble = exp( aDouble );
rPar.Get( 0 )->PutDouble( aDouble );
}
}
RTLFUNC(FileLen)
{
if ( rPar.Count() < 2 )
StarBASIC::Error( SbERR_BAD_ARGUMENT );
else
{
SbxVariableRef pArg = rPar.Get( 1 );
String aStr( pArg->GetString() );
INT32 nLen = 0;
// <-- UCB
if( hasUno() )
{
Reference< XSimpleFileAccess > xSFI = getFileAccess();
if( xSFI.is() )
{
try
{
nLen = xSFI->getSize( getFullPath( aStr ) );
}
catch( Exception & )
{
StarBASIC::Error( ERRCODE_IO_GENERAL );
}
}
}
else
// --> UCB
{
2000-09-26 08:02:02 +00:00
#ifdef _OLD_FILE_IMPL
2000-09-18 15:18:56 +00:00
FileStat aStat = DirEntry( aStr );
nLen = aStat.GetSize();
2000-09-26 08:02:02 +00:00
#else
DirectoryItem aItem;
FileBase::RC nRet = DirectoryItem::get( getFullPathUNC( aStr ), aItem );
FileStatus aFileStatus( FileStatusMask_FileSize );
nRet = aItem.getFileStatus( aFileStatus );
nLen = (INT32)aFileStatus.getFileSize();
#endif
2000-09-18 15:18:56 +00:00
}
rPar.Get(0)->PutLong( (long)nLen );
}
}
RTLFUNC(Hex)
{
if ( rPar.Count() < 2 )
StarBASIC::Error( SbERR_BAD_ARGUMENT );
else
{
char aBuffer[16];
SbxVariableRef pArg = rPar.Get( 1 );
if ( pArg->IsInteger() )
sprintf( aBuffer,"%X", pArg->GetInteger() );
else
sprintf( aBuffer,"%lX", pArg->GetLong() );
rPar.Get(0)->PutString( String::CreateFromAscii( aBuffer ) );
}
}
// InStr( [start],string,string,[compare] )
RTLFUNC(InStr)
{
ULONG nArgCount = rPar.Count()-1;
if ( nArgCount < 2 )
StarBASIC::Error( SbERR_BAD_ARGUMENT );
else
{
USHORT nStartPos = 1;
USHORT nFirstStringPos = 1;
if ( nArgCount >= 3 )
{
nStartPos = (USHORT)(rPar.Get(1)->GetInteger());
if ( nStartPos == 0 )
{
StarBASIC::Error( SbERR_BAD_ARGUMENT );
nStartPos = 1;
}
nFirstStringPos++;
}
int bNotCaseSensitive = 1; // wird noch nicht ausgewertet
if ( nArgCount == 4 )
bNotCaseSensitive = rPar.Get(4)->GetInteger();
USHORT nPos;
if( !bNotCaseSensitive )
{
const String& rStr1 = rPar.Get(nFirstStringPos)->GetString();
const String& rToken = rPar.Get(nFirstStringPos+1)->GetString();
nPos = rStr1.Search( rToken, nStartPos-1 );
if ( nPos == STRING_NOTFOUND )
nPos = 0;
else
nPos++;
}
else
{
String aStr1 = rPar.Get(nFirstStringPos)->GetString();
String aToken = rPar.Get(nFirstStringPos+1)->GetString();
aStr1.ToUpperAscii();
aToken.ToUpperAscii();
nPos = aStr1.Search( aToken, nStartPos-1 );
if ( nPos == STRING_NOTFOUND )
nPos = 0;
else
nPos++;
}
rPar.Get(0)->PutInteger( (int)nPos );
}
}
/*
Int( 2.8 ) = 2.0
Int( -2.8 ) = -3.0
Fix( 2.8 ) = 2.0
Fix( -2.8 ) = -2.0 <- !!
*/
RTLFUNC(Int)
{
if ( rPar.Count() < 2 )
StarBASIC::Error( SbERR_BAD_ARGUMENT );
else
{
SbxVariableRef pArg = rPar.Get( 1 );
double aDouble= pArg->GetDouble();
/*
floor( 2.8 ) = 2.0
floor( -2.8 ) = -3.0
*/
aDouble = floor( aDouble );
rPar.Get(0)->PutDouble( aDouble );
}
}
RTLFUNC(Fix)
{
if ( rPar.Count() < 2 )
StarBASIC::Error( SbERR_BAD_ARGUMENT );
else
{
SbxVariableRef pArg = rPar.Get( 1 );
double aDouble = pArg->GetDouble();
if ( aDouble >= 0.0 )
aDouble = floor( aDouble );
else
aDouble = ceil( aDouble );
rPar.Get(0)->PutDouble( aDouble );
}
}
RTLFUNC(LCase)
{
if ( rPar.Count() < 2 )
StarBASIC::Error( SbERR_BAD_ARGUMENT );
else
{
CharClass& rCharClass = GetCharClass();
2000-09-18 15:18:56 +00:00
String aStr( rPar.Get(1)->GetString() );
rCharClass.toLower( aStr );
2000-09-18 15:18:56 +00:00
rPar.Get(0)->PutString( aStr );
}
}
RTLFUNC(Left)
{
ULONG nArgCount = rPar.Count();
if ( rPar.Count() < 3 )
StarBASIC::Error( SbERR_BAD_ARGUMENT );
else
{
String aStr( rPar.Get(1)->GetString() );
short nCount = (USHORT)( rPar.Get(2)->GetLong() );
if ( nCount < 0 )
StarBASIC::Error( SbERR_BAD_ARGUMENT );
else
{
aStr.Erase( (USHORT)nCount );
rPar.Get(0)->PutString( aStr );
}
}
}
RTLFUNC(Log)
{
if ( rPar.Count() < 2 )
StarBASIC::Error( SbERR_BAD_ARGUMENT );
else
{
double aArg = rPar.Get(1)->GetDouble();
if ( aArg > 0 )
rPar.Get( 0 )->PutDouble( log( aArg ));
else
StarBASIC::Error( SbERR_BAD_ARGUMENT );
}
}
RTLFUNC(LTrim)
{
if ( rPar.Count() < 2 )
StarBASIC::Error( SbERR_BAD_ARGUMENT );
else
{
String aStr( rPar.Get(1)->GetString() );
aStr.EraseLeadingChars();
rPar.Get(0)->PutString( aStr );
}
}
// Mid( String, nStart, nLength )
RTLFUNC(Mid)
{
ULONG nArgCount = rPar.Count()-1;
if ( nArgCount < 2 )
StarBASIC::Error( SbERR_BAD_ARGUMENT );
else
{
// #23178: Funktionalitaet von Mid$ als Anweisung nachbilden, indem
// als weiterer (4.) Parameter ein Ersetzungsstring aufgenommen wird.
// Anders als im Original kann in dieser Variante der 3. Parameter
// nLength nicht weggelassen werden. Ist ueber bWrite schon vorgesehen.
if( nArgCount == 4 )
bWrite = TRUE;
String aArgStr = rPar.Get(1)->GetString();
USHORT nStartPos = (USHORT)(rPar.Get(2)->GetLong() );
if ( nStartPos == 0 )
StarBASIC::Error( SbERR_BAD_ARGUMENT );
else
{
nStartPos--;
USHORT nLen = 0xffff;
if ( nArgCount == 3 || bWrite )
nLen = (USHORT)(rPar.Get(3)->GetLong() );
String aResultStr;
if ( bWrite )
{
aResultStr = aArgStr;
aResultStr.Erase( nStartPos, nLen );
aResultStr.Insert(rPar.Get(4)->GetString(),0,nLen,nStartPos);
rPar.Get(1)->PutString( aResultStr );
}
else
{
aResultStr = aArgStr.Copy( nStartPos, nLen );
rPar.Get(0)->PutString( aResultStr );
}
}
}
}
RTLFUNC(Oct)
{
if ( rPar.Count() < 2 )
StarBASIC::Error( SbERR_BAD_ARGUMENT );
else
{
char aBuffer[16];
SbxVariableRef pArg = rPar.Get( 1 );
if ( pArg->IsInteger() )
sprintf( aBuffer,"%o", pArg->GetInteger() );
else
sprintf( aBuffer,"%lo", pArg->GetLong() );
rPar.Get(0)->PutString( String::CreateFromAscii( aBuffer ) );
}
}
RTLFUNC(Right)
{
ULONG nArgCount = rPar.Count();
if ( rPar.Count() < 3 )
StarBASIC::Error( SbERR_BAD_ARGUMENT );
else
{
const String& rStr = rPar.Get(1)->GetString();
USHORT nResultLen = (USHORT)(rPar.Get(2)->GetLong() );
USHORT nStrLen = rStr.Len();
if ( nResultLen > nStrLen )
nResultLen = nStrLen;
String aResultStr = rStr.Copy( nStrLen-nResultLen );
rPar.Get(0)->PutString( aResultStr );
}
}
RTLFUNC(RTrim)
{
if ( rPar.Count() < 2 )
StarBASIC::Error( SbERR_BAD_ARGUMENT );
else
{
String aStr( rPar.Get(1)->GetString() );
aStr.EraseTrailingChars();
rPar.Get(0)->PutString( aStr );
}
}
RTLFUNC(Sgn)
{
ULONG nArgCount = rPar.Count();
if ( rPar.Count() < 2 )
StarBASIC::Error( SbERR_BAD_ARGUMENT );
else
{
double aDouble = rPar.Get(1)->GetDouble();
INT16 nResult = 0;
if ( aDouble > 0 )
nResult = 1;
else if ( aDouble < 0 )
nResult = -1;
rPar.Get(0)->PutInteger( nResult );
}
}
RTLFUNC(Space)
{
if ( rPar.Count() < 2 )
StarBASIC::Error( SbERR_BAD_ARGUMENT );
else
{
String aStr;
aStr.Fill( (USHORT)(rPar.Get(1)->GetLong() ));
rPar.Get(0)->PutString( aStr );
}
}
RTLFUNC(Spc)
{
if ( rPar.Count() < 2 )
StarBASIC::Error( SbERR_BAD_ARGUMENT );
else
{
String aStr;
aStr.Fill( (USHORT)(rPar.Get(1)->GetLong() ));
rPar.Get(0)->PutString( aStr );
}
}
RTLFUNC(Sqr)
{
if ( rPar.Count() < 2 )
StarBASIC::Error( SbERR_BAD_ARGUMENT );
else
{
double aDouble = rPar.Get(1)->GetDouble();
if ( aDouble >= 0 )
rPar.Get(0)->PutDouble( sqrt( aDouble ));
else
StarBASIC::Error( SbERR_BAD_ARGUMENT );
}
}
RTLFUNC(Str)
{
if ( rPar.Count() < 2 )
StarBASIC::Error( SbERR_BAD_ARGUMENT );
else
{
String aStr;
rPar.Get( 1 )->Format( aStr );
// Numbers start with a space
if( rPar.Get( 1 )->IsNumericRTL() )
aStr.Insert( ' ', 0 );
// Kommas durch Punkte ersetzen, damits symmetrisch zu Val ist!
aStr.SearchAndReplace( ',', '.' );
rPar.Get(0)->PutString( aStr );
}
}
RTLFUNC(StrComp)
{
if ( rPar.Count() < 3 )
{
StarBASIC::Error( SbERR_BAD_ARGUMENT );
rPar.Get(0)->PutEmpty();
return;
}
const String& rStr1 = rPar.Get(1)->GetString();
const String& rStr2 = rPar.Get(2)->GetString();
INT16 nNotCaseSensitive = TRUE;
if ( rPar.Count() == 4 )
nNotCaseSensitive = rPar.Get(3)->GetInteger();
const International& aInternational = GetpApp()->GetAppInternational();
StringCompare aResult;
if ( !nNotCaseSensitive )
aResult = aInternational.Compare( rStr1, rStr2 );
else
aResult = rStr1.CompareTo( rStr2 );
int nRetValue = 0;
if ( aResult == COMPARE_LESS )
nRetValue = -1;
else if ( aResult == COMPARE_GREATER )
nRetValue = 1;
rPar.Get(0)->PutInteger( nRetValue );
}
RTLFUNC(String)
{
if ( rPar.Count() < 2 )
StarBASIC::Error( SbERR_BAD_ARGUMENT );
else
{
String aStr;
sal_Unicode aFiller;
USHORT nCount = (USHORT)(rPar.Get(1)->GetLong());
if( rPar.Get(2)->GetType() == SbxINTEGER )
aFiller = (char)rPar.Get(2)->GetInteger();
else
{
const String& rStr = rPar.Get(2)->GetString();
aFiller = rStr.GetBuffer()[0];
}
aStr.Fill( nCount, aFiller );
rPar.Get(0)->PutString( aStr );
}
}
RTLFUNC(Tan)
{
if ( rPar.Count() < 2 )
StarBASIC::Error( SbERR_BAD_ARGUMENT );
else
{
SbxVariableRef pArg = rPar.Get( 1 );
rPar.Get( 0 )->PutDouble( tan( pArg->GetDouble() ) );
}
}
RTLFUNC(UCase)
{
if ( rPar.Count() < 2 )
StarBASIC::Error( SbERR_BAD_ARGUMENT );
else
{
CharClass& rCharClass = GetCharClass();
2000-09-18 15:18:56 +00:00
String aStr( rPar.Get(1)->GetString() );
rCharClass.toUpper( aStr );
2000-09-18 15:18:56 +00:00
rPar.Get(0)->PutString( aStr );
}
}
RTLFUNC(Val)
{
static International aEnglischIntn( LANGUAGE_ENGLISH_US, LANGUAGE_ENGLISH_US );
if ( rPar.Count() < 2 )
StarBASIC::Error( SbERR_BAD_ARGUMENT );
else
{
double nResult;
char* pEndPtr;
String aStr( rPar.Get(1)->GetString() );
// lt. Mikkysoft bei Kommas abbrechen!
// for( USHORT n=0; n < aStr.Len(); n++ )
// if( aStr[n] == ',' ) aStr[n] = '.';
FilterWhiteSpace( aStr );
if ( aStr.GetBuffer()[0] == '&' && aStr.Len() > 1 )
{
int nRadix = 10;
char aChar = (char)aStr.GetBuffer()[1];
2000-09-18 15:18:56 +00:00
if ( aChar == 'h' || aChar == 'H' )
nRadix = 16;
else if ( aChar == 'o' || aChar == 'O' )
nRadix = 8;
if ( nRadix != 10 )
{
ByteString aByteStr( aStr, gsl_getSystemTextEncoding() );
INT16 nlResult = (INT16)strtol( aByteStr.GetBuffer()+2, &pEndPtr, nRadix);
nResult = (double)nlResult;
}
}
else
{
// #57844 Lokalisierte Funktion benutzen
int nErrno;
nResult = SolarMath::StringToDouble( aStr.GetBuffer(), aEnglischIntn, nErrno );
// ATL: nResult = strtod( aStr.GetStr(), &pEndPtr );
}
rPar.Get(0)->PutDouble( nResult );
}
}
RTLFUNC(DateSerial)
{
if ( rPar.Count() < 4 )
{
StarBASIC::Error( SbERR_BAD_ARGUMENT );
return;
}
INT16 nYear = rPar.Get(1)->GetInteger();
INT16 nMonth = rPar.Get(2)->GetInteger();
INT16 nDay = rPar.Get(3)->GetInteger();
if ( nYear < 100 )
nYear += 1900;
if ((nYear < 100 || nYear > 9999) ||
(nMonth < 1 || nMonth > 12 ) ||
(nDay < 1 || nDay > 31 ))
{
StarBASIC::Error( SbERR_BAD_ARGUMENT );
return;
}
Date aCurDate( nDay, nMonth, nYear );
long nDiffDays = GetDayDiff( aCurDate );
rPar.Get(0)->PutDate( (double)nDiffDays ); // JSM
}
RTLFUNC(TimeSerial)
{
if ( rPar.Count() < 4 )
{
StarBASIC::Error( SbERR_BAD_ARGUMENT );
return;
}
INT16 nHour = rPar.Get(1)->GetInteger();
if ( nHour == 24 )
nHour = 0; // Wegen UNO DateTimes, die bis 24 Uhr gehen
INT16 nMinute = rPar.Get(2)->GetInteger();
INT16 nSecond = rPar.Get(3)->GetInteger();
if ((nHour < 0 || nHour > 23) ||
(nMinute < 0 || nMinute > 59 ) ||
(nSecond < 0 || nSecond > 59 ))
{
StarBASIC::Error( SbERR_BAD_ARGUMENT );
return;
}
INT32 nSeconds = nHour;
nSeconds *= 3600;
nSeconds += nMinute * 60;
nSeconds += nSecond;
double nDays = ((double)nSeconds) / (double)(86400.0);
rPar.Get(0)->PutDate( nDays ); // JSM
}
RTLFUNC(DateValue)
{
if ( rPar.Count() < 2 )
StarBASIC::Error( SbERR_BAD_ARGUMENT );
else
{
// #39629 pINST pruefen, kann aus URL-Zeile gerufen werden
SvNumberFormatter* pFormatter = NULL;
if( pINST )
pFormatter = pINST->GetNumberFormatter();
else
{
ULONG n; // Dummy
SbiInstance::PrepareNumberFormatter( pFormatter, n, n, n );
}
ULONG nIndex;
double fResult;
String aStr( rPar.Get(1)->GetString() );
BOOL bSuccess = pFormatter->IsNumberFormat( aStr, nIndex, fResult );
short nType = pFormatter->GetType( nIndex );
if(bSuccess && (nType==NUMBERFORMAT_DATE || nType==NUMBERFORMAT_DATETIME))
{
if ( nType == NUMBERFORMAT_DATETIME )
{
// Zeit abschneiden
if ( fResult > 0.0 )
fResult = floor( fResult );
else
fResult = ceil( fResult );
}
// fResult += 2.0; // Anpassung StarCalcFormatter
rPar.Get(0)->PutDate( fResult ); // JSM
}
else
StarBASIC::Error( SbERR_CONVERSION );
// #39629 pFormatter kann selbst angefordert sein
if( !pINST )
delete pFormatter;
}
}
RTLFUNC(TimeValue)
{
if ( rPar.Count() < 2 )
StarBASIC::Error( SbERR_BAD_ARGUMENT );
else
{
// #39629 pINST pruefen, kann aus URL-Zeile gerufen werden
SvNumberFormatter* pFormatter = NULL;
if( pINST )
pFormatter = pINST->GetNumberFormatter();
else
{
ULONG n; // Dummy
SbiInstance::PrepareNumberFormatter( pFormatter, n, n, n );
}
ULONG nIndex;
double fResult;
BOOL bSuccess = pFormatter->IsNumberFormat( rPar.Get(1)->GetString(),
nIndex, fResult );
short nType = pFormatter->GetType(nIndex);
if(bSuccess && (nType==NUMBERFORMAT_TIME||nType==NUMBERFORMAT_DATETIME))
{
if ( nType == NUMBERFORMAT_DATETIME )
// Tage abschneiden
fResult = fmod( fResult, 1 );
rPar.Get(0)->PutDate( fResult ); // JSM
}
else
StarBASIC::Error( SbERR_CONVERSION );
// #39629 pFormatter kann selbst angefordert sein
if( !pINST )
delete pFormatter;
}
}
RTLFUNC(Day)
{
if ( rPar.Count() < 2 )
StarBASIC::Error( SbERR_BAD_ARGUMENT );
else
{
SbxVariableRef pArg = rPar.Get( 1 );
double aDouble = pArg->GetDate();
aDouble -= 2.0; // normieren: 1.1.1900 => 0.0
Date aRefDate( 1, 1, 1900 );
// aDouble = Fix( aDouble );
if ( aDouble >= 0.0 )
{
aDouble = floor( aDouble );
aRefDate += (ULONG)aDouble;
}
else
{
aDouble = ceil( aDouble );
aRefDate -= (ULONG)(-1.0 * aDouble);
}
rPar.Get(0)->PutInteger( (INT16)(aRefDate.GetDay()));
}
}
RTLFUNC(Weekday)
{
if ( rPar.Count() < 2 )
StarBASIC::Error( SbERR_BAD_ARGUMENT );
else
{
Date aRefDate( 1,1,1900 );
long nDays = (long) rPar.Get(1)->GetDate();
nDays -= 2; // normieren: 1.1.1900 => 0
aRefDate += nDays;
DayOfWeek aDay = aRefDate.GetDayOfWeek();
INT16 nDay;
if ( aDay != SUNDAY )
nDay = (INT16)aDay + 2;
else
nDay = 1; // 1==Sonntag
rPar.Get(0)->PutInteger( nDay );
}
}
RTLFUNC(Year)
{
if ( rPar.Count() < 2 )
StarBASIC::Error( SbERR_BAD_ARGUMENT );
else
{
Date aRefDate( 1,1,1900 );
long nDays = (long) rPar.Get(1)->GetDate();
nDays -= 2; // normieren: 1.1.1900 => 0.0
aRefDate += nDays;
rPar.Get(0)->PutInteger( (INT16)(aRefDate.GetYear()) );
}
}
RTLFUNC(Hour)
{
if ( rPar.Count() < 2 )
StarBASIC::Error( SbERR_BAD_ARGUMENT );
else
{
double nArg = rPar.Get(1)->GetDate();
if ( nArg < 0.0 )
nArg *= -1.0;
double nFrac = nArg - floor( nArg );
nFrac *= 86400.0;
INT32 nSeconds = (INT32)nFrac;
INT16 nHour = (INT16)(nSeconds / 3600);
rPar.Get(0)->PutInteger( nHour );
}
}
RTLFUNC(Minute)
{
if ( rPar.Count() < 2 )
StarBASIC::Error( SbERR_BAD_ARGUMENT );
else
{
double nArg = rPar.Get(1)->GetDate();
if ( nArg < 0.0 )
nArg *= -1.0;
double nFrac = nArg - floor( nArg );
nFrac *= 86400.0;
INT32 nSeconds = (INT32)nFrac;
INT16 nTemp = (INT16)(nSeconds % 3600);
INT16 nMin = nTemp / 60;
rPar.Get(0)->PutInteger( nMin );
}
}
RTLFUNC(Month)
{
if ( rPar.Count() < 2 )
StarBASIC::Error( SbERR_BAD_ARGUMENT );
else
{
Date aRefDate( 1,1,1900 );
long nDays = (long) rPar.Get(1)->GetDate();
nDays -= 2; // normieren: 1.1.1900 => 0.0
aRefDate += nDays;
rPar.Get(0)->PutInteger( (INT16)(aRefDate.GetMonth()) );
}
}
RTLFUNC(Second)
{
if ( rPar.Count() < 2 )
StarBASIC::Error( SbERR_BAD_ARGUMENT );
else
{
double nArg = rPar.Get(1)->GetDate();
if ( nArg < 0.0 )
nArg *= -1.0;
double nFrac = nArg - floor( nArg );
nFrac *= 86400.0;
INT32 nSeconds = (INT32)nFrac;
INT16 nTemp = (INT16)(nSeconds / 3600);
nSeconds -= nTemp * 3600;
nTemp = (INT16)(nSeconds / 60);
nSeconds -= nTemp * 60;
rPar.Get(0)->PutInteger( (INT16)nSeconds );
}
}
// Date Now(void)
RTLFUNC(Now)
{
Date aDate;
Time aTime;
double aSerial = (double)GetDayDiff( aDate );
long nSeconds = aTime.GetHour();
nSeconds *= 3600;
nSeconds += aTime.GetMin() * 60;
nSeconds += aTime.GetSec();
double nDays = ((double)nSeconds) / (double)(24.0*3600.0);
aSerial += nDays;
rPar.Get(0)->PutDate( aSerial );
}
// Date Time(void)
RTLFUNC(Time)
{
if ( !bWrite )
{
Time aTime;
SbxVariable* pMeth = rPar.Get( 0 );
String aRes;
if( pMeth->IsFixed() )
{
// Time$: hh:mm:ss
char buf[ 20 ];
sprintf( buf, "%02d:%02d:%02d",
aTime.GetHour(), aTime.GetMin(), aTime.GetSec() );
aRes = String::CreateFromAscii( buf );
}
else
{
// Time: system dependent
long nSeconds=aTime.GetHour();
nSeconds *= 3600;
nSeconds += aTime.GetMin() * 60;
nSeconds += aTime.GetSec();
double nDays = (double)nSeconds * ( 1.0 / (24.0*3600.0) );
Color* pCol;
// #39629 pINST pruefen, kann aus URL-Zeile gerufen werden
SvNumberFormatter* pFormatter = NULL;
ULONG nIndex;
if( pINST )
{
pFormatter = pINST->GetNumberFormatter();
nIndex = pINST->GetStdTimeIdx();
}
else
{
ULONG n; // Dummy
SbiInstance::PrepareNumberFormatter( pFormatter, n, nIndex, n );
}
pFormatter->GetOutputString( nDays, nIndex, aRes, &pCol );
// #39629 pFormatter kann selbst angefordert sein
if( !pINST )
delete pFormatter;
}
pMeth->PutString( aRes );
}
else
{
StarBASIC::Error( SbERR_NOT_IMPLEMENTED );
}
}
RTLFUNC(Timer)
{
Time aTime;
long nSeconds = aTime.GetHour();
nSeconds *= 3600;
nSeconds += aTime.GetMin() * 60;
nSeconds += aTime.GetSec();
rPar.Get(0)->PutDate( (double)nSeconds );
}
RTLFUNC(Date)
{
if ( !bWrite )
{
Date aToday;
double nDays = (double)GetDayDiff( aToday );
SbxVariable* pMeth = rPar.Get( 0 );
if( pMeth->IsString() )
{
String aRes;
Color* pCol;
// #39629 pINST pruefen, kann aus URL-Zeile gerufen werden
SvNumberFormatter* pFormatter = NULL;
ULONG nIndex;
if( pINST )
{
pFormatter = pINST->GetNumberFormatter();
nIndex = pINST->GetStdDateIdx();
}
else
{
ULONG n; // Dummy
SbiInstance::PrepareNumberFormatter( pFormatter, nIndex, n, n );
}
pFormatter->GetOutputString( nDays, nIndex, aRes, &pCol );
pMeth->PutString( aRes );
// #39629 pFormatter kann selbst angefordert sein
if( !pINST )
delete pFormatter;
}
else
pMeth->PutDate( nDays );
}
else
{
StarBASIC::Error( SbERR_NOT_IMPLEMENTED );
}
}
RTLFUNC(IsArray)
{
if ( rPar.Count() < 2 )
StarBASIC::Error( SbERR_BAD_ARGUMENT );
else
rPar.Get(0)->PutBool((rPar.Get(1)->GetType() & SbxARRAY) ? TRUE : FALSE );
}
RTLFUNC(IsObject)
{
if ( rPar.Count() < 2 )
StarBASIC::Error( SbERR_BAD_ARGUMENT );
else
rPar.Get( 0 )->PutBool( rPar.Get(1)->IsObject() );
}
RTLFUNC(IsDate)
{
if ( rPar.Count() < 2 )
StarBASIC::Error( SbERR_BAD_ARGUMENT );
else
{
// #46134 Nur String wird konvertiert, andere Typen ergeben FALSE
SbxVariableRef xArg = rPar.Get( 1 );
SbxDataType eType = xArg->GetType();
BOOL bDate = FALSE;
if( eType == SbxDATE )
{
bDate = TRUE;
}
else if( eType == SbxSTRING )
{
// Error loeschen
SbxError nPrevError = SbxBase::GetError();
SbxBase::ResetError();
// Konvertierung des Parameters nach SbxDATE erzwingen
xArg->SbxValue::GetDate();
// Bei Fehler ist es kein Date
bDate = !SbxBase::IsError();
// Error-Situation wiederherstellen
SbxBase::ResetError();
SbxBase::SetError( nPrevError );
}
rPar.Get( 0 )->PutBool( bDate );
}
}
RTLFUNC(IsEmpty)
{
if ( rPar.Count() < 2 )
StarBASIC::Error( SbERR_BAD_ARGUMENT );
else
rPar.Get( 0 )->PutBool( rPar.Get(1)->IsEmpty() );
}
RTLFUNC(IsError)
{
if ( rPar.Count() < 2 )
StarBASIC::Error( SbERR_BAD_ARGUMENT );
else
rPar.Get( 0 )->PutBool( rPar.Get(1)->IsErr() );
}
RTLFUNC(IsNull)
{
if ( rPar.Count() < 2 )
StarBASIC::Error( SbERR_BAD_ARGUMENT );
else
{
// #51475 Wegen Uno-Objekten auch true liefern,
// wenn der pObj-Wert NULL ist
SbxVariableRef pArg = rPar.Get( 1 );
BOOL bNull = rPar.Get(1)->IsNull();
if( !bNull && pArg->GetType() == SbxOBJECT )
{
SbxBase* pObj = pArg->GetObject();
if( !pObj )
bNull = TRUE;
}
rPar.Get( 0 )->PutBool( bNull );
}
}
RTLFUNC(IsNumeric)
{
if ( rPar.Count() < 2 )
StarBASIC::Error( SbERR_BAD_ARGUMENT );
else
rPar.Get( 0 )->PutBool( rPar.Get( 1 )->IsNumericRTL() );
}
// Das machen wir auf die billige Tour
RTLFUNC(IsMissing)
{
if ( rPar.Count() < 2 )
StarBASIC::Error( SbERR_BAD_ARGUMENT );
else
// #57915 Missing wird durch Error angezeigt
rPar.Get( 0 )->PutBool( rPar.Get(1)->IsErr() );
}
// Dir( [Maske] [,Attrs] )
// ToDo: Library-globaler Datenbereich fuer Dir-Objekt und Flags
2000-12-08 15:35:54 +00:00
// #80200 HACK to provide minimum wildcard functionality (finally solution in UCB)
// Function looks for wildcards, removes them and always returns the pure path
String implSetupWildcard( const String& rFileParam, SbiRTLData* pRTLData, sal_Bool bUNC )
{
2001-03-08 12:54:27 +00:00
pRTLData->bNameCheck = sal_False;
2000-12-08 15:35:54 +00:00
pRTLData->sExtension = String();
pRTLData->sPreWildcard = String();
2001-03-08 12:54:27 +00:00
pRTLData->sFullNameToBeChecked = String();
2000-12-08 15:35:54 +00:00
String aFileParam = rFileParam;
String aPathStr;
if( bUNC )
{
aPathStr = getFullPathUNC( aFileParam );
}
else
{
aPathStr = getFullPath( aFileParam );
}
2001-03-29 14:15:18 +00:00
// #85023 If it's now recognized as folder everything
// is fine and we don't have to check for wildcards
Reference< XSimpleFileAccess > xSFI = getFileAccess();
if( xSFI->isFolder( aPathStr ) )
return aPathStr;
2000-12-08 15:35:54 +00:00
sal_Char cWild = '*';
2001-03-08 12:54:27 +00:00
sal_Char cDelim1 = (sal_Char)'/';
sal_Char cDelim2 = (sal_Char)'\\';
xub_StrLen nLen = aFileParam.Len();
2000-12-08 15:35:54 +00:00
2001-03-08 12:54:27 +00:00
xub_StrLen nLastDelim = aFileParam.SearchBackward( cDelim1 );
if( nLastDelim == STRING_NOTFOUND )
nLastDelim = aFileParam.SearchBackward( cDelim2 );
String aPureFileName;
if( nLastDelim == STRING_NOTFOUND )
{
aPureFileName = aFileParam;
aFileParam = String();
}
else
{
aPureFileName = aFileParam.Copy( nLastDelim + 1 );
aFileParam = aFileParam.Copy( 0, nLastDelim );
}
2000-12-08 15:35:54 +00:00
2001-03-08 12:54:27 +00:00
if( !aPathStr.Len() || aPathStr.SearchBackward( cWild ) != STRING_NOTFOUND )
{
2000-12-08 15:35:54 +00:00
// Try again to get a valid URL/UNC-path with only the path
if( bUNC )
aPathStr = getFullPathUNC( aFileParam );
else
aPathStr = getFullPath( aFileParam );
// Is there a pure file name left? Otherwise the path is
// invalid anyway because it was not accepted by OSL before
xub_StrLen nPureLen = aPureFileName.Len();
if( aPureFileName.Len() && aPureFileName != String::CreateFromAscii( "*.*" ) )
{
// We make it very easy and search only for "anything*.xxx" patterns
sal_Char cDot = '.';
xub_StrLen nLastWild = aPureFileName.SearchBackward( cWild );
xub_StrLen nLastDot = aPureFileName.SearchBackward( cDot );
2001-03-29 14:15:18 +00:00
// Handle ".*" and "x*"
2000-12-08 15:35:54 +00:00
sal_Bool bAnyExtension = sal_False;
2001-03-29 14:15:18 +00:00
if( nLastWild == nPureLen-1 )
2000-12-08 15:35:54 +00:00
{
2001-03-29 14:15:18 +00:00
if( nLastDot == nPureLen-2 )
{
bAnyExtension = sal_True;
nLastWild = aPureFileName.SearchBackward( cWild, nLastDot );
}
else if( nLastDot == STRING_NOTFOUND )
{
bAnyExtension = sal_True;
}
2000-12-08 15:35:54 +00:00
}
2001-03-29 14:15:18 +00:00
if( nLastWild == nLastDot-1 ||
( nLastDot == STRING_NOTFOUND && bAnyExtension ) )
2000-12-08 15:35:54 +00:00
{
2001-03-08 12:54:27 +00:00
pRTLData->bNameCheck = sal_True;
2000-12-08 15:35:54 +00:00
if( !bAnyExtension )
pRTLData->sExtension = aPureFileName.Copy( nLastDot + 1 );
pRTLData->sPreWildcard = aPureFileName.Copy( 0, nLastWild );
}
}
}
2001-03-08 12:54:27 +00:00
// Check if a complete file name has to be checked
else if( aPureFileName.Len() )
{
pRTLData->bNameCheck = sal_True;
pRTLData->sFullNameToBeChecked = aPureFileName;
}
2000-12-08 15:35:54 +00:00
return aPathStr;
}
sal_Bool implCheckWildcard( const String& rName, SbiRTLData* pRTLData )
{
sal_Bool bMatch = sal_True;
// #80200 HACK to provide minimum wildcard functionality (*.xxx)
2001-03-08 12:54:27 +00:00
if( pRTLData->bNameCheck )
2000-12-08 15:35:54 +00:00
{
bMatch = sal_False;
2001-03-08 12:54:27 +00:00
if( pRTLData->sFullNameToBeChecked.Len() )
{
#ifdef UNX
bMatch = rName.Equals( pRTLData->sFullNameToBeChecked );
#else
bMatch = rName.EqualsIgnoreCaseAscii( pRTLData->sFullNameToBeChecked );
#endif
}
else
2000-12-08 15:35:54 +00:00
{
2001-03-08 12:54:27 +00:00
sal_Char cDot = '.'; // char -> sal_Char ok, because ASCII
xub_StrLen nLastDot = rName.SearchBackward( cDot );
if( nLastDot != STRING_NOTFOUND )
2000-12-08 15:35:54 +00:00
{
2001-03-08 12:54:27 +00:00
String sExtension = rName.Copy( nLastDot + 1 );
String sMainName = rName.Copy( 0, nLastDot );
if( !pRTLData->sExtension.Len() || sExtension == pRTLData->sExtension )
2000-12-08 15:35:54 +00:00
{
2001-03-08 12:54:27 +00:00
sal_Int32 nPreWildcardLen = pRTLData->sPreWildcard.Len();
if( nPreWildcardLen )
{
String sTmp = sMainName.Copy( 0, (sal_Int32)nPreWildcardLen );
2000-12-08 15:35:54 +00:00
#ifdef UNX
2001-03-08 12:54:27 +00:00
bMatch = sTmp.Equals( pRTLData->sPreWildcard );
2000-12-08 15:35:54 +00:00
#else
2001-03-08 12:54:27 +00:00
bMatch = sTmp.EqualsIgnoreCaseAscii( pRTLData->sPreWildcard );
2000-12-08 15:35:54 +00:00
#endif
2001-03-08 12:54:27 +00:00
}
else
{
bMatch = sal_True;
}
2000-12-08 15:35:54 +00:00
}
}
}
}
return bMatch;
}
// End #80200 HACK
2000-09-18 15:18:56 +00:00
RTLFUNC(Dir)
{
String aPath;
USHORT nParCount = rPar.Count();
if( nParCount > 3 )
StarBASIC::Error( SbERR_BAD_ARGUMENT );
else
{
SbiRTLData* pRTLData = pINST->GetRTLData();
// #34645: Kann auch von der URL-Zeile ueber 'macro: Dir' aufgerufen werden
// dann existiert kein pRTLData und die Methode muss verlassen werden
if( !pRTLData )
return;
// <-- UCB
if( hasUno() )
{
Reference< XSimpleFileAccess > xSFI = getFileAccess();
if( xSFI.is() )
{
if ( nParCount >= 2 )
{
String aFileParam = rPar.Get(1)->GetString();
2000-12-08 15:35:54 +00:00
// #80200 HACK to provide minimum wildcard functionality
String aFileURLStr = implSetupWildcard( aFileParam, pRTLData, sal_False );
2000-09-18 15:18:56 +00:00
try
{
String aDirURLStr;
2001-03-29 14:15:18 +00:00
sal_Bool bFolder = xSFI->isFolder( aFileURLStr );
2000-09-18 15:18:56 +00:00
if( bFolder )
{
aDirURLStr = aFileURLStr;
}
else
{
INetURLObject aFileURL( aFileURLStr );
// Not folder but exists? Return file!
sal_Bool bExists = sal_False;
try { bExists = xSFI->exists( aFileURLStr ); }
catch( Exception & ) {}
if( bExists )
{
String aNameOnlyStr = aFileURL.getName( INetURLObject::LAST_SEGMENT,
true, INetURLObject::DECODE_WITH_CHARSET );
rPar.Get(0)->PutString( aNameOnlyStr );
return;
}
aDirURLStr = aFileURL.GetPath();
}
USHORT nFlags = 0;
if ( nParCount > 2 )
pRTLData->nDirFlags = nFlags = rPar.Get(2)->GetInteger();
else
pRTLData->nDirFlags = 0;
// Read directory
sal_Bool bIncludeFolders = ((nFlags & Sb_ATTR_DIRECTORY) != 0);
pRTLData->aDirSeq = xSFI->getFolderContents( aDirURLStr, bIncludeFolders );
pRTLData->nCurDirPos = 0;
// #78651 Add "." and ".." directories for VB compatibility
if( bIncludeFolders )
{
INetURLObject aDirURLObj( aDirURLStr );
BOOL bRoot = FALSE;
// Check if it's a root directory
sal_Int32 nCount = aDirURLObj.getSegmentCount();
// No segment means Unix root directory "file:///"
if( nCount == 0 )
{
bRoot = TRUE;
}
// Exactly one segment needs further checking, because it
// can be Unix "file:///foo/" -> no root
// or Windows "file:///c:/" -> root
else if( nCount == 1 )
{
OUString aSeg1 = aDirURLObj.getName( 0, TRUE,
INetURLObject::DECODE_WITH_CHARSET );
if( aSeg1.getStr()[1] == (sal_Unicode)':' )
{
bRoot = TRUE;
}
}
// More than one segments can never be root
// so bRoot remains FALSE
// If it's no root directory we flag the need for
// the "." and ".." directories by the value -2
// for the actual position. Later for -2 will be
// returned "." and for -1 ".."
if( !bRoot )
{
pRTLData->nCurDirPos = -2;
}
}
2000-09-18 15:18:56 +00:00
}
catch( Exception & )
{
//StarBASIC::Error( ERRCODE_IO_GENERAL );
}
}
if( pRTLData->aDirSeq.getLength() > 0 )
{
sal_Bool bOnlyFolders = ((pRTLData->nDirFlags & Sb_ATTR_DIRECTORY) != 0);
for( ;; )
{
if( pRTLData->nCurDirPos < 0 )
{
if( pRTLData->nCurDirPos == -2 )
{
aPath = OUString::createFromAscii( "." );
}
else if( pRTLData->nCurDirPos == -1 )
{
aPath = OUString::createFromAscii( ".." );
}
pRTLData->nCurDirPos++;
break;
}
else if( pRTLData->nCurDirPos >= pRTLData->aDirSeq.getLength() )
2000-09-18 15:18:56 +00:00
{
pRTLData->aDirSeq.realloc( 0 );
aPath.Erase();
break;
}
else
{
OUString aFile = pRTLData->aDirSeq.getConstArray()[pRTLData->nCurDirPos++];
// Only directories?
if( bOnlyFolders )
{
2001-03-29 14:15:18 +00:00
sal_Bool bFolder = xSFI->isFolder( aFile );
2000-09-18 15:18:56 +00:00
if( !bFolder )
continue;
}
INetURLObject aURL( aFile );
aPath = aURL.getName( INetURLObject::LAST_SEGMENT, TRUE,
2000-09-18 15:18:56 +00:00
INetURLObject::DECODE_WITH_CHARSET );
// #80200 HACK to provide minimum wildcard functionality (*.xxx)
2000-12-08 15:35:54 +00:00
sal_Bool bMatch = implCheckWildcard( aPath, pRTLData );
if( !bMatch )
continue;
// End #80200 HACK
2000-09-18 15:18:56 +00:00
break;
}
}
}
rPar.Get(0)->PutString( aPath );
}
}
else
// --> UCB
{
2000-09-26 08:02:02 +00:00
#ifdef _OLD_FILE_IMPL
2000-09-18 15:18:56 +00:00
if ( nParCount >= 2 )
{
delete pRTLData->pDir;
pRTLData->pDir = 0; // wg. Sonderbehandlung Sb_ATTR_VOLUME
DirEntry aEntry( rPar.Get(1)->GetString() );
FileStat aStat( aEntry );
if(!aStat.GetError() && (aStat.GetKind() & FSYS_KIND_FILE))
{
// ah ja, ist nur ein dateiname
// Pfad abschneiden (wg. VB4)
rPar.Get(0)->PutString( aEntry.GetName() );
return;
}
USHORT nFlags = 0;
if ( nParCount > 2 )
pRTLData->nDirFlags = nFlags = rPar.Get(2)->GetInteger();
else
pRTLData->nDirFlags = 0;
// Nur diese Bitmaske ist unter Windows erlaubt
#ifdef WIN
if( nFlags & ~0x1E )
StarBASIC::Error( SbERR_BAD_ARGUMENT ), pRTLData->nDirFlags = 0;
#endif
// Sb_ATTR_VOLUME wird getrennt gehandelt
if( pRTLData->nDirFlags & Sb_ATTR_VOLUME )
aPath = aEntry.GetVolume();
else
{
// Die richtige Auswahl treffen
USHORT nMode = FSYS_KIND_FILE;
if( nFlags & Sb_ATTR_DIRECTORY )
nMode |= FSYS_KIND_DIR;
if( nFlags == Sb_ATTR_DIRECTORY )
nMode = FSYS_KIND_DIR;
pRTLData->pDir = new Dir( aEntry, (DirEntryKind) nMode );
pRTLData->nCurDirPos = 0;
}
}
if( pRTLData->pDir )
{
for( ;; )
{
if( pRTLData->nCurDirPos >= pRTLData->pDir->Count() )
{
delete pRTLData->pDir;
pRTLData->pDir = 0;
aPath.Erase();
break;
}
DirEntry aNextEntry=(*(pRTLData->pDir))[pRTLData->nCurDirPos++];
aPath = aNextEntry.GetName(); //Full();
#ifdef WIN
aNextEntry.ToAbs();
String sFull(aNextEntry.GetFull());
unsigned nFlags;
if (_dos_getfileattr( sFull.GetStr(), &nFlags ))
StarBASIC::Error( SbERR_FILE_NOT_FOUND );
else
{
INT16 nCurFlags = pRTLData->nDirFlags;
if( (nCurFlags == Sb_ATTR_NORMAL)
&& !(nFlags & ( _A_HIDDEN | _A_SYSTEM | _A_VOLID | _A_SUBDIR ) ) )
break;
else if( (nCurFlags & Sb_ATTR_HIDDEN) && (nFlags & _A_HIDDEN) )
break;
else if( (nCurFlags & Sb_ATTR_SYSTEM) && (nFlags & _A_SYSTEM) )
break;
else if( (nCurFlags & Sb_ATTR_VOLUME) && (nFlags & _A_VOLID) )
break;
else if( (nCurFlags & Sb_ATTR_DIRECTORY) && (nFlags & _A_SUBDIR) )
break;
}
#else
break;
#endif
}
}
rPar.Get(0)->PutString( aPath );
2000-09-26 08:02:02 +00:00
#else
// TODO: OSL
if ( nParCount >= 2 )
{
2000-12-08 15:35:54 +00:00
String aFileParam = rPar.Get(1)->GetString();
2000-09-26 08:02:02 +00:00
2000-12-08 15:35:54 +00:00
// #80200 HACK to provide minimum wildcard functionality
2001-03-29 14:15:18 +00:00
Reference< XSimpleFileAccess > xSFI;
2000-12-08 15:35:54 +00:00
String aDirUNCStr = implSetupWildcard( aFileParam, pRTLData, sal_True );
2000-09-26 08:02:02 +00:00
USHORT nFlags = 0;
if ( nParCount > 2 )
pRTLData->nDirFlags = nFlags = rPar.Get(2)->GetInteger();
else
pRTLData->nDirFlags = 0;
// Read directory
//sal_Bool bIncludeFolders = ((nFlags & Sb_ATTR_DIRECTORY) != 0);
pRTLData->pDir = new Directory( aDirUNCStr );
2000-12-08 15:35:54 +00:00
FileBase::RC nRet = pRTLData->pDir->open();
2000-09-26 08:02:02 +00:00
if( nRet != FileBase::RC::E_None )
{
delete pRTLData->pDir;
pRTLData->pDir = NULL;
rPar.Get(0)->PutString( String() );
return;
}
//pRTLData->nCurDirPos = 0;
}
if( pRTLData->pDir )
{
sal_Bool bOnlyFolders = ((pRTLData->nDirFlags & Sb_ATTR_DIRECTORY) != 0);
for( ;; )
{
DirectoryItem aItem;
FileBase::RC nRet = pRTLData->pDir->getNextItem( aItem );
if( nRet != FileBase::RC::E_None )
{
delete pRTLData->pDir;
pRTLData->pDir = NULL;
aPath.Erase();
break;
}
// Handle flags
FileStatus aFileStatus( FileStatusMask_Type | FileStatusMask_FileName );
nRet = aItem.getFileStatus( aFileStatus );
// Only directories?
if( bOnlyFolders )
{
FileStatus::Type aType = aFileStatus.getFileType();
sal_Bool bFolder = (aType == FileStatus::Type::Directory);
if( !bFolder )
continue;
}
aPath = aFileStatus.getFileName();
2000-12-08 15:35:54 +00:00
// #80200 HACK to provide minimum wildcard functionality (*.xxx)
sal_Bool bMatch = implCheckWildcard( aPath, pRTLData );
if( !bMatch )
continue;
// End #80200 HACK
2000-09-26 08:02:02 +00:00
break;
}
}
rPar.Get(0)->PutString( aPath );
#endif
2000-09-18 15:18:56 +00:00
}
}
}
RTLFUNC(GetAttr)
{
if ( rPar.Count() == 2 )
{
INT16 nFlags = 0;
// <-- UCB
if( hasUno() )
{
Reference< XSimpleFileAccess > xSFI = getFileAccess();
if( xSFI.is() )
{
try
{
String aPath = getFullPath( rPar.Get(1)->GetString() );
sal_Bool bExists = sal_False;
try { bExists = xSFI->exists( aPath ); }
catch( Exception & ) {}
if( !bExists )
{
StarBASIC::Error( SbERR_FILE_NOT_FOUND );
return;
}
sal_Bool bReadOnly = xSFI->isReadOnly( aPath );
sal_Bool bDirectory = xSFI->isFolder( aPath );
if( bReadOnly )
nFlags |= 0x0001; // ATTR_READONLY
if( bDirectory )
nFlags |= 0x0010; // ATTR_DIRECTORY
}
catch( Exception & )
{
StarBASIC::Error( ERRCODE_IO_GENERAL );
}
}
}
else
// --> UCB
{
2000-09-26 08:02:02 +00:00
#ifdef _OLD_FILE_IMPL
2000-09-18 15:18:56 +00:00
DirEntry aEntry( rPar.Get(1)->GetString() );
aEntry.ToAbs();
BOOL bUseFileStat = FALSE;
// #57064 Bei virtuellen URLs den Real-Path extrahieren
String aFile = aEntry.GetFull();
ByteString aByteStrFullPath( aEntry.GetFull(), gsl_getSystemTextEncoding() );
#if defined( WIN )
int nErr = _dos_getfileattr( aByteStrFullPath.GetBuffer(),(unsigned *) &nFlags );
if ( nErr )
StarBASIC::Error( SbERR_FILE_NOT_FOUND );
#elif defined( WNT )
DWORD nRealFlags = GetFileAttributes (aByteStrFullPath.GetBuffer());
if (nRealFlags != 0xffffffff)
{
if (nRealFlags == FILE_ATTRIBUTE_NORMAL)
nRealFlags = 0;
nFlags = (INT16) (nRealFlags);
}
else
StarBASIC::Error( SbERR_FILE_NOT_FOUND );
#elif defined( OS2 )
FILESTATUS3 aFileStatus;
APIRET rc = DosQueryPathInfo(aByteStrFullPath.GetBuffer(),1,
&aFileStatus,sizeof(FILESTATUS3));
if (!rc)
nFlags = (INT16) aFileStatus.attrFile;
else
StarBASIC::Error( SbERR_FILE_NOT_FOUND );
#else
bUseFileStat = TRUE;
#endif
if( bUseFileStat )
{
if( FileStat::GetReadOnlyFlag( aEntry ) )
nFlags |= 0x0001; // ATTR_READONLY
FileStat aStat( aEntry );
DirEntryKind eKind = aStat.GetKind();
if( eKind & FSYS_KIND_DIR )
nFlags |= 0x0010; // ATTR_DIRECTORY
if( aEntry.GetFlag() & FSYS_FLAG_VOLUME )
nFlags |= 0x0008; // ATTR_VOLUME
}
2000-09-26 08:02:02 +00:00
#else
DirectoryItem aItem;
FileBase::RC nRet = DirectoryItem::get( getFullPathUNC( rPar.Get(1)->GetString() ), aItem );
FileStatus aFileStatus( FileStatusMask_Attributes | FileStatusMask_Type );
nRet = aItem.getFileStatus( aFileStatus );
sal_uInt64 nAttributes = aFileStatus.getAttributes();
sal_Bool bReadOnly = (nAttributes & Attribute_ReadOnly) != 0;
FileStatus::Type aType = aFileStatus.getFileType();
sal_Bool bDirectory = (aType == FileStatus::Type::Directory);
if( bReadOnly )
nFlags |= 0x0001; // ATTR_READONLY
if( bDirectory )
nFlags |= 0x0010; // ATTR_DIRECTORY
#endif
2000-09-18 15:18:56 +00:00
}
rPar.Get(0)->PutInteger( nFlags );
}
else
StarBASIC::Error( SbERR_BAD_ARGUMENT );
}
RTLFUNC(FileDateTime)
{
if ( rPar.Count() != 2 )
StarBASIC::Error( SbERR_BAD_ARGUMENT );
else
{
// <-- UCB
String aPath = rPar.Get(1)->GetString();
Time aTime;
Date aDate;
if( hasUno() )
{
Reference< XSimpleFileAccess > xSFI = getFileAccess();
if( xSFI.is() )
{
try
{
com::sun::star::util::DateTime aUnoDT = xSFI->getDateTimeModified( aPath );
aTime = Time( aUnoDT.Hours, aUnoDT.Minutes, aUnoDT.Seconds, aUnoDT.HundredthSeconds );
aDate = Date( aUnoDT.Day, aUnoDT.Month, aUnoDT.Year );
}
catch( Exception & )
{
StarBASIC::Error( ERRCODE_IO_GENERAL );
}
}
}
else
// --> UCB
{
2000-09-26 08:02:02 +00:00
#ifdef _OLD_FILE_IMPL
2000-09-18 15:18:56 +00:00
DirEntry aEntry( aPath );
FileStat aStat( aEntry );
aTime = Time( aStat.TimeModified() );
aDate = Date( aStat.DateModified() );
2000-09-26 08:02:02 +00:00
#else
DirectoryItem aItem;
FileBase::RC nRet = DirectoryItem::get( getFullPathUNC( aPath ), aItem );
FileStatus aFileStatus( FileStatusMask_ModifyTime );
nRet = aItem.getFileStatus( aFileStatus );
TimeValue aTimeVal = aFileStatus.getModifyTime();
oslDateTime aDT;
sal_Bool bRet = osl_getDateTimeFromTimeValue( &aTimeVal, &aDT );
aTime = Time( aDT.Hours, aDT.Minutes, aDT.Seconds, 10000000*aDT.NanoSeconds );
aDate = Date( aDT.Day, aDT.Month, aDT.Year );
#endif
2000-09-18 15:18:56 +00:00
}
double fSerial = (double)GetDayDiff( aDate );
long nSeconds = aTime.GetHour();
nSeconds *= 3600;
nSeconds += aTime.GetMin() * 60;
nSeconds += aTime.GetSec();
double nDays = ((double)nSeconds) / (double)(24.0*3600.0);
fSerial += nDays;
Color* pCol;
// #39629 pINST pruefen, kann aus URL-Zeile gerufen werden
SvNumberFormatter* pFormatter = NULL;
ULONG nIndex;
if( pINST )
{
pFormatter = pINST->GetNumberFormatter();
nIndex = pINST->GetStdDateTimeIdx();
}
else
{
ULONG n; // Dummy
SbiInstance::PrepareNumberFormatter( pFormatter, n, n, nIndex );
}
String aRes;
pFormatter->GetOutputString( fSerial, nIndex, aRes, &pCol );
rPar.Get(0)->PutString( aRes );
// #39629 pFormatter kann selbst angefordert sein
if( !pINST )
delete pFormatter;
}
}
RTLFUNC(EOF)
{
// AB 08/16/2000: No changes for UCB
if ( rPar.Count() != 2 )
StarBASIC::Error( SbERR_BAD_ARGUMENT );
else
{
INT16 nChannel = rPar.Get(1)->GetInteger();
// nChannel--; // macht MD beim Oeffnen auch nicht
SbiIoSystem* pIO = pINST->GetIoSystem();
SbiStream* pSbStrm = pIO->GetStream( nChannel );
if ( !pSbStrm )
{
StarBASIC::Error( SbERR_BAD_CHANNEL );
return;
}
BOOL bIsEof;
SvStream* pSvStrm = pSbStrm->GetStrm();
if ( pSbStrm->IsText() )
{
char cBla;
(*pSvStrm) >> cBla; // koennen wir noch ein Zeichen lesen
bIsEof = pSvStrm->IsEof();
if ( !bIsEof )
pSvStrm->SeekRel( -1 );
}
else
bIsEof = pSvStrm->IsEof(); // fuer binaerdateien!
rPar.Get(0)->PutBool( bIsEof );
}
}
RTLFUNC(FileAttr)
{
// AB 08/16/2000: No changes for UCB
// #57064 Obwohl diese Funktion nicht mit DirEntry arbeitet, ist sie von
// der Anpassung an virtuelle URLs nich betroffen, da sie nur auf bereits
// geoeffneten Dateien arbeitet und der Name hier keine Rolle spielt.
if ( rPar.Count() != 3 )
StarBASIC::Error( SbERR_BAD_ARGUMENT );
else
{
INT16 nChannel = rPar.Get(1)->GetInteger();
// nChannel--;
SbiIoSystem* pIO = pINST->GetIoSystem();
SbiStream* pSbStrm = pIO->GetStream( nChannel );
if ( !pSbStrm )
{
StarBASIC::Error( SbERR_BAD_CHANNEL );
return;
}
INT16 nRet;
if ( rPar.Get(2)->GetInteger() == 1 )
nRet = (INT16)(pSbStrm->GetMode());
else
nRet = 0; // System file handle not supported
rPar.Get(0)->PutInteger( nRet );
}
}
RTLFUNC(Loc)
{
// AB 08/16/2000: No changes for UCB
if ( rPar.Count() != 2 )
StarBASIC::Error( SbERR_BAD_ARGUMENT );
else
{
INT16 nChannel = rPar.Get(1)->GetInteger();
SbiIoSystem* pIO = pINST->GetIoSystem();
SbiStream* pSbStrm = pIO->GetStream( nChannel );
if ( !pSbStrm )
{
StarBASIC::Error( SbERR_BAD_CHANNEL );
return;
}
SvStream* pSvStrm = pSbStrm->GetStrm();
ULONG nPos;
if( pSbStrm->IsRandom())
{
short nBlockLen = pSbStrm->GetBlockLen();
nPos = nBlockLen ? (pSvStrm->Tell() / nBlockLen) : 0;
nPos++; // Blockpositionen beginnen bei 1
}
else if ( pSbStrm->IsText() )
nPos = pSbStrm->GetLine();
else if( pSbStrm->IsBinary() )
nPos = pSvStrm->Tell();
else if ( pSbStrm->IsSeq() )
nPos = ( pSvStrm->Tell()+1 ) / 128;
else
nPos = pSvStrm->Tell();
rPar.Get(0)->PutLong( (INT32)nPos );
}
}
RTLFUNC(Lof)
{
// AB 08/16/2000: No changes for UCB
if ( rPar.Count() != 2 )
StarBASIC::Error( SbERR_BAD_ARGUMENT );
else
{
INT16 nChannel = rPar.Get(1)->GetInteger();
SbiIoSystem* pIO = pINST->GetIoSystem();
SbiStream* pSbStrm = pIO->GetStream( nChannel );
if ( !pSbStrm )
{
StarBASIC::Error( SbERR_BAD_CHANNEL );
return;
}
SvStream* pSvStrm = pSbStrm->GetStrm();
ULONG nOldPos = pSvStrm->Tell();
ULONG nLen = pSvStrm->Seek( STREAM_SEEK_TO_END );
pSvStrm->Seek( nOldPos );
rPar.Get(0)->PutLong( (INT32)nLen );
}
}
RTLFUNC(Seek)
{
// AB 08/16/2000: No changes for UCB
int nArgs = (int)rPar.Count();
if ( nArgs < 2 || nArgs > 3 )
{
StarBASIC::Error( SbERR_BAD_ARGUMENT );
return;
}
INT16 nChannel = rPar.Get(1)->GetInteger();
// nChannel--;
SbiIoSystem* pIO = pINST->GetIoSystem();
SbiStream* pSbStrm = pIO->GetStream( nChannel );
if ( !pSbStrm )
{
StarBASIC::Error( SbERR_BAD_CHANNEL );
return;
}
SvStream* pStrm = pSbStrm->GetStrm();
if ( nArgs == 2 ) // Seek-Function
{
ULONG nPos = pStrm->Tell();
if( pSbStrm->IsRandom() )
nPos = nPos / pSbStrm->GetBlockLen();
nPos++; // Basic zaehlt ab 1
rPar.Get(0)->PutLong( (INT32)nPos );
}
else // Seek-Statement
{
INT32 nPos = rPar.Get(2)->GetLong();
if ( nPos < 1 )
{
StarBASIC::Error( SbERR_BAD_ARGUMENT );
return;
}
nPos--; // Basic zaehlt ab 1, SvStreams zaehlen ab 0
pSbStrm->SetExpandOnWriteTo( 0 );
if ( pSbStrm->IsRandom() )
nPos *= pSbStrm->GetBlockLen();
pStrm->Seek( (ULONG)nPos );
pSbStrm->SetExpandOnWriteTo( nPos );
}
}
RTLFUNC(Format)
{
USHORT nArgCount = (USHORT)rPar.Count();
if ( nArgCount < 2 || nArgCount > 3 )
StarBASIC::Error( SbERR_BAD_ARGUMENT );
else
{
String aResult;
if( nArgCount == 2 )
rPar.Get(1)->Format( aResult );
else
{
String aFmt( rPar.Get(2)->GetString() );
rPar.Get(1)->Format( aResult, &aFmt );
}
rPar.Get(0)->PutString( aResult );
}
}
RTLFUNC(Randomize)
{
if ( rPar.Count() > 2 )
StarBASIC::Error( SbERR_BAD_ARGUMENT );
INT16 nSeed;
if( rPar.Count() == 2 )
nSeed = (INT16)rPar.Get(1)->GetInteger();
else
nSeed = (INT16)rand();
srand( nSeed );
}
RTLFUNC(Rnd)
{
if ( rPar.Count() > 2 )
StarBASIC::Error( SbERR_BAD_ARGUMENT );
else
{
double nRand = (double)rand();
nRand = ( nRand / (double)RAND_MAX );
rPar.Get(0)->PutDouble( nRand );
}
}
//
// Syntax: Shell("Path",[ Window-Style,[ "Params", [ bSync = FALSE ]]])
//
// WindowStyles (VBA-kompatibel):
// 2 == Minimized
// 3 == Maximized
// 10 == Full-Screen (Textmodus-Anwendungen OS/2, WIN95, WNT)
//
// !!!HACK der WindowStyle wird im Creator an Application::StartApp
// uebergeben. Format: "xxxx2"
//
RTLFUNC(Shell)
{
// No shell command for "virtual" portal users
if( needSecurityRestrictions() )
{
StarBASIC::Error(SbERR_NOT_IMPLEMENTED);
return;
}
if ( rPar.Count() < 2 || rPar.Count() > 5 )
{
rPar.Get(0)->PutLong(0);
StarBASIC::Error( SbERR_BAD_ARGUMENT );
}
else
{
USHORT nOptions = NAMESPACE_VOS(OProcess)::TOption_SearchPath|
NAMESPACE_VOS(OProcess)::TOption_Detached;
String aCmdLine = rPar.Get(1)->GetString();
// Zusaetzliche Parameter anhaengen, es muss eh alles geparsed werden
if( rPar.Count() >= 4 )
{
aCmdLine.AppendAscii( " " );
aCmdLine += rPar.Get(3)->GetString();
}
else if( !aCmdLine.Len() )
{
// Spezial-Behandlung (leere Liste) vermeiden
aCmdLine.AppendAscii( " " );
}
USHORT nLen = aCmdLine.Len();
// #55735 Wenn Parameter dabei sind, muessen die abgetrennt werden
// #72471 Auch die einzelnen Parameter trennen
std::list<String> aTokenList;
String aToken;
USHORT i = 0;
char c;
while( i < nLen )
{
// Spaces weg
while( ( c = aCmdLine.GetBuffer()[ i ] ) == ' ' || c == '\t' )
i++;
if( c == '\"' || c == '\'' )
{
USHORT iFoundPos = aCmdLine.Search( c, i + 1 );
// Wenn nichts gefunden wurde, Rest kopieren
if( iFoundPos == STRING_NOTFOUND )
{
aToken = aCmdLine.Copy( i, STRING_LEN );
i = nLen;
}
else
{
aToken = aCmdLine.Copy( i + 1, (iFoundPos - i - 1) );
i = iFoundPos + 1;
}
}
else
{
USHORT iFoundSpacePos = aCmdLine.Search( ' ', i );
USHORT iFoundTabPos = aCmdLine.Search( '\t', i );
USHORT iFoundPos = Min( iFoundSpacePos, iFoundTabPos );
// Wenn nichts gefunden wurde, Rest kopieren
if( iFoundPos == STRING_NOTFOUND )
{
aToken = aCmdLine.Copy( i, STRING_LEN );
i = nLen;
}
else
{
aToken = aCmdLine.Copy( i, (iFoundPos - i) );
i = iFoundPos;
}
}
// In die Liste uebernehmen
aTokenList.push_back( aToken );
}
// #55735 / #72471 Ende
INT16 nWinStyle = 0;
if( rPar.Count() >= 3 )
{
nWinStyle = rPar.Get(2)->GetInteger();
switch( nWinStyle )
{
case 2:
nOptions |= NAMESPACE_VOS(OProcess)::TOption_Minimized;
break;
case 3:
nOptions |= NAMESPACE_VOS(OProcess)::TOption_Maximized;
break;
case 10:
nOptions |= NAMESPACE_VOS(OProcess)::TOption_FullScreen;
break;
}
}
NAMESPACE_VOS(OProcess)::TProcessOption eOptions =
(NAMESPACE_VOS(OProcess)::TProcessOption)nOptions;
// #72471 Parameter aufbereiten
std::list<String>::const_iterator iter = aTokenList.begin();
const String& rStr = *iter;
2001-03-21 14:07:28 +00:00
::rtl::OUString aOUStrProg( rStr.GetBuffer(), rStr.Len() );
String aOUStrProgUNC = getFullPathUNC( aOUStrProg );
2000-09-18 15:18:56 +00:00
iter++;
USHORT nParamCount = aTokenList.size() - 1;
2001-03-21 14:07:28 +00:00
::rtl::OUString* pArgumentList = NULL;
2000-09-18 15:18:56 +00:00
//const char** pParamList = NULL;
if( nParamCount )
{
2001-03-21 14:07:28 +00:00
pArgumentList = new ::rtl::OUString[ nParamCount ];
2000-09-18 15:18:56 +00:00
//pParamList = new const char*[ nParamCount ];
USHORT iList = 0;
while( iter != aTokenList.end() )
{
const String& rParamStr = (*iter);
2001-03-21 14:07:28 +00:00
pArgumentList[iList++] = ::rtl::OUString( rParamStr.GetBuffer(), rParamStr.Len() );
2000-09-18 15:18:56 +00:00
//pParamList[iList++] = (*iter).GetStr();
iter++;
}
}
//const char* pParams = aParams.Len() ? aParams.GetStr() : 0;
NAMESPACE_VOS(OProcess)* pApp;
pApp = new NAMESPACE_VOS(OProcess)( aOUStrProgUNC );
2000-09-18 15:18:56 +00:00
BOOL bSucc;
if( nParamCount == 0 )
{
bSucc = pApp->execute( eOptions ) == NAMESPACE_VOS(OProcess)::E_None;
}
else
{
NAMESPACE_VOS(OArgumentList) aArgList( pArgumentList, nParamCount );
bSucc = pApp->execute( eOptions, aArgList ) == NAMESPACE_VOS(OProcess)::E_None;
}
/*
if( nParamCount == 0 )
pApp = new NAMESPACE_VOS(OProcess)( pProg );
else
pApp = new NAMESPACE_VOS(OProcess)( pProg, pParamList, nParamCount );
BOOL bSucc = pApp->execute( eOptions ) == NAMESPACE_VOS(OProcess)::E_None;
*/
delete pApp;
delete[] pArgumentList;
if( !bSucc )
StarBASIC::Error( SbERR_FILE_NOT_FOUND );
else
rPar.Get(0)->PutLong( 0 );
}
}
RTLFUNC(VarType)
{
if ( rPar.Count() != 2 )
StarBASIC::Error( SbERR_BAD_ARGUMENT );
else
{
SbxDataType eType = rPar.Get(1)->GetType();
rPar.Get(0)->PutInteger( (INT16)eType );
}
}
RTLFUNC(TypeName)
{
static const char* pTypeNames[] =
{
"Empty",
"Null",
"Integer",
"Long",
"Single",
"Double",
"Currency",
"Date",
"String",
"Object",
"Error",
"Boolean",
"Variant",
"DataObject",
"Unknown Type",
"Unknown Type",
"Char",
"Byte",
"UShort",
"ULong",
"Long64",
"ULong64",
"Int",
"UInt",
"Void",
"HResult",
"Pointer",
"DimArray",
"CArray",
"Userdef",
"Lpstr",
"Lpwstr",
"Unknown Type",
};
if ( rPar.Count() != 2 )
StarBASIC::Error( SbERR_BAD_ARGUMENT );
else
{
SbxDataType eType = rPar.Get(1)->GetType();
BOOL bIsArray = ( ( eType & SbxARRAY ) != 0 );
int nPos = ((int)eType) & 0x0FFF;
USHORT nTypeNameCount = sizeof( pTypeNames ) / sizeof( char* );
if ( nPos < 0 || nPos >= nTypeNameCount )
nPos = nTypeNameCount - 1;
String aRetStr = String::CreateFromAscii( pTypeNames[nPos] );
if( bIsArray )
aRetStr.AppendAscii( "()" );
rPar.Get(0)->PutString( aRetStr );
}
}
RTLFUNC(Len)
{
if ( rPar.Count() != 2 )
StarBASIC::Error( SbERR_BAD_ARGUMENT );
else
{
const String& rStr = rPar.Get(1)->GetString();
rPar.Get(0)->PutLong( (INT32)rStr.Len() );
}
}
RTLFUNC(DDEInitiate)
{
// No DDE for "virtual" portal users
if( needSecurityRestrictions() )
{
StarBASIC::Error(SbERR_NOT_IMPLEMENTED);
return;
}
int nArgs = (int)rPar.Count();
if ( nArgs != 3 )
{
StarBASIC::Error( SbERR_BAD_ARGUMENT );
return;
}
const String& rApp = rPar.Get(1)->GetString();
const String& rTopic = rPar.Get(2)->GetString();
SbiDdeControl* pDDE = pINST->GetDdeControl();
INT16 nChannel;
SbError nDdeErr = pDDE->Initiate( rApp, rTopic, nChannel );
if( nDdeErr )
StarBASIC::Error( nDdeErr );
else
rPar.Get(0)->PutInteger( nChannel );
}
RTLFUNC(DDETerminate)
{
// No DDE for "virtual" portal users
if( needSecurityRestrictions() )
{
StarBASIC::Error(SbERR_NOT_IMPLEMENTED);
return;
}
rPar.Get(0)->PutEmpty();
int nArgs = (int)rPar.Count();
if ( nArgs != 2 )
{
StarBASIC::Error( SbERR_BAD_ARGUMENT );
return;
}
INT16 nChannel = rPar.Get(1)->GetInteger();
SbiDdeControl* pDDE = pINST->GetDdeControl();
SbError nDdeErr = pDDE->Terminate( nChannel );
if( nDdeErr )
StarBASIC::Error( nDdeErr );
}
RTLFUNC(DDETerminateAll)
{
// No DDE for "virtual" portal users
if( needSecurityRestrictions() )
{
StarBASIC::Error(SbERR_NOT_IMPLEMENTED);
return;
}
rPar.Get(0)->PutEmpty();
int nArgs = (int)rPar.Count();
if ( nArgs != 1 )
{
StarBASIC::Error( SbERR_BAD_ARGUMENT );
return;
}
SbiDdeControl* pDDE = pINST->GetDdeControl();
SbError nDdeErr = pDDE->TerminateAll();
if( nDdeErr )
StarBASIC::Error( nDdeErr );
}
RTLFUNC(DDERequest)
{
// No DDE for "virtual" portal users
if( needSecurityRestrictions() )
{
StarBASIC::Error(SbERR_NOT_IMPLEMENTED);
return;
}
int nArgs = (int)rPar.Count();
if ( nArgs != 3 )
{
StarBASIC::Error( SbERR_BAD_ARGUMENT );
return;
}
INT16 nChannel = rPar.Get(1)->GetInteger();
const String& rItem = rPar.Get(2)->GetString();
SbiDdeControl* pDDE = pINST->GetDdeControl();
String aResult;
SbError nDdeErr = pDDE->Request( nChannel, rItem, aResult );
if( nDdeErr )
StarBASIC::Error( nDdeErr );
else
rPar.Get(0)->PutString( aResult );
}
RTLFUNC(DDEExecute)
{
// No DDE for "virtual" portal users
if( needSecurityRestrictions() )
{
StarBASIC::Error(SbERR_NOT_IMPLEMENTED);
return;
}
rPar.Get(0)->PutEmpty();
int nArgs = (int)rPar.Count();
if ( nArgs != 3 )
{
StarBASIC::Error( SbERR_BAD_ARGUMENT );
return;
}
INT16 nChannel = rPar.Get(1)->GetInteger();
const String& rCommand = rPar.Get(2)->GetString();
SbiDdeControl* pDDE = pINST->GetDdeControl();
SbError nDdeErr = pDDE->Execute( nChannel, rCommand );
if( nDdeErr )
StarBASIC::Error( nDdeErr );
}
RTLFUNC(DDEPoke)
{
// No DDE for "virtual" portal users
if( needSecurityRestrictions() )
{
StarBASIC::Error(SbERR_NOT_IMPLEMENTED);
return;
}
rPar.Get(0)->PutEmpty();
int nArgs = (int)rPar.Count();
if ( nArgs != 4 )
{
StarBASIC::Error( SbERR_BAD_ARGUMENT );
return;
}
INT16 nChannel = rPar.Get(1)->GetInteger();
const String& rItem = rPar.Get(2)->GetString();
const String& rData = rPar.Get(3)->GetString();
SbiDdeControl* pDDE = pINST->GetDdeControl();
SbError nDdeErr = pDDE->Poke( nChannel, rItem, rData );
if( nDdeErr )
StarBASIC::Error( nDdeErr );
}
RTLFUNC(FreeFile)
{
if ( rPar.Count() != 1 )
{
StarBASIC::Error( SbERR_BAD_ARGUMENT );
return;
}
SbiIoSystem* pIO = pINST->GetIoSystem();
short nChannel = 1;
while( nChannel < CHANNELS )
{
SbiStream* pStrm = pIO->GetStream( nChannel );
if( !pStrm )
{
rPar.Get(0)->PutInteger( nChannel );
return;
}
nChannel++;
}
StarBASIC::Error( SbERR_TOO_MANY_FILES );
}
RTLFUNC(LBound)
{
USHORT nParCount = rPar.Count();
if ( nParCount != 3 && nParCount != 2 )
{
StarBASIC::Error( SbERR_BAD_ARGUMENT );
return;
}
SbxBase* pParObj = rPar.Get(1)->GetObject();
SbxDimArray* pArr = PTR_CAST(SbxDimArray,pParObj);
if( pArr )
{
short nLower, nUpper;
short nDim = (nParCount == 3) ? (short)rPar.Get(2)->GetInteger() : 1;
if( !pArr->GetDim( nDim, nLower, nUpper ) )
StarBASIC::Error( SbERR_OUT_OF_RANGE );
else
rPar.Get(0)->PutInteger( (INT16)nLower );
}
else
StarBASIC::Error( SbERR_MUST_HAVE_DIMS );
}
RTLFUNC(UBound)
{
USHORT nParCount = rPar.Count();
if ( nParCount != 3 && nParCount != 2 )
{
StarBASIC::Error( SbERR_BAD_ARGUMENT );
return;
}
SbxBase* pParObj = rPar.Get(1)->GetObject();
SbxDimArray* pArr = PTR_CAST(SbxDimArray,pParObj);
if( pArr )
{
short nLower, nUpper;
short nDim = (nParCount == 3) ? (short)rPar.Get(2)->GetInteger() : 1;
if( !pArr->GetDim( nDim, nLower, nUpper ) )
StarBASIC::Error( SbERR_OUT_OF_RANGE );
else
rPar.Get(0)->PutInteger( (INT16)nUpper );
}
else
StarBASIC::Error( SbERR_MUST_HAVE_DIMS );
}
RTLFUNC(RGB)
{
if ( rPar.Count() != 4 )
{
StarBASIC::Error( SbERR_BAD_ARGUMENT );
return;
}
ULONG nRed = rPar.Get(1)->GetInteger() & 0xFF;
ULONG nGreen = rPar.Get(2)->GetInteger() & 0xFF;
ULONG nBlue = rPar.Get(3)->GetInteger() & 0xFF;
ULONG nRGB = (nRed << 16) | (nGreen << 8) | nBlue;
rPar.Get(0)->PutLong( nRGB );
}
RTLFUNC(QBColor)
{
if ( rPar.Count() != 2 )
{
StarBASIC::Error( SbERR_BAD_ARGUMENT );
return;
}
Color aCol( (ColorName)rPar.Get(1)->GetInteger() );
ULONG nRed = aCol.GetRed() >> 8;
ULONG nGreen = aCol.GetGreen() >> 8;
ULONG nBlue = aCol.GetBlue() >> 8;
ULONG nRGB = (nRed << 16) | (nGreen << 8) | nBlue;
rPar.Get(0)->PutLong( nRGB );
}
RTLFUNC(StrConv)
{
DBG_ASSERT(0,"StrConv:Not implemented");
// if ( rPar.Count() != 3 )
// {
StarBASIC::Error( SbERR_BAD_ARGUMENT );
// return;
// }
}
RTLFUNC(Beep)
{
if ( rPar.Count() != 1 )
{
StarBASIC::Error( SbERR_BAD_ARGUMENT );
return;
}
Sound::Beep();
}
RTLFUNC(Load)
{
if( rPar.Count() != 2 )
{
StarBASIC::Error( SbERR_BAD_ARGUMENT );
return;
}
// Diesen Call einfach an das Object weiterreichen
SbxBase* pObj = (SbxObject*)rPar.Get(1)->GetObject();
if( pObj && pObj->IsA( TYPE( SbxObject ) ) )
{
SbxVariable* pVar = ((SbxObject*)pObj)->
Find( String( RTL_CONSTASCII_USTRINGPARAM("Load") ), SbxCLASS_METHOD );
if( pVar )
pVar->GetInteger();
}
}
RTLFUNC(Unload)
{
rPar.Get(0)->PutEmpty();
if( rPar.Count() != 2 )
{
StarBASIC::Error( SbERR_BAD_ARGUMENT );
return;
}
// Diesen Call einfach an das Object weitereichen
SbxBase* pObj = (SbxObject*)rPar.Get(1)->GetObject();
if( pObj && pObj->IsA( TYPE( SbxObject ) ) )
{
SbxVariable* pVar = ((SbxObject*)pObj)->
Find( String( RTL_CONSTASCII_USTRINGPARAM("Unload") ), SbxCLASS_METHOD );
if( pVar )
pVar->GetInteger();
}
}
RTLFUNC(LoadPicture)
{
if( rPar.Count() != 2 )
{
StarBASIC::Error( SbERR_BAD_ARGUMENT );
return;
}
String aFileURL = getFullPath( rPar.Get(1)->GetString() );
SvStream* pStream = utl::UcbStreamHelper::CreateStream( aFileURL, STREAM_READ );
if( pStream != NULL )
{
Bitmap aBmp;
*pStream >> aBmp;
Graphic aGraphic( aBmp );
2000-09-18 15:18:56 +00:00
SbxObjectRef xRef = new SbStdPicture;
((SbStdPicture*)(SbxObject*)xRef)->SetGraphic( aGraphic );
rPar.Get(0)->PutObject( xRef );
}
delete pStream;
2000-09-18 15:18:56 +00:00
}
RTLFUNC(SavePicture)
{
rPar.Get(0)->PutEmpty();
if( rPar.Count() != 3 )
{
StarBASIC::Error( SbERR_BAD_ARGUMENT );
return;
}
SbxBase* pObj = (SbxObject*)rPar.Get(1)->GetObject();
if( pObj->IsA( TYPE( SbStdPicture ) ) )
{
SvFileStream aOStream( rPar.Get(2)->GetString(), STREAM_WRITE | STREAM_TRUNC );
Graphic aGraphic = ((SbStdPicture*)pObj)->GetGraphic();
aOStream << aGraphic;
}
}
//-----------------------------------------------------------------------------------------
/*
class SbiAboutStarBasicDlg : public ModalDialog
{
OKButton aOkButton;
Control aCtrl;
public:
SbiAboutStarBasicDlg();
};
SbiAboutStarBasicDlg::SbiAboutStarBasicDlg() :
ModalDialog( GetpApp()->GetAppWindow(), BasicResId( RID_BASIC_START ) ),
aOkButton( this, BasicResId( 1 ) ),
aCtrl( this, BasicResId( 1 ) )
{
FreeResource();
}
*/
//-----------------------------------------------------------------------------------------
RTLFUNC(AboutStarBasic)
{
/*
String aName;
if( rPar.Count() >= 2 )
{
aName = rPar.Get(1)->GetString();
}
SbiAboutStarBasicDlg* pDlg = new SbiAboutStarBasicDlg;
pDlg->Execute();
delete pDlg;
*/
}
// MsgBox( msg [,type[,title]] )
RTLFUNC(MsgBox)
{
static const WinBits nStyleMap[] =
{
WB_OK, // MB_OK
WB_OK_CANCEL, // MB_OKCANCEL
WB_RETRY_CANCEL, // MB_ABORTRETRYIGNORE
WB_YES_NO_CANCEL, // MB_YESNOCANCEL
WB_YES_NO, // MB_YESNO
WB_RETRY_CANCEL // MB_RETRYCANCEL
};
static const INT16 nButtonMap[] =
{
2, // #define RET_CANCEL FALSE
1, // #define RET_OK TRUE
6, // #define RET_YES 2
7, // #define RET_NO 3
4 // #define RET_RETRY 4
};
USHORT nArgCount = (USHORT)rPar.Count();
if( nArgCount < 2 || nArgCount > 4 )
{
StarBASIC::Error( SbERR_BAD_ARGUMENT );
return;
}
WinBits nWinBits;
WinBits nType = 0; // MB_OK
if( nArgCount >= 3 )
nType = (WinBits)rPar.Get(2)->GetInteger();
WinBits nStyle = nType;
nStyle &= 15; // Bits 4-16 loeschen
if( nStyle > 5 )
nStyle = 0;
nWinBits = nStyleMap[ nStyle ];
if( nType & 4096 )
nWinBits |= WB_SYSMODAL;
if( nType & 256 )
{
if( nStyle == 5 || nStyle == 2)
nWinBits |= WB_DEF_CANCEL;
else
nWinBits |= (WB_DEF_CANCEL | WB_DEF_RETRY | WB_DEF_NO);
}
if( nType & 512 )
nWinBits |= WB_DEF_CANCEL;
String aMsg = rPar.Get(1)->GetString();
String aTitle;
if( nArgCount == 4 )
aTitle = rPar.Get(3)->GetString();
else
aTitle = GetpApp()->GetAppName();
nType &= (16+32+64);
MessBox* pBox = 0;
Window* pParent = GetpApp()->GetDefModalDialogParent();
switch( nType )
{
case 16:
pBox = new ErrorBox( pParent, nWinBits, aMsg );
break;
case 32:
pBox = new QueryBox( pParent, nWinBits, aMsg );
break;
case 48:
pBox = new WarningBox( pParent, nWinBits, aMsg );
break;
case 64:
pBox = new InfoBox( pParent, aMsg );
break;
default:
pBox = new MessBox( pParent, nWinBits, aTitle, aMsg );
}
pBox->SetText( aTitle );
USHORT nRet = (USHORT)pBox->Execute();
if( nRet == TRUE )
nRet = 1;
rPar.Get(0)->PutInteger( nButtonMap[ nRet ] );
delete pBox;
}
RTLFUNC(SetAttr) // JSM
{
rPar.Get(0)->PutEmpty();
if ( rPar.Count() == 3 )
{
String aStr = rPar.Get(1)->GetString();
INT16 nFlags = rPar.Get(2)->GetInteger();
// <-- UCB
if( hasUno() )
{
Reference< XSimpleFileAccess > xSFI = getFileAccess();
if( xSFI.is() )
{
try
{
sal_Bool bReadOnly = (nFlags & 0x0001) != 0; // ATTR_READONLY
xSFI->setReadOnly( aStr, bReadOnly );
}
catch( Exception & )
{
StarBASIC::Error( ERRCODE_IO_GENERAL );
}
}
}
else
// --> UCB
{
2000-09-26 08:02:02 +00:00
#ifdef _OLD_FILE_IMPL
2000-09-18 15:18:56 +00:00
// #57064 Bei virtuellen URLs den Real-Path extrahieren
DirEntry aEntry( aStr );
String aFile = aEntry.GetFull();
#ifdef WIN
int nErr = _dos_setfileattr( aFile.GetStr(),(unsigned ) nFlags );
if ( nErr )
{
if (errno == EACCES)
StarBASIC::Error( SbERR_ACCESS_DENIED );
else
StarBASIC::Error( SbERR_FILE_NOT_FOUND );
}
#endif
ByteString aByteFile( aFile, gsl_getSystemTextEncoding() );
#ifdef WNT
if (!SetFileAttributes (aByteFile.GetBuffer(),(DWORD)nFlags))
StarBASIC::Error(SbERR_FILE_NOT_FOUND);
#endif
#ifdef OS2
FILESTATUS3 aFileStatus;
APIRET rc = DosQueryPathInfo(aByteFile.GetBuffer(),1,
&aFileStatus,sizeof(FILESTATUS3));
if (!rc)
{
if (aFileStatus.attrFile != nFlags)
{
aFileStatus.attrFile = nFlags;
rc = DosSetPathInfo(aFile.GetStr(),1,
&aFileStatus,sizeof(FILESTATUS3),0);
if (rc)
StarBASIC::Error( SbERR_FILE_NOT_FOUND );
}
}
else
StarBASIC::Error( SbERR_FILE_NOT_FOUND );
#endif
2000-09-26 08:02:02 +00:00
#else
sal_Bool bReadOnly = (nFlags & 0x0001) != 0; // ATTR_READONLY
sal_uInt64 nAttrs = bReadOnly ? Attribute_ReadOnly : 0;
String aPath = getFullPathUNC( rPar.Get(1)->GetString() );
#endif
2000-09-18 15:18:56 +00:00
}
}
else
StarBASIC::Error( SbERR_BAD_ARGUMENT );
}
RTLFUNC(Reset) // JSM
{
SbiIoSystem* pIO = pINST->GetIoSystem();
if (pIO)
pIO->CloseAll();
}
RTLFUNC(DumpAllObjects)
{
USHORT nArgCount = (USHORT)rPar.Count();
if( nArgCount < 2 || nArgCount > 3 )
StarBASIC::Error( SbERR_BAD_ARGUMENT );
else if( !pBasic )
StarBASIC::Error( SbERR_INTERNAL_ERROR );
else
{
SbxObject* p = pBasic;
while( p->GetParent() )
p = p->GetParent();
SvFileStream aStrm( rPar.Get( 1 )->GetString(),
STREAM_WRITE | STREAM_TRUNC );
p->Dump( aStrm, rPar.Get( 2 )->GetBool() );
aStrm.Close();
if( aStrm.GetError() != SVSTREAM_OK )
StarBASIC::Error( SbERR_IO_ERROR );
}
}
RTLFUNC(FileExists)
{
if ( rPar.Count() == 2 )
{
String aStr = rPar.Get(1)->GetString();
BOOL bExists = FALSE;
// <-- UCB
if( hasUno() )
{
Reference< XSimpleFileAccess > xSFI = getFileAccess();
if( xSFI.is() )
{
try
{
bExists = xSFI->exists( aStr );
}
catch( Exception & )
{
StarBASIC::Error( ERRCODE_IO_GENERAL );
}
}
}
else
// --> UCB
{
2000-09-26 08:02:02 +00:00
#ifdef _OLD_FILE_IMPL
2000-09-18 15:18:56 +00:00
DirEntry aEntry( aStr );
bExists = aEntry.Exists();
2000-09-26 08:02:02 +00:00
#else
DirectoryItem aItem;
FileBase::RC nRet = DirectoryItem::get( getFullPathUNC( aStr ), aItem );
bExists = (nRet == FileBase::RC::E_None);
#endif
2000-09-18 15:18:56 +00:00
}
rPar.Get(0)->PutBool( bExists );
}
else
StarBASIC::Error( SbERR_BAD_ARGUMENT );
}