summaryrefslogtreecommitdiff
path: root/sc/source/filter/excel/excform.cxx
diff options
context:
space:
mode:
Diffstat (limited to 'sc/source/filter/excel/excform.cxx')
-rw-r--r--sc/source/filter/excel/excform.cxx2013
1 files changed, 2013 insertions, 0 deletions
diff --git a/sc/source/filter/excel/excform.cxx b/sc/source/filter/excel/excform.cxx
new file mode 100644
index 000000000000..0652363e8822
--- /dev/null
+++ b/sc/source/filter/excel/excform.cxx
@@ -0,0 +1,2013 @@
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org 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 version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+// MARKER(update_precomp.py): autogen include statement, do not remove
+#include "precompiled_sc.hxx"
+#include "excform.hxx"
+#include <osl/endian.h>
+
+#include "cell.hxx"
+#include "document.hxx"
+#include "rangenam.hxx"
+#include "global.hxx"
+#include "formula/errorcodes.hxx"
+
+#include "imp_op.hxx"
+#include "root.hxx"
+#include "xltracer.hxx"
+#include "xihelper.hxx"
+#include "xilink.hxx"
+#include "xiname.hxx"
+
+using ::std::vector;
+
+const UINT16 ExcelToSc::nRowMask = 0x3FFF;
+const UINT16 ExcelToSc::nLastInd = 399;
+
+
+
+
+void ImportExcel::Formula25()
+{
+ XclAddress aXclPos;
+ UINT16 nXF = 0, nFormLen;
+ double fCurVal;
+ BYTE nAttr0, nFlag0;
+ BOOL bShrFmla;
+
+ aIn >> aXclPos;
+
+ if( GetBiff() == EXC_BIFF2 )
+ {// BIFF2
+ BYTE nDummy;
+
+ aIn.Ignore( 3 );
+
+ aIn >> fCurVal;
+ aIn.Ignore( 1 );
+ aIn >> nDummy;
+ nFormLen = nDummy;
+ bShrFmla = FALSE;
+ nAttr0 = 0x01; // Always calculate
+ }
+ else
+ {// BIFF5
+ aIn >> nXF >> fCurVal >> nFlag0;
+ aIn.Ignore( 5 );
+
+ aIn >> nFormLen;
+
+ bShrFmla = nFlag0 & 0x08; // shared or not shared
+ }
+
+ nLastXF = nXF;
+
+ Formula( aXclPos, nXF, nFormLen, fCurVal, bShrFmla );
+}
+
+
+void ImportExcel::Formula3()
+{
+ Formula4();
+}
+
+
+void ImportExcel::Formula4()
+{
+ XclAddress aXclPos;
+ UINT16 nXF, nFormLen;
+ double fCurVal;
+ BYTE nFlag0;
+
+ aIn >> aXclPos >> nXF >> fCurVal >> nFlag0;
+ aIn.Ignore( 1 );
+ aIn >> nFormLen;
+
+ nLastXF = nXF;
+
+ Formula( aXclPos, nXF, nFormLen, fCurVal, FALSE );
+}
+
+
+void ImportExcel::Formula( const XclAddress& rXclPos,
+ UINT16 nXF, UINT16 nFormLen, double& rCurVal, BOOL bShrFmla )
+{
+ ConvErr eErr = ConvOK;
+
+ ScAddress aScPos( ScAddress::UNINITIALIZED );
+ if( GetAddressConverter().ConvertAddress( aScPos, rXclPos, GetCurrScTab(), true ) )
+ {
+ // jetzt steht Lesemarke auf Formel, Laenge in nFormLen
+ const ScTokenArray* pErgebnis = 0;
+ BOOL bConvert;
+
+ pFormConv->Reset( aScPos );
+
+ if( bShrFmla )
+ bConvert = !pFormConv->GetShrFmla( pErgebnis, maStrm, nFormLen );
+ else
+ bConvert = TRUE;
+
+ if( bConvert )
+ eErr = pFormConv->Convert( pErgebnis, maStrm, nFormLen, true, FT_CellFormula);
+
+ ScFormulaCell* pZelle = NULL;
+
+ if( pErgebnis )
+ {
+ pZelle = new ScFormulaCell( pD, aScPos, pErgebnis );
+ pD->PutCell( aScPos.Col(), aScPos.Row(), aScPos.Tab(), pZelle, (BOOL)TRUE );
+ }
+ else
+ {
+ CellType eCellType;
+ ScBaseCell* pBaseCell;
+ pD->GetCellType( aScPos.Col(), aScPos.Row(), aScPos.Tab(), eCellType );
+ if( eCellType == CELLTYPE_FORMULA )
+ {
+ pD->GetCell( aScPos.Col(), aScPos.Row(), aScPos.Tab(), pBaseCell );
+ pZelle = ( ScFormulaCell* ) pBaseCell;
+ if( pZelle )
+ pZelle->AddRecalcMode( RECALCMODE_ONLOAD_ONCE );
+ }
+ }
+
+ if( pZelle )
+ {
+ if( eErr != ConvOK )
+ ExcelToSc::SetError( *pZelle, eErr );
+#if 0
+ else
+ ExcelToSc::SetCurVal( *pZelle, rCurVal );
+#else
+ (void)rCurVal;
+#endif
+ }
+
+ GetXFRangeBuffer().SetXF( aScPos, nXF );
+ }
+}
+
+
+
+
+ExcelToSc::ExcelToSc( const XclImpRoot& rRoot ) :
+ ExcelConverterBase( 512 ),
+ XclImpRoot( rRoot ),
+ maFuncProv( rRoot ),
+ meBiff( rRoot.GetBiff() )
+{
+}
+
+ExcelToSc::~ExcelToSc()
+{
+}
+
+void ExcelToSc::GetDummy( const ScTokenArray*& pErgebnis )
+{
+ aPool.Store( CREATE_STRING( "Dummy()" ) );
+ aPool >> aStack;
+ pErgebnis = aPool[ aStack.Get() ];
+}
+
+
+// if bAllowArrays is false stream seeks to first byte after <nFormulaLen>
+// otherwise it will seek to the first byte after the additional content (eg
+// inline arrays) following <nFormulaLen>
+ConvErr ExcelToSc::Convert( const ScTokenArray*& pErgebnis, XclImpStream& aIn, sal_Size nFormulaLen, bool bAllowArrays, const FORMULA_TYPE eFT )
+{
+ RootData& rR = GetOldRoot();
+ BYTE nOp, nLen, nByte;
+ UINT16 nUINT16;
+ INT16 nINT16;
+ double fDouble;
+ String aString;
+ BOOL bError = FALSE;
+ BOOL bArrayFormula = FALSE;
+ TokenId nMerk0;
+ const BOOL bRangeName = eFT == FT_RangeName;
+ const BOOL bSharedFormula = eFT == FT_SharedFormula;
+ const BOOL bRNorSF = bRangeName || bSharedFormula;
+
+ ScSingleRefData aSRD;
+ ScComplexRefData aCRD;
+ ExtensionTypeVec aExtensions;
+
+ bExternName = FALSE;
+
+ if( eStatus != ConvOK )
+ {
+ aIn.Ignore( nFormulaLen );
+ return eStatus;
+ }
+
+ if( nFormulaLen == 0 )
+ {
+ aPool.Store( CREATE_STRING( "-/-" ) );
+ aPool >> aStack;
+ pErgebnis = aPool[ aStack.Get() ];
+ return ConvOK;
+ }
+
+ sal_Size nEndPos = aIn.GetRecPos() + nFormulaLen;
+
+ while( (aIn.GetRecPos() < nEndPos) && !bError )
+ {
+ aIn >> nOp;
+
+ // #98524# always reset flags
+ aSRD.InitFlags();
+ aCRD.InitFlags();
+
+ switch( nOp ) // Buch Seite:
+ { // SDK4 SDK5
+ case 0x01: // Array Formula [325 ]
+ // Array Formula or Shared Formula [ 277]
+ case 0x02: // Data Table [325 277]
+ nUINT16 = 3;
+
+ if( meBiff != EXC_BIFF2 )
+ nUINT16++;
+
+ aIn.Ignore( nUINT16 );
+
+ bArrayFormula = TRUE;
+ break;
+ case 0x03: // Addition [312 264]
+ aStack >> nMerk0;
+ aPool << aStack << ocAdd << nMerk0;
+ aPool >> aStack;
+ break;
+ case 0x04: // Subtraction [313 264]
+ // SECOMD-TOP minus TOP
+ aStack >> nMerk0;
+ aPool << aStack << ocSub << nMerk0;
+ aPool >> aStack;
+ break;
+ case 0x05: // Multiplication [313 264]
+ aStack >> nMerk0;
+ aPool << aStack << ocMul << nMerk0;
+ aPool >> aStack;
+ break;
+ case 0x06: // Division [313 264]
+ // divide TOP by SECOND-TOP
+ aStack >> nMerk0;
+ aPool << aStack << ocDiv << nMerk0;
+ aPool >> aStack;
+ break;
+ case 0x07: // Exponetiation [313 265]
+ // raise SECOND-TOP to power of TOP
+ aStack >> nMerk0;
+ aPool << aStack << ocPow << nMerk0;
+ aPool >> aStack;
+ break;
+ case 0x08: // Concatenation [313 265]
+ // append TOP to SECOND-TOP
+ aStack >> nMerk0;
+ aPool << aStack << ocAmpersand << nMerk0;
+ aPool >> aStack;
+ break;
+ case 0x09: // Less Than [313 265]
+ // SECOND-TOP < TOP
+ aStack >> nMerk0;
+ aPool << aStack << ocLess << nMerk0;
+ aPool >> aStack;
+ break;
+ case 0x0A: // Less Than or Equal [313 265]
+ // SECOND-TOP <= TOP
+ aStack >> nMerk0;
+ aPool << aStack << ocLessEqual << nMerk0;
+ aPool >> aStack;
+ break;
+ case 0x0B: // Equal [313 265]
+ // SECOND-TOP == TOP
+ aStack >> nMerk0;
+ aPool << aStack << ocEqual << nMerk0;
+ aPool >> aStack;
+ break;
+ case 0x0C: // Greater Than or Equal [313 265]
+ // SECOND-TOP == TOP
+ aStack >> nMerk0;
+ aPool << aStack << ocGreaterEqual << nMerk0;
+ aPool >> aStack;
+ break;
+ case 0x0D: // Greater Than [313 265]
+ // SECOND-TOP == TOP
+ aStack >> nMerk0;
+ aPool << aStack << ocGreater << nMerk0;
+ aPool >> aStack;
+ break;
+ case 0x0E: // Not Equal [313 265]
+ // SECOND-TOP == TOP
+ aStack >> nMerk0;
+ aPool << aStack << ocNotEqual << nMerk0;
+ aPool >> aStack;
+ break;
+ case 0x0F: // Intersection [314 265]
+ aStack >> nMerk0;
+ aPool << aStack << ocIntersect << nMerk0;
+ aPool >> aStack;
+ break;
+ case 0x10: // Union [314 265]
+ // ocSep behelfsweise statt 'ocUnion'
+ aStack >> nMerk0;
+//#100928# aPool << ocOpen << aStack << ocSep << nMerk0 << ocClose;
+ aPool << aStack << ocSep << nMerk0;
+ // doesn't fit exactly, but is more Excel-like
+ aPool >> aStack;
+ break;
+ case 0x11: // Range [314 265]
+ aStack >> nMerk0;
+ aPool << aStack << ocRange << nMerk0;
+ aPool >> aStack;
+ break;
+ case 0x12: // Unary Plus [312 264]
+ aPool << ocAdd << aStack;
+ aPool >> aStack;
+ break;
+ case 0x13: // Unary Minus [312 264]
+ aPool << ocNegSub << aStack;
+ aPool >> aStack;
+ break;
+ case 0x14: // Percent Sign [312 264]
+ aPool << aStack << ocPercentSign;
+ aPool >> aStack;
+ break;
+ case 0x15: // Parenthesis [326 278]
+ aPool << ocOpen << aStack << ocClose;
+ aPool >> aStack;
+ break;
+ case 0x16: // Missing Argument [314 266]
+ aPool << ocMissing;
+ aPool >> aStack;
+ GetTracer().TraceFormulaMissingArg();
+ break;
+ case 0x17: // String Constant [314 266]
+ aIn >> nLen;
+ aString = aIn.ReadRawByteString( nLen );
+
+ aStack << aPool.Store( aString );
+ break;
+ case 0x19: // Special Attribute [327 279]
+ {
+ UINT16 nData, nFakt;
+ BYTE nOpt;
+
+ aIn >> nOpt;
+
+ if( meBiff == EXC_BIFF2 )
+ {
+ nData = aIn.ReaduInt8();
+ nFakt = 1;
+ }
+ else
+ {
+ aIn >> nData;
+ nFakt = 2;
+ }
+
+ if( nOpt & 0x04 )
+ {// nFakt -> Bytes oder Words ueberlesen AttrChoose
+ nData++;
+ aIn.Ignore( nData * nFakt );
+ }
+ else if( nOpt & 0x10 ) // AttrSum
+ DoMulArgs( ocSum, 1 );
+ }
+ break;
+ case 0x1A: // External Reference [330 ]
+ switch( meBiff )
+ {
+ case EXC_BIFF2: aIn.Ignore( 7 ); break;
+ case EXC_BIFF3:
+ case EXC_BIFF4: aIn.Ignore( 10 ); break;
+ case EXC_BIFF5:
+ DBG_WARNING( "-ExcelToSc::Convert(): 0x1A gibt's nicht in Biff5!" );
+ default:
+ DBG_WARNING( "-ExcelToSc::Convert(): Ein wenig vergesslich, was?" );
+ }
+ break;
+ case 0x1B: // End External Reference [330 ]
+ switch( meBiff )
+ {
+ case EXC_BIFF2: aIn.Ignore( 3 ); break;
+ case EXC_BIFF3:
+ case EXC_BIFF4: aIn.Ignore( 4 ); break;
+ case EXC_BIFF5:
+ DBG_WARNING( "-ExcelToSc::Convert(): 0x1B gibt's nicht in Biff5!" );
+ default:
+ DBG_WARNING( "-ExcelToSc::Convert(): Ein wenig vergesslich, was?" );
+ }
+ break;
+ case 0x1C: // Error Value [314 266]
+ {
+ aIn >> nByte;
+#if 0 // erAck
+ aPool.StoreError( XclTools::GetScErrorCode( nByte ) );
+#else
+ DefTokenId eOc;
+ switch( nByte )
+ {
+ case EXC_ERR_NULL:
+ case EXC_ERR_DIV0:
+ case EXC_ERR_VALUE:
+ case EXC_ERR_REF:
+ case EXC_ERR_NAME:
+ case EXC_ERR_NUM: eOc = ocStop; break;
+ case EXC_ERR_NA: eOc = ocNotAvail; break;
+ default: eOc = ocNoName;
+ }
+ aPool << eOc;
+ if( eOc != ocStop )
+ aPool << ocOpen << ocClose;
+#endif
+ aPool >> aStack;
+ }
+ break;
+ case 0x1D: // Boolean [315 266]
+ aIn >> nByte;
+ if( nByte == 0 )
+ aPool << ocFalse << ocOpen << ocClose;
+ else
+ aPool << ocTrue << ocOpen << ocClose;
+ aPool >> aStack;
+ break;
+ case 0x1E: // Integer [315 266]
+ aIn >> nUINT16;
+ aStack << aPool.Store( ( double ) nUINT16 );
+ break;
+ case 0x1F: // Number [315 266]
+ aIn >> fDouble;
+ aStack << aPool.Store( fDouble );
+ break;
+ case 0x40:
+ case 0x60:
+ case 0x20: // Array Constant [317 268]
+ aIn >> nByte >> nUINT16;
+ aIn.Ignore( (meBiff == EXC_BIFF2) ? 3 : 4 );
+ if( bAllowArrays )
+ {
+ aStack << aPool.StoreMatrix();
+ aExtensions.push_back( EXTENSION_ARRAY );
+ }
+ else
+ {
+ aPool << ocBad;
+ aPool >> aStack;
+ }
+ break;
+ case 0x41:
+ case 0x61:
+ case 0x21: // Function, Fixed Number of Arguments [333 282]
+ {
+ sal_uInt16 nXclFunc;
+ if( meBiff <= EXC_BIFF3 )
+ nXclFunc = aIn.ReaduInt8();
+ else
+ aIn >> nXclFunc;
+ if( const XclFunctionInfo* pFuncInfo = maFuncProv.GetFuncInfoFromXclFunc( nXclFunc ) )
+ DoMulArgs( pFuncInfo->meOpCode, pFuncInfo->mnMaxParamCount, pFuncInfo->mnMinParamCount );
+ else
+ DoMulArgs( ocNoName, 0 );
+ }
+ break;
+ case 0x42:
+ case 0x62:
+ case 0x22: // Function, Variable Number of Arg. [333 283]
+ {
+ sal_uInt16 nXclFunc;
+ sal_uInt8 nParamCount;
+ aIn >> nParamCount;
+ nParamCount &= 0x7F;
+ if( meBiff <= EXC_BIFF3 )
+ nXclFunc = aIn.ReaduInt8();
+ else
+ aIn >> nXclFunc;
+ if( const XclFunctionInfo* pFuncInfo = maFuncProv.GetFuncInfoFromXclFunc( nXclFunc ) )
+ DoMulArgs( pFuncInfo->meOpCode, nParamCount, pFuncInfo->mnMinParamCount );
+ else
+ DoMulArgs( ocNoName, 0 );
+ }
+ break;
+ case 0x43:
+ case 0x63:
+ case 0x23: // Name [318 269]
+ {
+ aIn >> nUINT16;
+ switch( meBiff )
+ {
+ case EXC_BIFF2: aIn.Ignore( 5 ); break;
+ case EXC_BIFF3:
+ case EXC_BIFF4: aIn.Ignore( 8 ); break;
+ case EXC_BIFF5: aIn.Ignore( 12 ); break;
+ default:
+ DBG_ERROR(
+ "-ExcelToSc::Convert(): Ein wenig vergesslich, was?" );
+ }
+ const XclImpName* pName = GetNameManager().GetName( nUINT16 );
+ if(pName && !pName->GetScRangeData())
+ aStack << aPool.Store( ocMacro, pName->GetXclName() );
+ else
+ aStack << aPool.Store( nUINT16 );
+ }
+ break;
+ case 0x44:
+ case 0x64:
+ case 0x24: // Cell Reference [319 270]
+ case 0x4A:
+ case 0x6A:
+ case 0x2A: // Deleted Cell Reference [323 273]
+ aIn >> nUINT16 >> nByte;
+ aSRD.nCol = static_cast<SCsCOL>(nByte);
+ aSRD.nRow = nUINT16 & 0x3FFF;
+ aSRD.nRelTab = 0;
+ aSRD.SetTabRel( TRUE );
+ aSRD.SetFlag3D( bRangeName );
+
+ ExcRelToScRel( nUINT16, nByte, aSRD, bRangeName );
+
+ switch ( nOp )
+ {
+ case 0x4A:
+ case 0x6A:
+ case 0x2A: // Deleted Cell Reference [323 273]
+ // no information which part is deleted, set both
+ aSRD.SetColDeleted( TRUE );
+ aSRD.SetRowDeleted( TRUE );
+ }
+
+ aStack << aPool.Store( aSRD );
+ break;
+ case 0x45:
+ case 0x65:
+ case 0x25: // Area Reference [320 270]
+ case 0x4B:
+ case 0x6B:
+ case 0x2B: // Deleted Area Refernce [323 273]
+ {
+ UINT16 nRowFirst, nRowLast;
+ UINT8 nColFirst, nColLast;
+ ScSingleRefData& rSRef1 = aCRD.Ref1;
+ ScSingleRefData& rSRef2 = aCRD.Ref2;
+
+ aIn >> nRowFirst >> nRowLast >> nColFirst >> nColLast;
+
+ rSRef1.nRelTab = rSRef2.nRelTab = 0;
+ rSRef1.SetTabRel( TRUE );
+ rSRef2.SetTabRel( TRUE );
+ rSRef1.SetFlag3D( bRangeName );
+ rSRef2.SetFlag3D( bRangeName );
+
+ ExcRelToScRel( nRowFirst, nColFirst, aCRD.Ref1, bRangeName );
+ ExcRelToScRel( nRowLast, nColLast, aCRD.Ref2, bRangeName );
+
+ if( IsComplColRange( nColFirst, nColLast ) )
+ SetComplCol( aCRD );
+ else if( IsComplRowRange( nRowFirst, nRowLast ) )
+ SetComplRow( aCRD );
+
+ switch ( nOp )
+ {
+ case 0x4B:
+ case 0x6B:
+ case 0x2B: // Deleted Area Refernce [323 273]
+ // no information which part is deleted, set all
+ rSRef1.SetColDeleted( TRUE );
+ rSRef1.SetRowDeleted( TRUE );
+ rSRef2.SetColDeleted( TRUE );
+ rSRef2.SetRowDeleted( TRUE );
+ }
+
+ aStack << aPool.Store( aCRD );
+ }
+ break;
+ case 0x46:
+ case 0x66:
+ case 0x26: // Constant Reference Subexpression [321 271]
+ aExtensions.push_back( EXTENSION_MEMAREA );
+ // fall through
+
+ case 0x47:
+ case 0x67:
+ case 0x27: // Erroneous Constant Reference Subexpr. [322 272]
+ case 0x48:
+ case 0x68:
+ case 0x28: // Incomplete Constant Reference Subexpr.[331 281]
+ aIn.Ignore( (meBiff == EXC_BIFF2) ? 4 : 6 );
+ break;
+ case 0x4C:
+ case 0x6C:
+ case 0x2C: // Cell Reference Within a Name [323 ]
+ // Cell Reference Within a Shared Formula[ 273]
+ {
+ aIn >> nUINT16 >> nByte; // >> Attribute, Row >> Col
+
+ aSRD.nRelTab = 0;
+ aSRD.SetTabRel( TRUE );
+ aSRD.SetFlag3D( bRangeName );
+
+ ExcRelToScRel( nUINT16, nByte, aSRD, bRNorSF );
+
+ aStack << aPool.Store( aSRD );
+ }
+ break;
+ case 0x4D:
+ case 0x6D:
+ case 0x2D: // Area Reference Within a Name [324 ]
+ { // Area Reference Within a Shared Formula[ 274]
+ UINT16 nRowFirst, nRowLast;
+ UINT8 nColFirst, nColLast;
+
+ aCRD.Ref1.nRelTab = aCRD.Ref2.nRelTab = 0;
+ aCRD.Ref1.SetTabRel( TRUE );
+ aCRD.Ref2.SetTabRel( TRUE );
+ aCRD.Ref1.SetFlag3D( bRangeName );
+ aCRD.Ref2.SetFlag3D( bRangeName );
+
+ aIn >> nRowFirst >> nRowLast >> nColFirst >> nColLast;
+
+ ExcRelToScRel( nRowFirst, nColFirst, aCRD.Ref1, bRNorSF );
+ ExcRelToScRel( nRowLast, nColLast, aCRD.Ref2, bRNorSF );
+
+ if( IsComplColRange( nColFirst, nColLast ) )
+ SetComplCol( aCRD );
+ else if( IsComplRowRange( nRowFirst, nRowLast ) )
+ SetComplRow( aCRD );
+
+ aStack << aPool.Store( aCRD );
+ }
+ break;
+ case 0x49:
+ case 0x69:
+ case 0x29: // Variable Reference Subexpression [331 281]
+ case 0x4E:
+ case 0x6E:
+ case 0x2E: // Reference Subexpression Within a Name [332 282]
+ case 0x4F:
+ case 0x6F:
+ case 0x2F: // Incomplete Reference Subexpression... [332 282]
+ aIn.Ignore( (meBiff == EXC_BIFF2) ? 1 : 2 );
+ break;
+ case 0x58:
+ case 0x78:
+ case 0x38: // Command-Equivalent Function [333 ]
+ aString.AssignAscii( "COMM_EQU_FUNC" );
+ aIn >> nByte;
+ aString += String::CreateFromInt32( nByte );
+ aIn >> nByte;
+ aStack << aPool.Store( aString );
+ DoMulArgs( ocPush, nByte + 1 );
+ break;
+ case 0x59:
+ case 0x79:
+ case 0x39: // Name or External Name [ 275]
+ aIn >> nINT16;
+ aIn.Ignore( 8 );
+ aIn >> nUINT16;
+ if( nINT16 >= 0 )
+ {
+ const ExtName* pExtName = rR.pExtNameBuff->GetNameByIndex( nINT16, nUINT16 );
+ if( pExtName && pExtName->IsDDE() &&
+ rR.pExtSheetBuff->IsLink( ( UINT16 ) nINT16 ) )
+ {
+ String aAppl, aExtDoc;
+ TokenId nPar1, nPar2;
+
+ rR.pExtSheetBuff->GetLink( ( UINT16 ) nINT16 , aAppl, aExtDoc );
+ nPar1 = aPool.Store( aAppl );
+ nPar2 = aPool.Store( aExtDoc );
+ nMerk0 = aPool.Store( pExtName->aName );
+ aPool << ocDde << ocOpen << nPar1 << ocSep << nPar2 << ocSep
+ << nMerk0 << ocClose;
+
+ GetDoc().CreateDdeLink( aAppl, aExtDoc, pExtName->aName, SC_DDE_DEFAULT );
+ }
+ else
+ aPool << ocBad;
+
+ aPool >> aStack;
+ }
+ else
+ aStack << aPool.Store( nUINT16 );
+ aIn.Ignore( 12 );
+ break;
+ case 0x5A:
+ case 0x7A:
+ case 0x3A: // 3-D Cell Reference [ 275]
+ case 0x5C:
+ case 0x7C:
+ case 0x3C: // Deleted 3-D Cell Reference [ 277]
+ {
+ UINT16 nTabFirst, nTabLast, nRow;
+ INT16 nExtSheet;
+ BYTE nCol;
+
+ aIn >> nExtSheet;
+ aIn.Ignore( 8 );
+ aIn >> nTabFirst >> nTabLast >> nRow >> nCol;
+
+ if( nExtSheet >= 0 )
+ { // von extern
+ if( rR.pExtSheetBuff->GetScTabIndex( nExtSheet, nTabLast ) )
+ {
+ nTabFirst = nTabLast;
+ nExtSheet = 0; // gefunden
+ }
+ else
+ {
+ aPool << ocBad;
+ aPool >> aStack;
+ nExtSheet = 1; // verhindert Erzeugung einer SingleRef
+ }
+ }
+
+ if( nExtSheet <= 0 )
+ { // in aktuellem Workbook
+ aSRD.nTab = static_cast<SCTAB>(nTabFirst);
+ aSRD.SetFlag3D( TRUE );
+ aSRD.SetTabRel( FALSE );
+
+ ExcRelToScRel( nRow, nCol, aSRD, bRangeName );
+
+ switch ( nOp )
+ {
+ case 0x5C:
+ case 0x7C:
+ case 0x3C: // Deleted 3-D Cell Reference [ 277]
+ // no information which part is deleted, set both
+ aSRD.SetColDeleted( TRUE );
+ aSRD.SetRowDeleted( TRUE );
+ }
+ if ( !ValidTab(static_cast<SCTAB>(nTabFirst)) )
+ aSRD.SetTabDeleted( TRUE );
+
+ if( nTabLast != nTabFirst )
+ {
+ aCRD.Ref1 = aCRD.Ref2 = aSRD;
+ aCRD.Ref2.nTab = static_cast<SCTAB>(nTabLast);
+ aCRD.Ref2.SetTabDeleted( !ValidTab(static_cast<SCTAB>(nTabLast)) );
+ aStack << aPool.Store( aCRD );
+ }
+ else
+ aStack << aPool.Store( aSRD );
+ }
+ }
+
+ break;
+ case 0x5B:
+ case 0x7B:
+ case 0x3B: // 3-D Area Reference [ 276]
+ case 0x5D:
+ case 0x7D:
+ case 0x3D: // Deleted 3-D Area Reference [ 277]
+ {
+ UINT16 nTabFirst, nTabLast, nRowFirst, nRowLast;
+ INT16 nExtSheet;
+ BYTE nColFirst, nColLast;
+
+ aIn >> nExtSheet;
+ aIn.Ignore( 8 );
+ aIn >> nTabFirst >> nTabLast >> nRowFirst >> nRowLast
+ >> nColFirst >> nColLast;
+
+ if( nExtSheet >= 0 )
+ // von extern
+ {
+ if( rR.pExtSheetBuff->GetScTabIndex( nExtSheet, nTabLast ) )
+ {
+ nTabFirst = nTabLast;
+ nExtSheet = 0; // gefunden
+ }
+ else
+ {
+ aPool << ocBad;
+ aPool >> aStack;
+ nExtSheet = 1; // verhindert Erzeugung einer CompleteRef
+ }
+ }
+
+ if( nExtSheet <= 0 )
+ {// in aktuellem Workbook
+ // erster Teil des Bereichs
+ ScSingleRefData& rR1 = aCRD.Ref1;
+ ScSingleRefData& rR2 = aCRD.Ref2;
+
+ rR1.nTab = static_cast<SCTAB>(nTabFirst);
+ rR2.nTab = static_cast<SCTAB>(nTabLast);
+ rR1.SetFlag3D( TRUE );
+ rR1.SetTabRel( FALSE );
+ rR2.SetFlag3D( nTabFirst != nTabLast );
+ rR2.SetTabRel( FALSE );
+
+ ExcRelToScRel( nRowFirst, nColFirst, aCRD.Ref1, bRangeName );
+ ExcRelToScRel( nRowLast, nColLast, aCRD.Ref2, bRangeName );
+
+ if( IsComplColRange( nColFirst, nColLast ) )
+ SetComplCol( aCRD );
+ else if( IsComplRowRange( nRowFirst, nRowLast ) )
+ SetComplRow( aCRD );
+
+ switch ( nOp )
+ {
+ case 0x5D:
+ case 0x7D:
+ case 0x3D: // Deleted 3-D Area Reference [ 277]
+ // no information which part is deleted, set all
+ rR1.SetColDeleted( TRUE );
+ rR1.SetRowDeleted( TRUE );
+ rR2.SetColDeleted( TRUE );
+ rR2.SetRowDeleted( TRUE );
+ }
+ if ( !ValidTab(static_cast<SCTAB>(nTabFirst)) )
+ rR1.SetTabDeleted( TRUE );
+ if ( !ValidTab(static_cast<SCTAB>(nTabLast)) )
+ rR2.SetTabDeleted( TRUE );
+
+ aStack << aPool.Store( aCRD );
+ }//ENDE in aktuellem Workbook
+ }
+ break;
+ default: bError = TRUE;
+ }
+ bError |= !aIn.IsValid();
+ }
+
+ ConvErr eRet;
+
+ if( bError )
+ {
+ aPool << ocBad;
+ aPool >> aStack;
+ pErgebnis = aPool[ aStack.Get() ];
+ eRet = ConvErrNi;
+ }
+ else if( aIn.GetRecPos() != nEndPos )
+ {
+ aPool << ocBad;
+ aPool >> aStack;
+ pErgebnis = aPool[ aStack.Get() ];
+ eRet = ConvErrCount;
+ }
+ else if( bExternName )
+ {
+ pErgebnis = aPool[ aStack.Get() ];
+ eRet = ConvErrExternal;
+ }
+ else if( bArrayFormula )
+ {
+ pErgebnis = NULL;
+ eRet = ConvOK;
+ }
+ else
+ {
+ pErgebnis = aPool[ aStack.Get() ];
+ eRet = ConvOK;
+ }
+
+ aIn.Seek( nEndPos );
+
+ if( eRet == ConvOK )
+ ReadExtensions( aExtensions, aIn );
+
+ return eRet;
+}
+
+
+// stream seeks to first byte after <nFormulaLen>
+ConvErr ExcelToSc::Convert( _ScRangeListTabs& rRangeList, XclImpStream& aIn, sal_Size nFormulaLen, const FORMULA_TYPE eFT )
+{
+ RootData& rR = GetOldRoot();
+ BYTE nOp, nLen;
+ sal_Size nIgnore;
+ UINT16 nUINT16;
+ UINT8 nByte;
+ BOOL bError = FALSE;
+ BOOL bArrayFormula = FALSE;
+ const BOOL bRangeName = eFT == FT_RangeName;
+ const BOOL bSharedFormula = eFT == FT_SharedFormula;
+ const BOOL bRNorSF = bRangeName || bSharedFormula;
+
+ ScSingleRefData aSRD;
+ ScComplexRefData aCRD;
+ aCRD.Ref1.nTab = aCRD.Ref2.nTab = aEingPos.Tab();
+
+ bExternName = FALSE;
+
+ if( eStatus != ConvOK )
+ {
+ aIn.Ignore( nFormulaLen );
+ return eStatus;
+ }
+
+ if( nFormulaLen == 0 )
+ return ConvOK;
+
+ sal_Size nEndPos = aIn.GetRecPos() + nFormulaLen;
+
+ while( (aIn.GetRecPos() < nEndPos) && !bError )
+ {
+ aIn >> nOp;
+ nIgnore = 0;
+
+ // #98524# always reset flags
+ aSRD.InitFlags();
+ aCRD.InitFlags();
+
+ switch( nOp ) // Buch Seite:
+ { // SDK4 SDK5
+ case 0x01: // Array Formula [325 ]
+ // Array Formula or Shared Formula [ 277]
+ nIgnore = (meBiff == EXC_BIFF2) ? 3 : 4;
+ bArrayFormula = TRUE;
+ break;
+ case 0x02: // Data Table [325 277]
+ nIgnore = (meBiff == EXC_BIFF2) ? 3 : 4;
+ break;
+ case 0x03: // Addition [312 264]
+ case 0x04: // Subtraction [313 264]
+ case 0x05: // Multiplication [313 264]
+ case 0x06: // Division [313 264]
+ case 0x07: // Exponetiation [313 265]
+ case 0x08: // Concatenation [313 265]
+ case 0x09: // Less Than [313 265]
+ case 0x0A: // Less Than or Equal [313 265]
+ case 0x0B: // Equal [313 265]
+ case 0x0C: // Greater Than or Equal [313 265]
+ case 0x0D: // Greater Than [313 265]
+ case 0x0E: // Not Equal [313 265]
+ case 0x0F: // Intersection [314 265]
+ case 0x10: // Union [314 265]
+ case 0x11: // Range [314 265]
+ case 0x12: // Unary Plus [312 264]
+ case 0x13: // Unary Minus [312 264]
+ case 0x14: // Percent Sign [312 264]
+ case 0x15: // Parenthesis [326 278]
+ case 0x16: // Missing Argument [314 266]
+ break;
+ case 0x17: // String Constant [314 266]
+ aIn >> nLen;
+ nIgnore = nLen;
+ break;
+ case 0x19: // Special Attribute [327 279]
+ {
+ UINT16 nData, nFakt;
+ BYTE nOpt;
+
+ aIn >> nOpt;
+
+ if( meBiff == EXC_BIFF2 )
+ {
+ nData = aIn.ReaduInt8();
+ nFakt = 1;
+ }
+ else
+ {
+ aIn >> nData;
+ nFakt = 2;
+ }
+
+ if( nOpt & 0x04 )
+ {// nFakt -> Bytes oder Words ueberlesen AttrChoose
+ nData++;
+ aIn.Ignore( nData * nFakt );
+ }
+ }
+ break;
+ case 0x1A: // External Reference [330 ]
+ switch( meBiff )
+ {
+ case EXC_BIFF2: nIgnore = 7; break;
+ case EXC_BIFF3:
+ case EXC_BIFF4: nIgnore = 10; break;
+ case EXC_BIFF5: DBG_WARNING( "-ExcelToSc::Convert(): 0x1A gibt's nicht in Biff5!" );
+ default: DBG_WARNING( "-ExcelToSc::Convert(): Ein wenig vergesslich, was?" );
+ }
+ break;
+ case 0x1B: // End External Reference [330 ]
+ switch( meBiff )
+ {
+ case EXC_BIFF2: nIgnore = 3; break;
+ case EXC_BIFF3:
+ case EXC_BIFF4: nIgnore = 4; break;
+ case EXC_BIFF5: DBG_WARNING( "-ExcelToSc::Convert(): 0x1B gibt's nicht in Biff5!" );
+ default: DBG_WARNING( "-ExcelToSc::Convert(): Ein wenig vergesslich, was?" );
+ }
+ break;
+ case 0x1C: // Error Value [314 266]
+ case 0x1D: // Boolean [315 266]
+ nIgnore = 1;
+ break;
+ case 0x1E: // Integer [315 266]
+ nIgnore = 2;
+ break;
+ case 0x1F: // Number [315 266]
+ nIgnore = 8;
+ break;
+ case 0x40:
+ case 0x60:
+ case 0x20: // Array Constant [317 268]
+ nIgnore = (meBiff == EXC_BIFF2) ? 6 : 7;
+ break;
+ case 0x41:
+ case 0x61:
+ case 0x21: // Function, Fixed Number of Arguments [333 282]
+ nIgnore = (meBiff <= EXC_BIFF3) ? 1 : 2;
+ break;
+ case 0x42:
+ case 0x62:
+ case 0x22: // Function, Variable Number of Arg. [333 283]
+ nIgnore = (meBiff <= EXC_BIFF3) ? 2 : 3;
+ break;
+ case 0x43:
+ case 0x63:
+ case 0x23: // Name [318 269]
+ switch( meBiff )
+ {
+ case EXC_BIFF2: nIgnore = 7; break;
+ case EXC_BIFF3:
+ case EXC_BIFF4: nIgnore = 10; break;
+ case EXC_BIFF5: nIgnore = 14; break;
+ default: DBG_ERROR( "-ExcelToSc::Convert(): Ein wenig vergesslich, was?" );
+ }
+ break;
+ case 0x44:
+ case 0x64:
+ case 0x24: // Cell Reference [319 270]
+ aIn >> nUINT16 >> nByte;
+ aSRD.nCol = static_cast<SCsCOL>(nByte);
+ aSRD.nRow = nUINT16 & 0x3FFF;
+ aSRD.nRelTab = 0;
+ aSRD.SetTabRel( TRUE );
+ aSRD.SetFlag3D( bRangeName );
+
+ ExcRelToScRel( nUINT16, nByte, aSRD, bRangeName );
+
+ rRangeList.Append( aSRD );
+ break;
+ case 0x45:
+ case 0x65:
+ case 0x25: // Area Reference [320 270]
+ {
+ UINT16 nRowFirst, nRowLast;
+ UINT8 nColFirst, nColLast;
+ ScSingleRefData &rSRef1 = aCRD.Ref1;
+ ScSingleRefData &rSRef2 = aCRD.Ref2;
+
+ aIn >> nRowFirst >> nRowLast >> nColFirst >> nColLast;
+
+ rSRef1.nRelTab = rSRef2.nRelTab = 0;
+ rSRef1.SetTabRel( TRUE );
+ rSRef2.SetTabRel( TRUE );
+ rSRef1.SetFlag3D( bRangeName );
+ rSRef2.SetFlag3D( bRangeName );
+
+ ExcRelToScRel( nRowFirst, nColFirst, aCRD.Ref1, bRangeName );
+ ExcRelToScRel( nRowLast, nColLast, aCRD.Ref2, bRangeName );
+
+ if( IsComplColRange( nColFirst, nColLast ) )
+ SetComplCol( aCRD );
+ else if( IsComplRowRange( nRowFirst, nRowLast ) )
+ SetComplRow( aCRD );
+
+ rRangeList.Append( aCRD );
+ }
+ break;
+ case 0x46:
+ case 0x66:
+ case 0x26: // Constant Reference Subexpression [321 271]
+ case 0x47:
+ case 0x67:
+ case 0x27: // Erroneous Constant Reference Subexpr. [322 272]
+ case 0x48:
+ case 0x68:
+ case 0x28: // Incomplete Constant Reference Subexpr.[331 281]
+ nIgnore = (meBiff == EXC_BIFF2) ? 4 : 6;
+ break;
+ case 0x4A:
+ case 0x6A:
+ case 0x2A: // Deleted Cell Reference [323 273]
+ nIgnore = 3;
+ break;
+ case 0x4B:
+ case 0x6B:
+ case 0x2B: // Deleted Area Refernce [323 273]
+ nIgnore = 6;
+ break;
+ case 0x4C:
+ case 0x6C:
+ case 0x2C: // Cell Reference Within a Name [323 ]
+ // Cell Reference Within a Shared Formula[ 273]
+ {
+ aIn >> nUINT16 >> nByte; // >> Attribute, Row >> Col
+
+ aSRD.nRelTab = 0;
+ aSRD.SetTabRel( TRUE );
+ aSRD.SetFlag3D( bRangeName );
+
+ ExcRelToScRel( nUINT16, nByte, aSRD, bRNorSF );
+
+ rRangeList.Append( aSRD );
+ }
+ break;
+ case 0x4D:
+ case 0x6D:
+ case 0x2D: // Area Reference Within a Name [324 ]
+ { // Area Reference Within a Shared Formula[ 274]
+ UINT16 nRowFirst, nRowLast;
+ UINT8 nColFirst, nColLast;
+
+ aCRD.Ref1.nRelTab = aCRD.Ref2.nRelTab = 0;
+ aCRD.Ref1.SetTabRel( TRUE );
+ aCRD.Ref2.SetTabRel( TRUE );
+ aCRD.Ref1.SetFlag3D( bRangeName );
+ aCRD.Ref2.SetFlag3D( bRangeName );
+
+ aIn >> nRowFirst >> nRowLast >> nColFirst >> nColLast;
+
+ ExcRelToScRel( nRowFirst, nColFirst, aCRD.Ref1, bRNorSF );
+ ExcRelToScRel( nRowLast, nColLast, aCRD.Ref2, bRNorSF );
+
+ if( IsComplColRange( nColFirst, nColLast ) )
+ SetComplCol( aCRD );
+ else if( IsComplRowRange( nRowFirst, nRowLast ) )
+ SetComplRow( aCRD );
+
+ rRangeList.Append( aCRD );
+ }
+ break;
+ case 0x49:
+ case 0x69:
+ case 0x29: // Variable Reference Subexpression [331 281]
+ case 0x4E:
+ case 0x6E:
+ case 0x2E: // Reference Subexpression Within a Name [332 282]
+ case 0x4F:
+ case 0x6F:
+ case 0x2F: // Incomplete Reference Subexpression... [332 282]
+ nIgnore = (meBiff == EXC_BIFF2) ? 1 : 2;
+ break;
+ case 0x58:
+ case 0x78:
+ case 0x38: // Command-Equivalent Function [333 ]
+ nIgnore = 2;
+ break;
+ case 0x59:
+ case 0x79:
+ case 0x39: // Name or External Name [ 275]
+ nIgnore = 24;
+ break;
+ case 0x5A:
+ case 0x7A:
+ case 0x3A: // 3-D Cell Reference [ 275]
+ {
+ UINT16 nTabFirst, nTabLast, nRow;
+ INT16 nExtSheet;
+ BYTE nCol;
+
+ aIn >> nExtSheet;
+ aIn.Ignore( 8 );
+ aIn >> nTabFirst >> nTabLast >> nRow >> nCol;
+
+ if( nExtSheet >= 0 )
+ // von extern
+ {
+ if( rR.pExtSheetBuff->GetScTabIndex( nExtSheet, nTabLast ) )
+ {
+ nTabFirst = nTabLast;
+ nExtSheet = 0; // gefunden
+ }
+ else
+ {
+ aPool << ocBad;
+ aPool >> aStack;
+ nExtSheet = 1; // verhindert Erzeugung einer SingleRef
+ }
+ }
+
+ if( nExtSheet <= 0 )
+ {// in aktuellem Workbook
+ BOOL b3D = ( static_cast<SCTAB>(nTabFirst) != aEingPos.Tab() ) || bRangeName;
+ aSRD.nTab = static_cast<SCTAB>(nTabFirst);
+ aSRD.SetFlag3D( b3D );
+ aSRD.SetTabRel( FALSE );
+
+ ExcRelToScRel( nRow, nCol, aSRD, bRangeName );
+
+ if( nTabLast != nTabFirst )
+ {
+ aCRD.Ref1 = aSRD;
+ aCRD.Ref2.nCol = aSRD.nCol;
+ aCRD.Ref2.nRow = aSRD.nRow;
+ aCRD.Ref2.nTab = static_cast<SCTAB>(nTabLast);
+ b3D = ( static_cast<SCTAB>(nTabLast) != aEingPos.Tab() );
+ aCRD.Ref2.SetFlag3D( b3D );
+ aCRD.Ref2.SetTabRel( FALSE );
+ rRangeList.Append( aCRD );
+ }
+ else
+ rRangeList.Append( aSRD );
+ }
+ }
+
+ break;
+ case 0x5B:
+ case 0x7B:
+ case 0x3B: // 3-D Area Reference [ 276]
+ {
+ UINT16 nTabFirst, nTabLast, nRowFirst, nRowLast;
+ INT16 nExtSheet;
+ BYTE nColFirst, nColLast;
+
+ aIn >> nExtSheet;
+ aIn.Ignore( 8 );
+ aIn >> nTabFirst >> nTabLast >> nRowFirst >> nRowLast
+ >> nColFirst >> nColLast;
+
+ if( nExtSheet >= 0 )
+ // von extern
+ {
+ if( rR.pExtSheetBuff->GetScTabIndex( nExtSheet, nTabLast ) )
+ {
+ nTabFirst = nTabLast;
+ nExtSheet = 0; // gefunden
+ }
+ else
+ {
+ aPool << ocBad;
+ aPool >> aStack;
+ nExtSheet = 1; // verhindert Erzeugung einer CompleteRef
+ }
+ }
+
+ if( nExtSheet <= 0 )
+ {// in aktuellem Workbook
+ // erster Teil des Bereichs
+ ScSingleRefData &rR1 = aCRD.Ref1;
+ ScSingleRefData &rR2 = aCRD.Ref2;
+
+ rR1.nTab = static_cast<SCTAB>(nTabFirst);
+ rR2.nTab = static_cast<SCTAB>(nTabLast);
+ rR1.SetFlag3D( ( static_cast<SCTAB>(nTabFirst) != aEingPos.Tab() ) || bRangeName );
+ rR1.SetTabRel( FALSE );
+ rR2.SetFlag3D( ( static_cast<SCTAB>(nTabLast) != aEingPos.Tab() ) || bRangeName );
+ rR2.SetTabRel( FALSE );
+
+ ExcRelToScRel( nRowFirst, nColFirst, aCRD.Ref1, bRangeName );
+ ExcRelToScRel( nRowLast, nColLast, aCRD.Ref2, bRangeName );
+
+ if( IsComplColRange( nColFirst, nColLast ) )
+ SetComplCol( aCRD );
+ else if( IsComplRowRange( nRowFirst, nRowLast ) )
+ SetComplRow( aCRD );
+
+ rRangeList.Append( aCRD );
+ }//ENDE in aktuellem Workbook
+ }
+ break;
+ case 0x5C:
+ case 0x7C:
+ case 0x3C: // Deleted 3-D Cell Reference [ 277]
+ nIgnore = 17;
+ break;
+ case 0x5D:
+ case 0x7D:
+ case 0x3D: // Deleted 3-D Area Reference [ 277]
+ nIgnore = 20;
+ break;
+ default: bError = TRUE;
+ }
+ bError |= !aIn.IsValid();
+
+ aIn.Ignore( nIgnore );
+ }
+
+ ConvErr eRet;
+
+ if( bError )
+ eRet = ConvErrNi;
+ else if( aIn.GetRecPos() != nEndPos )
+ eRet = ConvErrCount;
+ else if( bExternName )
+ eRet = ConvErrExternal;
+ else if( bArrayFormula )
+ eRet = ConvOK;
+ else
+ eRet = ConvOK;
+
+ aIn.Seek( nEndPos );
+ return eRet;
+}
+
+ConvErr ExcelToSc::ConvertExternName( const ScTokenArray*& /*rpArray*/, XclImpStream& /*rStrm*/, sal_Size /*nFormulaLen*/,
+ const String& /*rUrl*/, const vector<String>& /*rTabNames*/ )
+{
+ // not implemented ...
+ return ConvErrNi;
+}
+
+BOOL ExcelToSc::GetAbsRefs( ScRangeList& rRangeList, XclImpStream& rStrm, sal_Size nLen )
+{
+ DBG_ASSERT_BIFF( GetBiff() == EXC_BIFF5 );
+ if( GetBiff() != EXC_BIFF5 )
+ return FALSE;
+
+ sal_uInt8 nOp;
+ sal_uInt16 nRow1, nRow2;
+ sal_uInt8 nCol1, nCol2;
+ SCTAB nTab1, nTab2;
+ sal_uInt16 nTabFirst, nTabLast;
+ sal_Int16 nRefIdx;
+
+ sal_Size nSeek;
+ sal_Size nEndPos = rStrm.GetRecPos() + nLen;
+
+ while( rStrm.IsValid() && (rStrm.GetRecPos() < nEndPos) )
+ {
+ rStrm >> nOp;
+ nSeek = 0;
+
+ switch( nOp )
+ {
+ case 0x44:
+ case 0x64:
+ case 0x24: // Cell Reference [319 270]
+ case 0x4C:
+ case 0x6C:
+ case 0x2C: // Cell Reference Within a Name [323 ]
+ // Cell Reference Within a Shared Formula[ 273]
+ rStrm >> nRow1 >> nCol1;
+
+ nRow2 = nRow1;
+ nCol2 = nCol1;
+ nTab1 = nTab2 = GetCurrScTab();
+ goto _common;
+ case 0x45:
+ case 0x65:
+ case 0x25: // Area Reference [320 270]
+ case 0x4D:
+ case 0x6D:
+ case 0x2D: // Area Reference Within a Name [324 ]
+ // Area Reference Within a Shared Formula[ 274]
+ rStrm >> nRow1 >> nRow2 >> nCol1 >> nCol2;
+
+ nTab1 = nTab2 = GetCurrScTab();
+ goto _common;
+ case 0x5A:
+ case 0x7A:
+ case 0x3A: // 3-D Cell Reference [ 275]
+ rStrm >> nRefIdx;
+ rStrm.Ignore( 8 );
+ rStrm >> nTabFirst >> nTabLast >> nRow1 >> nCol1;
+
+ nRow2 = nRow1;
+ nCol2 = nCol1;
+
+ goto _3d_common;
+ case 0x5B:
+ case 0x7B:
+ case 0x3B: // 3-D Area Reference [ 276]
+ rStrm >> nRefIdx;
+ rStrm.Ignore( 8 );
+ rStrm >> nTabFirst >> nTabLast >> nRow1 >> nRow2 >> nCol1 >> nCol2;
+
+ _3d_common:
+ nTab1 = static_cast< SCTAB >( nTabFirst );
+ nTab2 = static_cast< SCTAB >( nTabLast );
+
+ // #122885# skip references to deleted sheets
+ if( (nRefIdx >= 0) || !ValidTab( nTab1 ) || (nTab1 != nTab2) )
+ break;
+
+ goto _common;
+ _common:
+ // do not check abs/rel flags, linked controls have set them!
+// if( !(( nCol1 & 0xC000 ) || ( nCol2 & 0xC000 )) )
+ {
+ ScRange aScRange;
+ nRow1 &= 0x3FFF;
+ nRow2 &= 0x3FFF;
+ if( GetAddressConverter().ConvertRange( aScRange, XclRange( nCol1, nRow1, nCol2, nRow2 ), nTab1, nTab2, true ) )
+ rRangeList.Append( aScRange );
+ }
+ break;
+
+ case 0x03: // Addition [312 264]
+ case 0x04: // Subtraction [313 264]
+ case 0x05: // Multiplication [313 264]
+ case 0x06: // Division [313 264]
+ case 0x07: // Exponetiation [313 265]
+ case 0x08: // Concatenation [313 265]
+ case 0x09: // Less Than [313 265]
+ case 0x0A: // Less Than or Equal [313 265]
+ case 0x0B: // Equal [313 265]
+ case 0x0C: // Greater Than or Equal [313 265]
+ case 0x0D: // Greater Than [313 265]
+ case 0x0E: // Not Equal [313 265]
+ case 0x0F: // Intersection [314 265]
+ case 0x10: // Union [314 265]
+ case 0x11: // Range [314 265]
+ case 0x12: // Unary Plus [312 264]
+ case 0x13: // Unary Minus [312 264]
+ case 0x14: // Percent Sign [312 264]
+ case 0x15: // Parenthesis [326 278]
+ case 0x16: // Missing Argument [314 266]
+ break;
+ case 0x1C: // Error Value [314 266]
+ case 0x1D: // Boolean [315 266]
+ nSeek = 1;
+ break;
+ case 0x1E: // Integer [315 266]
+ case 0x41:
+ case 0x61:
+ case 0x21: // Function, Fixed Number of Arguments [333 282]
+ case 0x49:
+ case 0x69:
+ case 0x29: // Variable Reference Subexpression [331 281]
+ case 0x4E:
+ case 0x6E:
+ case 0x2E: // Reference Subexpression Within a Name [332 282]
+ case 0x4F:
+ case 0x6F:
+ case 0x2F: // Incomplete Reference Subexpression... [332 282]
+ case 0x58:
+ case 0x78:
+ case 0x38: // Command-Equivalent Function [333 ]
+ nSeek = 2;
+ break;
+ case 0x42:
+ case 0x62:
+ case 0x22: // Function, Variable Number of Arg. [333 283]
+ case 0x4A:
+ case 0x6A:
+ case 0x2A: // Deleted Cell Reference [323 273]
+ nSeek = 3;
+ break;
+ case 0x01: // Array Formula [325 ]
+ // Array Formula or Shared Formula [ 277]
+ case 0x02: // Data Table [325 277]
+ nSeek = 4;
+ break;
+ case 0x46:
+ case 0x66:
+ case 0x26: // Constant Reference Subexpression [321 271]
+ case 0x47:
+ case 0x67:
+ case 0x27: // Erroneous Constant Reference Subexpr. [322 272]
+ case 0x48:
+ case 0x68:
+ case 0x28: // Incomplete Constant Reference Subexpr.[331 281]
+ case 0x4B:
+ case 0x6B:
+ case 0x2B: // Deleted Area Refernce [323 273]
+ nSeek = 6;
+ break;
+ case 0x40:
+ case 0x60:
+ case 0x20: // Array Constant [317 268]
+ nSeek = 7;
+ break;
+ case 0x1F: // Number [315 266]
+ nSeek = 8;
+ break;
+ case 0x43:
+ case 0x63:
+ case 0x23: // Name [318 269]
+ nSeek = 14;
+ break;
+ case 0x5C:
+ case 0x7C:
+ case 0x3C: // Deleted 3-D Cell Reference [ 277]
+ nSeek = 17;
+ break;
+ case 0x5D:
+ case 0x7D:
+ case 0x3D: // Deleted 3-D Area Reference [ 277]
+ nSeek = 20;
+ break;
+ case 0x59:
+ case 0x79:
+ case 0x39: // Name or External Name [ 275]
+ nSeek = 24;
+ break;
+ case 0x17: // String Constant [314 266]
+ nSeek = rStrm.ReaduInt8();
+ break;
+ case 0x19: // Special Attribute [327 279]
+ {
+ BYTE nOpt;
+ UINT16 nData;
+ rStrm >> nOpt >> nData;
+ if( nOpt & 0x04 )
+ nSeek = nData * 2 + 2;
+ }
+ break;
+ }
+
+ rStrm.Ignore( nSeek );
+ }
+ rStrm.Seek( nEndPos );
+
+ return rRangeList.Count() != 0;
+}
+
+void ExcelToSc::DoMulArgs( DefTokenId eId, sal_uInt8 nAnz, sal_uInt8 nMinParamCount )
+{
+ TokenId eParam[ 256 ];
+ INT32 nLauf;
+
+ if( eId == ocCeil || eId == ocFloor )
+ {
+ aStack << aPool.Store( 1.0 ); // default, da in Excel nicht vorhanden
+ nAnz++;
+ }
+
+ for( nLauf = 0; aStack.HasMoreTokens() && (nLauf < nAnz); nLauf++ )
+ aStack >> eParam[ nLauf ];
+ // #i70925# reduce parameter count, if no more tokens available on token stack
+ if( nLauf < nAnz )
+ nAnz = static_cast< sal_uInt8 >( nLauf );
+
+ if( nAnz > 0 && eId == ocExternal )
+ {
+ TokenId n = eParam[ nAnz - 1 ];
+//##### GRUETZE FUER BASIC-FUNCS RICHTEN!
+ if( const String* pExt = aPool.GetExternal( n ) )
+ {
+ if( const XclFunctionInfo* pFuncInfo = maFuncProv.GetFuncInfoFromXclMacroName( *pExt ) )
+ aPool << pFuncInfo->meOpCode;
+ else
+ aPool << n;
+ nAnz--;
+ }
+ else
+ aPool << eId;
+ }
+ else
+ aPool << eId;
+
+ aPool << ocOpen;
+
+ if( nAnz > 0 )
+ {
+ // attention: 0 = last parameter, nAnz-1 = first parameter
+ INT16 nNull = -1; // skip this parameter
+ INT16 nSkipEnd = -1; // skip all parameters <= nSkipEnd
+
+ INT16 nLast = nAnz - 1;
+
+ // Funktionen, bei denen Parameter wegfallen muessen
+ if( eId == ocPercentrank && nAnz == 3 )
+ nSkipEnd = 0; // letzten Parameter bei Bedarf weglassen
+
+ // Joost-Spezialfaelle
+ else if( eId == ocIf )
+ {
+ UINT16 nNullParam = 0;
+ for( nLauf = 0 ; nLauf < nAnz ; nLauf++ )
+ {
+ if( aPool.IsSingleOp( eParam[ nLauf ], ocMissing ) )
+ {
+ if( !nNullParam )
+ nNullParam = (UINT16) aPool.Store( ( double ) 0.0 );
+ eParam[ nLauf ] = nNullParam;
+ }
+ }
+ }
+
+ // FIXME: ideally we'd want to import all missing args, but this
+ // conflicts with lots of fn's understanding of nParams - we need
+ // a function table, and pre-call argument normalisation 1st.
+ INT16 nLastRemovable = nLast - nMinParamCount;
+
+ // #84453# skip missing parameters at end of parameter list
+ while( nSkipEnd < nLastRemovable &&
+ aPool.IsSingleOp( eParam[ nSkipEnd + 1 ], ocMissing ) )
+ nSkipEnd++;
+
+// fprintf (stderr, "Fn %d nSkipEnd %d nLast %d nMinParamCnt %d %d\n",
+// eId, nSkipEnd, nLast, nMinParamCount, nLastRemovable);
+
+ // [Parameter{;Parameter}]
+ if( nLast > nSkipEnd )
+ {
+ aPool << eParam[ nLast ];
+ for( nLauf = nLast - 1 ; nLauf > nSkipEnd ; nLauf-- )
+ {
+ if( nLauf != nNull )
+ aPool << ocSep << eParam[ nLauf ];
+ }
+ }
+ }
+ aPool << ocClose;
+
+ aPool >> aStack;
+}
+
+
+void ExcelToSc::ExcRelToScRel( UINT16 nRow, UINT8 nCol, ScSingleRefData &rSRD, const BOOL bName )
+{
+ if( bName )
+ {
+ // C O L
+ if( nRow & 0x4000 )
+ {// rel Col
+ rSRD.SetColRel( TRUE );
+ rSRD.nRelCol = static_cast<SCsCOL>(static_cast<INT8>(nCol));
+ }
+ else
+ {// abs Col
+ rSRD.SetColRel( FALSE );
+ rSRD.nCol = static_cast<SCCOL>(nCol);
+ }
+
+ // R O W
+ if( nRow & 0x8000 )
+ {// rel Row
+ rSRD.SetRowRel( TRUE );
+ if( nRow & 0x2000 ) // Bit 13 gesetzt?
+ // -> Row negativ
+ rSRD.nRelRow = static_cast<SCsROW>(static_cast<INT16>(nRow | 0xC000));
+ else
+ // -> Row positiv
+ rSRD.nRelRow = static_cast<SCsROW>(nRow & nRowMask);
+ }
+ else
+ {// abs Row
+ rSRD.SetRowRel( FALSE );
+ rSRD.nRow = static_cast<SCROW>(nRow & nRowMask);
+ }
+
+ // T A B
+ // #67965# abs needed if rel in shared formula for ScCompiler UpdateNameReference
+ if ( rSRD.IsTabRel() && !rSRD.IsFlag3D() )
+ rSRD.nTab = GetCurrScTab();
+ }
+ else
+ {
+ // C O L
+ rSRD.SetColRel( ( nRow & 0x4000 ) > 0 );
+ rSRD.nCol = static_cast<SCsCOL>(nCol);
+
+ // R O W
+ rSRD.SetRowRel( ( nRow & 0x8000 ) > 0 );
+ rSRD.nRow = static_cast<SCsROW>(nRow & nRowMask);
+
+ if ( rSRD.IsColRel() )
+ rSRD.nRelCol = rSRD.nCol - aEingPos.Col();
+ if ( rSRD.IsRowRel() )
+ rSRD.nRelRow = rSRD.nRow - aEingPos.Row();
+
+ // T A B
+ // #i10184# abs needed if rel in shared formula for ScCompiler UpdateNameReference
+ if ( rSRD.IsTabRel() && !rSRD.IsFlag3D() )
+ rSRD.nTab = GetCurrScTab() + rSRD.nRelTab;
+ }
+}
+
+
+const ScTokenArray* ExcelToSc::GetBoolErr( XclBoolError eType )
+{
+ UINT16 nError;
+ aPool.Reset();
+ aStack.Reset();
+
+ DefTokenId eOc;
+
+ switch( eType )
+ {
+ case xlErrNull: eOc = ocStop; nError = errNoCode; break;
+ case xlErrDiv0: eOc = ocStop; nError = errDivisionByZero; break;
+ case xlErrValue: eOc = ocStop; nError = errNoValue; break;
+ case xlErrRef: eOc = ocStop; nError = errNoRef; break;
+ case xlErrName: eOc = ocStop; nError = errNoName; break;
+ case xlErrNum: eOc = ocStop; nError = errIllegalFPOperation; break;
+ case xlErrNA: eOc = ocNotAvail; nError = NOTAVAILABLE; break;
+ case xlErrTrue: eOc = ocTrue; nError = 0; break;
+ case xlErrFalse: eOc = ocFalse; nError = 0; break;
+ case xlErrUnknown: eOc = ocStop; nError = errUnknownState; break;
+ default:
+ DBG_ERROR( "ExcelToSc::GetBoolErr - wrong enum!" );
+ eOc = ocNoName;
+ nError = errUnknownState;
+ }
+
+ aPool << eOc;
+ if( eOc != ocStop )
+ aPool << ocOpen << ocClose;
+
+ aPool >> aStack;
+
+ const ScTokenArray* pErgebnis = aPool[ aStack.Get() ];
+ if( nError )
+ ( ( ScTokenArray* ) pErgebnis )->SetCodeError( nError );
+
+ ( ( ScTokenArray* ) pErgebnis )->SetRecalcModeNormal();
+
+ return pErgebnis;
+}
+
+
+// if a shared formula was found, stream seeks to first byte after <nFormulaLen>,
+// else stream pointer stays unchanged
+BOOL ExcelToSc::GetShrFmla( const ScTokenArray*& rpErgebnis, XclImpStream& aIn, sal_Size nFormulaLen )
+{
+ BYTE nOp;
+ BOOL bRet = TRUE;
+
+ if( nFormulaLen == 0 )
+ bRet = FALSE;
+ else
+ {
+ aIn.PushPosition();
+
+ aIn >> nOp;
+
+ if( nOp == 0x01 ) // Shared Formula [ 277]
+ {
+ UINT16 nCol, nRow;
+
+ aIn >> nRow >> nCol;
+
+ aStack << aPool.Store( GetOldRoot().pShrfmlaBuff->Find(
+ ScAddress( static_cast<SCCOL>(nCol), static_cast<SCROW>(nRow), GetCurrScTab() ) ) );
+
+ bRet = TRUE;
+ }
+ else
+ bRet = FALSE;
+
+ aIn.PopPosition();
+ }
+
+ if( bRet )
+ {
+ aIn.Ignore( nFormulaLen );
+ rpErgebnis = aPool[ aStack.Get() ];
+ }
+ else
+ rpErgebnis = NULL;
+
+ return bRet;
+}
+
+
+#if 0
+BOOL ExcelToSc::SetCurVal( ScFormulaCell &rCell, double &rfCurVal )
+{
+ UINT16 nInd;
+ BYTE nType;
+ BYTE nVal;
+ BOOL bString = FALSE;
+
+#ifdef OSL_BIGENDIAN
+ // Code fuer alle anstaendigen Prozessoren
+ nType = *( ( ( BYTE * ) &rfCurVal ) + 7 );
+ nVal = *( ( ( BYTE * ) &rfCurVal ) + 5 );
+ nInd = *( ( UINT16 * ) &rfCurVal );
+#else
+ // fuer Schund-Prozessoren
+ nType = *( ( BYTE * ) &rfCurVal );
+ nVal = *( ( ( BYTE * ) &rfCurVal ) + 2 );
+ nInd = *( ( ( UINT16 * ) &rfCurVal ) + 3 );
+#endif
+
+ if( ( UINT16 ) ~nInd )
+ // Wert ist Float
+ rCell.SetHybridDouble( rfCurVal );
+ else
+ {
+ switch( nType )
+ {
+ case 0: // String
+ bString = TRUE;
+ break;
+ case 1: // Bool
+ if( nVal )
+ rfCurVal = 1.0;
+ else
+ rfCurVal = 0.0;
+ rCell.SetHybridDouble( rfCurVal );
+ break;
+ case 2: // Error
+ rCell.SetErrCode( XclTools::GetScErrorCode( nVal ) );
+ break;
+ }
+ }
+
+ return bString;
+}
+#endif
+
+
+void ExcelToSc::SetError( ScFormulaCell &rCell, const ConvErr eErr )
+{
+ UINT16 nInd;
+
+ switch( eErr )
+ {
+ case ConvErrNi: nInd = errUnknownToken; break;
+ case ConvErrNoMem: nInd = errCodeOverflow; break;
+ case ConvErrExternal: nInd = errNoName; break;
+ case ConvErrCount: nInd = errCodeOverflow; break;
+ default: nInd = errNoCode; // hier fiel mir nichts
+ // Besseres ein...
+ }
+
+ rCell.SetErrCode( nInd );
+}
+
+
+void ExcelToSc::SetComplCol( ScComplexRefData &rCRD )
+{
+ ScSingleRefData &rSRD = rCRD.Ref2;
+ if( rSRD.IsColRel() )
+ rSRD.nRelCol = MAXCOL - aEingPos.Col();
+ else
+ rSRD.nCol = MAXCOL;
+}
+
+
+void ExcelToSc::SetComplRow( ScComplexRefData &rCRD )
+{
+ ScSingleRefData &rSRD = rCRD.Ref2;
+ if( rSRD.IsRowRel() )
+ rSRD.nRelRow = MAXROW - aEingPos.Row();
+ else
+ rSRD.nRow = MAXROW;
+}
+
+void ExcelToSc::ReadExtensionArray( unsigned int n, XclImpStream& aIn )
+{
+ // printf( "inline array;\n" );
+
+ BYTE nByte;
+ UINT16 nUINT16;
+ double fDouble;
+ String aString;
+ ScMatrix* pMatrix;
+
+ aIn >> nByte >> nUINT16;
+
+ SCSIZE nC, nCols;
+ SCSIZE nR, nRows;
+ if( GetBiff() == EXC_BIFF8 )
+ {
+ nCols = nByte + 1;
+ nRows = nUINT16 + 1;
+ }
+ else
+ {
+ nCols = nByte ? nByte : 256;
+ nRows = nUINT16;
+ }
+
+ pMatrix = aPool.GetMatrix( n );
+
+ if( NULL != pMatrix )
+ {
+ pMatrix->Resize(nCols, nRows);
+ pMatrix->GetDimensions( nC, nR);
+ if( nC != nCols || nR != nRows )
+ {
+ DBG_ERRORFILE( "ExcelToSc::ReadExtensionArray - matrix size mismatch" );
+ pMatrix = NULL;
+ }
+ }
+ else
+ {
+ DBG_ERRORFILE( "ExcelToSc::ReadExtensionArray - missing matrix" );
+ }
+
+ for( nR = 0 ; nR < nRows; nR++ )
+ {
+ for( nC = 0 ; nC < nCols; nC++ )
+ {
+ aIn >> nByte;
+ switch( nByte )
+ {
+ case EXC_CACHEDVAL_EMPTY:
+ aIn.Ignore( 8 );
+ if( NULL != pMatrix )
+ {
+ pMatrix->PutEmpty( nC, nR );
+ }
+ break;
+
+ case EXC_CACHEDVAL_DOUBLE:
+ aIn >> fDouble;
+ if( NULL != pMatrix )
+ {
+ pMatrix->PutDouble( fDouble, nC, nR );
+ }
+ break;
+
+ case EXC_CACHEDVAL_STRING:
+ if( GetBiff() == EXC_BIFF8 )
+ {
+ aIn >> nUINT16;
+ aString = aIn.ReadUniString( nUINT16 );
+ }
+ else
+ {
+ aIn >> nByte;
+ aString = aIn.ReadRawByteString( nByte );
+ }
+ if( NULL != pMatrix )
+ {
+ pMatrix->PutString( aString, nC, nR );
+ }
+ break;
+
+ case EXC_CACHEDVAL_BOOL:
+ aIn >> nByte;
+ aIn.Ignore( 7 );
+ if( NULL != pMatrix )
+ {
+ pMatrix->PutBoolean( nByte != 0, nC, nR );
+ }
+ break;
+
+ case EXC_CACHEDVAL_ERROR:
+ aIn >> nByte;
+ aIn.Ignore( 7 );
+ if( NULL != pMatrix )
+ {
+ pMatrix->PutError( XclTools::GetScErrorCode( nByte ), nC, nR );
+ }
+ break;
+ }
+ }
+ }
+}
+
+void ExcelToSc::ReadExtensionNlr( XclImpStream& aIn )
+{
+ // printf( "natural lang fmla;\n" );
+
+ sal_uInt32 nFlags;
+ aIn >> nFlags;
+
+ sal_uInt32 nCount = nFlags & EXC_TOK_NLR_ADDMASK;
+ aIn.Ignore( nCount * 4 ); // Drop the cell positions
+}
+
+void ExcelToSc::ReadExtensionMemArea( XclImpStream& aIn )
+{
+ // printf( "mem area;\n" );
+
+ sal_uInt16 nCount;
+ aIn >> nCount;
+
+ aIn.Ignore( nCount * ((GetBiff() == EXC_BIFF8) ? 8 : 6) ); // drop the ranges
+}
+
+void ExcelToSc::ReadExtensions( const ExtensionTypeVec& rExtensions,
+ XclImpStream& aIn )
+{
+ unsigned int nArray = 0;
+
+ for( unsigned int i = 0 ; i < rExtensions.size() ; i++ )
+ {
+ ExtensionType eType = rExtensions[i];
+
+ switch( eType )
+ {
+ case EXTENSION_ARRAY:
+ ReadExtensionArray( nArray++, aIn );
+ break;
+
+ case EXTENSION_NLR:
+ ReadExtensionNlr( aIn );
+ break;
+
+ case EXTENSION_MEMAREA:
+ ReadExtensionMemArea( aIn );
+ break;
+ }
+ }
+}
+