1*ca5ec200SAndrew Rist /**************************************************************
2cdf0e10cSrcweir *
3*ca5ec200SAndrew Rist * Licensed to the Apache Software Foundation (ASF) under one
4*ca5ec200SAndrew Rist * or more contributor license agreements. See the NOTICE file
5*ca5ec200SAndrew Rist * distributed with this work for additional information
6*ca5ec200SAndrew Rist * regarding copyright ownership. The ASF licenses this file
7*ca5ec200SAndrew Rist * to you under the Apache License, Version 2.0 (the
8*ca5ec200SAndrew Rist * "License"); you may not use this file except in compliance
9*ca5ec200SAndrew Rist * with the License. You may obtain a copy of the License at
10cdf0e10cSrcweir *
11*ca5ec200SAndrew Rist * http://www.apache.org/licenses/LICENSE-2.0
12cdf0e10cSrcweir *
13*ca5ec200SAndrew Rist * Unless required by applicable law or agreed to in writing,
14*ca5ec200SAndrew Rist * software distributed under the License is distributed on an
15*ca5ec200SAndrew Rist * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
16*ca5ec200SAndrew Rist * KIND, either express or implied. See the License for the
17*ca5ec200SAndrew Rist * specific language governing permissions and limitations
18*ca5ec200SAndrew Rist * under the License.
19cdf0e10cSrcweir *
20*ca5ec200SAndrew Rist *************************************************************/
21*ca5ec200SAndrew Rist
22*ca5ec200SAndrew Rist
23cdf0e10cSrcweir
24cdf0e10cSrcweir #include "oox/xls/formulaparser.hxx"
25cdf0e10cSrcweir
26cdf0e10cSrcweir #include <com/sun/star/lang/XMultiServiceFactory.hpp>
27cdf0e10cSrcweir #include <com/sun/star/sheet/ComplexReference.hpp>
28cdf0e10cSrcweir #include <com/sun/star/sheet/ExternalReference.hpp>
29cdf0e10cSrcweir #include <com/sun/star/sheet/FormulaToken.hpp>
30cdf0e10cSrcweir #include <com/sun/star/sheet/ReferenceFlags.hpp>
31cdf0e10cSrcweir #include <com/sun/star/sheet/SingleReference.hpp>
32cdf0e10cSrcweir #include "oox/core/filterbase.hxx"
33cdf0e10cSrcweir #include "oox/xls/addressconverter.hxx"
34cdf0e10cSrcweir #include "oox/xls/biffinputstream.hxx"
35cdf0e10cSrcweir #include "oox/xls/defnamesbuffer.hxx"
36cdf0e10cSrcweir #include "oox/xls/externallinkbuffer.hxx"
37cdf0e10cSrcweir #include "oox/xls/tablebuffer.hxx"
38cdf0e10cSrcweir #include "oox/xls/worksheethelper.hxx"
39cdf0e10cSrcweir
40cdf0e10cSrcweir namespace oox {
41cdf0e10cSrcweir namespace xls {
42cdf0e10cSrcweir
43cdf0e10cSrcweir // ============================================================================
44cdf0e10cSrcweir
45cdf0e10cSrcweir using namespace ::com::sun::star::sheet;
46cdf0e10cSrcweir using namespace ::com::sun::star::sheet::ReferenceFlags;
47cdf0e10cSrcweir using namespace ::com::sun::star::table;
48cdf0e10cSrcweir using namespace ::com::sun::star::uno;
49cdf0e10cSrcweir
50cdf0e10cSrcweir using ::rtl::OUString;
51cdf0e10cSrcweir
52cdf0e10cSrcweir // ============================================================================
53cdf0e10cSrcweir
54cdf0e10cSrcweir namespace {
55cdf0e10cSrcweir
lclReadFmlaSize(BiffInputStream & rStrm,BiffType eBiff,const sal_uInt16 * pnFmlaSize)56cdf0e10cSrcweir sal_uInt16 lclReadFmlaSize( BiffInputStream& rStrm, BiffType eBiff, const sal_uInt16* pnFmlaSize )
57cdf0e10cSrcweir {
58cdf0e10cSrcweir return pnFmlaSize ? *pnFmlaSize : ((eBiff == BIFF2) ? rStrm.readuInt8() : rStrm.readuInt16());
59cdf0e10cSrcweir }
60cdf0e10cSrcweir
61cdf0e10cSrcweir } // namespace
62cdf0e10cSrcweir
63cdf0e10cSrcweir // formula finalizer ==========================================================
64cdf0e10cSrcweir
FormulaFinalizer(const OpCodeProvider & rOpCodeProv)65cdf0e10cSrcweir FormulaFinalizer::FormulaFinalizer( const OpCodeProvider& rOpCodeProv ) :
66cdf0e10cSrcweir OpCodeProvider( rOpCodeProv ),
67cdf0e10cSrcweir ApiOpCodes( getOpCodes() )
68cdf0e10cSrcweir {
69cdf0e10cSrcweir maTokens.reserve( 0x2000 );
70cdf0e10cSrcweir }
71cdf0e10cSrcweir
finalizeTokenArray(const ApiTokenSequence & rTokens)72cdf0e10cSrcweir ApiTokenSequence FormulaFinalizer::finalizeTokenArray( const ApiTokenSequence& rTokens )
73cdf0e10cSrcweir {
74cdf0e10cSrcweir maTokens.clear();
75cdf0e10cSrcweir if( rTokens.hasElements() )
76cdf0e10cSrcweir {
77cdf0e10cSrcweir const ApiToken* pToken = rTokens.getConstArray();
78cdf0e10cSrcweir processTokens( pToken, pToken + rTokens.getLength() );
79cdf0e10cSrcweir }
80cdf0e10cSrcweir return ContainerHelper::vectorToSequence( maTokens );
81cdf0e10cSrcweir }
82cdf0e10cSrcweir
resolveBadFuncName(const OUString &) const83cdf0e10cSrcweir const FunctionInfo* FormulaFinalizer::resolveBadFuncName( const OUString& ) const
84cdf0e10cSrcweir {
85cdf0e10cSrcweir return 0;
86cdf0e10cSrcweir }
87cdf0e10cSrcweir
resolveDefinedName(sal_Int32) const88cdf0e10cSrcweir OUString FormulaFinalizer::resolveDefinedName( sal_Int32 ) const
89cdf0e10cSrcweir {
90cdf0e10cSrcweir return OUString();
91cdf0e10cSrcweir }
92cdf0e10cSrcweir
getFunctionInfo(ApiToken & orFuncToken)93cdf0e10cSrcweir const FunctionInfo* FormulaFinalizer::getFunctionInfo( ApiToken& orFuncToken )
94cdf0e10cSrcweir {
95cdf0e10cSrcweir // first, try to find a regular function info from token op-code
96cdf0e10cSrcweir if( const FunctionInfo* pRegFuncInfo = getFuncInfoFromApiToken( orFuncToken ) )
97cdf0e10cSrcweir return pRegFuncInfo;
98cdf0e10cSrcweir
99cdf0e10cSrcweir // try to recognize a function from an external library
100cdf0e10cSrcweir if( (orFuncToken.OpCode == OPCODE_BAD) && orFuncToken.Data.has< OUString >() )
101cdf0e10cSrcweir {
102cdf0e10cSrcweir // virtual call to resolveBadFuncName()
103cdf0e10cSrcweir if( const FunctionInfo* pLibFuncInfo = resolveBadFuncName( orFuncToken.Data.get< OUString >() ) )
104cdf0e10cSrcweir {
105cdf0e10cSrcweir // write function op-code to the OPCODE_BAD token
106cdf0e10cSrcweir orFuncToken.OpCode = pLibFuncInfo->mnApiOpCode;
107cdf0e10cSrcweir // if it is an external function, insert programmatic function name
108cdf0e10cSrcweir if( (orFuncToken.OpCode == OPCODE_EXTERNAL) && (pLibFuncInfo->maExtProgName.getLength() > 0) )
109cdf0e10cSrcweir orFuncToken.Data <<= pLibFuncInfo->maExtProgName;
110cdf0e10cSrcweir else
111cdf0e10cSrcweir orFuncToken.Data.clear(); // clear string from OPCODE_BAD
112cdf0e10cSrcweir return pLibFuncInfo;
113cdf0e10cSrcweir }
114cdf0e10cSrcweir }
115cdf0e10cSrcweir
116cdf0e10cSrcweir // no success - return null
117cdf0e10cSrcweir return 0;
118cdf0e10cSrcweir }
119cdf0e10cSrcweir
getExternCallInfo(ApiToken & orFuncToken,const ApiToken & rECToken)120cdf0e10cSrcweir const FunctionInfo* FormulaFinalizer::getExternCallInfo( ApiToken& orFuncToken, const ApiToken& rECToken )
121cdf0e10cSrcweir {
122cdf0e10cSrcweir // try to resolve the passed token to a supported sheet function
123cdf0e10cSrcweir if( const FunctionInfo* pFuncInfo = getFuncInfoFromApiToken( rECToken ) )
124cdf0e10cSrcweir {
125cdf0e10cSrcweir orFuncToken.OpCode = pFuncInfo->mnApiOpCode;
126cdf0e10cSrcweir // programmatic add-in function name
127cdf0e10cSrcweir if( (pFuncInfo->mnApiOpCode == OPCODE_EXTERNAL) && (pFuncInfo->maExtProgName.getLength() > 0) )
128cdf0e10cSrcweir orFuncToken.Data <<= pFuncInfo->maExtProgName;
129cdf0e10cSrcweir // name of unsupported function, convert to OPCODE_BAD to preserve the name
130cdf0e10cSrcweir else if( (pFuncInfo->mnApiOpCode == OPCODE_BAD) && (pFuncInfo->maOoxFuncName.getLength() > 0) )
131cdf0e10cSrcweir orFuncToken.Data <<= pFuncInfo->maOoxFuncName;
132cdf0e10cSrcweir return pFuncInfo;
133cdf0e10cSrcweir }
134cdf0e10cSrcweir
135cdf0e10cSrcweir // macro call or unknown function name, move data to function token
136cdf0e10cSrcweir if( (rECToken.OpCode == OPCODE_MACRO) || (rECToken.OpCode == OPCODE_BAD) )
137cdf0e10cSrcweir orFuncToken = rECToken;
138cdf0e10cSrcweir
139cdf0e10cSrcweir // defined name used as function call, convert to OPCODE_BAD to preserve the name
140cdf0e10cSrcweir if( (rECToken.OpCode == OPCODE_NAME) && rECToken.Data.has< sal_Int32 >() )
141cdf0e10cSrcweir {
142cdf0e10cSrcweir OUString aDefName = resolveDefinedName( rECToken.Data.get< sal_Int32 >() );
143cdf0e10cSrcweir if( aDefName.getLength() > 0 )
144cdf0e10cSrcweir {
145cdf0e10cSrcweir orFuncToken.OpCode = OPCODE_BAD;
146cdf0e10cSrcweir orFuncToken.Data <<= aDefName;
147cdf0e10cSrcweir }
148cdf0e10cSrcweir }
149cdf0e10cSrcweir
150cdf0e10cSrcweir return 0;
151cdf0e10cSrcweir }
152cdf0e10cSrcweir
processTokens(const ApiToken * pToken,const ApiToken * pTokenEnd)153cdf0e10cSrcweir void FormulaFinalizer::processTokens( const ApiToken* pToken, const ApiToken* pTokenEnd )
154cdf0e10cSrcweir {
155cdf0e10cSrcweir while( pToken < pTokenEnd )
156cdf0e10cSrcweir {
157cdf0e10cSrcweir // push the current token into the vector
158cdf0e10cSrcweir bool bValid = appendFinalToken( *pToken );
159cdf0e10cSrcweir // try to process a function
160cdf0e10cSrcweir if( const FunctionInfo* pFuncInfo = bValid ? getFunctionInfo( maTokens.back() ) : 0 )
161cdf0e10cSrcweir pToken = processParameters( *pFuncInfo, pToken + 1, pTokenEnd );
162cdf0e10cSrcweir // otherwise, go to next token
163cdf0e10cSrcweir else
164cdf0e10cSrcweir ++pToken;
165cdf0e10cSrcweir }
166cdf0e10cSrcweir }
167cdf0e10cSrcweir
processParameters(const FunctionInfo & rFuncInfo,const ApiToken * pToken,const ApiToken * pTokenEnd)168cdf0e10cSrcweir const ApiToken* FormulaFinalizer::processParameters(
169cdf0e10cSrcweir const FunctionInfo& rFuncInfo, const ApiToken* pToken, const ApiToken* pTokenEnd )
170cdf0e10cSrcweir {
171cdf0e10cSrcweir // remember position of the token containing the function op-code
172cdf0e10cSrcweir size_t nFuncNameIdx = maTokens.size() - 1;
173cdf0e10cSrcweir
174cdf0e10cSrcweir // process a function, if an OPCODE_OPEN token is following
175cdf0e10cSrcweir OSL_ENSURE( (pToken < pTokenEnd) && (pToken->OpCode == OPCODE_OPEN), "FormulaFinalizer::processParameters - OPCODE_OPEN expected" );
176cdf0e10cSrcweir if( (pToken < pTokenEnd) && (pToken->OpCode == OPCODE_OPEN) )
177cdf0e10cSrcweir {
178cdf0e10cSrcweir // append the OPCODE_OPEN token to the vector
179cdf0e10cSrcweir maTokens.append( OPCODE_OPEN );
180cdf0e10cSrcweir
181cdf0e10cSrcweir // store positions of OPCODE_OPEN, parameter separators, and OPCODE_CLOSE
182cdf0e10cSrcweir ParameterPosVector aParams;
183cdf0e10cSrcweir pToken = findParameters( aParams, pToken, pTokenEnd );
184cdf0e10cSrcweir OSL_ENSURE( aParams.size() >= 2, "FormulaFinalizer::processParameters - missing tokens" );
185cdf0e10cSrcweir size_t nParamCount = aParams.size() - 1;
186cdf0e10cSrcweir
187cdf0e10cSrcweir if( (nParamCount == 1) && isEmptyParameter( aParams[ 0 ] + 1, aParams[ 1 ] ) )
188cdf0e10cSrcweir {
189cdf0e10cSrcweir /* Empty pair of parentheses -> function call without parameters,
190cdf0e10cSrcweir process parameter, there might be spaces between parentheses. */
191cdf0e10cSrcweir processTokens( aParams[ 0 ] + 1, aParams[ 1 ] );
192cdf0e10cSrcweir }
193cdf0e10cSrcweir else
194cdf0e10cSrcweir {
195cdf0e10cSrcweir const FunctionInfo* pRealFuncInfo = &rFuncInfo;
196cdf0e10cSrcweir ParameterPosVector::const_iterator aPosIt = aParams.begin();
197cdf0e10cSrcweir
198cdf0e10cSrcweir /* Preprocess EXTERN.CALL functions. The actual function name is
199cdf0e10cSrcweir contained as reference to a defined name in the first (hidden)
200cdf0e10cSrcweir parameter. */
201cdf0e10cSrcweir if( rFuncInfo.mnBiffFuncId == BIFF_FUNC_EXTERNCALL )
202cdf0e10cSrcweir {
203cdf0e10cSrcweir ApiToken& rFuncToken = maTokens[ nFuncNameIdx ];
204cdf0e10cSrcweir rFuncToken.OpCode = OPCODE_NONAME;
205cdf0e10cSrcweir
206cdf0e10cSrcweir // try to initialize function token from first parameter
207cdf0e10cSrcweir if( const ApiToken* pECToken = getSingleToken( *aPosIt + 1, *(aPosIt + 1) ) )
208cdf0e10cSrcweir if( const FunctionInfo* pECFuncInfo = getExternCallInfo( rFuncToken, *pECToken ) )
209cdf0e10cSrcweir pRealFuncInfo = pECFuncInfo;
210cdf0e10cSrcweir
211cdf0e10cSrcweir /* On success (something has been inserted into rFuncToken),
212cdf0e10cSrcweir skip the first parameter. */
213cdf0e10cSrcweir if( rFuncToken.OpCode != OPCODE_NONAME )
214cdf0e10cSrcweir {
215cdf0e10cSrcweir --nParamCount;
216cdf0e10cSrcweir ++aPosIt;
217cdf0e10cSrcweir }
218cdf0e10cSrcweir }
219cdf0e10cSrcweir
220cdf0e10cSrcweir // process all parameters
221cdf0e10cSrcweir FunctionParamInfoIterator aParamInfoIt( *pRealFuncInfo );
222cdf0e10cSrcweir size_t nLastValidSize = maTokens.size();
223cdf0e10cSrcweir size_t nLastValidCount = 0;
224cdf0e10cSrcweir for( size_t nParam = 0; nParam < nParamCount; ++nParam, ++aPosIt, ++aParamInfoIt )
225cdf0e10cSrcweir {
226cdf0e10cSrcweir // add embedded Calc-only parameters
227cdf0e10cSrcweir if( aParamInfoIt.isCalcOnlyParam() )
228cdf0e10cSrcweir {
229cdf0e10cSrcweir appendCalcOnlyParameter( *pRealFuncInfo, nParam );
230cdf0e10cSrcweir while( aParamInfoIt.isCalcOnlyParam() ) ++aParamInfoIt;
231cdf0e10cSrcweir }
232cdf0e10cSrcweir
233cdf0e10cSrcweir const ApiToken* pParamBegin = *aPosIt + 1;
234cdf0e10cSrcweir const ApiToken* pParamEnd = *(aPosIt + 1);
235cdf0e10cSrcweir bool bIsEmpty = isEmptyParameter( pParamBegin, pParamEnd );
236cdf0e10cSrcweir
237cdf0e10cSrcweir if( !aParamInfoIt.isExcelOnlyParam() )
238cdf0e10cSrcweir {
239cdf0e10cSrcweir // handle empty parameters
240cdf0e10cSrcweir if( bIsEmpty )
241cdf0e10cSrcweir {
242cdf0e10cSrcweir // append leading space tokens from original token array
243cdf0e10cSrcweir while( (pParamBegin < pParamEnd) && (pParamBegin->OpCode == OPCODE_SPACES) )
244cdf0e10cSrcweir maTokens.push_back( *pParamBegin++ );
245cdf0e10cSrcweir // add default values for some empty parameters, or the OPCODE_MISSING token
246cdf0e10cSrcweir appendEmptyParameter( *pRealFuncInfo, nParam );
247cdf0e10cSrcweir // reset bIsEmpty flag, if something has been appended in appendEmptyParameter()
248cdf0e10cSrcweir bIsEmpty = maTokens.back().OpCode == OPCODE_MISSING;
249cdf0e10cSrcweir // skip OPCODE_MISSING token in the original token array
250cdf0e10cSrcweir OSL_ENSURE( (pParamBegin == pParamEnd) || (pParamBegin->OpCode == OPCODE_MISSING), "FormulaFinalizer::processParameters - OPCODE_MISSING expected" );
251cdf0e10cSrcweir if( pParamBegin < pParamEnd ) ++pParamBegin;
252cdf0e10cSrcweir // append trailing space tokens from original token array
253cdf0e10cSrcweir while( (pParamBegin < pParamEnd) && (pParamBegin->OpCode == OPCODE_SPACES) )
254cdf0e10cSrcweir maTokens.push_back( *pParamBegin++ );
255cdf0e10cSrcweir }
256cdf0e10cSrcweir else
257cdf0e10cSrcweir {
258cdf0e10cSrcweir // if parameter is not empty, process all tokens of the parameter
259cdf0e10cSrcweir processTokens( pParamBegin, pParamEnd );
260cdf0e10cSrcweir }
261cdf0e10cSrcweir
262cdf0e10cSrcweir // append parameter separator token
263cdf0e10cSrcweir maTokens.append( OPCODE_SEP );
264cdf0e10cSrcweir }
265cdf0e10cSrcweir
266cdf0e10cSrcweir /* #84453# Update size of new token sequence with valid parameters
267cdf0e10cSrcweir to be able to remove trailing optional empty parameters. */
268cdf0e10cSrcweir if( !bIsEmpty || (nParam < pRealFuncInfo->mnMinParamCount) )
269cdf0e10cSrcweir {
270cdf0e10cSrcweir nLastValidSize = maTokens.size();
271cdf0e10cSrcweir nLastValidCount = nParam + 1;
272cdf0e10cSrcweir }
273cdf0e10cSrcweir }
274cdf0e10cSrcweir
275cdf0e10cSrcweir // #84453# remove trailing optional empty parameters
276cdf0e10cSrcweir maTokens.resize( nLastValidSize );
277cdf0e10cSrcweir
278cdf0e10cSrcweir // add trailing Calc-only parameters
279cdf0e10cSrcweir if( aParamInfoIt.isCalcOnlyParam() )
280cdf0e10cSrcweir appendCalcOnlyParameter( *pRealFuncInfo, nLastValidCount );
281cdf0e10cSrcweir
282cdf0e10cSrcweir // add optional parameters that are required in Calc
283cdf0e10cSrcweir appendRequiredParameters( *pRealFuncInfo, nLastValidCount );
284cdf0e10cSrcweir
285cdf0e10cSrcweir // remove last parameter separator token
286cdf0e10cSrcweir if( maTokens.back().OpCode == OPCODE_SEP )
287cdf0e10cSrcweir maTokens.pop_back();
288cdf0e10cSrcweir }
289cdf0e10cSrcweir
290cdf0e10cSrcweir /* Append the OPCODE_CLOSE token to the vector, but only if there is
291cdf0e10cSrcweir no OPCODE_BAD token at the end, this token already contains the
292cdf0e10cSrcweir trailing closing parentheses. */
293cdf0e10cSrcweir if( (pTokenEnd - 1)->OpCode != OPCODE_BAD )
294cdf0e10cSrcweir maTokens.append( OPCODE_CLOSE );
295cdf0e10cSrcweir }
296cdf0e10cSrcweir
297cdf0e10cSrcweir /* Replace OPCODE_EXTERNAL with OPCODE_NONAME to get #NAME! error in cell,
298cdf0e10cSrcweir if no matching add-in function was found. */
299cdf0e10cSrcweir ApiToken& rFuncNameToken = maTokens[ nFuncNameIdx ];
300cdf0e10cSrcweir if( (rFuncNameToken.OpCode == OPCODE_EXTERNAL) && !rFuncNameToken.Data.hasValue() )
301cdf0e10cSrcweir rFuncNameToken.OpCode = OPCODE_NONAME;
302cdf0e10cSrcweir
303cdf0e10cSrcweir return pToken;
304cdf0e10cSrcweir }
305cdf0e10cSrcweir
isEmptyParameter(const ApiToken * pToken,const ApiToken * pTokenEnd) const306cdf0e10cSrcweir bool FormulaFinalizer::isEmptyParameter( const ApiToken* pToken, const ApiToken* pTokenEnd ) const
307cdf0e10cSrcweir {
308cdf0e10cSrcweir while( (pToken < pTokenEnd) && (pToken->OpCode == OPCODE_SPACES) ) ++pToken;
309cdf0e10cSrcweir if( (pToken < pTokenEnd) && (pToken->OpCode == OPCODE_MISSING) ) ++pToken;
310cdf0e10cSrcweir while( (pToken < pTokenEnd) && (pToken->OpCode == OPCODE_SPACES) ) ++pToken;
311cdf0e10cSrcweir return pToken == pTokenEnd;
312cdf0e10cSrcweir }
313cdf0e10cSrcweir
getSingleToken(const ApiToken * pToken,const ApiToken * pTokenEnd) const314cdf0e10cSrcweir const ApiToken* FormulaFinalizer::getSingleToken( const ApiToken* pToken, const ApiToken* pTokenEnd ) const
315cdf0e10cSrcweir {
316cdf0e10cSrcweir const ApiToken* pSingleToken = 0;
317cdf0e10cSrcweir // skip leading whitespace tokens
318cdf0e10cSrcweir while( (pToken < pTokenEnd) && (pToken->OpCode == OPCODE_SPACES) ) ++pToken;
319cdf0e10cSrcweir // remember first non-whitespace token
320cdf0e10cSrcweir if( pToken < pTokenEnd ) pSingleToken = pToken++;
321cdf0e10cSrcweir // skip trailing whitespace tokens
322cdf0e10cSrcweir while( (pToken < pTokenEnd) && (pToken->OpCode == OPCODE_SPACES) ) ++pToken;
323cdf0e10cSrcweir // return null, if other non-whitespace tokens follow
324cdf0e10cSrcweir return (pToken == pTokenEnd) ? pSingleToken : 0;
325cdf0e10cSrcweir }
326cdf0e10cSrcweir
skipParentheses(const ApiToken * pToken,const ApiToken * pTokenEnd) const327cdf0e10cSrcweir const ApiToken* FormulaFinalizer::skipParentheses( const ApiToken* pToken, const ApiToken* pTokenEnd ) const
328cdf0e10cSrcweir {
329cdf0e10cSrcweir // skip tokens between OPCODE_OPEN and OPCODE_CLOSE
330cdf0e10cSrcweir OSL_ENSURE( (pToken < pTokenEnd) && (pToken->OpCode == OPCODE_OPEN), "skipParentheses - OPCODE_OPEN expected" );
331cdf0e10cSrcweir ++pToken;
332cdf0e10cSrcweir while( (pToken < pTokenEnd) && (pToken->OpCode != OPCODE_CLOSE) )
333cdf0e10cSrcweir {
334cdf0e10cSrcweir if( pToken->OpCode == OPCODE_OPEN )
335cdf0e10cSrcweir pToken = skipParentheses( pToken, pTokenEnd );
336cdf0e10cSrcweir else
337cdf0e10cSrcweir ++pToken;
338cdf0e10cSrcweir }
339cdf0e10cSrcweir // skip the OPCODE_CLOSE token
340cdf0e10cSrcweir OSL_ENSURE( ((pToken < pTokenEnd) && (pToken->OpCode == OPCODE_CLOSE)) || ((pTokenEnd - 1)->OpCode == OPCODE_BAD), "skipParentheses - OPCODE_CLOSE expected" );
341cdf0e10cSrcweir return (pToken < pTokenEnd) ? (pToken + 1) : pTokenEnd;
342cdf0e10cSrcweir }
343cdf0e10cSrcweir
findParameters(ParameterPosVector & rParams,const ApiToken * pToken,const ApiToken * pTokenEnd) const344cdf0e10cSrcweir const ApiToken* FormulaFinalizer::findParameters( ParameterPosVector& rParams,
345cdf0e10cSrcweir const ApiToken* pToken, const ApiToken* pTokenEnd ) const
346cdf0e10cSrcweir {
347cdf0e10cSrcweir // push position of OPCODE_OPEN
348cdf0e10cSrcweir OSL_ENSURE( (pToken < pTokenEnd) && (pToken->OpCode == OPCODE_OPEN), "FormulaFinalizer::findParameters - OPCODE_OPEN expected" );
349cdf0e10cSrcweir rParams.push_back( pToken++ );
350cdf0e10cSrcweir
351cdf0e10cSrcweir // find positions of parameter separators
352cdf0e10cSrcweir while( (pToken < pTokenEnd) && (pToken->OpCode != OPCODE_CLOSE) )
353cdf0e10cSrcweir {
354cdf0e10cSrcweir if( pToken->OpCode == OPCODE_OPEN )
355cdf0e10cSrcweir pToken = skipParentheses( pToken, pTokenEnd );
356cdf0e10cSrcweir else if( pToken->OpCode == OPCODE_SEP )
357cdf0e10cSrcweir rParams.push_back( pToken++ );
358cdf0e10cSrcweir else
359cdf0e10cSrcweir ++pToken;
360cdf0e10cSrcweir }
361cdf0e10cSrcweir
362cdf0e10cSrcweir // push position of OPCODE_CLOSE
363cdf0e10cSrcweir OSL_ENSURE( ((pToken < pTokenEnd) && (pToken->OpCode == OPCODE_CLOSE)) || ((pTokenEnd - 1)->OpCode == OPCODE_BAD), "FormulaFinalizer::findParameters - OPCODE_CLOSE expected" );
364cdf0e10cSrcweir rParams.push_back( pToken );
365cdf0e10cSrcweir return (pToken < pTokenEnd) ? (pToken + 1) : pTokenEnd;
366cdf0e10cSrcweir }
367cdf0e10cSrcweir
appendEmptyParameter(const FunctionInfo & rFuncInfo,size_t nParam)368cdf0e10cSrcweir void FormulaFinalizer::appendEmptyParameter( const FunctionInfo& rFuncInfo, size_t nParam )
369cdf0e10cSrcweir {
370cdf0e10cSrcweir // remeber old size of the token array
371cdf0e10cSrcweir size_t nTokenArraySize = maTokens.size();
372cdf0e10cSrcweir
373cdf0e10cSrcweir switch( rFuncInfo.mnBiff12FuncId )
374cdf0e10cSrcweir {
375cdf0e10cSrcweir case BIFF_FUNC_IF:
376cdf0e10cSrcweir if( (nParam == 1) || (nParam == 2) )
377cdf0e10cSrcweir maTokens.append< double >( OPCODE_PUSH, 0.0 );
378cdf0e10cSrcweir break;
379cdf0e10cSrcweir default:;
380cdf0e10cSrcweir }
381cdf0e10cSrcweir
382cdf0e10cSrcweir // if no token has been added, append a OPCODE_MISSING token
383cdf0e10cSrcweir if( nTokenArraySize == maTokens.size() )
384cdf0e10cSrcweir maTokens.append( OPCODE_MISSING );
385cdf0e10cSrcweir }
386cdf0e10cSrcweir
appendCalcOnlyParameter(const FunctionInfo & rFuncInfo,size_t nParam)387cdf0e10cSrcweir void FormulaFinalizer::appendCalcOnlyParameter( const FunctionInfo& rFuncInfo, size_t nParam )
388cdf0e10cSrcweir {
389cdf0e10cSrcweir (void)nParam; // prevent 'unused' warning
390cdf0e10cSrcweir switch( rFuncInfo.mnBiff12FuncId )
391cdf0e10cSrcweir {
392cdf0e10cSrcweir case BIFF_FUNC_FLOOR:
393cdf0e10cSrcweir case BIFF_FUNC_CEILING:
394cdf0e10cSrcweir OSL_ENSURE( nParam == 2, "FormulaFinalizer::appendCalcOnlyParameter - unexpected parameter index" );
395cdf0e10cSrcweir maTokens.append< double >( OPCODE_PUSH, 1.0 );
396cdf0e10cSrcweir maTokens.append( OPCODE_SEP );
397cdf0e10cSrcweir break;
398cdf0e10cSrcweir }
399cdf0e10cSrcweir }
400cdf0e10cSrcweir
appendRequiredParameters(const FunctionInfo & rFuncInfo,size_t nParamCount)401cdf0e10cSrcweir void FormulaFinalizer::appendRequiredParameters( const FunctionInfo& rFuncInfo, size_t nParamCount )
402cdf0e10cSrcweir {
403cdf0e10cSrcweir switch( rFuncInfo.mnBiff12FuncId )
404cdf0e10cSrcweir {
405cdf0e10cSrcweir case BIFF_FUNC_WEEKNUM:
406cdf0e10cSrcweir if( nParamCount == 1 )
407cdf0e10cSrcweir {
408cdf0e10cSrcweir maTokens.append< double >( OPCODE_PUSH, 1.0 );
409cdf0e10cSrcweir maTokens.append( OPCODE_SEP );
410cdf0e10cSrcweir }
411cdf0e10cSrcweir break;
412cdf0e10cSrcweir }
413cdf0e10cSrcweir }
414cdf0e10cSrcweir
appendFinalToken(const ApiToken & rToken)415cdf0e10cSrcweir bool FormulaFinalizer::appendFinalToken( const ApiToken& rToken )
416cdf0e10cSrcweir {
417cdf0e10cSrcweir // replace OPCODE_MACRO without macro name with #NAME? error code
418cdf0e10cSrcweir bool bValid = (rToken.OpCode != OPCODE_MACRO) || rToken.Data.hasValue();
419cdf0e10cSrcweir if( bValid )
420cdf0e10cSrcweir {
421cdf0e10cSrcweir maTokens.push_back( rToken );
422cdf0e10cSrcweir }
423cdf0e10cSrcweir else
424cdf0e10cSrcweir {
425cdf0e10cSrcweir maTokens.append( OPCODE_ARRAY_OPEN );
426cdf0e10cSrcweir maTokens.append( OPCODE_PUSH, BiffHelper::calcDoubleFromError( BIFF_ERR_NAME ) );
427cdf0e10cSrcweir maTokens.append( OPCODE_ARRAY_CLOSE );
428cdf0e10cSrcweir }
429cdf0e10cSrcweir return bValid;
430cdf0e10cSrcweir }
431cdf0e10cSrcweir
432cdf0e10cSrcweir // parser implementation base =================================================
433cdf0e10cSrcweir
434cdf0e10cSrcweir class FormulaParserImpl : public FormulaFinalizer, public WorkbookHelper
435cdf0e10cSrcweir {
436cdf0e10cSrcweir public:
437cdf0e10cSrcweir explicit FormulaParserImpl( const FormulaParser& rParent );
438cdf0e10cSrcweir
439cdf0e10cSrcweir /** Converts an OOXML formula string. */
440cdf0e10cSrcweir virtual ApiTokenSequence importOoxFormula(
441cdf0e10cSrcweir const CellAddress& rBaseAddress,
442cdf0e10cSrcweir const OUString& rFormulaString );
443cdf0e10cSrcweir
444cdf0e10cSrcweir /** Imports and converts a BIFF12 token array from the passed stream. */
445cdf0e10cSrcweir virtual ApiTokenSequence importBiff12Formula(
446cdf0e10cSrcweir const CellAddress& rBaseAddress,
447cdf0e10cSrcweir FormulaType eType,
448cdf0e10cSrcweir SequenceInputStream& rStrm );
449cdf0e10cSrcweir
450cdf0e10cSrcweir /** Imports and converts a BIFF2-BIFF8 token array from the passed stream. */
451cdf0e10cSrcweir virtual ApiTokenSequence importBiffFormula(
452cdf0e10cSrcweir const CellAddress& rBaseAddress,
453cdf0e10cSrcweir FormulaType eType,
454cdf0e10cSrcweir BiffInputStream& rStrm, const sal_uInt16* pnFmlaSize );
455cdf0e10cSrcweir
456cdf0e10cSrcweir /** Tries to resolve the passed ref-id to an OLE target URL. */
457cdf0e10cSrcweir OUString resolveOleTarget( sal_Int32 nRefId, bool bUseRefSheets ) const;
458cdf0e10cSrcweir
459cdf0e10cSrcweir protected:
460cdf0e10cSrcweir typedef ::std::pair< sal_Int32, bool > WhiteSpace;
461cdf0e10cSrcweir typedef ::std::vector< WhiteSpace > WhiteSpaceVec;
462cdf0e10cSrcweir
463cdf0e10cSrcweir /** Initializes the formula parser before importing a formula. */
464cdf0e10cSrcweir void initializeImport( const CellAddress& rBaseAddress, FormulaType eType );
465cdf0e10cSrcweir /** Finalizes the internal token storage after import. */
466cdf0e10cSrcweir ApiTokenSequence finalizeImport();
467cdf0e10cSrcweir
468cdf0e10cSrcweir // token array ------------------------------------------------------------
469cdf0e10cSrcweir
470cdf0e10cSrcweir bool resetSpaces();
471cdf0e10cSrcweir static void appendSpaces( WhiteSpaceVec& orSpaces, sal_Int32 nCount, bool bLineFeed );
472cdf0e10cSrcweir void appendLeadingSpaces( sal_Int32 nCount, bool bLineFeed );
473cdf0e10cSrcweir void appendOpeningSpaces( sal_Int32 nCount, bool bLineFeed );
474cdf0e10cSrcweir void appendClosingSpaces( sal_Int32 nCount, bool bLineFeed );
475cdf0e10cSrcweir
476cdf0e10cSrcweir size_t getFormulaSize() const;
477cdf0e10cSrcweir Any& appendRawToken( sal_Int32 nOpCode );
478cdf0e10cSrcweir Any& insertRawToken( sal_Int32 nOpCode, size_t nIndexFromEnd );
479cdf0e10cSrcweir size_t appendWhiteSpaceTokens( const WhiteSpaceVec* pSpaces );
480cdf0e10cSrcweir size_t insertWhiteSpaceTokens( const WhiteSpaceVec* pSpaces, size_t nIndexFromEnd );
481cdf0e10cSrcweir
482cdf0e10cSrcweir size_t getOperandSize( size_t nOpCountFromEnd, size_t nOpIndex ) const;
483cdf0e10cSrcweir void pushOperandSize( size_t nSize );
484cdf0e10cSrcweir size_t popOperandSize();
485cdf0e10cSrcweir
486cdf0e10cSrcweir ApiToken& getOperandToken( size_t nOpCountFromEnd, size_t nOpIndex, size_t nTokenIndex );
487cdf0e10cSrcweir void removeOperand( size_t nOpCountFromEnd, size_t nOpIndex );
488cdf0e10cSrcweir void removeLastOperands( size_t nOpCountFromEnd );
489cdf0e10cSrcweir
490cdf0e10cSrcweir bool pushOperandToken( sal_Int32 nOpCode, const WhiteSpaceVec* pSpaces = 0 );
491cdf0e10cSrcweir bool pushAnyOperandToken( const Any& rAny, sal_Int32 nOpCode, const WhiteSpaceVec* pSpaces = 0 );
492cdf0e10cSrcweir template< typename Type >
493cdf0e10cSrcweir bool pushValueOperandToken( const Type& rValue, sal_Int32 nOpCode, const WhiteSpaceVec* pSpaces = 0 );
494cdf0e10cSrcweir template< typename Type >
pushValueOperandToken(const Type & rValue,const WhiteSpaceVec * pSpaces=0)495cdf0e10cSrcweir inline bool pushValueOperandToken( const Type& rValue, const WhiteSpaceVec* pSpaces = 0 )
496cdf0e10cSrcweir { return pushValueOperandToken( rValue, OPCODE_PUSH, pSpaces ); }
497cdf0e10cSrcweir bool pushParenthesesOperandToken( const WhiteSpaceVec* pOpeningSpaces = 0, const WhiteSpaceVec* pClosingSpaces = 0 );
498cdf0e10cSrcweir bool pushUnaryPreOperatorToken( sal_Int32 nOpCode, const WhiteSpaceVec* pSpaces = 0 );
499cdf0e10cSrcweir bool pushUnaryPostOperatorToken( sal_Int32 nOpCode, const WhiteSpaceVec* pSpaces = 0 );
500cdf0e10cSrcweir bool pushBinaryOperatorToken( sal_Int32 nOpCode, const WhiteSpaceVec* pSpaces = 0 );
501cdf0e10cSrcweir bool pushParenthesesOperatorToken( const WhiteSpaceVec* pOpeningSpaces = 0, const WhiteSpaceVec* pClosingSpaces = 0 );
502cdf0e10cSrcweir bool pushFunctionOperatorToken( sal_Int32 nOpCode, size_t nParamCount, const WhiteSpaceVec* pLeadingSpaces = 0, const WhiteSpaceVec* pClosingSpaces = 0 );
503cdf0e10cSrcweir bool pushFunctionOperatorToken( const FunctionInfo& rFuncInfo, size_t nParamCount, const WhiteSpaceVec* pLeadingSpaces = 0, const WhiteSpaceVec* pClosingSpaces = 0 );
504cdf0e10cSrcweir
505cdf0e10cSrcweir bool pushOperand( sal_Int32 nOpCode );
506cdf0e10cSrcweir bool pushAnyOperand( const Any& rAny, sal_Int32 nOpCode );
507cdf0e10cSrcweir template< typename Type >
508cdf0e10cSrcweir bool pushValueOperand( const Type& rValue, sal_Int32 nOpCode );
509cdf0e10cSrcweir template< typename Type >
pushValueOperand(const Type & rValue)510cdf0e10cSrcweir inline bool pushValueOperand( const Type& rValue )
511cdf0e10cSrcweir { return pushValueOperand( rValue, OPCODE_PUSH ); }
512cdf0e10cSrcweir bool pushBoolOperand( bool bValue );
513cdf0e10cSrcweir bool pushErrorOperand( double fEncodedError );
514cdf0e10cSrcweir bool pushBiffBoolOperand( sal_uInt8 nValue );
515cdf0e10cSrcweir bool pushBiffErrorOperand( sal_uInt8 nErrorCode );
516cdf0e10cSrcweir bool pushParenthesesOperand();
517cdf0e10cSrcweir bool pushReferenceOperand( const BinSingleRef2d& rRef, bool bDeleted, bool bRelativeAsOffset );
518cdf0e10cSrcweir bool pushReferenceOperand( const BinComplexRef2d& rRef, bool bDeleted, bool bRelativeAsOffset );
519cdf0e10cSrcweir template< typename Type >
520cdf0e10cSrcweir bool pushReferenceOperand( const LinkSheetRange& rSheetRange, const Type& rApiRef );
521cdf0e10cSrcweir bool pushReferenceOperand( const LinkSheetRange& rSheetRange, const BinSingleRef2d& rRef, bool bDeleted, bool bRelativeAsOffset );
522cdf0e10cSrcweir bool pushReferenceOperand( const LinkSheetRange& rSheetRange, const BinComplexRef2d& rRef, bool bDeleted, bool bRelativeAsOffset );
523cdf0e10cSrcweir bool pushNlrOperand( const BinSingleRef2d& rRef );
524cdf0e10cSrcweir bool pushEmbeddedRefOperand( const DefinedNameBase& rName, bool bPushBadToken );
525cdf0e10cSrcweir bool pushDefinedNameOperand( const DefinedNameRef& rxDefName );
526cdf0e10cSrcweir bool pushExternalFuncOperand( const FunctionInfo& rFuncInfo );
527cdf0e10cSrcweir bool pushDdeLinkOperand( const OUString& rDdeServer, const OUString& rDdeTopic, const OUString& rDdeItem );
528cdf0e10cSrcweir bool pushExternalNameOperand( const ExternalNameRef& rxExtName, const ExternalLink& rExtLink );
529cdf0e10cSrcweir bool pushSpecialTokenOperand( const BinAddress& rBaseAddr, bool bTable );
530cdf0e10cSrcweir
531cdf0e10cSrcweir bool pushUnaryPreOperator( sal_Int32 nOpCode );
532cdf0e10cSrcweir bool pushUnaryPostOperator( sal_Int32 nOpCode );
533cdf0e10cSrcweir bool pushBinaryOperator( sal_Int32 nOpCode );
534cdf0e10cSrcweir bool pushParenthesesOperator();
535cdf0e10cSrcweir bool pushFunctionOperator( sal_Int32 nOpCode, size_t nParamCount );
536cdf0e10cSrcweir bool pushFunctionOperator( const FunctionInfo& rFuncInfo, size_t nParamCount );
537cdf0e10cSrcweir
538cdf0e10cSrcweir private:
539cdf0e10cSrcweir // reference conversion ---------------------------------------------------
540cdf0e10cSrcweir
541cdf0e10cSrcweir void initReference2d( SingleReference& orApiRef ) const;
542cdf0e10cSrcweir void initReference3d( SingleReference& orApiRef, sal_Int32 nSheet, bool bSameSheet ) const;
543cdf0e10cSrcweir void convertColRow( SingleReference& orApiRef, const BinSingleRef2d& rRef, bool bRelativeAsOffset ) const;
544cdf0e10cSrcweir void convertReference( SingleReference& orApiRef, const BinSingleRef2d& rRef, bool bDeleted, bool bRelativeAsOffset ) const;
545cdf0e10cSrcweir void convertReference( ComplexReference& orApiRef, const BinSingleRef2d& rRef1, const BinSingleRef2d& rRef2, bool bDeleted, bool bRelativeAsOffset ) const;
546cdf0e10cSrcweir void convertReference2d( SingleReference& orApiRef, const BinSingleRef2d& rRef, bool bDeleted, bool bRelativeAsOffset ) const;
547cdf0e10cSrcweir void convertReference2d( ComplexReference& orApiRef, const BinSingleRef2d& rRef1, const BinSingleRef2d& rRef2, bool bDeleted, bool bRelativeAsOffset ) const;
548cdf0e10cSrcweir void convertReference3d( SingleReference& orApiRef, sal_Int32 nSheet, bool bSameSheet, const BinSingleRef2d& rRef, bool bDeleted, bool bRelativeAsOffset ) const;
549cdf0e10cSrcweir void convertReference3d( ComplexReference& orApiRef, const LinkSheetRange& rSheetRange, const BinSingleRef2d& rRef1, const BinSingleRef2d& rRef2, bool bDeleted, bool bRelativeAsOffset ) const;
550cdf0e10cSrcweir
551cdf0e10cSrcweir private:
552cdf0e10cSrcweir // finalize token sequence ------------------------------------------------
553cdf0e10cSrcweir
554cdf0e10cSrcweir virtual const FunctionInfo* resolveBadFuncName( const OUString& rTokenData ) const;
555cdf0e10cSrcweir virtual ::rtl::OUString resolveDefinedName( sal_Int32 nTokenIndex ) const;
556cdf0e10cSrcweir
557cdf0e10cSrcweir protected:
558cdf0e10cSrcweir const sal_Int32 mnMaxApiCol; /// Maximum column index in own document.
559cdf0e10cSrcweir const sal_Int32 mnMaxApiRow; /// Maximum row index in own document.
560cdf0e10cSrcweir const sal_Int32 mnMaxXlsCol; /// Maximum column index in imported document.
561cdf0e10cSrcweir const sal_Int32 mnMaxXlsRow; /// Maximum row index in imported document.
562cdf0e10cSrcweir
563cdf0e10cSrcweir CellAddress maBaseAddr; /// Base address for relative references.
564cdf0e10cSrcweir bool mbRelativeAsOffset; /// True = relative row/column index is (signed) offset, false = explicit index.
565cdf0e10cSrcweir bool mb2dRefsAs3dRefs; /// True = convert all 2D references to 3D references in sheet specified by base address.
566cdf0e10cSrcweir bool mbSpecialTokens; /// True = special handling for tExp and tTbl tokens, false = exit with error.
567cdf0e10cSrcweir bool mbAllowNulChars; /// True = keep NUL characters in string tokens.
568cdf0e10cSrcweir
569cdf0e10cSrcweir private:
570cdf0e10cSrcweir typedef ::std::vector< size_t > SizeTypeVector;
571cdf0e10cSrcweir
572cdf0e10cSrcweir ApiTokenVector maTokenStorage; /// Raw unordered token storage.
573cdf0e10cSrcweir SizeTypeVector maTokenIndexes; /// Indexes into maTokenStorage.
574cdf0e10cSrcweir SizeTypeVector maOperandSizeStack; /// Stack with token sizes per operand.
575cdf0e10cSrcweir WhiteSpaceVec maLeadingSpaces; /// List of whitespaces before next token.
576cdf0e10cSrcweir WhiteSpaceVec maOpeningSpaces; /// List of whitespaces before opening parenthesis.
577cdf0e10cSrcweir WhiteSpaceVec maClosingSpaces; /// List of whitespaces before closing parenthesis.
578cdf0e10cSrcweir };
579cdf0e10cSrcweir
580cdf0e10cSrcweir // ----------------------------------------------------------------------------
581cdf0e10cSrcweir
FormulaParserImpl(const FormulaParser & rParent)582cdf0e10cSrcweir FormulaParserImpl::FormulaParserImpl( const FormulaParser& rParent ) :
583cdf0e10cSrcweir FormulaFinalizer( rParent ),
584cdf0e10cSrcweir WorkbookHelper( rParent ),
585cdf0e10cSrcweir mnMaxApiCol( rParent.getAddressConverter().getMaxApiAddress().Column ),
586cdf0e10cSrcweir mnMaxApiRow( rParent.getAddressConverter().getMaxApiAddress().Row ),
587cdf0e10cSrcweir mnMaxXlsCol( rParent.getAddressConverter().getMaxXlsAddress().Column ),
588cdf0e10cSrcweir mnMaxXlsRow( rParent.getAddressConverter().getMaxXlsAddress().Row ),
589cdf0e10cSrcweir mbRelativeAsOffset( false ),
590cdf0e10cSrcweir mb2dRefsAs3dRefs( false ),
591cdf0e10cSrcweir mbAllowNulChars( false )
592cdf0e10cSrcweir {
593cdf0e10cSrcweir // reserve enough space to make resize(), push_back() etc. cheap
594cdf0e10cSrcweir maTokenStorage.reserve( 0x2000 );
595cdf0e10cSrcweir maTokenIndexes.reserve( 0x2000 );
596cdf0e10cSrcweir maOperandSizeStack.reserve( 256 );
597cdf0e10cSrcweir maLeadingSpaces.reserve( 256 );
598cdf0e10cSrcweir maOpeningSpaces.reserve( 256 );
599cdf0e10cSrcweir maClosingSpaces.reserve( 256 );
600cdf0e10cSrcweir }
601cdf0e10cSrcweir
importOoxFormula(const CellAddress &,const OUString &)602cdf0e10cSrcweir ApiTokenSequence FormulaParserImpl::importOoxFormula( const CellAddress&, const OUString& )
603cdf0e10cSrcweir {
604cdf0e10cSrcweir OSL_ENSURE( false, "FormulaParserImpl::importOoxFormula - not implemented" );
605cdf0e10cSrcweir return ApiTokenSequence();
606cdf0e10cSrcweir }
607cdf0e10cSrcweir
importBiff12Formula(const CellAddress &,FormulaType,SequenceInputStream &)608cdf0e10cSrcweir ApiTokenSequence FormulaParserImpl::importBiff12Formula( const CellAddress&, FormulaType, SequenceInputStream& )
609cdf0e10cSrcweir {
610cdf0e10cSrcweir OSL_ENSURE( false, "FormulaParserImpl::importBiff12Formula - not implemented" );
611cdf0e10cSrcweir return ApiTokenSequence();
612cdf0e10cSrcweir }
613cdf0e10cSrcweir
importBiffFormula(const CellAddress &,FormulaType,BiffInputStream &,const sal_uInt16 *)614cdf0e10cSrcweir ApiTokenSequence FormulaParserImpl::importBiffFormula( const CellAddress&, FormulaType, BiffInputStream&, const sal_uInt16* )
615cdf0e10cSrcweir {
616cdf0e10cSrcweir OSL_ENSURE( false, "FormulaParserImpl::importBiffFormula - not implemented" );
617cdf0e10cSrcweir return ApiTokenSequence();
618cdf0e10cSrcweir }
619cdf0e10cSrcweir
resolveOleTarget(sal_Int32 nRefId,bool bUseRefSheets) const620cdf0e10cSrcweir OUString FormulaParserImpl::resolveOleTarget( sal_Int32 nRefId, bool bUseRefSheets ) const
621cdf0e10cSrcweir {
622cdf0e10cSrcweir const ExternalLink* pExtLink = getExternalLinks().getExternalLink( nRefId, bUseRefSheets ).get();
623cdf0e10cSrcweir OSL_ENSURE( pExtLink && (pExtLink->getLinkType() == LINKTYPE_OLE), "FormulaParserImpl::resolveOleTarget - missing or wrong link" );
624cdf0e10cSrcweir if( pExtLink && (pExtLink->getLinkType() == LINKTYPE_OLE) )
625cdf0e10cSrcweir return getBaseFilter().getAbsoluteUrl( pExtLink->getTargetUrl() );
626cdf0e10cSrcweir return OUString();
627cdf0e10cSrcweir }
628cdf0e10cSrcweir
initializeImport(const CellAddress & rBaseAddr,FormulaType eType)629cdf0e10cSrcweir void FormulaParserImpl::initializeImport( const CellAddress& rBaseAddr, FormulaType eType )
630cdf0e10cSrcweir {
631cdf0e10cSrcweir maBaseAddr = rBaseAddr;
632cdf0e10cSrcweir mbRelativeAsOffset = mb2dRefsAs3dRefs = mbSpecialTokens = mbAllowNulChars = false;
633cdf0e10cSrcweir switch( eType )
634cdf0e10cSrcweir {
635cdf0e10cSrcweir case FORMULATYPE_CELL:
636cdf0e10cSrcweir mbSpecialTokens = true;
637cdf0e10cSrcweir break;
638cdf0e10cSrcweir case FORMULATYPE_ARRAY:
639cdf0e10cSrcweir break;
640cdf0e10cSrcweir case FORMULATYPE_SHAREDFORMULA:
641cdf0e10cSrcweir mbRelativeAsOffset = true;
642cdf0e10cSrcweir break;
643cdf0e10cSrcweir case FORMULATYPE_CONDFORMAT:
644cdf0e10cSrcweir mbRelativeAsOffset = true;
645cdf0e10cSrcweir break;
646cdf0e10cSrcweir case FORMULATYPE_VALIDATION:
647cdf0e10cSrcweir mbRelativeAsOffset = true;
648cdf0e10cSrcweir // enable NUL characters in BIFF import, string list is single tStr token with NUL separators
649cdf0e10cSrcweir mbAllowNulChars = getFilterType() == FILTER_BIFF;
650cdf0e10cSrcweir break;
651cdf0e10cSrcweir case FORMULATYPE_DEFINEDNAME:
652cdf0e10cSrcweir mbRelativeAsOffset = true;
653cdf0e10cSrcweir // BIFF2-BIFF4: convert 2D referebces to absolute 3D references
654cdf0e10cSrcweir mb2dRefsAs3dRefs = (getFilterType() == FILTER_BIFF) && (getBiff() <= BIFF4);
655cdf0e10cSrcweir break;
656cdf0e10cSrcweir }
657cdf0e10cSrcweir
658cdf0e10cSrcweir maTokenStorage.clear();
659cdf0e10cSrcweir maTokenIndexes.clear();
660cdf0e10cSrcweir maOperandSizeStack.clear();
661cdf0e10cSrcweir }
662cdf0e10cSrcweir
finalizeImport()663cdf0e10cSrcweir ApiTokenSequence FormulaParserImpl::finalizeImport()
664cdf0e10cSrcweir {
665cdf0e10cSrcweir ApiTokenSequence aTokens( static_cast< sal_Int32 >( maTokenIndexes.size() ) );
666cdf0e10cSrcweir if( aTokens.hasElements() )
667cdf0e10cSrcweir {
668cdf0e10cSrcweir ApiToken* pToken = aTokens.getArray();
669cdf0e10cSrcweir for( SizeTypeVector::const_iterator aIt = maTokenIndexes.begin(), aEnd = maTokenIndexes.end(); aIt != aEnd; ++aIt, ++pToken )
670cdf0e10cSrcweir *pToken = maTokenStorage[ *aIt ];
671cdf0e10cSrcweir }
672cdf0e10cSrcweir return finalizeTokenArray( aTokens );
673cdf0e10cSrcweir }
674cdf0e10cSrcweir
675cdf0e10cSrcweir // token array ----------------------------------------------------------------
676cdf0e10cSrcweir
resetSpaces()677cdf0e10cSrcweir bool FormulaParserImpl::resetSpaces()
678cdf0e10cSrcweir {
679cdf0e10cSrcweir maLeadingSpaces.clear();
680cdf0e10cSrcweir maOpeningSpaces.clear();
681cdf0e10cSrcweir maClosingSpaces.clear();
682cdf0e10cSrcweir return true;
683cdf0e10cSrcweir }
684cdf0e10cSrcweir
appendSpaces(WhiteSpaceVec & orSpaces,sal_Int32 nCount,bool bLineFeed)685cdf0e10cSrcweir void FormulaParserImpl::appendSpaces( WhiteSpaceVec& orSpaces, sal_Int32 nCount, bool bLineFeed )
686cdf0e10cSrcweir {
687cdf0e10cSrcweir OSL_ENSURE( nCount >= 0, "FormulaParserImpl::appendSpaces - negative count" );
688cdf0e10cSrcweir if( nCount > 0 )
689cdf0e10cSrcweir orSpaces.push_back( WhiteSpace( nCount, bLineFeed ) );
690cdf0e10cSrcweir }
691cdf0e10cSrcweir
appendLeadingSpaces(sal_Int32 nCount,bool bLineFeed)692cdf0e10cSrcweir void FormulaParserImpl::appendLeadingSpaces( sal_Int32 nCount, bool bLineFeed )
693cdf0e10cSrcweir {
694cdf0e10cSrcweir appendSpaces( maLeadingSpaces, nCount, bLineFeed );
695cdf0e10cSrcweir }
696cdf0e10cSrcweir
appendOpeningSpaces(sal_Int32 nCount,bool bLineFeed)697cdf0e10cSrcweir void FormulaParserImpl::appendOpeningSpaces( sal_Int32 nCount, bool bLineFeed )
698cdf0e10cSrcweir {
699cdf0e10cSrcweir appendSpaces( maOpeningSpaces, nCount, bLineFeed );
700cdf0e10cSrcweir }
701cdf0e10cSrcweir
appendClosingSpaces(sal_Int32 nCount,bool bLineFeed)702cdf0e10cSrcweir void FormulaParserImpl::appendClosingSpaces( sal_Int32 nCount, bool bLineFeed )
703cdf0e10cSrcweir {
704cdf0e10cSrcweir appendSpaces( maClosingSpaces, nCount, bLineFeed );
705cdf0e10cSrcweir }
706cdf0e10cSrcweir
getFormulaSize() const707cdf0e10cSrcweir size_t FormulaParserImpl::getFormulaSize() const
708cdf0e10cSrcweir {
709cdf0e10cSrcweir return maTokenIndexes.size();
710cdf0e10cSrcweir }
711cdf0e10cSrcweir
appendRawToken(sal_Int32 nOpCode)712cdf0e10cSrcweir Any& FormulaParserImpl::appendRawToken( sal_Int32 nOpCode )
713cdf0e10cSrcweir {
714cdf0e10cSrcweir maTokenIndexes.push_back( maTokenStorage.size() );
715cdf0e10cSrcweir return maTokenStorage.append( nOpCode );
716cdf0e10cSrcweir }
717cdf0e10cSrcweir
insertRawToken(sal_Int32 nOpCode,size_t nIndexFromEnd)718cdf0e10cSrcweir Any& FormulaParserImpl::insertRawToken( sal_Int32 nOpCode, size_t nIndexFromEnd )
719cdf0e10cSrcweir {
720cdf0e10cSrcweir maTokenIndexes.insert( maTokenIndexes.end() - nIndexFromEnd, maTokenStorage.size() );
721cdf0e10cSrcweir return maTokenStorage.append( nOpCode );
722cdf0e10cSrcweir }
723cdf0e10cSrcweir
appendWhiteSpaceTokens(const WhiteSpaceVec * pSpaces)724cdf0e10cSrcweir size_t FormulaParserImpl::appendWhiteSpaceTokens( const WhiteSpaceVec* pSpaces )
725cdf0e10cSrcweir {
726cdf0e10cSrcweir if( pSpaces && !pSpaces->empty() )
727cdf0e10cSrcweir for( WhiteSpaceVec::const_iterator aIt = pSpaces->begin(), aEnd = pSpaces->end(); aIt != aEnd; ++aIt )
728cdf0e10cSrcweir appendRawToken( OPCODE_SPACES ) <<= aIt->first;
729cdf0e10cSrcweir return pSpaces ? pSpaces->size() : 0;
730cdf0e10cSrcweir }
731cdf0e10cSrcweir
insertWhiteSpaceTokens(const WhiteSpaceVec * pSpaces,size_t nIndexFromEnd)732cdf0e10cSrcweir size_t FormulaParserImpl::insertWhiteSpaceTokens( const WhiteSpaceVec* pSpaces, size_t nIndexFromEnd )
733cdf0e10cSrcweir {
734cdf0e10cSrcweir if( pSpaces && !pSpaces->empty() )
735cdf0e10cSrcweir for( WhiteSpaceVec::const_iterator aIt = pSpaces->begin(), aEnd = pSpaces->end(); aIt != aEnd; ++aIt )
736cdf0e10cSrcweir insertRawToken( OPCODE_SPACES, nIndexFromEnd ) <<= aIt->first;
737cdf0e10cSrcweir return pSpaces ? pSpaces->size() : 0;
738cdf0e10cSrcweir }
739cdf0e10cSrcweir
getOperandSize(size_t nOpCountFromEnd,size_t nOpIndex) const740cdf0e10cSrcweir size_t FormulaParserImpl::getOperandSize( size_t nOpCountFromEnd, size_t nOpIndex ) const
741cdf0e10cSrcweir {
742cdf0e10cSrcweir OSL_ENSURE( (nOpIndex < nOpCountFromEnd) && (nOpCountFromEnd <= maOperandSizeStack.size()),
743cdf0e10cSrcweir "FormulaParserImpl::getOperandSize - invalid parameters" );
744cdf0e10cSrcweir return maOperandSizeStack[ maOperandSizeStack.size() - nOpCountFromEnd + nOpIndex ];
745cdf0e10cSrcweir }
746cdf0e10cSrcweir
pushOperandSize(size_t nSize)747cdf0e10cSrcweir void FormulaParserImpl::pushOperandSize( size_t nSize )
748cdf0e10cSrcweir {
749cdf0e10cSrcweir maOperandSizeStack.push_back( nSize );
750cdf0e10cSrcweir }
751cdf0e10cSrcweir
popOperandSize()752cdf0e10cSrcweir size_t FormulaParserImpl::popOperandSize()
753cdf0e10cSrcweir {
754cdf0e10cSrcweir OSL_ENSURE( !maOperandSizeStack.empty(), "FormulaParserImpl::popOperandSize - invalid call" );
755cdf0e10cSrcweir size_t nOpSize = maOperandSizeStack.back();
756cdf0e10cSrcweir maOperandSizeStack.pop_back();
757cdf0e10cSrcweir return nOpSize;
758cdf0e10cSrcweir }
759cdf0e10cSrcweir
getOperandToken(size_t nOpCountFromEnd,size_t nOpIndex,size_t nTokenIndex)760cdf0e10cSrcweir ApiToken& FormulaParserImpl::getOperandToken( size_t nOpCountFromEnd, size_t nOpIndex, size_t nTokenIndex )
761cdf0e10cSrcweir {
762cdf0e10cSrcweir OSL_ENSURE( getOperandSize( nOpCountFromEnd, nOpIndex ) > nTokenIndex,
763cdf0e10cSrcweir "FormulaParserImpl::getOperandToken - invalid parameters" );
764cdf0e10cSrcweir SizeTypeVector::const_iterator aIndexIt = maTokenIndexes.end();
765cdf0e10cSrcweir for( SizeTypeVector::const_iterator aEnd = maOperandSizeStack.end(), aIt = aEnd - nOpCountFromEnd + nOpIndex; aIt != aEnd; ++aIt )
766cdf0e10cSrcweir aIndexIt -= *aIt;
767cdf0e10cSrcweir return maTokenStorage[ *(aIndexIt + nTokenIndex) ];
768cdf0e10cSrcweir }
769cdf0e10cSrcweir
removeOperand(size_t nOpCountFromEnd,size_t nOpIndex)770cdf0e10cSrcweir void FormulaParserImpl::removeOperand( size_t nOpCountFromEnd, size_t nOpIndex )
771cdf0e10cSrcweir {
772cdf0e10cSrcweir OSL_ENSURE( (nOpIndex < nOpCountFromEnd) && (nOpCountFromEnd <= maOperandSizeStack.size()),
773cdf0e10cSrcweir "FormulaParserImpl::removeOperand - invalid parameters" );
774cdf0e10cSrcweir // remove indexes into token storage, but do not touch storage itself
775cdf0e10cSrcweir SizeTypeVector::iterator aSizeEnd = maOperandSizeStack.end();
776cdf0e10cSrcweir SizeTypeVector::iterator aSizeIt = aSizeEnd - nOpCountFromEnd + nOpIndex;
777cdf0e10cSrcweir size_t nRemainingSize = 0;
778cdf0e10cSrcweir for( SizeTypeVector::iterator aIt = aSizeIt + 1; aIt != aSizeEnd; ++aIt )
779cdf0e10cSrcweir nRemainingSize += *aIt;
780cdf0e10cSrcweir maTokenIndexes.erase( maTokenIndexes.end() - nRemainingSize - *aSizeIt, maTokenIndexes.end() - nRemainingSize );
781cdf0e10cSrcweir maOperandSizeStack.erase( aSizeIt );
782cdf0e10cSrcweir }
783cdf0e10cSrcweir
removeLastOperands(size_t nOpCountFromEnd)784cdf0e10cSrcweir void FormulaParserImpl::removeLastOperands( size_t nOpCountFromEnd )
785cdf0e10cSrcweir {
786cdf0e10cSrcweir for( size_t nOpIndex = 0; nOpIndex < nOpCountFromEnd; ++nOpIndex )
787cdf0e10cSrcweir removeOperand( 1, 0 );
788cdf0e10cSrcweir }
789cdf0e10cSrcweir
pushOperandToken(sal_Int32 nOpCode,const WhiteSpaceVec * pSpaces)790cdf0e10cSrcweir bool FormulaParserImpl::pushOperandToken( sal_Int32 nOpCode, const WhiteSpaceVec* pSpaces )
791cdf0e10cSrcweir {
792cdf0e10cSrcweir size_t nSpacesSize = appendWhiteSpaceTokens( pSpaces );
793cdf0e10cSrcweir appendRawToken( nOpCode );
794cdf0e10cSrcweir pushOperandSize( nSpacesSize + 1 );
795cdf0e10cSrcweir return true;
796cdf0e10cSrcweir }
797cdf0e10cSrcweir
pushAnyOperandToken(const Any & rAny,sal_Int32 nOpCode,const WhiteSpaceVec * pSpaces)798cdf0e10cSrcweir bool FormulaParserImpl::pushAnyOperandToken( const Any& rAny, sal_Int32 nOpCode, const WhiteSpaceVec* pSpaces )
799cdf0e10cSrcweir {
800cdf0e10cSrcweir size_t nSpacesSize = appendWhiteSpaceTokens( pSpaces );
801cdf0e10cSrcweir appendRawToken( nOpCode ) = rAny;
802cdf0e10cSrcweir pushOperandSize( nSpacesSize + 1 );
803cdf0e10cSrcweir return true;
804cdf0e10cSrcweir }
805cdf0e10cSrcweir
806cdf0e10cSrcweir template< typename Type >
pushValueOperandToken(const Type & rValue,sal_Int32 nOpCode,const WhiteSpaceVec * pSpaces)807cdf0e10cSrcweir bool FormulaParserImpl::pushValueOperandToken( const Type& rValue, sal_Int32 nOpCode, const WhiteSpaceVec* pSpaces )
808cdf0e10cSrcweir {
809cdf0e10cSrcweir size_t nSpacesSize = appendWhiteSpaceTokens( pSpaces );
810cdf0e10cSrcweir appendRawToken( nOpCode ) <<= rValue;
811cdf0e10cSrcweir pushOperandSize( nSpacesSize + 1 );
812cdf0e10cSrcweir return true;
813cdf0e10cSrcweir }
814cdf0e10cSrcweir
pushParenthesesOperandToken(const WhiteSpaceVec * pOpeningSpaces,const WhiteSpaceVec * pClosingSpaces)815cdf0e10cSrcweir bool FormulaParserImpl::pushParenthesesOperandToken( const WhiteSpaceVec* pOpeningSpaces, const WhiteSpaceVec* pClosingSpaces )
816cdf0e10cSrcweir {
817cdf0e10cSrcweir size_t nSpacesSize = appendWhiteSpaceTokens( pOpeningSpaces );
818cdf0e10cSrcweir appendRawToken( OPCODE_OPEN );
819cdf0e10cSrcweir nSpacesSize += appendWhiteSpaceTokens( pClosingSpaces );
820cdf0e10cSrcweir appendRawToken( OPCODE_CLOSE );
821cdf0e10cSrcweir pushOperandSize( nSpacesSize + 2 );
822cdf0e10cSrcweir return true;
823cdf0e10cSrcweir }
824cdf0e10cSrcweir
pushUnaryPreOperatorToken(sal_Int32 nOpCode,const WhiteSpaceVec * pSpaces)825cdf0e10cSrcweir bool FormulaParserImpl::pushUnaryPreOperatorToken( sal_Int32 nOpCode, const WhiteSpaceVec* pSpaces )
826cdf0e10cSrcweir {
827cdf0e10cSrcweir bool bOk = maOperandSizeStack.size() >= 1;
828cdf0e10cSrcweir if( bOk )
829cdf0e10cSrcweir {
830cdf0e10cSrcweir size_t nOpSize = popOperandSize();
831cdf0e10cSrcweir size_t nSpacesSize = insertWhiteSpaceTokens( pSpaces, nOpSize );
832cdf0e10cSrcweir insertRawToken( nOpCode, nOpSize );
833cdf0e10cSrcweir pushOperandSize( nOpSize + nSpacesSize + 1 );
834cdf0e10cSrcweir }
835cdf0e10cSrcweir return bOk;
836cdf0e10cSrcweir }
837cdf0e10cSrcweir
pushUnaryPostOperatorToken(sal_Int32 nOpCode,const WhiteSpaceVec * pSpaces)838cdf0e10cSrcweir bool FormulaParserImpl::pushUnaryPostOperatorToken( sal_Int32 nOpCode, const WhiteSpaceVec* pSpaces )
839cdf0e10cSrcweir {
840cdf0e10cSrcweir bool bOk = maOperandSizeStack.size() >= 1;
841cdf0e10cSrcweir if( bOk )
842cdf0e10cSrcweir {
843cdf0e10cSrcweir size_t nOpSize = popOperandSize();
844cdf0e10cSrcweir size_t nSpacesSize = appendWhiteSpaceTokens( pSpaces );
845cdf0e10cSrcweir appendRawToken( nOpCode );
846cdf0e10cSrcweir pushOperandSize( nOpSize + nSpacesSize + 1 );
847cdf0e10cSrcweir }
848cdf0e10cSrcweir return bOk;
849cdf0e10cSrcweir }
850cdf0e10cSrcweir
pushBinaryOperatorToken(sal_Int32 nOpCode,const WhiteSpaceVec * pSpaces)851cdf0e10cSrcweir bool FormulaParserImpl::pushBinaryOperatorToken( sal_Int32 nOpCode, const WhiteSpaceVec* pSpaces )
852cdf0e10cSrcweir {
853cdf0e10cSrcweir bool bOk = maOperandSizeStack.size() >= 2;
854cdf0e10cSrcweir if( bOk )
855cdf0e10cSrcweir {
856cdf0e10cSrcweir size_t nOp2Size = popOperandSize();
857cdf0e10cSrcweir size_t nOp1Size = popOperandSize();
858cdf0e10cSrcweir size_t nSpacesSize = insertWhiteSpaceTokens( pSpaces, nOp2Size );
859cdf0e10cSrcweir insertRawToken( nOpCode, nOp2Size );
860cdf0e10cSrcweir pushOperandSize( nOp1Size + nSpacesSize + 1 + nOp2Size );
861cdf0e10cSrcweir }
862cdf0e10cSrcweir return bOk;
863cdf0e10cSrcweir }
864cdf0e10cSrcweir
pushParenthesesOperatorToken(const WhiteSpaceVec * pOpeningSpaces,const WhiteSpaceVec * pClosingSpaces)865cdf0e10cSrcweir bool FormulaParserImpl::pushParenthesesOperatorToken( const WhiteSpaceVec* pOpeningSpaces, const WhiteSpaceVec* pClosingSpaces )
866cdf0e10cSrcweir {
867cdf0e10cSrcweir bool bOk = maOperandSizeStack.size() >= 1;
868cdf0e10cSrcweir if( bOk )
869cdf0e10cSrcweir {
870cdf0e10cSrcweir size_t nOpSize = popOperandSize();
871cdf0e10cSrcweir size_t nSpacesSize = insertWhiteSpaceTokens( pOpeningSpaces, nOpSize );
872cdf0e10cSrcweir insertRawToken( OPCODE_OPEN, nOpSize );
873cdf0e10cSrcweir nSpacesSize += appendWhiteSpaceTokens( pClosingSpaces );
874cdf0e10cSrcweir appendRawToken( OPCODE_CLOSE );
875cdf0e10cSrcweir pushOperandSize( nOpSize + nSpacesSize + 2 );
876cdf0e10cSrcweir }
877cdf0e10cSrcweir return bOk;
878cdf0e10cSrcweir }
879cdf0e10cSrcweir
pushFunctionOperatorToken(sal_Int32 nOpCode,size_t nParamCount,const WhiteSpaceVec * pLeadingSpaces,const WhiteSpaceVec * pClosingSpaces)880cdf0e10cSrcweir bool FormulaParserImpl::pushFunctionOperatorToken( sal_Int32 nOpCode, size_t nParamCount, const WhiteSpaceVec* pLeadingSpaces, const WhiteSpaceVec* pClosingSpaces )
881cdf0e10cSrcweir {
882cdf0e10cSrcweir /* #i70925# if there are not enough tokens available on token stack, do
883cdf0e10cSrcweir not exit with error, but reduce parameter count. */
884cdf0e10cSrcweir nParamCount = ::std::min( maOperandSizeStack.size(), nParamCount );
885cdf0e10cSrcweir
886cdf0e10cSrcweir // convert all parameters on stack to a single operand separated with OPCODE_SEP
887cdf0e10cSrcweir bool bOk = true;
888cdf0e10cSrcweir for( size_t nParam = 1; bOk && (nParam < nParamCount); ++nParam )
889cdf0e10cSrcweir bOk = pushBinaryOperatorToken( OPCODE_SEP );
890cdf0e10cSrcweir
891cdf0e10cSrcweir // add function parentheses and function name
892cdf0e10cSrcweir return bOk &&
893cdf0e10cSrcweir ((nParamCount > 0) ? pushParenthesesOperatorToken( 0, pClosingSpaces ) : pushParenthesesOperandToken( 0, pClosingSpaces )) &&
894cdf0e10cSrcweir pushUnaryPreOperatorToken( nOpCode, pLeadingSpaces );
895cdf0e10cSrcweir }
896cdf0e10cSrcweir
pushFunctionOperatorToken(const FunctionInfo & rFuncInfo,size_t nParamCount,const WhiteSpaceVec * pLeadingSpaces,const WhiteSpaceVec * pClosingSpaces)897cdf0e10cSrcweir bool FormulaParserImpl::pushFunctionOperatorToken( const FunctionInfo& rFuncInfo, size_t nParamCount, const WhiteSpaceVec* pLeadingSpaces, const WhiteSpaceVec* pClosingSpaces )
898cdf0e10cSrcweir {
899cdf0e10cSrcweir bool bOk = pushFunctionOperatorToken( rFuncInfo.mnApiOpCode, nParamCount, pLeadingSpaces, pClosingSpaces );
900cdf0e10cSrcweir if( bOk )
901cdf0e10cSrcweir {
902cdf0e10cSrcweir // create an external add-in call for the passed built-in function
903cdf0e10cSrcweir if( (rFuncInfo.mnApiOpCode == OPCODE_EXTERNAL) && (rFuncInfo.maExtProgName.getLength() > 0) )
904cdf0e10cSrcweir getOperandToken( 1, 0, 0 ).Data <<= rFuncInfo.maExtProgName;
905cdf0e10cSrcweir // create a bad token with unsupported function name
906cdf0e10cSrcweir else if( (rFuncInfo.mnApiOpCode == OPCODE_BAD) && (rFuncInfo.maOoxFuncName.getLength() > 0) )
907cdf0e10cSrcweir getOperandToken( 1, 0, 0 ).Data <<= rFuncInfo.maOoxFuncName;
908cdf0e10cSrcweir }
909cdf0e10cSrcweir return bOk;
910cdf0e10cSrcweir }
911cdf0e10cSrcweir
pushOperand(sal_Int32 nOpCode)912cdf0e10cSrcweir bool FormulaParserImpl::pushOperand( sal_Int32 nOpCode )
913cdf0e10cSrcweir {
914cdf0e10cSrcweir return pushOperandToken( nOpCode, &maLeadingSpaces ) && resetSpaces();
915cdf0e10cSrcweir }
916cdf0e10cSrcweir
pushAnyOperand(const Any & rAny,sal_Int32 nOpCode)917cdf0e10cSrcweir bool FormulaParserImpl::pushAnyOperand( const Any& rAny, sal_Int32 nOpCode )
918cdf0e10cSrcweir {
919cdf0e10cSrcweir return pushAnyOperandToken( rAny, nOpCode, &maLeadingSpaces ) && resetSpaces();
920cdf0e10cSrcweir }
921cdf0e10cSrcweir
922cdf0e10cSrcweir template< typename Type >
pushValueOperand(const Type & rValue,sal_Int32 nOpCode)923cdf0e10cSrcweir bool FormulaParserImpl::pushValueOperand( const Type& rValue, sal_Int32 nOpCode )
924cdf0e10cSrcweir {
925cdf0e10cSrcweir return pushValueOperandToken( rValue, nOpCode, &maLeadingSpaces ) && resetSpaces();
926cdf0e10cSrcweir }
927cdf0e10cSrcweir
pushBoolOperand(bool bValue)928cdf0e10cSrcweir bool FormulaParserImpl::pushBoolOperand( bool bValue )
929cdf0e10cSrcweir {
930cdf0e10cSrcweir if( const FunctionInfo* pFuncInfo = getFuncInfoFromBiff12FuncId( bValue ? BIFF_FUNC_TRUE : BIFF_FUNC_FALSE ) )
931cdf0e10cSrcweir return pushFunctionOperator( pFuncInfo->mnApiOpCode, 0 );
932cdf0e10cSrcweir return pushValueOperand< double >( bValue ? 1.0 : 0.0 );
933cdf0e10cSrcweir }
934cdf0e10cSrcweir
pushErrorOperand(double fEncodedError)935cdf0e10cSrcweir bool FormulaParserImpl::pushErrorOperand( double fEncodedError )
936cdf0e10cSrcweir {
937cdf0e10cSrcweir // HACK: enclose all error codes into an 1x1 matrix
938cdf0e10cSrcweir // start token array with opening brace and leading spaces
939cdf0e10cSrcweir pushOperand( OPCODE_ARRAY_OPEN );
940cdf0e10cSrcweir size_t nOpSize = popOperandSize();
941cdf0e10cSrcweir size_t nOldArraySize = maTokenIndexes.size();
942cdf0e10cSrcweir // push a double containing the Calc error code
943cdf0e10cSrcweir appendRawToken( OPCODE_PUSH ) <<= fEncodedError;
944cdf0e10cSrcweir // close token array and set resulting operand size
945cdf0e10cSrcweir appendRawToken( OPCODE_ARRAY_CLOSE );
946cdf0e10cSrcweir pushOperandSize( nOpSize + maTokenIndexes.size() - nOldArraySize );
947cdf0e10cSrcweir return true;
948cdf0e10cSrcweir }
949cdf0e10cSrcweir
pushBiffBoolOperand(sal_uInt8 nValue)950cdf0e10cSrcweir bool FormulaParserImpl::pushBiffBoolOperand( sal_uInt8 nValue )
951cdf0e10cSrcweir {
952cdf0e10cSrcweir return pushBoolOperand( nValue != BIFF_TOK_BOOL_FALSE );
953cdf0e10cSrcweir }
954cdf0e10cSrcweir
pushBiffErrorOperand(sal_uInt8 nErrorCode)955cdf0e10cSrcweir bool FormulaParserImpl::pushBiffErrorOperand( sal_uInt8 nErrorCode )
956cdf0e10cSrcweir {
957cdf0e10cSrcweir return pushErrorOperand( BiffHelper::calcDoubleFromError( nErrorCode ) );
958cdf0e10cSrcweir }
959cdf0e10cSrcweir
pushParenthesesOperand()960cdf0e10cSrcweir bool FormulaParserImpl::pushParenthesesOperand()
961cdf0e10cSrcweir {
962cdf0e10cSrcweir return pushParenthesesOperandToken( &maOpeningSpaces, &maClosingSpaces ) && resetSpaces();
963cdf0e10cSrcweir }
964cdf0e10cSrcweir
pushReferenceOperand(const BinSingleRef2d & rRef,bool bDeleted,bool bRelativeAsOffset)965cdf0e10cSrcweir bool FormulaParserImpl::pushReferenceOperand( const BinSingleRef2d& rRef, bool bDeleted, bool bRelativeAsOffset )
966cdf0e10cSrcweir {
967cdf0e10cSrcweir SingleReference aApiRef;
968cdf0e10cSrcweir convertReference2d( aApiRef, rRef, bDeleted, bRelativeAsOffset );
969cdf0e10cSrcweir return pushValueOperand( aApiRef );
970cdf0e10cSrcweir }
971cdf0e10cSrcweir
pushReferenceOperand(const BinComplexRef2d & rRef,bool bDeleted,bool bRelativeAsOffset)972cdf0e10cSrcweir bool FormulaParserImpl::pushReferenceOperand( const BinComplexRef2d& rRef, bool bDeleted, bool bRelativeAsOffset )
973cdf0e10cSrcweir {
974cdf0e10cSrcweir ComplexReference aApiRef;
975cdf0e10cSrcweir convertReference2d( aApiRef, rRef.maRef1, rRef.maRef2, bDeleted, bRelativeAsOffset );
976cdf0e10cSrcweir return pushValueOperand( aApiRef );
977cdf0e10cSrcweir }
978cdf0e10cSrcweir
979cdf0e10cSrcweir template< typename Type >
pushReferenceOperand(const LinkSheetRange & rSheetRange,const Type & rApiRef)980cdf0e10cSrcweir bool FormulaParserImpl::pushReferenceOperand( const LinkSheetRange& rSheetRange, const Type& rApiRef )
981cdf0e10cSrcweir {
982cdf0e10cSrcweir if( rSheetRange.isExternal() )
983cdf0e10cSrcweir {
984cdf0e10cSrcweir ExternalReference aApiExtRef;
985cdf0e10cSrcweir aApiExtRef.Index = rSheetRange.getDocLinkIndex();
986cdf0e10cSrcweir aApiExtRef.Reference <<= rApiRef;
987cdf0e10cSrcweir return pushValueOperand( aApiExtRef );
988cdf0e10cSrcweir }
989cdf0e10cSrcweir return pushValueOperand( rApiRef );
990cdf0e10cSrcweir }
991cdf0e10cSrcweir
pushReferenceOperand(const LinkSheetRange & rSheetRange,const BinSingleRef2d & rRef,bool bDeleted,bool bRelativeAsOffset)992cdf0e10cSrcweir bool FormulaParserImpl::pushReferenceOperand( const LinkSheetRange& rSheetRange, const BinSingleRef2d& rRef, bool bDeleted, bool bRelativeAsOffset )
993cdf0e10cSrcweir {
994cdf0e10cSrcweir if( rSheetRange.is3dRange() )
995cdf0e10cSrcweir {
996cdf0e10cSrcweir // single-cell-range over several sheets, needs to create a ComplexReference
997cdf0e10cSrcweir ComplexReference aApiRef;
998cdf0e10cSrcweir convertReference3d( aApiRef, rSheetRange, rRef, rRef, bDeleted, bRelativeAsOffset );
999cdf0e10cSrcweir return pushReferenceOperand( rSheetRange, aApiRef );
1000cdf0e10cSrcweir }
1001cdf0e10cSrcweir SingleReference aApiRef;
1002cdf0e10cSrcweir convertReference3d( aApiRef, rSheetRange.getFirstSheet(), rSheetRange.isSameSheet(), rRef, bDeleted, bRelativeAsOffset );
1003cdf0e10cSrcweir return pushReferenceOperand( rSheetRange, aApiRef );
1004cdf0e10cSrcweir }
1005cdf0e10cSrcweir
pushReferenceOperand(const LinkSheetRange & rSheetRange,const BinComplexRef2d & rRef,bool bDeleted,bool bRelativeAsOffset)1006cdf0e10cSrcweir bool FormulaParserImpl::pushReferenceOperand( const LinkSheetRange& rSheetRange, const BinComplexRef2d& rRef, bool bDeleted, bool bRelativeAsOffset )
1007cdf0e10cSrcweir {
1008cdf0e10cSrcweir ComplexReference aApiRef;
1009cdf0e10cSrcweir convertReference3d( aApiRef, rSheetRange, rRef.maRef1, rRef.maRef2, bDeleted, bRelativeAsOffset );
1010cdf0e10cSrcweir return pushReferenceOperand( rSheetRange, aApiRef );
1011cdf0e10cSrcweir }
1012cdf0e10cSrcweir
pushNlrOperand(const BinSingleRef2d & rRef)1013cdf0e10cSrcweir bool FormulaParserImpl::pushNlrOperand( const BinSingleRef2d& rRef )
1014cdf0e10cSrcweir {
1015cdf0e10cSrcweir SingleReference aApiRef;
1016cdf0e10cSrcweir convertReference2d( aApiRef, rRef, false, false );
1017cdf0e10cSrcweir return pushValueOperand( aApiRef, OPCODE_NLR );
1018cdf0e10cSrcweir }
1019cdf0e10cSrcweir
pushEmbeddedRefOperand(const DefinedNameBase & rName,bool bPushBadToken)1020cdf0e10cSrcweir bool FormulaParserImpl::pushEmbeddedRefOperand( const DefinedNameBase& rName, bool bPushBadToken )
1021cdf0e10cSrcweir {
1022cdf0e10cSrcweir Any aRefAny = rName.getReference( maBaseAddr );
1023cdf0e10cSrcweir if( aRefAny.hasValue() )
1024cdf0e10cSrcweir return pushAnyOperand( aRefAny, OPCODE_PUSH );
1025cdf0e10cSrcweir if( bPushBadToken && (rName.getModelName().getLength() > 0) && (rName.getModelName()[ 0 ] >= ' ') )
1026cdf0e10cSrcweir return pushValueOperand( rName.getModelName(), OPCODE_BAD );
1027cdf0e10cSrcweir return pushBiffErrorOperand( BIFF_ERR_NAME );
1028cdf0e10cSrcweir }
1029cdf0e10cSrcweir
pushDefinedNameOperand(const DefinedNameRef & rxDefName)1030cdf0e10cSrcweir bool FormulaParserImpl::pushDefinedNameOperand( const DefinedNameRef& rxDefName )
1031cdf0e10cSrcweir {
1032cdf0e10cSrcweir if( !rxDefName || (rxDefName->getModelName().getLength() == 0) )
1033cdf0e10cSrcweir return pushBiffErrorOperand( BIFF_ERR_NAME );
1034cdf0e10cSrcweir if( rxDefName->isMacroFunction() )
1035cdf0e10cSrcweir return pushValueOperand( rxDefName->getModelName(), OPCODE_MACRO );
1036cdf0e10cSrcweir if( rxDefName->getTokenIndex() >= 0 )
1037cdf0e10cSrcweir return pushValueOperand( rxDefName->getTokenIndex(), OPCODE_NAME );
1038cdf0e10cSrcweir return pushEmbeddedRefOperand( *rxDefName, true );
1039cdf0e10cSrcweir }
1040cdf0e10cSrcweir
pushExternalFuncOperand(const FunctionInfo & rFuncInfo)1041cdf0e10cSrcweir bool FormulaParserImpl::pushExternalFuncOperand( const FunctionInfo& rFuncInfo )
1042cdf0e10cSrcweir {
1043cdf0e10cSrcweir return (rFuncInfo.mnApiOpCode == OPCODE_EXTERNAL) ?
1044cdf0e10cSrcweir pushValueOperand( rFuncInfo.maExtProgName, OPCODE_EXTERNAL ) :
1045cdf0e10cSrcweir pushOperand( rFuncInfo.mnApiOpCode );
1046cdf0e10cSrcweir }
1047cdf0e10cSrcweir
pushDdeLinkOperand(const OUString & rDdeServer,const OUString & rDdeTopic,const OUString & rDdeItem)1048cdf0e10cSrcweir bool FormulaParserImpl::pushDdeLinkOperand( const OUString& rDdeServer, const OUString& rDdeTopic, const OUString& rDdeItem )
1049cdf0e10cSrcweir {
1050cdf0e10cSrcweir // create the function call DDE("server";"topic";"item")
1051cdf0e10cSrcweir return
1052cdf0e10cSrcweir pushValueOperandToken( rDdeServer ) &&
1053cdf0e10cSrcweir pushValueOperandToken( rDdeTopic ) &&
1054cdf0e10cSrcweir pushValueOperandToken( rDdeItem ) &&
1055cdf0e10cSrcweir pushFunctionOperator( OPCODE_DDE, 3 );
1056cdf0e10cSrcweir }
1057cdf0e10cSrcweir
pushExternalNameOperand(const ExternalNameRef & rxExtName,const ExternalLink & rExtLink)1058cdf0e10cSrcweir bool FormulaParserImpl::pushExternalNameOperand( const ExternalNameRef& rxExtName, const ExternalLink& rExtLink )
1059cdf0e10cSrcweir {
1060cdf0e10cSrcweir if( rxExtName.get() ) switch( rExtLink.getLinkType() )
1061cdf0e10cSrcweir {
1062cdf0e10cSrcweir case LINKTYPE_INTERNAL:
1063cdf0e10cSrcweir case LINKTYPE_EXTERNAL:
1064cdf0e10cSrcweir return pushEmbeddedRefOperand( *rxExtName, false );
1065cdf0e10cSrcweir
1066cdf0e10cSrcweir case LINKTYPE_ANALYSIS:
1067cdf0e10cSrcweir // TODO: need support for localized addin function names
1068cdf0e10cSrcweir if( const FunctionInfo* pFuncInfo = getFuncInfoFromOoxFuncName( rxExtName->getUpcaseModelName() ) )
1069cdf0e10cSrcweir return pushExternalFuncOperand( *pFuncInfo );
1070cdf0e10cSrcweir break;
1071cdf0e10cSrcweir
1072cdf0e10cSrcweir case LINKTYPE_LIBRARY:
1073cdf0e10cSrcweir if( const FunctionInfo* pFuncInfo = getFuncInfoFromOoxFuncName( rxExtName->getUpcaseModelName() ) )
1074cdf0e10cSrcweir if( (pFuncInfo->meFuncLibType != FUNCLIB_UNKNOWN) && (pFuncInfo->meFuncLibType == rExtLink.getFuncLibraryType()) )
1075cdf0e10cSrcweir return pushExternalFuncOperand( *pFuncInfo );
1076cdf0e10cSrcweir break;
1077cdf0e10cSrcweir
1078cdf0e10cSrcweir case LINKTYPE_DDE:
1079cdf0e10cSrcweir {
1080cdf0e10cSrcweir OUString aDdeServer, aDdeTopic, aDdeItem;
1081cdf0e10cSrcweir if( rxExtName->getDdeLinkData( aDdeServer, aDdeTopic, aDdeItem ) )
1082cdf0e10cSrcweir return pushDdeLinkOperand( aDdeServer, aDdeTopic, aDdeItem );
1083cdf0e10cSrcweir }
1084cdf0e10cSrcweir break;
1085cdf0e10cSrcweir
1086cdf0e10cSrcweir default:
1087cdf0e10cSrcweir OSL_ENSURE( rExtLink.getLinkType() != LINKTYPE_SELF, "FormulaParserImpl::pushExternalNameOperand - invalid call" );
1088cdf0e10cSrcweir }
1089cdf0e10cSrcweir return pushBiffErrorOperand( BIFF_ERR_NAME );
1090cdf0e10cSrcweir }
1091cdf0e10cSrcweir
pushSpecialTokenOperand(const BinAddress & rBaseAddr,bool bTable)1092cdf0e10cSrcweir bool FormulaParserImpl::pushSpecialTokenOperand( const BinAddress& rBaseAddr, bool bTable )
1093cdf0e10cSrcweir {
1094cdf0e10cSrcweir CellAddress aBaseAddr( maBaseAddr.Sheet, rBaseAddr.mnCol, rBaseAddr.mnRow );
1095cdf0e10cSrcweir ApiSpecialTokenInfo aTokenInfo( aBaseAddr, bTable );
1096cdf0e10cSrcweir return mbSpecialTokens && (getFormulaSize() == 0) && pushValueOperand( aTokenInfo, OPCODE_BAD );
1097cdf0e10cSrcweir }
1098cdf0e10cSrcweir
pushUnaryPreOperator(sal_Int32 nOpCode)1099cdf0e10cSrcweir bool FormulaParserImpl::pushUnaryPreOperator( sal_Int32 nOpCode )
1100cdf0e10cSrcweir {
1101cdf0e10cSrcweir return pushUnaryPreOperatorToken( nOpCode, &maLeadingSpaces ) && resetSpaces();
1102cdf0e10cSrcweir }
1103cdf0e10cSrcweir
pushUnaryPostOperator(sal_Int32 nOpCode)1104cdf0e10cSrcweir bool FormulaParserImpl::pushUnaryPostOperator( sal_Int32 nOpCode )
1105cdf0e10cSrcweir {
1106cdf0e10cSrcweir return pushUnaryPostOperatorToken( nOpCode, &maLeadingSpaces ) && resetSpaces();
1107cdf0e10cSrcweir }
1108cdf0e10cSrcweir
pushBinaryOperator(sal_Int32 nOpCode)1109cdf0e10cSrcweir bool FormulaParserImpl::pushBinaryOperator( sal_Int32 nOpCode )
1110cdf0e10cSrcweir {
1111cdf0e10cSrcweir return pushBinaryOperatorToken( nOpCode, &maLeadingSpaces ) && resetSpaces();
1112cdf0e10cSrcweir }
1113cdf0e10cSrcweir
pushParenthesesOperator()1114cdf0e10cSrcweir bool FormulaParserImpl::pushParenthesesOperator()
1115cdf0e10cSrcweir {
1116cdf0e10cSrcweir return pushParenthesesOperatorToken( &maOpeningSpaces, &maClosingSpaces ) && resetSpaces();
1117cdf0e10cSrcweir }
1118cdf0e10cSrcweir
pushFunctionOperator(sal_Int32 nOpCode,size_t nParamCount)1119cdf0e10cSrcweir bool FormulaParserImpl::pushFunctionOperator( sal_Int32 nOpCode, size_t nParamCount )
1120cdf0e10cSrcweir {
1121cdf0e10cSrcweir return pushFunctionOperatorToken( nOpCode, nParamCount, &maLeadingSpaces, &maClosingSpaces ) && resetSpaces();
1122cdf0e10cSrcweir }
1123cdf0e10cSrcweir
pushFunctionOperator(const FunctionInfo & rFuncInfo,size_t nParamCount)1124cdf0e10cSrcweir bool FormulaParserImpl::pushFunctionOperator( const FunctionInfo& rFuncInfo, size_t nParamCount )
1125cdf0e10cSrcweir {
1126cdf0e10cSrcweir return pushFunctionOperatorToken( rFuncInfo, nParamCount, &maLeadingSpaces, &maClosingSpaces ) && resetSpaces();
1127cdf0e10cSrcweir }
1128cdf0e10cSrcweir
1129cdf0e10cSrcweir // reference conversion -------------------------------------------------------
1130cdf0e10cSrcweir
initReference2d(SingleReference & orApiRef) const1131cdf0e10cSrcweir void FormulaParserImpl::initReference2d( SingleReference& orApiRef ) const
1132cdf0e10cSrcweir {
1133cdf0e10cSrcweir if( mb2dRefsAs3dRefs )
1134cdf0e10cSrcweir {
1135cdf0e10cSrcweir initReference3d( orApiRef, maBaseAddr.Sheet, false );
1136cdf0e10cSrcweir }
1137cdf0e10cSrcweir else
1138cdf0e10cSrcweir {
1139cdf0e10cSrcweir orApiRef.Flags = SHEET_RELATIVE;
1140cdf0e10cSrcweir // #i10184# absolute sheet index needed for relative references in shared formulas
1141cdf0e10cSrcweir orApiRef.Sheet = maBaseAddr.Sheet;
1142cdf0e10cSrcweir orApiRef.RelativeSheet = 0;
1143cdf0e10cSrcweir }
1144cdf0e10cSrcweir }
1145cdf0e10cSrcweir
initReference3d(SingleReference & orApiRef,sal_Int32 nSheet,bool bSameSheet) const1146cdf0e10cSrcweir void FormulaParserImpl::initReference3d( SingleReference& orApiRef, sal_Int32 nSheet, bool bSameSheet ) const
1147cdf0e10cSrcweir {
1148cdf0e10cSrcweir orApiRef.Flags = SHEET_3D;
1149cdf0e10cSrcweir if( nSheet < 0 )
1150cdf0e10cSrcweir {
1151cdf0e10cSrcweir orApiRef.Sheet = 0;
1152cdf0e10cSrcweir orApiRef.Flags |= SHEET_DELETED;
1153cdf0e10cSrcweir }
1154cdf0e10cSrcweir else if( bSameSheet )
1155cdf0e10cSrcweir {
1156cdf0e10cSrcweir OSL_ENSURE( nSheet == 0, "FormulaParserImpl::initReference3d - invalid sheet index" );
1157cdf0e10cSrcweir orApiRef.Flags |= SHEET_RELATIVE;
1158cdf0e10cSrcweir orApiRef.RelativeSheet = 0;
1159cdf0e10cSrcweir }
1160cdf0e10cSrcweir else
1161cdf0e10cSrcweir {
1162cdf0e10cSrcweir orApiRef.Sheet = nSheet;
1163cdf0e10cSrcweir }
1164cdf0e10cSrcweir }
1165cdf0e10cSrcweir
convertReference(SingleReference & orApiRef,const BinSingleRef2d & rRef,bool bDeleted,bool bRelativeAsOffset) const1166cdf0e10cSrcweir void FormulaParserImpl::convertReference( SingleReference& orApiRef, const BinSingleRef2d& rRef, bool bDeleted, bool bRelativeAsOffset ) const
1167cdf0e10cSrcweir {
1168cdf0e10cSrcweir if( bDeleted )
1169cdf0e10cSrcweir {
1170cdf0e10cSrcweir orApiRef.Column = 0;
1171cdf0e10cSrcweir orApiRef.Row = 0;
1172cdf0e10cSrcweir // no explicit information about whether row or column is deleted
1173cdf0e10cSrcweir orApiRef.Flags |= COLUMN_DELETED | ROW_DELETED;
1174cdf0e10cSrcweir }
1175cdf0e10cSrcweir else
1176cdf0e10cSrcweir {
1177cdf0e10cSrcweir // column/row indexes and flags
1178cdf0e10cSrcweir setFlag( orApiRef.Flags, COLUMN_RELATIVE, rRef.mbColRel );
1179cdf0e10cSrcweir setFlag( orApiRef.Flags, ROW_RELATIVE, rRef.mbRowRel );
1180cdf0e10cSrcweir (rRef.mbColRel ? orApiRef.RelativeColumn : orApiRef.Column) = rRef.mnCol;
1181cdf0e10cSrcweir (rRef.mbRowRel ? orApiRef.RelativeRow : orApiRef.Row) = rRef.mnRow;
1182cdf0e10cSrcweir // convert absolute indexes to relative offsets used in API
1183cdf0e10cSrcweir if( !bRelativeAsOffset )
1184cdf0e10cSrcweir {
1185cdf0e10cSrcweir if( rRef.mbColRel )
1186cdf0e10cSrcweir orApiRef.RelativeColumn -= maBaseAddr.Column;
1187cdf0e10cSrcweir if( rRef.mbRowRel )
1188cdf0e10cSrcweir orApiRef.RelativeRow -= maBaseAddr.Row;
1189cdf0e10cSrcweir }
1190cdf0e10cSrcweir }
1191cdf0e10cSrcweir }
1192cdf0e10cSrcweir
convertReference(ComplexReference & orApiRef,const BinSingleRef2d & rRef1,const BinSingleRef2d & rRef2,bool bDeleted,bool bRelativeAsOffset) const1193cdf0e10cSrcweir void FormulaParserImpl::convertReference( ComplexReference& orApiRef, const BinSingleRef2d& rRef1, const BinSingleRef2d& rRef2, bool bDeleted, bool bRelativeAsOffset ) const
1194cdf0e10cSrcweir {
1195cdf0e10cSrcweir convertReference( orApiRef.Reference1, rRef1, bDeleted, bRelativeAsOffset );
1196cdf0e10cSrcweir convertReference( orApiRef.Reference2, rRef2, bDeleted, bRelativeAsOffset );
1197cdf0e10cSrcweir /* Handle references to complete rows or columns (e.g. $1:$2 or C:D),
1198cdf0e10cSrcweir need to expand or shrink to limits of own document. */
1199cdf0e10cSrcweir if( !bDeleted && !rRef1.mbColRel && !rRef2.mbColRel && (orApiRef.Reference1.Column == 0) && (orApiRef.Reference2.Column == mnMaxXlsCol) )
1200cdf0e10cSrcweir orApiRef.Reference2.Column = mnMaxApiCol;
1201cdf0e10cSrcweir if( !bDeleted && !rRef1.mbRowRel && !rRef2.mbRowRel && (orApiRef.Reference1.Row == 0) && (orApiRef.Reference2.Row == mnMaxXlsRow) )
1202cdf0e10cSrcweir orApiRef.Reference2.Row = mnMaxApiRow;
1203cdf0e10cSrcweir }
1204cdf0e10cSrcweir
convertReference2d(SingleReference & orApiRef,const BinSingleRef2d & rRef,bool bDeleted,bool bRelativeAsOffset) const1205cdf0e10cSrcweir void FormulaParserImpl::convertReference2d( SingleReference& orApiRef, const BinSingleRef2d& rRef, bool bDeleted, bool bRelativeAsOffset ) const
1206cdf0e10cSrcweir {
1207cdf0e10cSrcweir initReference2d( orApiRef );
1208cdf0e10cSrcweir convertReference( orApiRef, rRef, bDeleted, bRelativeAsOffset );
1209cdf0e10cSrcweir }
1210cdf0e10cSrcweir
convertReference2d(ComplexReference & orApiRef,const BinSingleRef2d & rRef1,const BinSingleRef2d & rRef2,bool bDeleted,bool bRelativeAsOffset) const1211cdf0e10cSrcweir void FormulaParserImpl::convertReference2d( ComplexReference& orApiRef, const BinSingleRef2d& rRef1, const BinSingleRef2d& rRef2, bool bDeleted, bool bRelativeAsOffset ) const
1212cdf0e10cSrcweir {
1213cdf0e10cSrcweir initReference2d( orApiRef.Reference1 );
1214cdf0e10cSrcweir initReference2d( orApiRef.Reference2 );
1215cdf0e10cSrcweir convertReference( orApiRef, rRef1, rRef2, bDeleted, bRelativeAsOffset );
1216cdf0e10cSrcweir // remove sheet name from second part of reference
1217cdf0e10cSrcweir setFlag( orApiRef.Reference2.Flags, SHEET_3D, false );
1218cdf0e10cSrcweir }
1219cdf0e10cSrcweir
convertReference3d(SingleReference & orApiRef,sal_Int32 nSheet,bool bSameSheet,const BinSingleRef2d & rRef,bool bDeleted,bool bRelativeAsOffset) const1220cdf0e10cSrcweir void FormulaParserImpl::convertReference3d( SingleReference& orApiRef, sal_Int32 nSheet, bool bSameSheet, const BinSingleRef2d& rRef, bool bDeleted, bool bRelativeAsOffset ) const
1221cdf0e10cSrcweir {
1222cdf0e10cSrcweir initReference3d( orApiRef, nSheet, bSameSheet );
1223cdf0e10cSrcweir convertReference( orApiRef, rRef, bDeleted, bRelativeAsOffset );
1224cdf0e10cSrcweir }
1225cdf0e10cSrcweir
convertReference3d(ComplexReference & orApiRef,const LinkSheetRange & rSheetRange,const BinSingleRef2d & rRef1,const BinSingleRef2d & rRef2,bool bDeleted,bool bRelativeAsOffset) const1226cdf0e10cSrcweir void FormulaParserImpl::convertReference3d( ComplexReference& orApiRef, const LinkSheetRange& rSheetRange, const BinSingleRef2d& rRef1, const BinSingleRef2d& rRef2, bool bDeleted, bool bRelativeAsOffset ) const
1227cdf0e10cSrcweir {
1228cdf0e10cSrcweir bool bSameSheet = rSheetRange.isSameSheet();
1229cdf0e10cSrcweir initReference3d( orApiRef.Reference1, rSheetRange.getFirstSheet(), bSameSheet );
1230cdf0e10cSrcweir initReference3d( orApiRef.Reference2, rSheetRange.getLastSheet(), bSameSheet );
1231cdf0e10cSrcweir convertReference( orApiRef, rRef1, rRef2, bDeleted, bRelativeAsOffset );
1232cdf0e10cSrcweir // remove sheet name from second part of reference
1233cdf0e10cSrcweir setFlag( orApiRef.Reference2.Flags, SHEET_3D, rSheetRange.is3dRange() );
1234cdf0e10cSrcweir }
1235cdf0e10cSrcweir
1236cdf0e10cSrcweir // finalize token sequence ----------------------------------------------------
1237cdf0e10cSrcweir
resolveBadFuncName(const OUString & rTokenData) const1238cdf0e10cSrcweir const FunctionInfo* FormulaParserImpl::resolveBadFuncName( const OUString& rTokenData ) const
1239cdf0e10cSrcweir {
1240cdf0e10cSrcweir /* Try to parse calls to library functions. The format of such a function
1241cdf0e10cSrcweir call is "[n]!funcname", n>0 being the link identifier of the function
1242cdf0e10cSrcweir library spreadsheet file. */
1243cdf0e10cSrcweir sal_Int32 nBracketOpen = rTokenData.indexOf( '[' );
1244cdf0e10cSrcweir sal_Int32 nBracketClose = rTokenData.indexOf( ']' );
1245cdf0e10cSrcweir sal_Int32 nExclamation = rTokenData.indexOf( '!' );
1246cdf0e10cSrcweir if( (0 == nBracketOpen) && (nBracketOpen + 1 < nBracketClose) && (nBracketClose + 1 == nExclamation) && (nExclamation + 1 < rTokenData.getLength()) )
1247cdf0e10cSrcweir {
1248cdf0e10cSrcweir sal_Int32 nRefId = rTokenData.copy( nBracketOpen + 1, nBracketClose - nBracketOpen - 1 ).toInt32();
1249cdf0e10cSrcweir const ExternalLink* pExtLink = getExternalLinks().getExternalLink( nRefId ).get();
1250cdf0e10cSrcweir if( pExtLink && (pExtLink->getLinkType() == LINKTYPE_LIBRARY) )
1251cdf0e10cSrcweir {
1252cdf0e10cSrcweir OUString aFuncName = rTokenData.copy( nExclamation + 1 ).toAsciiUpperCase();
1253cdf0e10cSrcweir if( const FunctionInfo* pFuncInfo = getFuncInfoFromOoxFuncName( aFuncName ) )
1254cdf0e10cSrcweir if( (pFuncInfo->meFuncLibType != FUNCLIB_UNKNOWN) && (pFuncInfo->meFuncLibType == pExtLink->getFuncLibraryType()) )
1255cdf0e10cSrcweir return pFuncInfo;
1256cdf0e10cSrcweir }
1257cdf0e10cSrcweir }
1258cdf0e10cSrcweir return 0;
1259cdf0e10cSrcweir }
1260cdf0e10cSrcweir
resolveDefinedName(sal_Int32 nTokenIndex) const1261cdf0e10cSrcweir OUString FormulaParserImpl::resolveDefinedName( sal_Int32 nTokenIndex ) const
1262cdf0e10cSrcweir {
1263cdf0e10cSrcweir if( const DefinedName* pDefName = getDefinedNames().getByTokenIndex( nTokenIndex ).get() )
1264cdf0e10cSrcweir return pDefName->getCalcName();
1265cdf0e10cSrcweir return OUString();
1266cdf0e10cSrcweir }
1267cdf0e10cSrcweir
1268cdf0e10cSrcweir // OOXML/BIFF12 parser implementation =========================================
1269cdf0e10cSrcweir
1270cdf0e10cSrcweir class OoxFormulaParserImpl : public FormulaParserImpl
1271cdf0e10cSrcweir {
1272cdf0e10cSrcweir public:
1273cdf0e10cSrcweir explicit OoxFormulaParserImpl( const FormulaParser& rParent );
1274cdf0e10cSrcweir
1275cdf0e10cSrcweir virtual ApiTokenSequence importOoxFormula(
1276cdf0e10cSrcweir const CellAddress& rBaseAddr,
1277cdf0e10cSrcweir const OUString& rFormulaString );
1278cdf0e10cSrcweir
1279cdf0e10cSrcweir virtual ApiTokenSequence importBiff12Formula(
1280cdf0e10cSrcweir const CellAddress& rBaseAddr,
1281cdf0e10cSrcweir FormulaType eType,
1282cdf0e10cSrcweir SequenceInputStream& rStrm );
1283cdf0e10cSrcweir
1284cdf0e10cSrcweir private:
1285cdf0e10cSrcweir // import token contents and create API formula token ---------------------
1286cdf0e10cSrcweir
1287cdf0e10cSrcweir bool importAttrToken( SequenceInputStream& rStrm );
1288cdf0e10cSrcweir bool importSpaceToken( SequenceInputStream& rStrm );
1289cdf0e10cSrcweir bool importTableToken( SequenceInputStream& rStrm );
1290cdf0e10cSrcweir bool importArrayToken( SequenceInputStream& rStrm );
1291cdf0e10cSrcweir bool importRefToken( SequenceInputStream& rStrm, bool bDeleted, bool bRelativeAsOffset );
1292cdf0e10cSrcweir bool importAreaToken( SequenceInputStream& rStrm, bool bDeleted, bool bRelativeAsOffset );
1293cdf0e10cSrcweir bool importRef3dToken( SequenceInputStream& rStrm, bool bDeleted, bool bRelativeAsOffset );
1294cdf0e10cSrcweir bool importArea3dToken( SequenceInputStream& rStrm, bool bDeleted, bool bRelativeAsOffset );
1295cdf0e10cSrcweir bool importMemAreaToken( SequenceInputStream& rStrm, bool bAddData );
1296cdf0e10cSrcweir bool importMemFuncToken( SequenceInputStream& rStrm );
1297cdf0e10cSrcweir bool importNameToken( SequenceInputStream& rStrm );
1298cdf0e10cSrcweir bool importNameXToken( SequenceInputStream& rStrm );
1299cdf0e10cSrcweir bool importFuncToken( SequenceInputStream& rStrm );
1300cdf0e10cSrcweir bool importFuncVarToken( SequenceInputStream& rStrm );
1301cdf0e10cSrcweir bool importExpToken( SequenceInputStream& rStrm );
1302cdf0e10cSrcweir
1303cdf0e10cSrcweir LinkSheetRange readSheetRange( SequenceInputStream& rStrm );
1304cdf0e10cSrcweir
1305cdf0e10cSrcweir void swapStreamPosition( SequenceInputStream& rStrm );
1306cdf0e10cSrcweir void skipMemAreaAddData( SequenceInputStream& rStrm );
1307cdf0e10cSrcweir
1308cdf0e10cSrcweir // convert BIN token and push API operand or operator ---------------------
1309cdf0e10cSrcweir
1310cdf0e10cSrcweir bool pushBiff12Name( sal_Int32 nNameId );
1311cdf0e10cSrcweir bool pushBiff12ExtName( sal_Int32 nRefId, sal_Int32 nNameId );
1312cdf0e10cSrcweir bool pushBiff12Function( sal_uInt16 nFuncId );
1313cdf0e10cSrcweir bool pushBiff12Function( sal_uInt16 nFuncId, sal_uInt8 nParamCount );
1314cdf0e10cSrcweir
1315cdf0e10cSrcweir private:
1316cdf0e10cSrcweir ApiParserWrapper maApiParser; /// Wrapper for the API formula parser object.
1317cdf0e10cSrcweir sal_Int64 mnAddDataPos; /// Current stream position for additional data (tExp, tArray, tMemArea).
1318cdf0e10cSrcweir bool mbNeedExtRefs; /// True = parser needs initialization of external reference info.
1319cdf0e10cSrcweir };
1320cdf0e10cSrcweir
1321cdf0e10cSrcweir // ----------------------------------------------------------------------------
1322cdf0e10cSrcweir
OoxFormulaParserImpl(const FormulaParser & rParent)1323cdf0e10cSrcweir OoxFormulaParserImpl::OoxFormulaParserImpl( const FormulaParser& rParent ) :
1324cdf0e10cSrcweir FormulaParserImpl( rParent ),
1325cdf0e10cSrcweir maApiParser( rParent.getBaseFilter().getModelFactory(), rParent ),
1326cdf0e10cSrcweir mnAddDataPos( 0 ),
1327cdf0e10cSrcweir mbNeedExtRefs( true )
1328cdf0e10cSrcweir {
1329cdf0e10cSrcweir }
1330cdf0e10cSrcweir
importOoxFormula(const CellAddress & rBaseAddr,const OUString & rFormulaString)1331cdf0e10cSrcweir ApiTokenSequence OoxFormulaParserImpl::importOoxFormula( const CellAddress& rBaseAddr, const OUString& rFormulaString )
1332cdf0e10cSrcweir {
1333cdf0e10cSrcweir if( mbNeedExtRefs )
1334cdf0e10cSrcweir {
1335cdf0e10cSrcweir maApiParser.getParserProperties().setProperty( PROP_ExternalLinks, getExternalLinks().getLinkInfos() );
1336cdf0e10cSrcweir mbNeedExtRefs = false;
1337cdf0e10cSrcweir }
1338cdf0e10cSrcweir return finalizeTokenArray( maApiParser.parseFormula( rFormulaString, rBaseAddr ) );
1339cdf0e10cSrcweir }
1340cdf0e10cSrcweir
importBiff12Formula(const CellAddress & rBaseAddr,FormulaType eType,SequenceInputStream & rStrm)1341cdf0e10cSrcweir ApiTokenSequence OoxFormulaParserImpl::importBiff12Formula( const CellAddress& rBaseAddr, FormulaType eType, SequenceInputStream& rStrm )
1342cdf0e10cSrcweir {
1343cdf0e10cSrcweir initializeImport( rBaseAddr, eType );
1344cdf0e10cSrcweir
1345cdf0e10cSrcweir sal_Int32 nFmlaSize = rStrm.readInt32();
1346cdf0e10cSrcweir sal_Int64 nFmlaPos = rStrm.tell();
1347cdf0e10cSrcweir sal_Int64 nFmlaEndPos = nFmlaPos + nFmlaSize;
1348cdf0e10cSrcweir
1349cdf0e10cSrcweir rStrm.seek( nFmlaEndPos );
1350cdf0e10cSrcweir sal_Int32 nAddDataSize = rStrm.readInt32();
1351cdf0e10cSrcweir mnAddDataPos = rStrm.tell();
1352cdf0e10cSrcweir sal_Int64 nAddDataEndPos = mnAddDataPos + nAddDataSize;
1353cdf0e10cSrcweir rStrm.seek( nFmlaPos );
1354cdf0e10cSrcweir
1355cdf0e10cSrcweir bool bOk = (nFmlaSize >= 0) && (nAddDataSize >= 0);
1356cdf0e10cSrcweir bool bRelativeAsOffset = mbRelativeAsOffset;
1357cdf0e10cSrcweir
1358cdf0e10cSrcweir while( bOk && !rStrm.isEof() && (rStrm.tell() < nFmlaEndPos) )
1359cdf0e10cSrcweir {
1360cdf0e10cSrcweir sal_uInt8 nTokenId;
1361cdf0e10cSrcweir rStrm >> nTokenId;
1362cdf0e10cSrcweir sal_uInt8 nTokenClass = nTokenId & BIFF_TOKCLASS_MASK;
1363cdf0e10cSrcweir sal_uInt8 nBaseId = nTokenId & BIFF_TOKID_MASK;
1364cdf0e10cSrcweir
1365cdf0e10cSrcweir if( nTokenClass == BIFF_TOKCLASS_NONE )
1366cdf0e10cSrcweir {
1367cdf0e10cSrcweir // base tokens
1368cdf0e10cSrcweir switch( nBaseId )
1369cdf0e10cSrcweir {
1370cdf0e10cSrcweir case BIFF_TOKID_EXP: bOk = importExpToken( rStrm ); break;
1371cdf0e10cSrcweir case BIFF_TOKID_ADD: bOk = pushBinaryOperator( OPCODE_ADD ); break;
1372cdf0e10cSrcweir case BIFF_TOKID_SUB: bOk = pushBinaryOperator( OPCODE_SUB ); break;
1373cdf0e10cSrcweir case BIFF_TOKID_MUL: bOk = pushBinaryOperator( OPCODE_MULT ); break;
1374cdf0e10cSrcweir case BIFF_TOKID_DIV: bOk = pushBinaryOperator( OPCODE_DIV ); break;
1375cdf0e10cSrcweir case BIFF_TOKID_POWER: bOk = pushBinaryOperator( OPCODE_POWER ); break;
1376cdf0e10cSrcweir case BIFF_TOKID_CONCAT: bOk = pushBinaryOperator( OPCODE_CONCAT ); break;
1377cdf0e10cSrcweir case BIFF_TOKID_LT: bOk = pushBinaryOperator( OPCODE_LESS ); break;
1378cdf0e10cSrcweir case BIFF_TOKID_LE: bOk = pushBinaryOperator( OPCODE_LESS_EQUAL ); break;
1379cdf0e10cSrcweir case BIFF_TOKID_EQ: bOk = pushBinaryOperator( OPCODE_EQUAL ); break;
1380cdf0e10cSrcweir case BIFF_TOKID_GE: bOk = pushBinaryOperator( OPCODE_GREATER_EQUAL ); break;
1381cdf0e10cSrcweir case BIFF_TOKID_GT: bOk = pushBinaryOperator( OPCODE_GREATER ); break;
1382cdf0e10cSrcweir case BIFF_TOKID_NE: bOk = pushBinaryOperator( OPCODE_NOT_EQUAL ); break;
1383cdf0e10cSrcweir case BIFF_TOKID_ISECT: bOk = pushBinaryOperator( OPCODE_INTERSECT ); break;
1384cdf0e10cSrcweir case BIFF_TOKID_LIST: bOk = pushBinaryOperator( OPCODE_LIST ); break;
1385cdf0e10cSrcweir case BIFF_TOKID_RANGE: bOk = pushBinaryOperator( OPCODE_RANGE ); break;
1386cdf0e10cSrcweir case BIFF_TOKID_UPLUS: bOk = pushUnaryPreOperator( OPCODE_PLUS_SIGN ); break;
1387cdf0e10cSrcweir case BIFF_TOKID_UMINUS: bOk = pushUnaryPreOperator( OPCODE_MINUS_SIGN ); break;
1388cdf0e10cSrcweir case BIFF_TOKID_PERCENT: bOk = pushUnaryPostOperator( OPCODE_PERCENT ); break;
1389cdf0e10cSrcweir case BIFF_TOKID_PAREN: bOk = pushParenthesesOperator(); break;
1390cdf0e10cSrcweir case BIFF_TOKID_MISSARG: bOk = pushOperand( OPCODE_MISSING ); break;
1391cdf0e10cSrcweir case BIFF_TOKID_STR: bOk = pushValueOperand( BiffHelper::readString( rStrm, false ) ); break;
1392cdf0e10cSrcweir case BIFF_TOKID_NLR: bOk = importTableToken( rStrm ); break;
1393cdf0e10cSrcweir case BIFF_TOKID_ATTR: bOk = importAttrToken( rStrm ); break;
1394cdf0e10cSrcweir case BIFF_TOKID_ERR: bOk = pushBiffErrorOperand( rStrm.readuInt8() ); break;
1395cdf0e10cSrcweir case BIFF_TOKID_BOOL: bOk = pushBiffBoolOperand( rStrm.readuInt8() ); break;
1396cdf0e10cSrcweir case BIFF_TOKID_INT: bOk = pushValueOperand< double >( rStrm.readuInt16() ); break;
1397cdf0e10cSrcweir case BIFF_TOKID_NUM: bOk = pushValueOperand( rStrm.readDouble() ); break;
1398cdf0e10cSrcweir default: bOk = false;
1399cdf0e10cSrcweir }
1400cdf0e10cSrcweir }
1401cdf0e10cSrcweir else
1402cdf0e10cSrcweir {
1403cdf0e10cSrcweir // classified tokens
1404cdf0e10cSrcweir switch( nBaseId )
1405cdf0e10cSrcweir {
1406cdf0e10cSrcweir case BIFF_TOKID_ARRAY: bOk = importArrayToken( rStrm ); break;
1407cdf0e10cSrcweir case BIFF_TOKID_FUNC: bOk = importFuncToken( rStrm ); break;
1408cdf0e10cSrcweir case BIFF_TOKID_FUNCVAR: bOk = importFuncVarToken( rStrm ); break;
1409cdf0e10cSrcweir case BIFF_TOKID_NAME: bOk = importNameToken( rStrm ); break;
1410cdf0e10cSrcweir case BIFF_TOKID_REF: bOk = importRefToken( rStrm, false, false ); break;
1411cdf0e10cSrcweir case BIFF_TOKID_AREA: bOk = importAreaToken( rStrm, false, false ); break;
1412cdf0e10cSrcweir case BIFF_TOKID_MEMAREA: bOk = importMemAreaToken( rStrm, true ); break;
1413cdf0e10cSrcweir case BIFF_TOKID_MEMERR: bOk = importMemAreaToken( rStrm, false ); break;
1414cdf0e10cSrcweir case BIFF_TOKID_MEMNOMEM: bOk = importMemAreaToken( rStrm, false ); break;
1415cdf0e10cSrcweir case BIFF_TOKID_MEMFUNC: bOk = importMemFuncToken( rStrm ); break;
1416cdf0e10cSrcweir case BIFF_TOKID_REFERR: bOk = importRefToken( rStrm, true, false ); break;
1417cdf0e10cSrcweir case BIFF_TOKID_AREAERR: bOk = importAreaToken( rStrm, true, false ); break;
1418cdf0e10cSrcweir case BIFF_TOKID_REFN: bOk = importRefToken( rStrm, false, true ); break;
1419cdf0e10cSrcweir case BIFF_TOKID_AREAN: bOk = importAreaToken( rStrm, false, true ); break;
1420cdf0e10cSrcweir case BIFF_TOKID_MEMAREAN: bOk = importMemFuncToken( rStrm ); break;
1421cdf0e10cSrcweir case BIFF_TOKID_MEMNOMEMN: bOk = importMemFuncToken( rStrm ); break;
1422cdf0e10cSrcweir case BIFF_TOKID_NAMEX: bOk = importNameXToken( rStrm ); break;
1423cdf0e10cSrcweir case BIFF_TOKID_REF3D: bOk = importRef3dToken( rStrm, false, bRelativeAsOffset ); break;
1424cdf0e10cSrcweir case BIFF_TOKID_AREA3D: bOk = importArea3dToken( rStrm, false, bRelativeAsOffset ); break;
1425cdf0e10cSrcweir case BIFF_TOKID_REFERR3D: bOk = importRef3dToken( rStrm, true, bRelativeAsOffset ); break;
1426cdf0e10cSrcweir case BIFF_TOKID_AREAERR3D: bOk = importArea3dToken( rStrm, true, bRelativeAsOffset ); break;
1427cdf0e10cSrcweir default: bOk = false;
1428cdf0e10cSrcweir }
1429cdf0e10cSrcweir }
1430cdf0e10cSrcweir }
1431cdf0e10cSrcweir
1432cdf0e10cSrcweir // build and finalize the token sequence
1433cdf0e10cSrcweir ApiTokenSequence aFinalTokens;
1434cdf0e10cSrcweir if( bOk && (rStrm.tell() == nFmlaEndPos) && (mnAddDataPos == nAddDataEndPos) )
1435cdf0e10cSrcweir aFinalTokens = finalizeImport();
1436cdf0e10cSrcweir
1437cdf0e10cSrcweir // seek behind token array
1438cdf0e10cSrcweir if( (nFmlaSize >= 0) && (nAddDataSize >= 0) )
1439cdf0e10cSrcweir rStrm.seek( nAddDataEndPos );
1440cdf0e10cSrcweir
1441cdf0e10cSrcweir // return the final token sequence
1442cdf0e10cSrcweir return aFinalTokens;
1443cdf0e10cSrcweir }
1444cdf0e10cSrcweir
1445cdf0e10cSrcweir // import token contents and create API formula token -------------------------
1446cdf0e10cSrcweir
importAttrToken(SequenceInputStream & rStrm)1447cdf0e10cSrcweir bool OoxFormulaParserImpl::importAttrToken( SequenceInputStream& rStrm )
1448cdf0e10cSrcweir {
1449cdf0e10cSrcweir bool bOk = true;
1450cdf0e10cSrcweir sal_uInt8 nType;
1451cdf0e10cSrcweir rStrm >> nType;
1452cdf0e10cSrcweir // equal flags in all BIFFs
1453cdf0e10cSrcweir switch( nType )
1454cdf0e10cSrcweir {
1455cdf0e10cSrcweir case 0: // sometimes, tAttrSkip tokens miss the type flag
1456cdf0e10cSrcweir case BIFF_TOK_ATTR_VOLATILE:
1457cdf0e10cSrcweir case BIFF_TOK_ATTR_IF:
1458cdf0e10cSrcweir case BIFF_TOK_ATTR_SKIP:
1459cdf0e10cSrcweir case BIFF_TOK_ATTR_ASSIGN:
1460cdf0e10cSrcweir case BIFF_TOK_ATTR_IFERROR:
1461cdf0e10cSrcweir rStrm.skip( 2 );
1462cdf0e10cSrcweir break;
1463cdf0e10cSrcweir case BIFF_TOK_ATTR_CHOOSE:
1464cdf0e10cSrcweir rStrm.skip( 2 * rStrm.readuInt16() + 2 );
1465cdf0e10cSrcweir break;
1466cdf0e10cSrcweir case BIFF_TOK_ATTR_SUM:
1467cdf0e10cSrcweir rStrm.skip( 2 );
1468cdf0e10cSrcweir bOk = pushBiff12Function( BIFF_FUNC_SUM, 1 );
1469cdf0e10cSrcweir break;
1470cdf0e10cSrcweir case BIFF_TOK_ATTR_SPACE:
1471cdf0e10cSrcweir case BIFF_TOK_ATTR_SPACE_VOLATILE:
1472cdf0e10cSrcweir bOk = importSpaceToken( rStrm );
1473cdf0e10cSrcweir break;
1474cdf0e10cSrcweir default:
1475cdf0e10cSrcweir bOk = false;
1476cdf0e10cSrcweir }
1477cdf0e10cSrcweir return bOk;
1478cdf0e10cSrcweir }
1479cdf0e10cSrcweir
importSpaceToken(SequenceInputStream & rStrm)1480cdf0e10cSrcweir bool OoxFormulaParserImpl::importSpaceToken( SequenceInputStream& rStrm )
1481cdf0e10cSrcweir {
1482cdf0e10cSrcweir // equal constants in BIFF and OOX
1483cdf0e10cSrcweir sal_uInt8 nType, nCount;
1484cdf0e10cSrcweir rStrm >> nType >> nCount;
1485cdf0e10cSrcweir switch( nType )
1486cdf0e10cSrcweir {
1487cdf0e10cSrcweir case BIFF_TOK_ATTR_SPACE_SP:
1488cdf0e10cSrcweir appendLeadingSpaces( nCount, false );
1489cdf0e10cSrcweir break;
1490cdf0e10cSrcweir case BIFF_TOK_ATTR_SPACE_BR:
1491cdf0e10cSrcweir appendLeadingSpaces( nCount, true );
1492cdf0e10cSrcweir break;
1493cdf0e10cSrcweir case BIFF_TOK_ATTR_SPACE_SP_OPEN:
1494cdf0e10cSrcweir appendOpeningSpaces( nCount, false );
1495cdf0e10cSrcweir break;
1496cdf0e10cSrcweir case BIFF_TOK_ATTR_SPACE_BR_OPEN:
1497cdf0e10cSrcweir appendOpeningSpaces( nCount, true );
1498cdf0e10cSrcweir break;
1499cdf0e10cSrcweir case BIFF_TOK_ATTR_SPACE_SP_CLOSE:
1500cdf0e10cSrcweir appendClosingSpaces( nCount, false );
1501cdf0e10cSrcweir break;
1502cdf0e10cSrcweir case BIFF_TOK_ATTR_SPACE_BR_CLOSE:
1503cdf0e10cSrcweir appendClosingSpaces( nCount, true );
1504cdf0e10cSrcweir break;
1505cdf0e10cSrcweir }
1506cdf0e10cSrcweir return true;
1507cdf0e10cSrcweir }
1508cdf0e10cSrcweir
importTableToken(SequenceInputStream & rStrm)1509cdf0e10cSrcweir bool OoxFormulaParserImpl::importTableToken( SequenceInputStream& rStrm )
1510cdf0e10cSrcweir {
1511cdf0e10cSrcweir sal_uInt16 nFlags, nTableId, nCol1, nCol2;
1512cdf0e10cSrcweir rStrm.skip( 3 );
1513cdf0e10cSrcweir rStrm >> nFlags >> nTableId;
1514cdf0e10cSrcweir rStrm.skip( 2 );
1515cdf0e10cSrcweir rStrm >> nCol1 >> nCol2;
1516cdf0e10cSrcweir TableRef xTable = getTables().getTable( nTableId );
1517cdf0e10cSrcweir sal_Int32 nTokenIndex = xTable.get() ? xTable->getTokenIndex() : -1;
1518cdf0e10cSrcweir if( nTokenIndex >= 0 )
1519cdf0e10cSrcweir {
1520cdf0e10cSrcweir sal_Int32 nWidth = xTable->getWidth();
1521cdf0e10cSrcweir sal_Int32 nHeight = xTable->getHeight();
1522cdf0e10cSrcweir sal_Int32 nStartCol = 0;
1523cdf0e10cSrcweir sal_Int32 nEndCol = nWidth - 1;
1524cdf0e10cSrcweir sal_Int32 nStartRow = 0;
1525cdf0e10cSrcweir sal_Int32 nEndRow = nHeight - 1;
1526cdf0e10cSrcweir bool bFixedStartRow = true;
1527cdf0e10cSrcweir bool bFixedHeight = false;
1528cdf0e10cSrcweir
1529cdf0e10cSrcweir bool bSingleCol = getFlag( nFlags, BIFF12_TOK_TABLE_COLUMN );
1530cdf0e10cSrcweir bool bColRange = getFlag( nFlags, BIFF12_TOK_TABLE_COLRANGE );
1531cdf0e10cSrcweir bool bValidRef = !bSingleCol || !bColRange;
1532cdf0e10cSrcweir OSL_ENSURE( bValidRef, "OoxFormulaParserImpl::importTableToken - illegal combination of single column and column range" );
1533cdf0e10cSrcweir if( bValidRef )
1534cdf0e10cSrcweir {
1535cdf0e10cSrcweir if( bSingleCol )
1536cdf0e10cSrcweir nStartCol = nEndCol = nCol1;
1537cdf0e10cSrcweir else if( bColRange )
1538cdf0e10cSrcweir { nStartCol = nCol1; nEndCol = nCol2; }
1539cdf0e10cSrcweir bValidRef = (nStartCol <= nEndCol) && (nEndCol < nWidth);
1540cdf0e10cSrcweir OSL_ENSURE( bValidRef, "OoxFormulaParserImpl::importTableToken - invalid column range" );
1541cdf0e10cSrcweir }
1542cdf0e10cSrcweir
1543cdf0e10cSrcweir if( bValidRef )
1544cdf0e10cSrcweir {
1545cdf0e10cSrcweir bool bAllRows = getFlag( nFlags, BIFF12_TOK_TABLE_ALL );
1546cdf0e10cSrcweir bool bHeaderRows = getFlag( nFlags, BIFF12_TOK_TABLE_HEADERS );
1547cdf0e10cSrcweir bool bDataRows = getFlag( nFlags, BIFF12_TOK_TABLE_DATA );
1548cdf0e10cSrcweir bool bTotalsRows = getFlag( nFlags, BIFF12_TOK_TABLE_TOTALS );
1549cdf0e10cSrcweir bool bThisRow = getFlag( nFlags, BIFF12_TOK_TABLE_THISROW );
1550cdf0e10cSrcweir
1551cdf0e10cSrcweir sal_Int32 nStartDataRow = xTable->getHeaderRows();
1552cdf0e10cSrcweir sal_Int32 nEndDataRow = nEndRow - xTable->getTotalsRows();
1553cdf0e10cSrcweir bValidRef = (nStartRow <= nStartDataRow) && (nStartDataRow <= nEndDataRow) && (nEndDataRow <= nEndRow);
1554cdf0e10cSrcweir OSL_ENSURE( bValidRef, "OoxFormulaParserImpl::importTableToken - invalid data row range" );
1555cdf0e10cSrcweir if( bValidRef )
1556cdf0e10cSrcweir {
1557cdf0e10cSrcweir if( bAllRows )
1558cdf0e10cSrcweir {
1559cdf0e10cSrcweir bValidRef = !bHeaderRows && !bDataRows && !bTotalsRows && !bThisRow;
1560cdf0e10cSrcweir OSL_ENSURE( bValidRef, "OoxFormulaParserImpl::importTableToken - unexpected flags in [#All] table token" );
1561cdf0e10cSrcweir }
1562cdf0e10cSrcweir else if( bHeaderRows )
1563cdf0e10cSrcweir {
1564cdf0e10cSrcweir bValidRef = !bTotalsRows && !bThisRow;
1565cdf0e10cSrcweir OSL_ENSURE( bValidRef, "OoxFormulaParserImpl::importTableToken - unexpected flags in [#Headers] table token" );
1566cdf0e10cSrcweir nEndRow = bDataRows ? nEndDataRow : (nStartDataRow - 1);
1567cdf0e10cSrcweir bFixedHeight = !bDataRows;
1568cdf0e10cSrcweir }
1569cdf0e10cSrcweir else if( bDataRows )
1570cdf0e10cSrcweir {
1571cdf0e10cSrcweir bValidRef = !bThisRow;
1572cdf0e10cSrcweir OSL_ENSURE( bValidRef, "OoxFormulaParserImpl::importTableToken - unexpected flags in [#Data] table token" );
1573cdf0e10cSrcweir nStartRow = nStartDataRow;
1574cdf0e10cSrcweir if( !bTotalsRows ) nEndRow = nEndDataRow;
1575cdf0e10cSrcweir }
1576cdf0e10cSrcweir else if( bTotalsRows )
1577cdf0e10cSrcweir {
1578cdf0e10cSrcweir bValidRef = !bThisRow;
1579cdf0e10cSrcweir OSL_ENSURE( bValidRef, "OoxFormulaParserImpl::importTableToken - unexpected flags in [#Totals] table token" );
1580cdf0e10cSrcweir nStartRow = nEndDataRow + 1;
1581cdf0e10cSrcweir bFixedStartRow = false;
1582cdf0e10cSrcweir bFixedHeight = !bDataRows;
1583cdf0e10cSrcweir }
1584cdf0e10cSrcweir else if( bThisRow )
1585cdf0e10cSrcweir {
1586cdf0e10cSrcweir nStartRow = nEndRow = maBaseAddr.Row - xTable->getRange().StartRow;
1587cdf0e10cSrcweir bFixedHeight = true;
1588cdf0e10cSrcweir }
1589cdf0e10cSrcweir else
1590cdf0e10cSrcweir {
1591cdf0e10cSrcweir // nothing is the same as [#Data]
1592cdf0e10cSrcweir nStartRow = nStartDataRow;
1593cdf0e10cSrcweir nEndRow = nEndDataRow;
1594cdf0e10cSrcweir }
1595cdf0e10cSrcweir }
1596cdf0e10cSrcweir if( bValidRef )
1597cdf0e10cSrcweir bValidRef = (0 <= nStartRow) && (nStartRow <= nEndRow) && (nEndRow < nHeight);
1598cdf0e10cSrcweir }
1599cdf0e10cSrcweir if( bValidRef )
1600cdf0e10cSrcweir {
1601cdf0e10cSrcweir // push single database area token, if table token refers to entire table
1602cdf0e10cSrcweir if( (nStartCol == 0) && (nEndCol + 1 == nWidth) && (nStartRow == 0) && (nEndRow + 1 == nHeight) )
1603cdf0e10cSrcweir return pushValueOperand( nTokenIndex, OPCODE_DBAREA );
1604cdf0e10cSrcweir // create an OFFSET function call to refer to a subrange of the table
1605cdf0e10cSrcweir const FunctionInfo* pRowsInfo = getFuncInfoFromBiff12FuncId( BIFF_FUNC_ROWS );
1606cdf0e10cSrcweir const FunctionInfo* pColumnsInfo = getFuncInfoFromBiff12FuncId( BIFF_FUNC_COLUMNS );
1607cdf0e10cSrcweir return
1608cdf0e10cSrcweir pRowsInfo && pColumnsInfo &&
1609cdf0e10cSrcweir pushValueOperandToken( nTokenIndex, OPCODE_DBAREA ) &&
1610cdf0e10cSrcweir (bFixedStartRow ?
1611cdf0e10cSrcweir pushValueOperandToken< double >( nStartRow ) :
1612cdf0e10cSrcweir (pushValueOperandToken( nTokenIndex, OPCODE_DBAREA ) &&
1613cdf0e10cSrcweir pushFunctionOperatorToken( *pRowsInfo, 1 ) &&
1614cdf0e10cSrcweir pushValueOperandToken< double >( nHeight - nStartRow ) &&
1615cdf0e10cSrcweir pushBinaryOperatorToken( OPCODE_SUB ))) &&
1616cdf0e10cSrcweir pushValueOperandToken< double >( nStartCol ) &&
1617cdf0e10cSrcweir (bFixedHeight ?
1618cdf0e10cSrcweir pushValueOperandToken< double >( nEndRow - nStartRow + 1 ) :
1619cdf0e10cSrcweir (pushValueOperandToken( nTokenIndex, OPCODE_DBAREA ) &&
1620cdf0e10cSrcweir pushFunctionOperatorToken( *pRowsInfo, 1 ) &&
1621cdf0e10cSrcweir (((nStartRow == 0) && (nEndRow + 1 == nHeight)) ||
1622cdf0e10cSrcweir (pushValueOperandToken< double >( nHeight - (nEndRow - nStartRow + 1) ) &&
1623cdf0e10cSrcweir pushBinaryOperatorToken( OPCODE_SUB ))))) &&
1624cdf0e10cSrcweir (((nStartCol == 0) && (nEndCol + 1 == nWidth)) ?
1625cdf0e10cSrcweir (pushValueOperandToken( nTokenIndex, OPCODE_DBAREA ) &&
1626cdf0e10cSrcweir pushFunctionOperatorToken( *pColumnsInfo, 1 )) :
1627cdf0e10cSrcweir pushValueOperandToken< double >( nEndCol - nStartCol + 1 )) &&
1628cdf0e10cSrcweir pushBiff12Function( BIFF_FUNC_OFFSET, 5 );
1629cdf0e10cSrcweir }
1630cdf0e10cSrcweir }
1631cdf0e10cSrcweir return pushBiffErrorOperand( BIFF_ERR_REF );
1632cdf0e10cSrcweir }
1633cdf0e10cSrcweir
importArrayToken(SequenceInputStream & rStrm)1634cdf0e10cSrcweir bool OoxFormulaParserImpl::importArrayToken( SequenceInputStream& rStrm )
1635cdf0e10cSrcweir {
1636cdf0e10cSrcweir rStrm.skip( 14 );
1637cdf0e10cSrcweir
1638cdf0e10cSrcweir // start token array with opening brace and leading spaces
1639cdf0e10cSrcweir pushOperand( OPCODE_ARRAY_OPEN );
1640cdf0e10cSrcweir size_t nOpSize = popOperandSize();
1641cdf0e10cSrcweir size_t nOldArraySize = getFormulaSize();
1642cdf0e10cSrcweir
1643cdf0e10cSrcweir // read array size
1644cdf0e10cSrcweir swapStreamPosition( rStrm );
1645cdf0e10cSrcweir sal_Int32 nRows = rStrm.readInt32();
1646cdf0e10cSrcweir sal_Int32 nCols = rStrm.readInt32();
1647cdf0e10cSrcweir OSL_ENSURE( (nCols > 0) && (nRows > 0), "OoxFormulaParserImpl::importArrayToken - empty array" );
1648cdf0e10cSrcweir
1649cdf0e10cSrcweir // read array values and build token array
1650cdf0e10cSrcweir for( sal_Int32 nRow = 0; !rStrm.isEof() && (nRow < nRows); ++nRow )
1651cdf0e10cSrcweir {
1652cdf0e10cSrcweir if( nRow > 0 )
1653cdf0e10cSrcweir appendRawToken( OPCODE_ARRAY_ROWSEP );
1654cdf0e10cSrcweir for( sal_Int32 nCol = 0; !rStrm.isEof() && (nCol < nCols); ++nCol )
1655cdf0e10cSrcweir {
1656cdf0e10cSrcweir if( nCol > 0 )
1657cdf0e10cSrcweir appendRawToken( OPCODE_ARRAY_COLSEP );
1658cdf0e10cSrcweir switch( rStrm.readuInt8() )
1659cdf0e10cSrcweir {
1660cdf0e10cSrcweir case BIFF_TOK_ARRAY_DOUBLE:
1661cdf0e10cSrcweir appendRawToken( OPCODE_PUSH ) <<= rStrm.readDouble();
1662cdf0e10cSrcweir break;
1663cdf0e10cSrcweir case BIFF_TOK_ARRAY_STRING:
1664cdf0e10cSrcweir appendRawToken( OPCODE_PUSH ) <<= BiffHelper::readString( rStrm, false );
1665cdf0e10cSrcweir break;
1666cdf0e10cSrcweir case BIFF_TOK_ARRAY_BOOL:
1667cdf0e10cSrcweir appendRawToken( OPCODE_PUSH ) <<= static_cast< double >( (rStrm.readuInt8() == BIFF_TOK_BOOL_FALSE) ? 0.0 : 1.0 );
1668cdf0e10cSrcweir break;
1669cdf0e10cSrcweir case BIFF_TOK_ARRAY_ERROR:
1670cdf0e10cSrcweir appendRawToken( OPCODE_PUSH ) <<= BiffHelper::calcDoubleFromError( rStrm.readuInt8() );
1671cdf0e10cSrcweir rStrm.skip( 3 );
1672cdf0e10cSrcweir break;
1673cdf0e10cSrcweir default:
1674cdf0e10cSrcweir OSL_ENSURE( false, "OoxFormulaParserImpl::importArrayToken - unknown data type" );
1675cdf0e10cSrcweir appendRawToken( OPCODE_PUSH ) <<= BiffHelper::calcDoubleFromError( BIFF_ERR_NA );
1676cdf0e10cSrcweir }
1677cdf0e10cSrcweir }
1678cdf0e10cSrcweir }
1679cdf0e10cSrcweir swapStreamPosition( rStrm );
1680cdf0e10cSrcweir
1681cdf0e10cSrcweir // close token array and set resulting operand size
1682cdf0e10cSrcweir appendRawToken( OPCODE_ARRAY_CLOSE );
1683cdf0e10cSrcweir pushOperandSize( nOpSize + getFormulaSize() - nOldArraySize );
1684cdf0e10cSrcweir return true;
1685cdf0e10cSrcweir }
1686cdf0e10cSrcweir
importRefToken(SequenceInputStream & rStrm,bool bDeleted,bool bRelativeAsOffset)1687cdf0e10cSrcweir bool OoxFormulaParserImpl::importRefToken( SequenceInputStream& rStrm, bool bDeleted, bool bRelativeAsOffset )
1688cdf0e10cSrcweir {
1689cdf0e10cSrcweir BinSingleRef2d aRef;
1690cdf0e10cSrcweir aRef.readBiff12Data( rStrm, bRelativeAsOffset );
1691cdf0e10cSrcweir return pushReferenceOperand( aRef, bDeleted, bRelativeAsOffset );
1692cdf0e10cSrcweir }
1693cdf0e10cSrcweir
importAreaToken(SequenceInputStream & rStrm,bool bDeleted,bool bRelativeAsOffset)1694cdf0e10cSrcweir bool OoxFormulaParserImpl::importAreaToken( SequenceInputStream& rStrm, bool bDeleted, bool bRelativeAsOffset )
1695cdf0e10cSrcweir {
1696cdf0e10cSrcweir BinComplexRef2d aRef;
1697cdf0e10cSrcweir aRef.readBiff12Data( rStrm, bRelativeAsOffset );
1698cdf0e10cSrcweir return pushReferenceOperand( aRef, bDeleted, bRelativeAsOffset );
1699cdf0e10cSrcweir }
1700cdf0e10cSrcweir
importRef3dToken(SequenceInputStream & rStrm,bool bDeleted,bool bRelativeAsOffset)1701cdf0e10cSrcweir bool OoxFormulaParserImpl::importRef3dToken( SequenceInputStream& rStrm, bool bDeleted, bool bRelativeAsOffset )
1702cdf0e10cSrcweir {
1703cdf0e10cSrcweir LinkSheetRange aSheetRange = readSheetRange( rStrm );
1704cdf0e10cSrcweir BinSingleRef2d aRef;
1705cdf0e10cSrcweir aRef.readBiff12Data( rStrm, bRelativeAsOffset );
1706cdf0e10cSrcweir return pushReferenceOperand( aSheetRange, aRef, bDeleted, bRelativeAsOffset );
1707cdf0e10cSrcweir }
1708cdf0e10cSrcweir
importArea3dToken(SequenceInputStream & rStrm,bool bDeleted,bool bRelativeAsOffset)1709cdf0e10cSrcweir bool OoxFormulaParserImpl::importArea3dToken( SequenceInputStream& rStrm, bool bDeleted, bool bRelativeAsOffset )
1710cdf0e10cSrcweir {
1711cdf0e10cSrcweir LinkSheetRange aSheetRange = readSheetRange( rStrm );
1712cdf0e10cSrcweir BinComplexRef2d aRef;
1713cdf0e10cSrcweir aRef.readBiff12Data( rStrm, bRelativeAsOffset );
1714cdf0e10cSrcweir return pushReferenceOperand( aSheetRange, aRef, bDeleted, bRelativeAsOffset );
1715cdf0e10cSrcweir }
1716cdf0e10cSrcweir
importMemAreaToken(SequenceInputStream & rStrm,bool bAddData)1717cdf0e10cSrcweir bool OoxFormulaParserImpl::importMemAreaToken( SequenceInputStream& rStrm, bool bAddData )
1718cdf0e10cSrcweir {
1719cdf0e10cSrcweir rStrm.skip( 6 );
1720cdf0e10cSrcweir if( bAddData )
1721cdf0e10cSrcweir skipMemAreaAddData( rStrm );
1722cdf0e10cSrcweir return true;
1723cdf0e10cSrcweir }
1724cdf0e10cSrcweir
importMemFuncToken(SequenceInputStream & rStrm)1725cdf0e10cSrcweir bool OoxFormulaParserImpl::importMemFuncToken( SequenceInputStream& rStrm )
1726cdf0e10cSrcweir {
1727cdf0e10cSrcweir rStrm.skip( 2 );
1728cdf0e10cSrcweir return true;
1729cdf0e10cSrcweir }
1730cdf0e10cSrcweir
importNameToken(SequenceInputStream & rStrm)1731cdf0e10cSrcweir bool OoxFormulaParserImpl::importNameToken( SequenceInputStream& rStrm )
1732cdf0e10cSrcweir {
1733cdf0e10cSrcweir return pushBiff12Name( rStrm.readInt32() );
1734cdf0e10cSrcweir }
1735cdf0e10cSrcweir
importNameXToken(SequenceInputStream & rStrm)1736cdf0e10cSrcweir bool OoxFormulaParserImpl::importNameXToken( SequenceInputStream& rStrm )
1737cdf0e10cSrcweir {
1738cdf0e10cSrcweir sal_Int32 nRefId = rStrm.readInt16();
1739cdf0e10cSrcweir sal_Int32 nNameId = rStrm.readInt32();
1740cdf0e10cSrcweir return pushBiff12ExtName( nRefId, nNameId );
1741cdf0e10cSrcweir }
1742cdf0e10cSrcweir
importFuncToken(SequenceInputStream & rStrm)1743cdf0e10cSrcweir bool OoxFormulaParserImpl::importFuncToken( SequenceInputStream& rStrm )
1744cdf0e10cSrcweir {
1745cdf0e10cSrcweir sal_uInt16 nFuncId;
1746cdf0e10cSrcweir rStrm >> nFuncId;
1747cdf0e10cSrcweir return pushBiff12Function( nFuncId );
1748cdf0e10cSrcweir }
1749cdf0e10cSrcweir
importFuncVarToken(SequenceInputStream & rStrm)1750cdf0e10cSrcweir bool OoxFormulaParserImpl::importFuncVarToken( SequenceInputStream& rStrm )
1751cdf0e10cSrcweir {
1752cdf0e10cSrcweir sal_uInt8 nParamCount;
1753cdf0e10cSrcweir sal_uInt16 nFuncId;
1754cdf0e10cSrcweir rStrm >> nParamCount >> nFuncId;
1755cdf0e10cSrcweir return pushBiff12Function( nFuncId, nParamCount );
1756cdf0e10cSrcweir }
1757cdf0e10cSrcweir
importExpToken(SequenceInputStream & rStrm)1758cdf0e10cSrcweir bool OoxFormulaParserImpl::importExpToken( SequenceInputStream& rStrm )
1759cdf0e10cSrcweir {
1760cdf0e10cSrcweir BinAddress aBaseAddr;
1761cdf0e10cSrcweir rStrm >> aBaseAddr.mnRow;
1762cdf0e10cSrcweir swapStreamPosition( rStrm );
1763cdf0e10cSrcweir rStrm >> aBaseAddr.mnCol;
1764cdf0e10cSrcweir swapStreamPosition( rStrm );
1765cdf0e10cSrcweir return pushSpecialTokenOperand( aBaseAddr, false );
1766cdf0e10cSrcweir }
1767cdf0e10cSrcweir
readSheetRange(SequenceInputStream & rStrm)1768cdf0e10cSrcweir LinkSheetRange OoxFormulaParserImpl::readSheetRange( SequenceInputStream& rStrm )
1769cdf0e10cSrcweir {
1770cdf0e10cSrcweir return getExternalLinks().getSheetRange( rStrm.readInt16() );
1771cdf0e10cSrcweir }
1772cdf0e10cSrcweir
swapStreamPosition(SequenceInputStream & rStrm)1773cdf0e10cSrcweir void OoxFormulaParserImpl::swapStreamPosition( SequenceInputStream& rStrm )
1774cdf0e10cSrcweir {
1775cdf0e10cSrcweir sal_Int64 nRecPos = rStrm.tell();
1776cdf0e10cSrcweir rStrm.seek( mnAddDataPos );
1777cdf0e10cSrcweir mnAddDataPos = nRecPos;
1778cdf0e10cSrcweir }
1779cdf0e10cSrcweir
skipMemAreaAddData(SequenceInputStream & rStrm)1780cdf0e10cSrcweir void OoxFormulaParserImpl::skipMemAreaAddData( SequenceInputStream& rStrm )
1781cdf0e10cSrcweir {
1782cdf0e10cSrcweir swapStreamPosition( rStrm );
1783cdf0e10cSrcweir rStrm.skip( 16 * rStrm.readInt32() );
1784cdf0e10cSrcweir swapStreamPosition( rStrm );
1785cdf0e10cSrcweir }
1786cdf0e10cSrcweir
1787cdf0e10cSrcweir // convert BIN token and push API operand or operator -------------------------
1788cdf0e10cSrcweir
pushBiff12Name(sal_Int32 nNameId)1789cdf0e10cSrcweir bool OoxFormulaParserImpl::pushBiff12Name( sal_Int32 nNameId )
1790cdf0e10cSrcweir {
1791cdf0e10cSrcweir // one-based in BIFF12 formulas
1792cdf0e10cSrcweir return pushDefinedNameOperand( getDefinedNames().getByIndex( nNameId - 1 ) );
1793cdf0e10cSrcweir }
1794cdf0e10cSrcweir
pushBiff12ExtName(sal_Int32 nRefId,sal_Int32 nNameId)1795cdf0e10cSrcweir bool OoxFormulaParserImpl::pushBiff12ExtName( sal_Int32 nRefId, sal_Int32 nNameId )
1796cdf0e10cSrcweir {
1797cdf0e10cSrcweir if( const ExternalLink* pExtLink = getExternalLinks().getExternalLink( nRefId ).get() )
1798cdf0e10cSrcweir {
1799cdf0e10cSrcweir if( pExtLink->getLinkType() == LINKTYPE_SELF )
1800cdf0e10cSrcweir return pushBiff12Name( nNameId );
1801cdf0e10cSrcweir // external name indexes are one-based in BIFF12
1802cdf0e10cSrcweir ExternalNameRef xExtName = pExtLink->getNameByIndex( nNameId - 1 );
1803cdf0e10cSrcweir return pushExternalNameOperand( xExtName, *pExtLink );
1804cdf0e10cSrcweir }
1805cdf0e10cSrcweir return pushBiffErrorOperand( BIFF_ERR_NAME );
1806cdf0e10cSrcweir }
1807cdf0e10cSrcweir
pushBiff12Function(sal_uInt16 nFuncId)1808cdf0e10cSrcweir bool OoxFormulaParserImpl::pushBiff12Function( sal_uInt16 nFuncId )
1809cdf0e10cSrcweir {
1810cdf0e10cSrcweir if( const FunctionInfo* pFuncInfo = getFuncInfoFromBiff12FuncId( nFuncId ) )
1811cdf0e10cSrcweir if( pFuncInfo->mnMinParamCount == pFuncInfo->mnMaxParamCount )
1812cdf0e10cSrcweir return pushFunctionOperator( *pFuncInfo, pFuncInfo->mnMinParamCount );
1813cdf0e10cSrcweir return pushFunctionOperator( OPCODE_NONAME, 0 );
1814cdf0e10cSrcweir }
1815cdf0e10cSrcweir
pushBiff12Function(sal_uInt16 nFuncId,sal_uInt8 nParamCount)1816cdf0e10cSrcweir bool OoxFormulaParserImpl::pushBiff12Function( sal_uInt16 nFuncId, sal_uInt8 nParamCount )
1817cdf0e10cSrcweir {
1818cdf0e10cSrcweir if( getFlag( nFuncId, BIFF_TOK_FUNCVAR_CMD ) )
1819cdf0e10cSrcweir nParamCount &= BIFF_TOK_FUNCVAR_COUNTMASK;
1820cdf0e10cSrcweir if( const FunctionInfo* pFuncInfo = getFuncInfoFromBiff12FuncId( nFuncId ) )
1821cdf0e10cSrcweir return pushFunctionOperator( *pFuncInfo, nParamCount );
1822cdf0e10cSrcweir return pushFunctionOperator( OPCODE_NONAME, nParamCount );
1823cdf0e10cSrcweir }
1824cdf0e10cSrcweir
1825cdf0e10cSrcweir // BIFF parser implementation =================================================
1826cdf0e10cSrcweir
1827cdf0e10cSrcweir namespace {
1828cdf0e10cSrcweir
1829cdf0e10cSrcweir /** A natural language reference struct with relative flag. */
1830cdf0e10cSrcweir struct BiffNlr
1831cdf0e10cSrcweir {
1832cdf0e10cSrcweir sal_Int32 mnCol; /// Column index.
1833cdf0e10cSrcweir sal_Int32 mnRow; /// Row index.
1834cdf0e10cSrcweir bool mbRel; /// True = relative column/row reference.
1835cdf0e10cSrcweir
1836cdf0e10cSrcweir explicit BiffNlr();
1837cdf0e10cSrcweir
1838cdf0e10cSrcweir void readBiff8Data( BiffInputStream& rStrm );
1839cdf0e10cSrcweir };
1840cdf0e10cSrcweir
BiffNlr()1841cdf0e10cSrcweir BiffNlr::BiffNlr() :
1842cdf0e10cSrcweir mnCol( 0 ),
1843cdf0e10cSrcweir mnRow( 0 ),
1844cdf0e10cSrcweir mbRel( false )
1845cdf0e10cSrcweir {
1846cdf0e10cSrcweir }
1847cdf0e10cSrcweir
readBiff8Data(BiffInputStream & rStrm)1848cdf0e10cSrcweir void BiffNlr::readBiff8Data( BiffInputStream& rStrm )
1849cdf0e10cSrcweir {
1850cdf0e10cSrcweir sal_uInt16 nRow, nCol;
1851cdf0e10cSrcweir rStrm >> nRow >> nCol;
1852cdf0e10cSrcweir mnCol = nCol & BIFF_TOK_NLR_MASK;
1853cdf0e10cSrcweir mnRow = nRow;
1854cdf0e10cSrcweir mbRel = getFlag( nCol, BIFF_TOK_NLR_REL );
1855cdf0e10cSrcweir }
1856cdf0e10cSrcweir
lclIsValidNlrStack(const BinAddress & rAddr1,const BinAddress & rAddr2,bool bRow)1857cdf0e10cSrcweir bool lclIsValidNlrStack( const BinAddress& rAddr1, const BinAddress& rAddr2, bool bRow )
1858cdf0e10cSrcweir {
1859cdf0e10cSrcweir return bRow ?
1860cdf0e10cSrcweir ((rAddr1.mnRow == rAddr2.mnRow) && (rAddr1.mnCol + 1 == rAddr2.mnCol)) :
1861cdf0e10cSrcweir ((rAddr1.mnCol == rAddr2.mnCol) && (rAddr1.mnRow + 1 == rAddr2.mnRow));
1862cdf0e10cSrcweir }
1863cdf0e10cSrcweir
lclIsValidNlrRange(const BiffNlr & rNlr,const BinRange & rRange,bool bRow)1864cdf0e10cSrcweir bool lclIsValidNlrRange( const BiffNlr& rNlr, const BinRange& rRange, bool bRow )
1865cdf0e10cSrcweir {
1866cdf0e10cSrcweir return bRow ?
1867cdf0e10cSrcweir ((rNlr.mnRow == rRange.maFirst.mnRow) && (rNlr.mnCol + 1 == rRange.maFirst.mnCol) && (rRange.maFirst.mnRow == rRange.maLast.mnRow)) :
1868cdf0e10cSrcweir ((rNlr.mnCol == rRange.maFirst.mnCol) && (rNlr.mnRow + 1 == rRange.maFirst.mnRow) && (rRange.maFirst.mnCol == rRange.maLast.mnCol));
1869cdf0e10cSrcweir }
1870cdf0e10cSrcweir
1871cdf0e10cSrcweir } // namespace
1872cdf0e10cSrcweir
1873cdf0e10cSrcweir // ----------------------------------------------------------------------------
1874cdf0e10cSrcweir
1875cdf0e10cSrcweir class BiffFormulaParserImpl : public FormulaParserImpl
1876cdf0e10cSrcweir {
1877cdf0e10cSrcweir public:
1878cdf0e10cSrcweir explicit BiffFormulaParserImpl( const FormulaParser& rParent );
1879cdf0e10cSrcweir
1880cdf0e10cSrcweir virtual ApiTokenSequence importBiffFormula(
1881cdf0e10cSrcweir const CellAddress& rBaseAddr,
1882cdf0e10cSrcweir FormulaType eType,
1883cdf0e10cSrcweir BiffInputStream& rStrm, const sal_uInt16* pnFmlaSize );
1884cdf0e10cSrcweir
1885cdf0e10cSrcweir private:
1886cdf0e10cSrcweir // import token contents and create API formula token ---------------------
1887cdf0e10cSrcweir
1888cdf0e10cSrcweir bool importTokenNotAvailable( BiffInputStream& rStrm );
1889cdf0e10cSrcweir bool importRefTokenNotAvailable( BiffInputStream& rStrm, bool bDeleted, bool bRelativeAsOffset );
1890cdf0e10cSrcweir bool importStrToken2( BiffInputStream& rStrm );
1891cdf0e10cSrcweir bool importStrToken8( BiffInputStream& rStrm );
1892cdf0e10cSrcweir bool importAttrToken( BiffInputStream& rStrm );
1893cdf0e10cSrcweir bool importSpaceToken3( BiffInputStream& rStrm );
1894cdf0e10cSrcweir bool importSpaceToken4( BiffInputStream& rStrm );
1895cdf0e10cSrcweir bool importSheetToken2( BiffInputStream& rStrm );
1896cdf0e10cSrcweir bool importSheetToken3( BiffInputStream& rStrm );
1897cdf0e10cSrcweir bool importEndSheetToken2( BiffInputStream& rStrm );
1898cdf0e10cSrcweir bool importEndSheetToken3( BiffInputStream& rStrm );
1899cdf0e10cSrcweir bool importNlrToken( BiffInputStream& rStrm );
1900cdf0e10cSrcweir bool importArrayToken( BiffInputStream& rStrm );
1901cdf0e10cSrcweir bool importRefToken2( BiffInputStream& rStrm, bool bDeleted, bool bRelativeAsOffset );
1902cdf0e10cSrcweir bool importRefToken8( BiffInputStream& rStrm, bool bDeleted, bool bRelativeAsOffset );
1903cdf0e10cSrcweir bool importAreaToken2( BiffInputStream& rStrm, bool bDeleted, bool bRelativeAsOffset );
1904cdf0e10cSrcweir bool importAreaToken8( BiffInputStream& rStrm, bool bDeleted, bool bRelativeAsOffset );
1905cdf0e10cSrcweir bool importRef3dToken5( BiffInputStream& rStrm, bool bDeleted, bool bRelativeAsOffset );
1906cdf0e10cSrcweir bool importRef3dToken8( BiffInputStream& rStrm, bool bDeleted, bool bRelativeAsOffset );
1907cdf0e10cSrcweir bool importArea3dToken5( BiffInputStream& rStrm, bool bDeleted, bool bRelativeAsOffset );
1908cdf0e10cSrcweir bool importArea3dToken8( BiffInputStream& rStrm, bool bDeleted, bool bRelativeAsOffset );
1909cdf0e10cSrcweir bool importMemAreaToken( BiffInputStream& rStrm, bool bAddData );
1910cdf0e10cSrcweir bool importMemFuncToken( BiffInputStream& rStrm );
1911cdf0e10cSrcweir bool importNameToken( BiffInputStream& rStrm );
1912cdf0e10cSrcweir bool importNameXToken( BiffInputStream& rStrm );
1913cdf0e10cSrcweir bool importFuncToken2( BiffInputStream& rStrm );
1914cdf0e10cSrcweir bool importFuncToken4( BiffInputStream& rStrm );
1915cdf0e10cSrcweir bool importFuncVarToken2( BiffInputStream& rStrm );
1916cdf0e10cSrcweir bool importFuncVarToken4( BiffInputStream& rStrm );
1917cdf0e10cSrcweir bool importFuncCEToken( BiffInputStream& rStrm );
1918cdf0e10cSrcweir bool importExpToken( BiffInputStream& rStrm );
1919cdf0e10cSrcweir bool importTblToken( BiffInputStream& rStrm );
1920cdf0e10cSrcweir
1921cdf0e10cSrcweir bool importNlrAddrToken( BiffInputStream& rStrm, bool bRow );
1922cdf0e10cSrcweir bool importNlrRangeToken( BiffInputStream& rStrm );
1923cdf0e10cSrcweir bool importNlrSAddrToken( BiffInputStream& rStrm, bool bRow );
1924cdf0e10cSrcweir bool importNlrSRangeToken( BiffInputStream& rStrm );
1925cdf0e10cSrcweir bool importNlrErrToken( BiffInputStream& rStrm, sal_uInt16 nSkip );
1926cdf0e10cSrcweir
1927cdf0e10cSrcweir sal_Int32 readRefId( BiffInputStream& rStrm );
1928cdf0e10cSrcweir sal_uInt16 readNameId( BiffInputStream& rStrm );
1929cdf0e10cSrcweir LinkSheetRange readSheetRange5( BiffInputStream& rStrm );
1930cdf0e10cSrcweir LinkSheetRange readSheetRange8( BiffInputStream& rStrm );
1931cdf0e10cSrcweir
1932cdf0e10cSrcweir void swapStreamPosition( BiffInputStream& rStrm );
1933cdf0e10cSrcweir void skipMemAreaAddData( BiffInputStream& rStrm );
1934cdf0e10cSrcweir bool readNlrSAddrAddData( BiffNlr& orNlr, BiffInputStream& rStrm, bool bRow );
1935cdf0e10cSrcweir bool readNlrSRangeAddData( BiffNlr& orNlr, bool& orbIsRow, BiffInputStream& rStrm );
1936cdf0e10cSrcweir
1937cdf0e10cSrcweir // convert BIFF token and push API operand or operator --------------------
1938cdf0e10cSrcweir
1939cdf0e10cSrcweir bool pushBiffReference( const BinSingleRef2d& rRef, bool bDeleted, bool bRelativeAsOffset );
1940cdf0e10cSrcweir bool pushBiffReference( const BinComplexRef2d& rRef, bool bDeleted, bool bRelativeAsOffset );
1941cdf0e10cSrcweir bool pushBiffNlrAddr( const BiffNlr& rNlr, bool bRow );
1942cdf0e10cSrcweir bool pushBiffNlrRange( const BiffNlr& rNlr, const BinRange& rRange );
1943cdf0e10cSrcweir bool pushBiffNlrSAddr( const BiffNlr& rNlr, bool bRow );
1944cdf0e10cSrcweir bool pushBiffNlrSRange( const BiffNlr& rNlr, const BinRange& rRange, bool bRow );
1945cdf0e10cSrcweir bool pushBiffName( sal_uInt16 nNameId );
1946cdf0e10cSrcweir bool pushBiffExtName( sal_Int32 nRefId, sal_uInt16 nNameId );
1947cdf0e10cSrcweir bool pushBiffFunction( sal_uInt16 nFuncId );
1948cdf0e10cSrcweir bool pushBiffFunction( sal_uInt16 nFuncId, sal_uInt8 nParamCount );
1949cdf0e10cSrcweir
1950cdf0e10cSrcweir // ------------------------------------------------------------------------
1951cdf0e10cSrcweir private:
1952cdf0e10cSrcweir typedef bool (BiffFormulaParserImpl::*ImportTokenFunc)( BiffInputStream& );
1953cdf0e10cSrcweir typedef bool (BiffFormulaParserImpl::*ImportRefTokenFunc)( BiffInputStream&, bool, bool );
1954cdf0e10cSrcweir
1955cdf0e10cSrcweir ImportTokenFunc mpImportStrToken; /// Pointer to tStr import function (string constant).
1956cdf0e10cSrcweir ImportTokenFunc mpImportSpaceToken; /// Pointer to tAttrSpace import function (spaces/line breaks).
1957cdf0e10cSrcweir ImportTokenFunc mpImportSheetToken; /// Pointer to tSheet import function (external reference).
1958cdf0e10cSrcweir ImportTokenFunc mpImportEndSheetToken; /// Pointer to tEndSheet import function (end of external reference).
1959cdf0e10cSrcweir ImportTokenFunc mpImportNlrToken; /// Pointer to tNlr import function (natural language reference).
1960cdf0e10cSrcweir ImportRefTokenFunc mpImportRefToken; /// Pointer to tRef import function (2d cell reference).
1961cdf0e10cSrcweir ImportRefTokenFunc mpImportAreaToken; /// Pointer to tArea import function (2d area reference).
1962cdf0e10cSrcweir ImportRefTokenFunc mpImportRef3dToken; /// Pointer to tRef3d import function (3d cell reference).
1963cdf0e10cSrcweir ImportRefTokenFunc mpImportArea3dToken; /// Pointer to tArea3d import function (3d area reference).
1964cdf0e10cSrcweir ImportTokenFunc mpImportNameXToken; /// Pointer to tNameX import function (external name).
1965cdf0e10cSrcweir ImportTokenFunc mpImportFuncToken; /// Pointer to tFunc import function (function with fixed parameter count).
1966cdf0e10cSrcweir ImportTokenFunc mpImportFuncVarToken; /// Pointer to tFuncVar import function (function with variable parameter count).
1967cdf0e10cSrcweir ImportTokenFunc mpImportFuncCEToken; /// Pointer to tFuncCE import function (command macro call).
1968cdf0e10cSrcweir sal_Int64 mnAddDataPos; /// Current stream position for additional data (tArray, tMemArea, tNlr).
1969cdf0e10cSrcweir sal_Int32 mnCurrRefId; /// Current ref-id from tSheet token (BIFF2-BIFF4 only).
1970cdf0e10cSrcweir sal_uInt16 mnAttrDataSize; /// Size of one tAttr data element.
1971cdf0e10cSrcweir sal_uInt16 mnArraySize; /// Size of tArray data.
1972cdf0e10cSrcweir sal_uInt16 mnNameSize; /// Size of tName data.
1973cdf0e10cSrcweir sal_uInt16 mnMemAreaSize; /// Size of tMemArea data.
1974cdf0e10cSrcweir sal_uInt16 mnMemFuncSize; /// Size of tMemFunc data.
1975cdf0e10cSrcweir sal_uInt16 mnRefIdSize; /// Size of unused data following a reference identifier.
1976cdf0e10cSrcweir };
1977cdf0e10cSrcweir
1978cdf0e10cSrcweir // ----------------------------------------------------------------------------
1979cdf0e10cSrcweir
BiffFormulaParserImpl(const FormulaParser & rParent)1980cdf0e10cSrcweir BiffFormulaParserImpl::BiffFormulaParserImpl( const FormulaParser& rParent ) :
1981cdf0e10cSrcweir FormulaParserImpl( rParent ),
1982cdf0e10cSrcweir mnAddDataPos( 0 ),
1983cdf0e10cSrcweir mnCurrRefId( 0 )
1984cdf0e10cSrcweir {
1985cdf0e10cSrcweir switch( getBiff() )
1986cdf0e10cSrcweir {
1987cdf0e10cSrcweir case BIFF2:
1988cdf0e10cSrcweir mpImportStrToken = &BiffFormulaParserImpl::importStrToken2;
1989cdf0e10cSrcweir mpImportSpaceToken = &BiffFormulaParserImpl::importTokenNotAvailable;
1990cdf0e10cSrcweir mpImportSheetToken = &BiffFormulaParserImpl::importSheetToken2;
1991cdf0e10cSrcweir mpImportEndSheetToken = &BiffFormulaParserImpl::importEndSheetToken2;
1992cdf0e10cSrcweir mpImportNlrToken = &BiffFormulaParserImpl::importTokenNotAvailable;
1993cdf0e10cSrcweir mpImportRefToken = &BiffFormulaParserImpl::importRefToken2;
1994cdf0e10cSrcweir mpImportAreaToken = &BiffFormulaParserImpl::importAreaToken2;
1995cdf0e10cSrcweir mpImportRef3dToken = &BiffFormulaParserImpl::importRefTokenNotAvailable;
1996cdf0e10cSrcweir mpImportArea3dToken = &BiffFormulaParserImpl::importRefTokenNotAvailable;
1997cdf0e10cSrcweir mpImportNameXToken = &BiffFormulaParserImpl::importTokenNotAvailable;
1998cdf0e10cSrcweir mpImportFuncToken = &BiffFormulaParserImpl::importFuncToken2;
1999cdf0e10cSrcweir mpImportFuncVarToken = &BiffFormulaParserImpl::importFuncVarToken2;
2000cdf0e10cSrcweir mpImportFuncCEToken = &BiffFormulaParserImpl::importFuncCEToken;
2001cdf0e10cSrcweir mnAttrDataSize = 1;
2002cdf0e10cSrcweir mnArraySize = 6;
2003cdf0e10cSrcweir mnNameSize = 5;
2004cdf0e10cSrcweir mnMemAreaSize = 4;
2005cdf0e10cSrcweir mnMemFuncSize = 1;
2006cdf0e10cSrcweir mnRefIdSize = 1;
2007cdf0e10cSrcweir break;
2008cdf0e10cSrcweir case BIFF3:
2009cdf0e10cSrcweir mpImportStrToken = &BiffFormulaParserImpl::importStrToken2;
2010cdf0e10cSrcweir mpImportSpaceToken = &BiffFormulaParserImpl::importSpaceToken3;
2011cdf0e10cSrcweir mpImportSheetToken = &BiffFormulaParserImpl::importSheetToken3;
2012cdf0e10cSrcweir mpImportEndSheetToken = &BiffFormulaParserImpl::importEndSheetToken3;
2013cdf0e10cSrcweir mpImportNlrToken = &BiffFormulaParserImpl::importTokenNotAvailable;
2014cdf0e10cSrcweir mpImportRefToken = &BiffFormulaParserImpl::importRefToken2;
2015cdf0e10cSrcweir mpImportAreaToken = &BiffFormulaParserImpl::importAreaToken2;
2016cdf0e10cSrcweir mpImportRef3dToken = &BiffFormulaParserImpl::importRefTokenNotAvailable;
2017cdf0e10cSrcweir mpImportArea3dToken = &BiffFormulaParserImpl::importRefTokenNotAvailable;
2018cdf0e10cSrcweir mpImportNameXToken = &BiffFormulaParserImpl::importTokenNotAvailable;
2019cdf0e10cSrcweir mpImportFuncToken = &BiffFormulaParserImpl::importFuncToken2;
2020cdf0e10cSrcweir mpImportFuncVarToken = &BiffFormulaParserImpl::importFuncVarToken2;
2021cdf0e10cSrcweir mpImportFuncCEToken = &BiffFormulaParserImpl::importFuncCEToken;
2022cdf0e10cSrcweir mnAttrDataSize = 2;
2023cdf0e10cSrcweir mnArraySize = 7;
2024cdf0e10cSrcweir mnNameSize = 8;
2025cdf0e10cSrcweir mnMemAreaSize = 6;
2026cdf0e10cSrcweir mnMemFuncSize = 2;
2027cdf0e10cSrcweir mnRefIdSize = 2;
2028cdf0e10cSrcweir break;
2029cdf0e10cSrcweir case BIFF4:
2030cdf0e10cSrcweir mpImportStrToken = &BiffFormulaParserImpl::importStrToken2;
2031cdf0e10cSrcweir mpImportSpaceToken = &BiffFormulaParserImpl::importSpaceToken4;
2032cdf0e10cSrcweir mpImportSheetToken = &BiffFormulaParserImpl::importSheetToken3;
2033cdf0e10cSrcweir mpImportEndSheetToken = &BiffFormulaParserImpl::importEndSheetToken3;
2034cdf0e10cSrcweir mpImportNlrToken = &BiffFormulaParserImpl::importTokenNotAvailable;
2035cdf0e10cSrcweir mpImportRefToken = &BiffFormulaParserImpl::importRefToken2;
2036cdf0e10cSrcweir mpImportAreaToken = &BiffFormulaParserImpl::importAreaToken2;
2037cdf0e10cSrcweir mpImportRef3dToken = &BiffFormulaParserImpl::importRefTokenNotAvailable;
2038cdf0e10cSrcweir mpImportArea3dToken = &BiffFormulaParserImpl::importRefTokenNotAvailable;
2039cdf0e10cSrcweir mpImportNameXToken = &BiffFormulaParserImpl::importTokenNotAvailable;
2040cdf0e10cSrcweir mpImportFuncToken = &BiffFormulaParserImpl::importFuncToken4;
2041cdf0e10cSrcweir mpImportFuncVarToken = &BiffFormulaParserImpl::importFuncVarToken4;
2042cdf0e10cSrcweir mpImportFuncCEToken = &BiffFormulaParserImpl::importTokenNotAvailable;
2043cdf0e10cSrcweir mnAttrDataSize = 2;
2044cdf0e10cSrcweir mnArraySize = 7;
2045cdf0e10cSrcweir mnNameSize = 8;
2046cdf0e10cSrcweir mnMemAreaSize = 6;
2047cdf0e10cSrcweir mnMemFuncSize = 2;
2048cdf0e10cSrcweir mnRefIdSize = 2;
2049cdf0e10cSrcweir break;
2050cdf0e10cSrcweir case BIFF5:
2051cdf0e10cSrcweir mpImportStrToken = &BiffFormulaParserImpl::importStrToken2;
2052cdf0e10cSrcweir mpImportSpaceToken = &BiffFormulaParserImpl::importSpaceToken4;
2053cdf0e10cSrcweir mpImportSheetToken = &BiffFormulaParserImpl::importTokenNotAvailable;
2054cdf0e10cSrcweir mpImportEndSheetToken = &BiffFormulaParserImpl::importTokenNotAvailable;
2055cdf0e10cSrcweir mpImportNlrToken = &BiffFormulaParserImpl::importTokenNotAvailable;
2056cdf0e10cSrcweir mpImportRefToken = &BiffFormulaParserImpl::importRefToken2;
2057cdf0e10cSrcweir mpImportAreaToken = &BiffFormulaParserImpl::importAreaToken2;
2058cdf0e10cSrcweir mpImportRef3dToken = &BiffFormulaParserImpl::importRef3dToken5;
2059cdf0e10cSrcweir mpImportArea3dToken = &BiffFormulaParserImpl::importArea3dToken5;
2060cdf0e10cSrcweir mpImportNameXToken = &BiffFormulaParserImpl::importNameXToken;
2061cdf0e10cSrcweir mpImportFuncToken = &BiffFormulaParserImpl::importFuncToken4;
2062cdf0e10cSrcweir mpImportFuncVarToken = &BiffFormulaParserImpl::importFuncVarToken4;
2063cdf0e10cSrcweir mpImportFuncCEToken = &BiffFormulaParserImpl::importTokenNotAvailable;
2064cdf0e10cSrcweir mnAttrDataSize = 2;
2065cdf0e10cSrcweir mnArraySize = 7;
2066cdf0e10cSrcweir mnNameSize = 12;
2067cdf0e10cSrcweir mnMemAreaSize = 6;
2068cdf0e10cSrcweir mnMemFuncSize = 2;
2069cdf0e10cSrcweir mnRefIdSize = 8;
2070cdf0e10cSrcweir break;
2071cdf0e10cSrcweir case BIFF8:
2072cdf0e10cSrcweir mpImportStrToken = &BiffFormulaParserImpl::importStrToken8;
2073cdf0e10cSrcweir mpImportSpaceToken = &BiffFormulaParserImpl::importSpaceToken4;
2074cdf0e10cSrcweir mpImportSheetToken = &BiffFormulaParserImpl::importTokenNotAvailable;
2075cdf0e10cSrcweir mpImportEndSheetToken = &BiffFormulaParserImpl::importTokenNotAvailable;
2076cdf0e10cSrcweir mpImportNlrToken = &BiffFormulaParserImpl::importNlrToken;
2077cdf0e10cSrcweir mpImportRefToken = &BiffFormulaParserImpl::importRefToken8;
2078cdf0e10cSrcweir mpImportAreaToken = &BiffFormulaParserImpl::importAreaToken8;
2079cdf0e10cSrcweir mpImportRef3dToken = &BiffFormulaParserImpl::importRef3dToken8;
2080cdf0e10cSrcweir mpImportArea3dToken = &BiffFormulaParserImpl::importArea3dToken8;
2081cdf0e10cSrcweir mpImportNameXToken = &BiffFormulaParserImpl::importNameXToken;
2082cdf0e10cSrcweir mpImportFuncToken = &BiffFormulaParserImpl::importFuncToken4;
2083cdf0e10cSrcweir mpImportFuncVarToken = &BiffFormulaParserImpl::importFuncVarToken4;
2084cdf0e10cSrcweir mpImportFuncCEToken = &BiffFormulaParserImpl::importTokenNotAvailable;
2085cdf0e10cSrcweir mnAttrDataSize = 2;
2086cdf0e10cSrcweir mnArraySize = 7;
2087cdf0e10cSrcweir mnNameSize = 2;
2088cdf0e10cSrcweir mnMemAreaSize = 6;
2089cdf0e10cSrcweir mnMemFuncSize = 2;
2090cdf0e10cSrcweir mnRefIdSize = 0;
2091cdf0e10cSrcweir break;
2092cdf0e10cSrcweir case BIFF_UNKNOWN: break;
2093cdf0e10cSrcweir }
2094cdf0e10cSrcweir }
2095cdf0e10cSrcweir
importBiffFormula(const CellAddress & rBaseAddr,FormulaType eType,BiffInputStream & rStrm,const sal_uInt16 * pnFmlaSize)2096cdf0e10cSrcweir ApiTokenSequence BiffFormulaParserImpl::importBiffFormula( const CellAddress& rBaseAddr,
2097cdf0e10cSrcweir FormulaType eType, BiffInputStream& rStrm, const sal_uInt16* pnFmlaSize )
2098cdf0e10cSrcweir {
2099cdf0e10cSrcweir initializeImport( rBaseAddr, eType );
2100cdf0e10cSrcweir mnCurrRefId = 0;
2101cdf0e10cSrcweir
2102cdf0e10cSrcweir sal_uInt16 nFmlaSize = lclReadFmlaSize( rStrm, getBiff(), pnFmlaSize );
2103cdf0e10cSrcweir sal_Int64 nEndPos = mnAddDataPos = rStrm.tell() + nFmlaSize;
2104cdf0e10cSrcweir
2105cdf0e10cSrcweir bool bOk = true;
2106cdf0e10cSrcweir while( bOk && !rStrm.isEof() && (rStrm.tell() < nEndPos) )
2107cdf0e10cSrcweir {
2108cdf0e10cSrcweir sal_uInt8 nTokenId;
2109cdf0e10cSrcweir rStrm >> nTokenId;
2110cdf0e10cSrcweir sal_uInt8 nTokenClass = nTokenId & BIFF_TOKCLASS_MASK;
2111cdf0e10cSrcweir sal_uInt8 nBaseId = nTokenId & BIFF_TOKID_MASK;
2112cdf0e10cSrcweir
2113cdf0e10cSrcweir bOk = !getFlag( nTokenId, BIFF_TOKFLAG_INVALID );
2114cdf0e10cSrcweir if( bOk )
2115cdf0e10cSrcweir {
2116cdf0e10cSrcweir if( nTokenClass == BIFF_TOKCLASS_NONE )
2117cdf0e10cSrcweir {
2118cdf0e10cSrcweir // base tokens
2119cdf0e10cSrcweir switch( nBaseId )
2120cdf0e10cSrcweir {
2121cdf0e10cSrcweir case BIFF_TOKID_EXP: bOk = importExpToken( rStrm ); break;
2122cdf0e10cSrcweir case BIFF_TOKID_TBL: bOk = importTblToken( rStrm ); break;
2123cdf0e10cSrcweir case BIFF_TOKID_ADD: bOk = pushBinaryOperator( OPCODE_ADD ); break;
2124cdf0e10cSrcweir case BIFF_TOKID_SUB: bOk = pushBinaryOperator( OPCODE_SUB ); break;
2125cdf0e10cSrcweir case BIFF_TOKID_MUL: bOk = pushBinaryOperator( OPCODE_MULT ); break;
2126cdf0e10cSrcweir case BIFF_TOKID_DIV: bOk = pushBinaryOperator( OPCODE_DIV ); break;
2127cdf0e10cSrcweir case BIFF_TOKID_POWER: bOk = pushBinaryOperator( OPCODE_POWER ); break;
2128cdf0e10cSrcweir case BIFF_TOKID_CONCAT: bOk = pushBinaryOperator( OPCODE_CONCAT ); break;
2129cdf0e10cSrcweir case BIFF_TOKID_LT: bOk = pushBinaryOperator( OPCODE_LESS ); break;
2130cdf0e10cSrcweir case BIFF_TOKID_LE: bOk = pushBinaryOperator( OPCODE_LESS_EQUAL ); break;
2131cdf0e10cSrcweir case BIFF_TOKID_EQ: bOk = pushBinaryOperator( OPCODE_EQUAL ); break;
2132cdf0e10cSrcweir case BIFF_TOKID_GE: bOk = pushBinaryOperator( OPCODE_GREATER_EQUAL ); break;
2133cdf0e10cSrcweir case BIFF_TOKID_GT: bOk = pushBinaryOperator( OPCODE_GREATER ); break;
2134cdf0e10cSrcweir case BIFF_TOKID_NE: bOk = pushBinaryOperator( OPCODE_NOT_EQUAL ); break;
2135cdf0e10cSrcweir case BIFF_TOKID_ISECT: bOk = pushBinaryOperator( OPCODE_INTERSECT ); break;
2136cdf0e10cSrcweir case BIFF_TOKID_LIST: bOk = pushBinaryOperator( OPCODE_LIST ); break;
2137cdf0e10cSrcweir case BIFF_TOKID_RANGE: bOk = pushBinaryOperator( OPCODE_RANGE ); break;
2138cdf0e10cSrcweir case BIFF_TOKID_UPLUS: bOk = pushUnaryPreOperator( OPCODE_PLUS_SIGN ); break;
2139cdf0e10cSrcweir case BIFF_TOKID_UMINUS: bOk = pushUnaryPreOperator( OPCODE_MINUS_SIGN ); break;
2140cdf0e10cSrcweir case BIFF_TOKID_PERCENT: bOk = pushUnaryPostOperator( OPCODE_PERCENT ); break;
2141cdf0e10cSrcweir case BIFF_TOKID_PAREN: bOk = pushParenthesesOperator(); break;
2142cdf0e10cSrcweir case BIFF_TOKID_MISSARG: bOk = pushOperand( OPCODE_MISSING ); break;
2143cdf0e10cSrcweir case BIFF_TOKID_STR: bOk = (this->*mpImportStrToken)( rStrm ); break;
2144cdf0e10cSrcweir case BIFF_TOKID_NLR: bOk = (this->*mpImportNlrToken)( rStrm ); break;
2145cdf0e10cSrcweir case BIFF_TOKID_ATTR: bOk = importAttrToken( rStrm ); break;
2146cdf0e10cSrcweir case BIFF_TOKID_SHEET: bOk = (this->*mpImportSheetToken)( rStrm ); break;
2147cdf0e10cSrcweir case BIFF_TOKID_ENDSHEET: bOk = (this->*mpImportEndSheetToken)( rStrm ); break;
2148cdf0e10cSrcweir case BIFF_TOKID_ERR: bOk = pushBiffErrorOperand( rStrm.readuInt8() ); break;
2149cdf0e10cSrcweir case BIFF_TOKID_BOOL: bOk = pushBiffBoolOperand( rStrm.readuInt8() ); break;
2150cdf0e10cSrcweir case BIFF_TOKID_INT: bOk = pushValueOperand< double >( rStrm.readuInt16() ); break;
2151cdf0e10cSrcweir case BIFF_TOKID_NUM: bOk = pushValueOperand( rStrm.readDouble() ); break;
2152cdf0e10cSrcweir default: bOk = false;
2153cdf0e10cSrcweir }
2154cdf0e10cSrcweir }
2155cdf0e10cSrcweir else
2156cdf0e10cSrcweir {
2157cdf0e10cSrcweir // classified tokens
2158cdf0e10cSrcweir switch( nBaseId )
2159cdf0e10cSrcweir {
2160cdf0e10cSrcweir case BIFF_TOKID_ARRAY: bOk = importArrayToken( rStrm ); break;
2161cdf0e10cSrcweir case BIFF_TOKID_FUNC: bOk = (this->*mpImportFuncToken)( rStrm ); break;
2162cdf0e10cSrcweir case BIFF_TOKID_FUNCVAR: bOk = (this->*mpImportFuncVarToken)( rStrm ); break;
2163cdf0e10cSrcweir case BIFF_TOKID_NAME: bOk = importNameToken( rStrm ); break;
2164cdf0e10cSrcweir case BIFF_TOKID_REF: bOk = (this->*mpImportRefToken)( rStrm, false, false ); break;
2165cdf0e10cSrcweir case BIFF_TOKID_AREA: bOk = (this->*mpImportAreaToken)( rStrm, false, false ); break;
2166cdf0e10cSrcweir case BIFF_TOKID_MEMAREA: bOk = importMemAreaToken( rStrm, true ); break;
2167cdf0e10cSrcweir case BIFF_TOKID_MEMERR: bOk = importMemAreaToken( rStrm, false ); break;
2168cdf0e10cSrcweir case BIFF_TOKID_MEMNOMEM: bOk = importMemAreaToken( rStrm, false ); break;
2169cdf0e10cSrcweir case BIFF_TOKID_MEMFUNC: bOk = importMemFuncToken( rStrm ); break;
2170cdf0e10cSrcweir case BIFF_TOKID_REFERR: bOk = (this->*mpImportRefToken)( rStrm, true, false ); break;
2171cdf0e10cSrcweir case BIFF_TOKID_AREAERR: bOk = (this->*mpImportAreaToken)( rStrm, true, false ); break;
2172cdf0e10cSrcweir case BIFF_TOKID_REFN: bOk = (this->*mpImportRefToken)( rStrm, false, true ); break;
2173cdf0e10cSrcweir case BIFF_TOKID_AREAN: bOk = (this->*mpImportAreaToken)( rStrm, false, true ); break;
2174cdf0e10cSrcweir case BIFF_TOKID_MEMAREAN: bOk = importMemFuncToken( rStrm ); break;
2175cdf0e10cSrcweir case BIFF_TOKID_MEMNOMEMN: bOk = importMemFuncToken( rStrm ); break;
2176cdf0e10cSrcweir case BIFF_TOKID_FUNCCE: bOk = (this->*mpImportFuncCEToken)( rStrm ); break;
2177cdf0e10cSrcweir case BIFF_TOKID_NAMEX: bOk = (this->*mpImportNameXToken)( rStrm ); break;
2178cdf0e10cSrcweir case BIFF_TOKID_REF3D: bOk = (this->*mpImportRef3dToken)( rStrm, false, mbRelativeAsOffset ); break;
2179cdf0e10cSrcweir case BIFF_TOKID_AREA3D: bOk = (this->*mpImportArea3dToken)( rStrm, false, mbRelativeAsOffset ); break;
2180cdf0e10cSrcweir case BIFF_TOKID_REFERR3D: bOk = (this->*mpImportRef3dToken)( rStrm, true, mbRelativeAsOffset ); break;
2181cdf0e10cSrcweir case BIFF_TOKID_AREAERR3D: bOk = (this->*mpImportArea3dToken)( rStrm, true, mbRelativeAsOffset ); break;
2182cdf0e10cSrcweir default: bOk = false;
2183cdf0e10cSrcweir }
2184cdf0e10cSrcweir }
2185cdf0e10cSrcweir }
2186cdf0e10cSrcweir }
2187cdf0e10cSrcweir
2188cdf0e10cSrcweir // build and finalize the token sequence
2189cdf0e10cSrcweir ApiTokenSequence aFinalTokens;
2190cdf0e10cSrcweir if( bOk && (rStrm.tell() == nEndPos) )
2191cdf0e10cSrcweir aFinalTokens = finalizeImport();
2192cdf0e10cSrcweir
2193cdf0e10cSrcweir // seek behind additional token data of tArray, tMemArea, tNlr tokens
2194cdf0e10cSrcweir rStrm.seek( mnAddDataPos );
2195cdf0e10cSrcweir
2196cdf0e10cSrcweir // return the final token sequence
2197cdf0e10cSrcweir return aFinalTokens;
2198cdf0e10cSrcweir }
2199cdf0e10cSrcweir
2200cdf0e10cSrcweir // import token contents and create API formula token -------------------------
2201cdf0e10cSrcweir
importTokenNotAvailable(BiffInputStream &)2202cdf0e10cSrcweir bool BiffFormulaParserImpl::importTokenNotAvailable( BiffInputStream& )
2203cdf0e10cSrcweir {
2204cdf0e10cSrcweir // dummy function for pointer-to-member-function
2205cdf0e10cSrcweir return false;
2206cdf0e10cSrcweir }
2207cdf0e10cSrcweir
importRefTokenNotAvailable(BiffInputStream &,bool,bool)2208cdf0e10cSrcweir bool BiffFormulaParserImpl::importRefTokenNotAvailable( BiffInputStream&, bool, bool )
2209cdf0e10cSrcweir {
2210cdf0e10cSrcweir // dummy function for pointer-to-member-function
2211cdf0e10cSrcweir return false;
2212cdf0e10cSrcweir }
2213cdf0e10cSrcweir
importStrToken2(BiffInputStream & rStrm)2214cdf0e10cSrcweir bool BiffFormulaParserImpl::importStrToken2( BiffInputStream& rStrm )
2215cdf0e10cSrcweir {
2216cdf0e10cSrcweir return pushValueOperand( rStrm.readByteStringUC( false, getTextEncoding(), mbAllowNulChars ) );
2217cdf0e10cSrcweir }
2218cdf0e10cSrcweir
importStrToken8(BiffInputStream & rStrm)2219cdf0e10cSrcweir bool BiffFormulaParserImpl::importStrToken8( BiffInputStream& rStrm )
2220cdf0e10cSrcweir {
2221cdf0e10cSrcweir // read flags field for empty strings also
2222cdf0e10cSrcweir return pushValueOperand( rStrm.readUniStringBody( rStrm.readuInt8(), mbAllowNulChars ) );
2223cdf0e10cSrcweir }
2224cdf0e10cSrcweir
importAttrToken(BiffInputStream & rStrm)2225cdf0e10cSrcweir bool BiffFormulaParserImpl::importAttrToken( BiffInputStream& rStrm )
2226cdf0e10cSrcweir {
2227cdf0e10cSrcweir bool bOk = true;
2228cdf0e10cSrcweir sal_uInt8 nType;
2229cdf0e10cSrcweir rStrm >> nType;
2230cdf0e10cSrcweir switch( nType )
2231cdf0e10cSrcweir {
2232cdf0e10cSrcweir case 0: // sometimes, tAttrSkip tokens miss the type flag
2233cdf0e10cSrcweir case BIFF_TOK_ATTR_VOLATILE:
2234cdf0e10cSrcweir case BIFF_TOK_ATTR_IF:
2235cdf0e10cSrcweir case BIFF_TOK_ATTR_SKIP:
2236cdf0e10cSrcweir case BIFF_TOK_ATTR_ASSIGN:
2237cdf0e10cSrcweir rStrm.skip( mnAttrDataSize );
2238cdf0e10cSrcweir break;
2239cdf0e10cSrcweir case BIFF_TOK_ATTR_CHOOSE:
2240cdf0e10cSrcweir rStrm.skip( mnAttrDataSize * (1 + ((getBiff() == BIFF2) ? rStrm.readuInt8() : rStrm.readuInt16())) );
2241cdf0e10cSrcweir break;
2242cdf0e10cSrcweir case BIFF_TOK_ATTR_SUM:
2243cdf0e10cSrcweir rStrm.skip( mnAttrDataSize );
2244cdf0e10cSrcweir bOk = pushBiffFunction( BIFF_FUNC_SUM, 1 );
2245cdf0e10cSrcweir break;
2246cdf0e10cSrcweir case BIFF_TOK_ATTR_SPACE:
2247cdf0e10cSrcweir case BIFF_TOK_ATTR_SPACE_VOLATILE:
2248cdf0e10cSrcweir bOk = (this->*mpImportSpaceToken)( rStrm );
2249cdf0e10cSrcweir break;
2250cdf0e10cSrcweir default:
2251cdf0e10cSrcweir bOk = false;
2252cdf0e10cSrcweir }
2253cdf0e10cSrcweir return bOk;
2254cdf0e10cSrcweir }
2255cdf0e10cSrcweir
importSpaceToken3(BiffInputStream & rStrm)2256cdf0e10cSrcweir bool BiffFormulaParserImpl::importSpaceToken3( BiffInputStream& rStrm )
2257cdf0e10cSrcweir {
2258cdf0e10cSrcweir rStrm.skip( 2 );
2259cdf0e10cSrcweir return true;
2260cdf0e10cSrcweir }
2261cdf0e10cSrcweir
importSpaceToken4(BiffInputStream & rStrm)2262cdf0e10cSrcweir bool BiffFormulaParserImpl::importSpaceToken4( BiffInputStream& rStrm )
2263cdf0e10cSrcweir {
2264cdf0e10cSrcweir sal_uInt8 nType, nCount;
2265cdf0e10cSrcweir rStrm >> nType >> nCount;
2266cdf0e10cSrcweir switch( nType )
2267cdf0e10cSrcweir {
2268cdf0e10cSrcweir case BIFF_TOK_ATTR_SPACE_SP:
2269cdf0e10cSrcweir appendLeadingSpaces( nCount, false );
2270cdf0e10cSrcweir break;
2271cdf0e10cSrcweir case BIFF_TOK_ATTR_SPACE_BR:
2272cdf0e10cSrcweir appendLeadingSpaces( nCount, true );
2273cdf0e10cSrcweir break;
2274cdf0e10cSrcweir case BIFF_TOK_ATTR_SPACE_SP_OPEN:
2275cdf0e10cSrcweir appendOpeningSpaces( nCount, false );
2276cdf0e10cSrcweir break;
2277cdf0e10cSrcweir case BIFF_TOK_ATTR_SPACE_BR_OPEN:
2278cdf0e10cSrcweir appendOpeningSpaces( nCount, true );
2279cdf0e10cSrcweir break;
2280cdf0e10cSrcweir case BIFF_TOK_ATTR_SPACE_SP_CLOSE:
2281cdf0e10cSrcweir appendClosingSpaces( nCount, false );
2282cdf0e10cSrcweir break;
2283cdf0e10cSrcweir case BIFF_TOK_ATTR_SPACE_BR_CLOSE:
2284cdf0e10cSrcweir appendClosingSpaces( nCount, true );
2285cdf0e10cSrcweir break;
2286cdf0e10cSrcweir }
2287cdf0e10cSrcweir return true;
2288cdf0e10cSrcweir }
2289cdf0e10cSrcweir
importSheetToken2(BiffInputStream & rStrm)2290cdf0e10cSrcweir bool BiffFormulaParserImpl::importSheetToken2( BiffInputStream& rStrm )
2291cdf0e10cSrcweir {
2292cdf0e10cSrcweir rStrm.skip( 4 );
2293cdf0e10cSrcweir mnCurrRefId = readRefId( rStrm );
2294cdf0e10cSrcweir return true;
2295cdf0e10cSrcweir }
2296cdf0e10cSrcweir
importSheetToken3(BiffInputStream & rStrm)2297cdf0e10cSrcweir bool BiffFormulaParserImpl::importSheetToken3( BiffInputStream& rStrm )
2298cdf0e10cSrcweir {
2299cdf0e10cSrcweir rStrm.skip( 6 );
2300cdf0e10cSrcweir mnCurrRefId = readRefId( rStrm );
2301cdf0e10cSrcweir return true;
2302cdf0e10cSrcweir }
2303cdf0e10cSrcweir
importEndSheetToken2(BiffInputStream & rStrm)2304cdf0e10cSrcweir bool BiffFormulaParserImpl::importEndSheetToken2( BiffInputStream& rStrm )
2305cdf0e10cSrcweir {
2306cdf0e10cSrcweir rStrm.skip( 3 );
2307cdf0e10cSrcweir mnCurrRefId = 0;
2308cdf0e10cSrcweir return true;
2309cdf0e10cSrcweir }
2310cdf0e10cSrcweir
importEndSheetToken3(BiffInputStream & rStrm)2311cdf0e10cSrcweir bool BiffFormulaParserImpl::importEndSheetToken3( BiffInputStream& rStrm )
2312cdf0e10cSrcweir {
2313cdf0e10cSrcweir rStrm.skip( 4 );
2314cdf0e10cSrcweir mnCurrRefId = 0;
2315cdf0e10cSrcweir return true;
2316cdf0e10cSrcweir }
2317cdf0e10cSrcweir
importNlrToken(BiffInputStream & rStrm)2318cdf0e10cSrcweir bool BiffFormulaParserImpl::importNlrToken( BiffInputStream& rStrm )
2319cdf0e10cSrcweir {
2320cdf0e10cSrcweir bool bOk = true;
2321cdf0e10cSrcweir sal_uInt8 nNlrType;
2322cdf0e10cSrcweir rStrm >> nNlrType;
2323cdf0e10cSrcweir switch( nNlrType )
2324cdf0e10cSrcweir {
2325cdf0e10cSrcweir case BIFF_TOK_NLR_ERR: bOk = importNlrErrToken( rStrm, 4 ); break;
2326cdf0e10cSrcweir case BIFF_TOK_NLR_ROWR: bOk = importNlrAddrToken( rStrm, true ); break;
2327cdf0e10cSrcweir case BIFF_TOK_NLR_COLR: bOk = importNlrAddrToken( rStrm, false ); break;
2328cdf0e10cSrcweir case BIFF_TOK_NLR_ROWV: bOk = importNlrAddrToken( rStrm, true ); break;
2329cdf0e10cSrcweir case BIFF_TOK_NLR_COLV: bOk = importNlrAddrToken( rStrm, false ); break;
2330cdf0e10cSrcweir case BIFF_TOK_NLR_RANGE: bOk = importNlrRangeToken( rStrm ); break;
2331cdf0e10cSrcweir case BIFF_TOK_NLR_SRANGE: bOk = importNlrSRangeToken( rStrm ); break;
2332cdf0e10cSrcweir case BIFF_TOK_NLR_SROWR: bOk = importNlrSAddrToken( rStrm, true ); break;
2333cdf0e10cSrcweir case BIFF_TOK_NLR_SCOLR: bOk = importNlrSAddrToken( rStrm, false ); break;
2334cdf0e10cSrcweir case BIFF_TOK_NLR_SROWV: bOk = importNlrSAddrToken( rStrm, true ); break;
2335cdf0e10cSrcweir case BIFF_TOK_NLR_SCOLV: bOk = importNlrSAddrToken( rStrm, false ); break;
2336cdf0e10cSrcweir case BIFF_TOK_NLR_RANGEERR: bOk = importNlrErrToken( rStrm, 13 ); break;
2337cdf0e10cSrcweir case BIFF_TOK_NLR_SXNAME: bOk = importNlrErrToken( rStrm, 4 ); break;
2338cdf0e10cSrcweir default: bOk = false;
2339cdf0e10cSrcweir }
2340cdf0e10cSrcweir return bOk;
2341cdf0e10cSrcweir }
2342cdf0e10cSrcweir
importArrayToken(BiffInputStream & rStrm)2343cdf0e10cSrcweir bool BiffFormulaParserImpl::importArrayToken( BiffInputStream& rStrm )
2344cdf0e10cSrcweir {
2345cdf0e10cSrcweir rStrm.skip( mnArraySize );
2346cdf0e10cSrcweir
2347cdf0e10cSrcweir // start token array with opening brace and leading spaces
2348cdf0e10cSrcweir pushOperand( OPCODE_ARRAY_OPEN );
2349cdf0e10cSrcweir size_t nOpSize = popOperandSize();
2350cdf0e10cSrcweir size_t nOldArraySize = getFormulaSize();
2351cdf0e10cSrcweir bool bBiff8 = getBiff() == BIFF8;
2352cdf0e10cSrcweir
2353cdf0e10cSrcweir // read array size
2354cdf0e10cSrcweir swapStreamPosition( rStrm );
2355cdf0e10cSrcweir sal_uInt16 nCols = rStrm.readuInt8();
2356cdf0e10cSrcweir sal_uInt16 nRows = rStrm.readuInt16();
2357cdf0e10cSrcweir if( bBiff8 ) { ++nCols; ++nRows; } else if( nCols == 0 ) nCols = 256;
2358cdf0e10cSrcweir OSL_ENSURE( (nCols > 0) && (nRows > 0), "BiffFormulaParserImpl::importArrayToken - empty array" );
2359cdf0e10cSrcweir
2360cdf0e10cSrcweir // read array values and build token array
2361cdf0e10cSrcweir for( sal_uInt16 nRow = 0; !rStrm.isEof() && (nRow < nRows); ++nRow )
2362cdf0e10cSrcweir {
2363cdf0e10cSrcweir if( nRow > 0 )
2364cdf0e10cSrcweir appendRawToken( OPCODE_ARRAY_ROWSEP );
2365cdf0e10cSrcweir for( sal_uInt16 nCol = 0; !rStrm.isEof() && (nCol < nCols); ++nCol )
2366cdf0e10cSrcweir {
2367cdf0e10cSrcweir if( nCol > 0 )
2368cdf0e10cSrcweir appendRawToken( OPCODE_ARRAY_COLSEP );
2369cdf0e10cSrcweir switch( rStrm.readuInt8() )
2370cdf0e10cSrcweir {
2371cdf0e10cSrcweir case BIFF_DATATYPE_EMPTY:
2372cdf0e10cSrcweir appendRawToken( OPCODE_PUSH ) <<= OUString();
2373cdf0e10cSrcweir rStrm.skip( 8 );
2374cdf0e10cSrcweir break;
2375cdf0e10cSrcweir case BIFF_DATATYPE_DOUBLE:
2376cdf0e10cSrcweir appendRawToken( OPCODE_PUSH ) <<= rStrm.readDouble();
2377cdf0e10cSrcweir break;
2378cdf0e10cSrcweir case BIFF_DATATYPE_STRING:
2379cdf0e10cSrcweir appendRawToken( OPCODE_PUSH ) <<= bBiff8 ?
2380cdf0e10cSrcweir rStrm.readUniString( mbAllowNulChars ) :
2381cdf0e10cSrcweir rStrm.readByteStringUC( false, getTextEncoding(), mbAllowNulChars );
2382cdf0e10cSrcweir break;
2383cdf0e10cSrcweir case BIFF_DATATYPE_BOOL:
2384cdf0e10cSrcweir appendRawToken( OPCODE_PUSH ) <<= static_cast< double >( (rStrm.readuInt8() == BIFF_TOK_BOOL_FALSE) ? 0.0 : 1.0 );
2385cdf0e10cSrcweir rStrm.skip( 7 );
2386cdf0e10cSrcweir break;
2387cdf0e10cSrcweir case BIFF_DATATYPE_ERROR:
2388cdf0e10cSrcweir appendRawToken( OPCODE_PUSH ) <<= BiffHelper::calcDoubleFromError( rStrm.readuInt8() );
2389cdf0e10cSrcweir rStrm.skip( 7 );
2390cdf0e10cSrcweir break;
2391cdf0e10cSrcweir default:
2392cdf0e10cSrcweir OSL_ENSURE( false, "BiffFormulaParserImpl::importArrayToken - unknown data type" );
2393cdf0e10cSrcweir appendRawToken( OPCODE_PUSH ) <<= BiffHelper::calcDoubleFromError( BIFF_ERR_NA );
2394cdf0e10cSrcweir }
2395cdf0e10cSrcweir }
2396cdf0e10cSrcweir }
2397cdf0e10cSrcweir swapStreamPosition( rStrm );
2398cdf0e10cSrcweir
2399cdf0e10cSrcweir // close token array and set resulting operand size
2400cdf0e10cSrcweir appendRawToken( OPCODE_ARRAY_CLOSE );
2401cdf0e10cSrcweir pushOperandSize( nOpSize + getFormulaSize() - nOldArraySize );
2402cdf0e10cSrcweir return true;
2403cdf0e10cSrcweir }
2404cdf0e10cSrcweir
importRefToken2(BiffInputStream & rStrm,bool bDeleted,bool bRelativeAsOffset)2405cdf0e10cSrcweir bool BiffFormulaParserImpl::importRefToken2( BiffInputStream& rStrm, bool bDeleted, bool bRelativeAsOffset )
2406cdf0e10cSrcweir {
2407cdf0e10cSrcweir BinSingleRef2d aRef;
2408cdf0e10cSrcweir aRef.readBiff2Data( rStrm, bRelativeAsOffset );
2409cdf0e10cSrcweir return pushBiffReference( aRef, bDeleted, bRelativeAsOffset );
2410cdf0e10cSrcweir }
2411cdf0e10cSrcweir
importRefToken8(BiffInputStream & rStrm,bool bDeleted,bool bRelativeAsOffset)2412cdf0e10cSrcweir bool BiffFormulaParserImpl::importRefToken8( BiffInputStream& rStrm, bool bDeleted, bool bRelativeAsOffset )
2413cdf0e10cSrcweir {
2414cdf0e10cSrcweir BinSingleRef2d aRef;
2415cdf0e10cSrcweir aRef.readBiff8Data( rStrm, bRelativeAsOffset );
2416cdf0e10cSrcweir return pushBiffReference( aRef, bDeleted, bRelativeAsOffset );
2417cdf0e10cSrcweir }
2418cdf0e10cSrcweir
importAreaToken2(BiffInputStream & rStrm,bool bDeleted,bool bRelativeAsOffset)2419cdf0e10cSrcweir bool BiffFormulaParserImpl::importAreaToken2( BiffInputStream& rStrm, bool bDeleted, bool bRelativeAsOffset )
2420cdf0e10cSrcweir {
2421cdf0e10cSrcweir BinComplexRef2d aRef;
2422cdf0e10cSrcweir aRef.readBiff2Data( rStrm, bRelativeAsOffset );
2423cdf0e10cSrcweir return pushBiffReference( aRef, bDeleted, bRelativeAsOffset );
2424cdf0e10cSrcweir }
2425cdf0e10cSrcweir
importAreaToken8(BiffInputStream & rStrm,bool bDeleted,bool bRelativeAsOffset)2426cdf0e10cSrcweir bool BiffFormulaParserImpl::importAreaToken8( BiffInputStream& rStrm, bool bDeleted, bool bRelativeAsOffset )
2427cdf0e10cSrcweir {
2428cdf0e10cSrcweir BinComplexRef2d aRef;
2429cdf0e10cSrcweir aRef.readBiff8Data( rStrm, bRelativeAsOffset );
2430cdf0e10cSrcweir return pushBiffReference( aRef, bDeleted, bRelativeAsOffset );
2431cdf0e10cSrcweir }
2432cdf0e10cSrcweir
importRef3dToken5(BiffInputStream & rStrm,bool bDeleted,bool bRelativeAsOffset)2433cdf0e10cSrcweir bool BiffFormulaParserImpl::importRef3dToken5( BiffInputStream& rStrm, bool bDeleted, bool bRelativeAsOffset )
2434cdf0e10cSrcweir {
2435cdf0e10cSrcweir LinkSheetRange aSheetRange = readSheetRange5( rStrm );
2436cdf0e10cSrcweir BinSingleRef2d aRef;
2437cdf0e10cSrcweir aRef.readBiff2Data( rStrm, bRelativeAsOffset );
2438cdf0e10cSrcweir return pushReferenceOperand( aSheetRange, aRef, bDeleted, bRelativeAsOffset );
2439cdf0e10cSrcweir }
2440cdf0e10cSrcweir
importRef3dToken8(BiffInputStream & rStrm,bool bDeleted,bool bRelativeAsOffset)2441cdf0e10cSrcweir bool BiffFormulaParserImpl::importRef3dToken8( BiffInputStream& rStrm, bool bDeleted, bool bRelativeAsOffset )
2442cdf0e10cSrcweir {
2443cdf0e10cSrcweir LinkSheetRange aSheetRange = readSheetRange8( rStrm );
2444cdf0e10cSrcweir BinSingleRef2d aRef;
2445cdf0e10cSrcweir aRef.readBiff8Data( rStrm, bRelativeAsOffset );
2446cdf0e10cSrcweir return pushReferenceOperand( aSheetRange, aRef, bDeleted, bRelativeAsOffset );
2447cdf0e10cSrcweir }
2448cdf0e10cSrcweir
importArea3dToken5(BiffInputStream & rStrm,bool bDeleted,bool bRelativeAsOffset)2449cdf0e10cSrcweir bool BiffFormulaParserImpl::importArea3dToken5( BiffInputStream& rStrm, bool bDeleted, bool bRelativeAsOffset )
2450cdf0e10cSrcweir {
2451cdf0e10cSrcweir LinkSheetRange aSheetRange = readSheetRange5( rStrm );
2452cdf0e10cSrcweir BinComplexRef2d aRef;
2453cdf0e10cSrcweir aRef.readBiff2Data( rStrm, bRelativeAsOffset );
2454cdf0e10cSrcweir return pushReferenceOperand( aSheetRange, aRef, bDeleted, bRelativeAsOffset );
2455cdf0e10cSrcweir }
2456cdf0e10cSrcweir
importArea3dToken8(BiffInputStream & rStrm,bool bDeleted,bool bRelativeAsOffset)2457cdf0e10cSrcweir bool BiffFormulaParserImpl::importArea3dToken8( BiffInputStream& rStrm, bool bDeleted, bool bRelativeAsOffset )
2458cdf0e10cSrcweir {
2459cdf0e10cSrcweir LinkSheetRange aSheetRange = readSheetRange8( rStrm );
2460cdf0e10cSrcweir BinComplexRef2d aRef;
2461cdf0e10cSrcweir aRef.readBiff8Data( rStrm, bRelativeAsOffset );
2462cdf0e10cSrcweir return pushReferenceOperand( aSheetRange, aRef, bDeleted, bRelativeAsOffset );
2463cdf0e10cSrcweir }
2464cdf0e10cSrcweir
importMemAreaToken(BiffInputStream & rStrm,bool bAddData)2465cdf0e10cSrcweir bool BiffFormulaParserImpl::importMemAreaToken( BiffInputStream& rStrm, bool bAddData )
2466cdf0e10cSrcweir {
2467cdf0e10cSrcweir rStrm.skip( mnMemAreaSize );
2468cdf0e10cSrcweir if( bAddData )
2469cdf0e10cSrcweir skipMemAreaAddData( rStrm );
2470cdf0e10cSrcweir return true;
2471cdf0e10cSrcweir }
2472cdf0e10cSrcweir
importMemFuncToken(BiffInputStream & rStrm)2473cdf0e10cSrcweir bool BiffFormulaParserImpl::importMemFuncToken( BiffInputStream& rStrm )
2474cdf0e10cSrcweir {
2475cdf0e10cSrcweir rStrm.skip( mnMemFuncSize );
2476cdf0e10cSrcweir return true;
2477cdf0e10cSrcweir }
2478cdf0e10cSrcweir
importNameToken(BiffInputStream & rStrm)2479cdf0e10cSrcweir bool BiffFormulaParserImpl::importNameToken( BiffInputStream& rStrm )
2480cdf0e10cSrcweir {
2481cdf0e10cSrcweir sal_uInt16 nNameId = readNameId( rStrm );
2482cdf0e10cSrcweir return (mnCurrRefId > 0) ? pushBiffExtName( mnCurrRefId, nNameId ) : pushBiffName( nNameId );
2483cdf0e10cSrcweir }
2484cdf0e10cSrcweir
importNameXToken(BiffInputStream & rStrm)2485cdf0e10cSrcweir bool BiffFormulaParserImpl::importNameXToken( BiffInputStream& rStrm )
2486cdf0e10cSrcweir {
2487cdf0e10cSrcweir sal_Int32 nRefId = readRefId( rStrm );
2488cdf0e10cSrcweir sal_uInt16 nNameId = readNameId( rStrm );
2489cdf0e10cSrcweir return pushBiffExtName( nRefId, nNameId );
2490cdf0e10cSrcweir }
2491cdf0e10cSrcweir
importFuncToken2(BiffInputStream & rStrm)2492cdf0e10cSrcweir bool BiffFormulaParserImpl::importFuncToken2( BiffInputStream& rStrm )
2493cdf0e10cSrcweir {
2494cdf0e10cSrcweir sal_uInt8 nFuncId;
2495cdf0e10cSrcweir rStrm >> nFuncId;
2496cdf0e10cSrcweir return pushBiffFunction( nFuncId );
2497cdf0e10cSrcweir }
2498cdf0e10cSrcweir
importFuncToken4(BiffInputStream & rStrm)2499cdf0e10cSrcweir bool BiffFormulaParserImpl::importFuncToken4( BiffInputStream& rStrm )
2500cdf0e10cSrcweir {
2501cdf0e10cSrcweir sal_uInt16 nFuncId;
2502cdf0e10cSrcweir rStrm >> nFuncId;
2503cdf0e10cSrcweir return pushBiffFunction( nFuncId );
2504cdf0e10cSrcweir }
2505cdf0e10cSrcweir
importFuncVarToken2(BiffInputStream & rStrm)2506cdf0e10cSrcweir bool BiffFormulaParserImpl::importFuncVarToken2( BiffInputStream& rStrm )
2507cdf0e10cSrcweir {
2508cdf0e10cSrcweir sal_uInt8 nParamCount, nFuncId;
2509cdf0e10cSrcweir rStrm >> nParamCount >> nFuncId;
2510cdf0e10cSrcweir return pushBiffFunction( nFuncId, nParamCount );
2511cdf0e10cSrcweir }
2512cdf0e10cSrcweir
importFuncVarToken4(BiffInputStream & rStrm)2513cdf0e10cSrcweir bool BiffFormulaParserImpl::importFuncVarToken4( BiffInputStream& rStrm )
2514cdf0e10cSrcweir {
2515cdf0e10cSrcweir sal_uInt8 nParamCount;
2516cdf0e10cSrcweir sal_uInt16 nFuncId;
2517cdf0e10cSrcweir rStrm >> nParamCount >> nFuncId;
2518cdf0e10cSrcweir return pushBiffFunction( nFuncId, nParamCount & BIFF_TOK_FUNCVAR_COUNTMASK );
2519cdf0e10cSrcweir }
2520cdf0e10cSrcweir
importFuncCEToken(BiffInputStream & rStrm)2521cdf0e10cSrcweir bool BiffFormulaParserImpl::importFuncCEToken( BiffInputStream& rStrm )
2522cdf0e10cSrcweir {
2523cdf0e10cSrcweir sal_uInt8 nParamCount, nFuncId;
2524cdf0e10cSrcweir rStrm >> nParamCount >> nFuncId;
2525cdf0e10cSrcweir sal_uInt16 nCmdId = nFuncId;
2526cdf0e10cSrcweir setFlag( nCmdId, BIFF_TOK_FUNCVAR_CMD );
2527cdf0e10cSrcweir return pushBiffFunction( nCmdId, nParamCount );
2528cdf0e10cSrcweir }
2529cdf0e10cSrcweir
importExpToken(BiffInputStream & rStrm)2530cdf0e10cSrcweir bool BiffFormulaParserImpl::importExpToken( BiffInputStream& rStrm )
2531cdf0e10cSrcweir {
2532cdf0e10cSrcweir BinAddress aBaseAddr;
2533cdf0e10cSrcweir aBaseAddr.read( rStrm );
2534cdf0e10cSrcweir return pushSpecialTokenOperand( aBaseAddr, false );
2535cdf0e10cSrcweir }
2536cdf0e10cSrcweir
importTblToken(BiffInputStream & rStrm)2537cdf0e10cSrcweir bool BiffFormulaParserImpl::importTblToken( BiffInputStream& rStrm )
2538cdf0e10cSrcweir {
2539cdf0e10cSrcweir BinAddress aBaseAddr;
2540cdf0e10cSrcweir aBaseAddr.read( rStrm );
2541cdf0e10cSrcweir return pushSpecialTokenOperand( aBaseAddr, true );
2542cdf0e10cSrcweir }
2543cdf0e10cSrcweir
importNlrAddrToken(BiffInputStream & rStrm,bool bRow)2544cdf0e10cSrcweir bool BiffFormulaParserImpl::importNlrAddrToken( BiffInputStream& rStrm, bool bRow )
2545cdf0e10cSrcweir {
2546cdf0e10cSrcweir BiffNlr aNlr;
2547cdf0e10cSrcweir aNlr.readBiff8Data( rStrm );
2548cdf0e10cSrcweir return pushBiffNlrAddr( aNlr, bRow );
2549cdf0e10cSrcweir }
2550cdf0e10cSrcweir
importNlrRangeToken(BiffInputStream & rStrm)2551cdf0e10cSrcweir bool BiffFormulaParserImpl::importNlrRangeToken( BiffInputStream& rStrm )
2552cdf0e10cSrcweir {
2553cdf0e10cSrcweir BiffNlr aNlr;
2554cdf0e10cSrcweir aNlr.readBiff8Data( rStrm );
2555cdf0e10cSrcweir rStrm.skip( 1 );
2556cdf0e10cSrcweir BinRange aRange;
2557cdf0e10cSrcweir rStrm >> aRange;
2558cdf0e10cSrcweir return pushBiffNlrRange( aNlr, aRange );
2559cdf0e10cSrcweir }
2560cdf0e10cSrcweir
importNlrSAddrToken(BiffInputStream & rStrm,bool bRow)2561cdf0e10cSrcweir bool BiffFormulaParserImpl::importNlrSAddrToken( BiffInputStream& rStrm, bool bRow )
2562cdf0e10cSrcweir {
2563cdf0e10cSrcweir rStrm.skip( 4 );
2564cdf0e10cSrcweir BiffNlr aNlr;
2565cdf0e10cSrcweir return readNlrSAddrAddData( aNlr, rStrm, bRow ) ? pushBiffNlrSAddr( aNlr, bRow ) : pushBiffErrorOperand( BIFF_ERR_REF );
2566cdf0e10cSrcweir }
2567cdf0e10cSrcweir
importNlrSRangeToken(BiffInputStream & rStrm)2568cdf0e10cSrcweir bool BiffFormulaParserImpl::importNlrSRangeToken( BiffInputStream& rStrm )
2569cdf0e10cSrcweir {
2570cdf0e10cSrcweir rStrm.skip( 5 );
2571cdf0e10cSrcweir BinRange aRange;
2572cdf0e10cSrcweir rStrm >> aRange;
2573cdf0e10cSrcweir BiffNlr aNlr;
2574cdf0e10cSrcweir bool bRow;
2575cdf0e10cSrcweir return readNlrSRangeAddData( aNlr, bRow, rStrm ) ? pushBiffNlrSRange( aNlr, aRange, bRow ) : pushBiffErrorOperand( BIFF_ERR_REF );
2576cdf0e10cSrcweir }
2577cdf0e10cSrcweir
importNlrErrToken(BiffInputStream & rStrm,sal_uInt16 nIgnore)2578cdf0e10cSrcweir bool BiffFormulaParserImpl::importNlrErrToken( BiffInputStream& rStrm, sal_uInt16 nIgnore )
2579cdf0e10cSrcweir {
2580cdf0e10cSrcweir rStrm.skip( nIgnore );
2581cdf0e10cSrcweir return pushBiffErrorOperand( BIFF_ERR_NAME );
2582cdf0e10cSrcweir }
2583cdf0e10cSrcweir
readRefId(BiffInputStream & rStrm)2584cdf0e10cSrcweir sal_Int32 BiffFormulaParserImpl::readRefId( BiffInputStream& rStrm )
2585cdf0e10cSrcweir {
2586cdf0e10cSrcweir sal_Int16 nRefId;
2587cdf0e10cSrcweir rStrm >> nRefId;
2588cdf0e10cSrcweir rStrm.skip( mnRefIdSize );
2589cdf0e10cSrcweir return nRefId;
2590cdf0e10cSrcweir }
2591cdf0e10cSrcweir
readNameId(BiffInputStream & rStrm)2592cdf0e10cSrcweir sal_uInt16 BiffFormulaParserImpl::readNameId( BiffInputStream& rStrm )
2593cdf0e10cSrcweir {
2594cdf0e10cSrcweir sal_uInt16 nNameId;
2595cdf0e10cSrcweir rStrm >> nNameId;
2596cdf0e10cSrcweir rStrm.skip( mnNameSize );
2597cdf0e10cSrcweir return nNameId;
2598cdf0e10cSrcweir }
2599cdf0e10cSrcweir
readSheetRange5(BiffInputStream & rStrm)2600cdf0e10cSrcweir LinkSheetRange BiffFormulaParserImpl::readSheetRange5( BiffInputStream& rStrm )
2601cdf0e10cSrcweir {
2602cdf0e10cSrcweir sal_Int32 nRefId = readRefId( rStrm );
2603cdf0e10cSrcweir sal_Int16 nTab1, nTab2;
2604cdf0e10cSrcweir rStrm >> nTab1 >> nTab2;
2605cdf0e10cSrcweir return getExternalLinks().getSheetRange( nRefId, nTab1, nTab2 );
2606cdf0e10cSrcweir }
2607cdf0e10cSrcweir
readSheetRange8(BiffInputStream & rStrm)2608cdf0e10cSrcweir LinkSheetRange BiffFormulaParserImpl::readSheetRange8( BiffInputStream& rStrm )
2609cdf0e10cSrcweir {
2610cdf0e10cSrcweir return getExternalLinks().getSheetRange( readRefId( rStrm ) );
2611cdf0e10cSrcweir }
2612cdf0e10cSrcweir
swapStreamPosition(BiffInputStream & rStrm)2613cdf0e10cSrcweir void BiffFormulaParserImpl::swapStreamPosition( BiffInputStream& rStrm )
2614cdf0e10cSrcweir {
2615cdf0e10cSrcweir sal_Int64 nRecPos = rStrm.tell();
2616cdf0e10cSrcweir rStrm.seek( mnAddDataPos );
2617cdf0e10cSrcweir mnAddDataPos = nRecPos;
2618cdf0e10cSrcweir }
2619cdf0e10cSrcweir
skipMemAreaAddData(BiffInputStream & rStrm)2620cdf0e10cSrcweir void BiffFormulaParserImpl::skipMemAreaAddData( BiffInputStream& rStrm )
2621cdf0e10cSrcweir {
2622cdf0e10cSrcweir swapStreamPosition( rStrm );
2623cdf0e10cSrcweir sal_Int32 nCount = rStrm.readuInt16();
2624cdf0e10cSrcweir rStrm.skip( ((getBiff() == BIFF8) ? 8 : 6) * nCount );
2625cdf0e10cSrcweir swapStreamPosition( rStrm );
2626cdf0e10cSrcweir }
2627cdf0e10cSrcweir
readNlrSAddrAddData(BiffNlr & orNlr,BiffInputStream & rStrm,bool bRow)2628cdf0e10cSrcweir bool BiffFormulaParserImpl::readNlrSAddrAddData( BiffNlr& orNlr, BiffInputStream& rStrm, bool bRow )
2629cdf0e10cSrcweir {
2630cdf0e10cSrcweir bool bIsRow;
2631cdf0e10cSrcweir return readNlrSRangeAddData( orNlr, bIsRow, rStrm ) && (bIsRow == bRow);
2632cdf0e10cSrcweir }
2633cdf0e10cSrcweir
readNlrSRangeAddData(BiffNlr & orNlr,bool & orbIsRow,BiffInputStream & rStrm)2634cdf0e10cSrcweir bool BiffFormulaParserImpl::readNlrSRangeAddData( BiffNlr& orNlr, bool& orbIsRow, BiffInputStream& rStrm )
2635cdf0e10cSrcweir {
2636cdf0e10cSrcweir swapStreamPosition( rStrm );
2637cdf0e10cSrcweir // read number of cell addresses and relative flag
2638cdf0e10cSrcweir sal_uInt32 nCount;
2639cdf0e10cSrcweir rStrm >> nCount;
2640cdf0e10cSrcweir bool bRel = getFlag( nCount, BIFF_TOK_NLR_ADDREL );
2641cdf0e10cSrcweir nCount &= BIFF_TOK_NLR_ADDMASK;
2642cdf0e10cSrcweir sal_Int64 nEndPos = rStrm.tell() + 4 * nCount;
2643cdf0e10cSrcweir // read list of cell addresses
2644cdf0e10cSrcweir bool bValid = false;
2645cdf0e10cSrcweir if( nCount >= 2 )
2646cdf0e10cSrcweir {
2647cdf0e10cSrcweir // detect column/row orientation
2648cdf0e10cSrcweir BinAddress aAddr1, aAddr2;
2649cdf0e10cSrcweir rStrm >> aAddr1 >> aAddr2;
2650cdf0e10cSrcweir orbIsRow = aAddr1.mnRow == aAddr2.mnRow;
2651cdf0e10cSrcweir bValid = lclIsValidNlrStack( aAddr1, aAddr2, orbIsRow );
2652cdf0e10cSrcweir // read and verify additional cell positions
2653cdf0e10cSrcweir for( sal_uInt32 nIndex = 2; bValid && (nIndex < nCount); ++nIndex )
2654cdf0e10cSrcweir {
2655cdf0e10cSrcweir aAddr1 = aAddr2;
2656cdf0e10cSrcweir rStrm >> aAddr2;
2657cdf0e10cSrcweir bValid = !rStrm.isEof() && lclIsValidNlrStack( aAddr1, aAddr2, orbIsRow );
2658cdf0e10cSrcweir }
2659cdf0e10cSrcweir // check that last imported position (aAddr2) is not at the end of the sheet
2660cdf0e10cSrcweir bValid = bValid && (orbIsRow ? (aAddr2.mnCol < mnMaxApiCol) : (aAddr2.mnRow < mnMaxApiRow));
2661cdf0e10cSrcweir // fill the NLR struct with the last imported position
2662cdf0e10cSrcweir if( bValid )
2663cdf0e10cSrcweir {
2664cdf0e10cSrcweir orNlr.mnCol = aAddr2.mnCol;
2665cdf0e10cSrcweir orNlr.mnRow = aAddr2.mnRow;
2666cdf0e10cSrcweir orNlr.mbRel = bRel;
2667cdf0e10cSrcweir }
2668cdf0e10cSrcweir }
2669cdf0e10cSrcweir // seek to end of additional data for this token
2670cdf0e10cSrcweir rStrm.seek( nEndPos );
2671cdf0e10cSrcweir swapStreamPosition( rStrm );
2672cdf0e10cSrcweir
2673cdf0e10cSrcweir return bValid;
2674cdf0e10cSrcweir }
2675cdf0e10cSrcweir
2676cdf0e10cSrcweir // convert BIFF token and push API operand or operator ------------------------
2677cdf0e10cSrcweir
pushBiffReference(const BinSingleRef2d & rRef,bool bDeleted,bool bRelativeAsOffset)2678cdf0e10cSrcweir bool BiffFormulaParserImpl::pushBiffReference( const BinSingleRef2d& rRef, bool bDeleted, bool bRelativeAsOffset )
2679cdf0e10cSrcweir {
2680cdf0e10cSrcweir return (mnCurrRefId > 0) ?
2681cdf0e10cSrcweir pushReferenceOperand( getExternalLinks().getSheetRange( mnCurrRefId, 0, 0 ), rRef, bDeleted, bRelativeAsOffset ) :
2682cdf0e10cSrcweir pushReferenceOperand( rRef, bDeleted, bRelativeAsOffset );
2683cdf0e10cSrcweir }
2684cdf0e10cSrcweir
pushBiffReference(const BinComplexRef2d & rRef,bool bDeleted,bool bRelativeAsOffset)2685cdf0e10cSrcweir bool BiffFormulaParserImpl::pushBiffReference( const BinComplexRef2d& rRef, bool bDeleted, bool bRelativeAsOffset )
2686cdf0e10cSrcweir {
2687cdf0e10cSrcweir return (mnCurrRefId > 0) ?
2688cdf0e10cSrcweir pushReferenceOperand( getExternalLinks().getSheetRange( mnCurrRefId, 0, 0 ), rRef, bDeleted, bRelativeAsOffset ) :
2689cdf0e10cSrcweir pushReferenceOperand( rRef, bDeleted, bRelativeAsOffset );
2690cdf0e10cSrcweir }
2691cdf0e10cSrcweir
pushBiffNlrAddr(const BiffNlr & rNlr,bool bRow)2692cdf0e10cSrcweir bool BiffFormulaParserImpl::pushBiffNlrAddr( const BiffNlr& rNlr, bool bRow )
2693cdf0e10cSrcweir {
2694cdf0e10cSrcweir BinSingleRef2d aRef;
2695cdf0e10cSrcweir aRef.mnCol = rNlr.mnCol;
2696cdf0e10cSrcweir aRef.mnRow = rNlr.mnRow;
2697cdf0e10cSrcweir aRef.mbColRel = !bRow;
2698cdf0e10cSrcweir aRef.mbRowRel = bRow;
2699cdf0e10cSrcweir return pushNlrOperand( aRef );
2700cdf0e10cSrcweir }
2701cdf0e10cSrcweir
pushBiffNlrRange(const BiffNlr & rNlr,const BinRange & rRange)2702cdf0e10cSrcweir bool BiffFormulaParserImpl::pushBiffNlrRange( const BiffNlr& rNlr, const BinRange& rRange )
2703cdf0e10cSrcweir {
2704cdf0e10cSrcweir bool bRow = rNlr.mnRow == rRange.maFirst.mnRow;
2705cdf0e10cSrcweir return lclIsValidNlrRange( rNlr, rRange, bRow ) ?
2706cdf0e10cSrcweir pushBiffNlrAddr( rNlr, bRow ) : pushBiffErrorOperand( BIFF_ERR_REF );
2707cdf0e10cSrcweir }
2708cdf0e10cSrcweir
pushBiffNlrSAddr(const BiffNlr & rNlr,bool bRow)2709cdf0e10cSrcweir bool BiffFormulaParserImpl::pushBiffNlrSAddr( const BiffNlr& rNlr, bool bRow )
2710cdf0e10cSrcweir {
2711cdf0e10cSrcweir BinRange aRange;
2712cdf0e10cSrcweir aRange.maFirst.mnCol = rNlr.mnCol + (bRow ? 1 : 0);
2713cdf0e10cSrcweir aRange.maFirst.mnRow = rNlr.mnRow + (bRow ? 0 : 1);
2714cdf0e10cSrcweir aRange.maLast.mnCol = bRow ? mnMaxApiCol : rNlr.mnCol;
2715cdf0e10cSrcweir aRange.maLast.mnRow = bRow ? rNlr.mnRow : mnMaxApiRow;
2716cdf0e10cSrcweir return pushBiffNlrSRange( rNlr, aRange, bRow );
2717cdf0e10cSrcweir }
2718cdf0e10cSrcweir
pushBiffNlrSRange(const BiffNlr & rNlr,const BinRange & rRange,bool bRow)2719cdf0e10cSrcweir bool BiffFormulaParserImpl::pushBiffNlrSRange( const BiffNlr& rNlr, const BinRange& rRange, bool bRow )
2720cdf0e10cSrcweir {
2721cdf0e10cSrcweir if( lclIsValidNlrRange( rNlr, rRange, bRow ) )
2722cdf0e10cSrcweir {
2723cdf0e10cSrcweir BinComplexRef2d aRef;
2724cdf0e10cSrcweir aRef.maRef1.mnCol = rRange.maFirst.mnCol;
2725cdf0e10cSrcweir aRef.maRef1.mnRow = rRange.maFirst.mnRow;
2726cdf0e10cSrcweir aRef.maRef2.mnCol = rRange.maLast.mnCol;
2727cdf0e10cSrcweir aRef.maRef2.mnRow = rRange.maLast.mnRow;
2728cdf0e10cSrcweir aRef.maRef1.mbColRel = aRef.maRef2.mbColRel = !bRow && rNlr.mbRel;
2729cdf0e10cSrcweir aRef.maRef1.mbRowRel = aRef.maRef2.mbRowRel = bRow && rNlr.mbRel;
2730cdf0e10cSrcweir return pushReferenceOperand( aRef, false, false );
2731cdf0e10cSrcweir }
2732cdf0e10cSrcweir return pushBiffErrorOperand( BIFF_ERR_REF );
2733cdf0e10cSrcweir }
2734cdf0e10cSrcweir
pushBiffName(sal_uInt16 nNameId)2735cdf0e10cSrcweir bool BiffFormulaParserImpl::pushBiffName( sal_uInt16 nNameId )
2736cdf0e10cSrcweir {
2737cdf0e10cSrcweir // one-based in BIFF formulas
2738cdf0e10cSrcweir return pushDefinedNameOperand( getDefinedNames().getByIndex( static_cast< sal_Int32 >( nNameId ) - 1 ) );
2739cdf0e10cSrcweir }
2740cdf0e10cSrcweir
pushBiffExtName(sal_Int32 nRefId,sal_uInt16 nNameId)2741cdf0e10cSrcweir bool BiffFormulaParserImpl::pushBiffExtName( sal_Int32 nRefId, sal_uInt16 nNameId )
2742cdf0e10cSrcweir {
2743cdf0e10cSrcweir if( const ExternalLink* pExtLink = getExternalLinks().getExternalLink( nRefId ).get() )
2744cdf0e10cSrcweir {
2745cdf0e10cSrcweir if( pExtLink->getLinkType() == LINKTYPE_SELF )
2746cdf0e10cSrcweir return pushBiffName( nNameId );
2747cdf0e10cSrcweir // external name indexes are one-based in BIFF
2748cdf0e10cSrcweir ExternalNameRef xExtName = pExtLink->getNameByIndex( static_cast< sal_Int32 >( nNameId ) - 1 );
2749cdf0e10cSrcweir return pushExternalNameOperand( xExtName, *pExtLink );
2750cdf0e10cSrcweir }
2751cdf0e10cSrcweir return pushBiffErrorOperand( BIFF_ERR_NAME );
2752cdf0e10cSrcweir }
2753cdf0e10cSrcweir
pushBiffFunction(sal_uInt16 nFuncId)2754cdf0e10cSrcweir bool BiffFormulaParserImpl::pushBiffFunction( sal_uInt16 nFuncId )
2755cdf0e10cSrcweir {
2756cdf0e10cSrcweir if( const FunctionInfo* pFuncInfo = getFuncInfoFromBiffFuncId( nFuncId ) )
2757cdf0e10cSrcweir if( pFuncInfo->mnMinParamCount == pFuncInfo->mnMaxParamCount )
2758cdf0e10cSrcweir return pushFunctionOperator( *pFuncInfo, pFuncInfo->mnMinParamCount );
2759cdf0e10cSrcweir return pushFunctionOperator( OPCODE_NONAME, 0 );
2760cdf0e10cSrcweir }
2761cdf0e10cSrcweir
pushBiffFunction(sal_uInt16 nFuncId,sal_uInt8 nParamCount)2762cdf0e10cSrcweir bool BiffFormulaParserImpl::pushBiffFunction( sal_uInt16 nFuncId, sal_uInt8 nParamCount )
2763cdf0e10cSrcweir {
2764cdf0e10cSrcweir if( getFlag( nFuncId, BIFF_TOK_FUNCVAR_CMD ) )
2765cdf0e10cSrcweir nParamCount &= BIFF_TOK_FUNCVAR_COUNTMASK;
2766cdf0e10cSrcweir if( const FunctionInfo* pFuncInfo = getFuncInfoFromBiffFuncId( nFuncId ) )
2767cdf0e10cSrcweir return pushFunctionOperator( *pFuncInfo, nParamCount );
2768cdf0e10cSrcweir return pushFunctionOperator( OPCODE_NONAME, nParamCount );
2769cdf0e10cSrcweir }
2770cdf0e10cSrcweir
2771cdf0e10cSrcweir // ============================================================================
2772cdf0e10cSrcweir
2773cdf0e10cSrcweir namespace {
2774cdf0e10cSrcweir
2775cdf0e10cSrcweir /** Extracts the reference identifier and the remaining data from a formula in
2776cdf0e10cSrcweir the format '[RefID]Remaining'. */
lclExtractRefId(sal_Int32 & rnRefId,OUString & rRemainder,const OUString & rFormulaString)2777cdf0e10cSrcweir bool lclExtractRefId( sal_Int32& rnRefId, OUString& rRemainder, const OUString& rFormulaString )
2778cdf0e10cSrcweir {
2779cdf0e10cSrcweir if( (rFormulaString.getLength() >= 4) && (rFormulaString[ 0 ] == '[') )
2780cdf0e10cSrcweir {
2781cdf0e10cSrcweir sal_Int32 nBracketClose = rFormulaString.indexOf( ']', 1 );
2782cdf0e10cSrcweir if( nBracketClose >= 2 )
2783cdf0e10cSrcweir {
2784cdf0e10cSrcweir rnRefId = rFormulaString.copy( 1, nBracketClose - 1 ).toInt32();
2785cdf0e10cSrcweir rRemainder = rFormulaString.copy( nBracketClose + 1 );
2786cdf0e10cSrcweir return rRemainder.getLength() > 0;
2787cdf0e10cSrcweir }
2788cdf0e10cSrcweir }
2789cdf0e10cSrcweir return false;
2790cdf0e10cSrcweir }
2791cdf0e10cSrcweir
2792cdf0e10cSrcweir }
2793cdf0e10cSrcweir
2794cdf0e10cSrcweir // ----------------------------------------------------------------------------
2795cdf0e10cSrcweir
FormulaParser(const WorkbookHelper & rHelper)2796cdf0e10cSrcweir FormulaParser::FormulaParser( const WorkbookHelper& rHelper ) :
2797cdf0e10cSrcweir FormulaProcessorBase( rHelper )
2798cdf0e10cSrcweir {
2799cdf0e10cSrcweir switch( getFilterType() )
2800cdf0e10cSrcweir {
2801cdf0e10cSrcweir case FILTER_OOXML: mxImpl.reset( new OoxFormulaParserImpl( *this ) ); break;
2802cdf0e10cSrcweir case FILTER_BIFF: mxImpl.reset( new BiffFormulaParserImpl( *this ) ); break;
2803cdf0e10cSrcweir case FILTER_UNKNOWN: break;
2804cdf0e10cSrcweir }
2805cdf0e10cSrcweir }
2806cdf0e10cSrcweir
~FormulaParser()2807cdf0e10cSrcweir FormulaParser::~FormulaParser()
2808cdf0e10cSrcweir {
2809cdf0e10cSrcweir }
2810cdf0e10cSrcweir
importFormula(const CellAddress & rBaseAddress,const OUString & rFormulaString) const2811cdf0e10cSrcweir ApiTokenSequence FormulaParser::importFormula( const CellAddress& rBaseAddress, const OUString& rFormulaString ) const
2812cdf0e10cSrcweir {
2813cdf0e10cSrcweir return mxImpl->importOoxFormula( rBaseAddress, rFormulaString );
2814cdf0e10cSrcweir }
2815cdf0e10cSrcweir
importFormula(const CellAddress & rBaseAddress,FormulaType eType,SequenceInputStream & rStrm) const2816cdf0e10cSrcweir ApiTokenSequence FormulaParser::importFormula( const CellAddress& rBaseAddress, FormulaType eType, SequenceInputStream& rStrm ) const
2817cdf0e10cSrcweir {
2818cdf0e10cSrcweir return mxImpl->importBiff12Formula( rBaseAddress, eType, rStrm );
2819cdf0e10cSrcweir }
2820cdf0e10cSrcweir
importFormula(const CellAddress & rBaseAddress,FormulaType eType,BiffInputStream & rStrm,const sal_uInt16 * pnFmlaSize) const2821cdf0e10cSrcweir ApiTokenSequence FormulaParser::importFormula( const CellAddress& rBaseAddress, FormulaType eType, BiffInputStream& rStrm, const sal_uInt16* pnFmlaSize ) const
2822cdf0e10cSrcweir {
2823cdf0e10cSrcweir return mxImpl->importBiffFormula( rBaseAddress, eType, rStrm, pnFmlaSize );
2824cdf0e10cSrcweir }
2825cdf0e10cSrcweir
convertBoolToFormula(bool bValue) const2826cdf0e10cSrcweir ApiTokenSequence FormulaParser::convertBoolToFormula( bool bValue ) const
2827cdf0e10cSrcweir {
2828cdf0e10cSrcweir if( const FunctionInfo* pFuncInfo = getFuncInfoFromBiffFuncId( bValue ? BIFF_FUNC_TRUE : BIFF_FUNC_FALSE ) )
2829cdf0e10cSrcweir {
2830cdf0e10cSrcweir ApiTokenSequence aTokens( 3 );
2831cdf0e10cSrcweir aTokens[ 0 ].OpCode = pFuncInfo->mnApiOpCode;
2832cdf0e10cSrcweir aTokens[ 1 ].OpCode = OPCODE_OPEN;
2833cdf0e10cSrcweir aTokens[ 2 ].OpCode = OPCODE_CLOSE;
2834cdf0e10cSrcweir return aTokens;
2835cdf0e10cSrcweir }
2836cdf0e10cSrcweir return ApiTokenSequence();
2837cdf0e10cSrcweir }
2838cdf0e10cSrcweir
convertErrorToFormula(sal_uInt8 nErrorCode) const2839cdf0e10cSrcweir ApiTokenSequence FormulaParser::convertErrorToFormula( sal_uInt8 nErrorCode ) const
2840cdf0e10cSrcweir {
2841cdf0e10cSrcweir ApiTokenSequence aTokens( 3 );
2842cdf0e10cSrcweir // HACK: enclose all error codes into an 1x1 matrix
2843cdf0e10cSrcweir aTokens[ 0 ].OpCode = OPCODE_ARRAY_OPEN;
2844cdf0e10cSrcweir aTokens[ 1 ].OpCode = OPCODE_PUSH;
2845cdf0e10cSrcweir aTokens[ 1 ].Data <<= BiffHelper::calcDoubleFromError( nErrorCode );
2846cdf0e10cSrcweir aTokens[ 2 ].OpCode = OPCODE_ARRAY_CLOSE;
2847cdf0e10cSrcweir return aTokens;
2848cdf0e10cSrcweir }
2849cdf0e10cSrcweir
convertNameToFormula(sal_Int32 nTokenIndex) const2850cdf0e10cSrcweir ApiTokenSequence FormulaParser::convertNameToFormula( sal_Int32 nTokenIndex ) const
2851cdf0e10cSrcweir {
2852cdf0e10cSrcweir if( nTokenIndex < 0 )
2853cdf0e10cSrcweir return convertErrorToFormula( BIFF_ERR_REF );
2854cdf0e10cSrcweir
2855cdf0e10cSrcweir ApiTokenSequence aTokens( 1 );
2856cdf0e10cSrcweir aTokens[ 0 ].OpCode = OPCODE_NAME;
2857cdf0e10cSrcweir aTokens[ 0 ].Data <<= nTokenIndex;
2858cdf0e10cSrcweir return aTokens;
2859cdf0e10cSrcweir }
2860cdf0e10cSrcweir
convertNumberToHyperlink(const OUString & rUrl,double fValue) const2861cdf0e10cSrcweir ApiTokenSequence FormulaParser::convertNumberToHyperlink( const OUString& rUrl, double fValue ) const
2862cdf0e10cSrcweir {
2863cdf0e10cSrcweir OSL_ENSURE( rUrl.getLength() > 0, "FormulaParser::convertNumberToHyperlink - missing URL" );
2864cdf0e10cSrcweir if( const FunctionInfo* pFuncInfo = getFuncInfoFromBiffFuncId( BIFF_FUNC_HYPERLINK ) )
2865cdf0e10cSrcweir {
2866cdf0e10cSrcweir ApiTokenSequence aTokens( 6 );
2867cdf0e10cSrcweir aTokens[ 0 ].OpCode = pFuncInfo->mnApiOpCode;
2868cdf0e10cSrcweir aTokens[ 1 ].OpCode = OPCODE_OPEN;
2869cdf0e10cSrcweir aTokens[ 2 ].OpCode = OPCODE_PUSH;
2870cdf0e10cSrcweir aTokens[ 2 ].Data <<= rUrl;
2871cdf0e10cSrcweir aTokens[ 3 ].OpCode = OPCODE_SEP;
2872cdf0e10cSrcweir aTokens[ 4 ].OpCode = OPCODE_PUSH;
2873cdf0e10cSrcweir aTokens[ 4 ].Data <<= fValue;
2874cdf0e10cSrcweir aTokens[ 5 ].OpCode = OPCODE_CLOSE;
2875cdf0e10cSrcweir return aTokens;
2876cdf0e10cSrcweir }
2877cdf0e10cSrcweir return ApiTokenSequence();
2878cdf0e10cSrcweir }
2879cdf0e10cSrcweir
importOleTargetLink(const OUString & rFormulaString)2880cdf0e10cSrcweir OUString FormulaParser::importOleTargetLink( const OUString& rFormulaString )
2881cdf0e10cSrcweir {
2882cdf0e10cSrcweir sal_Int32 nRefId = -1;
2883cdf0e10cSrcweir OUString aRemainder;
2884cdf0e10cSrcweir if( lclExtractRefId( nRefId, aRemainder, rFormulaString ) && (aRemainder.getLength() >= 3) &&
2885cdf0e10cSrcweir (aRemainder[ 0 ] == '!') && (aRemainder[ 1 ] == '\'') && (aRemainder[ aRemainder.getLength() - 1 ] == '\'') )
2886cdf0e10cSrcweir return mxImpl->resolveOleTarget( nRefId, false );
2887cdf0e10cSrcweir return OUString();
2888cdf0e10cSrcweir }
2889cdf0e10cSrcweir
importOleTargetLink(SequenceInputStream & rStrm)2890cdf0e10cSrcweir OUString FormulaParser::importOleTargetLink( SequenceInputStream& rStrm )
2891cdf0e10cSrcweir {
2892cdf0e10cSrcweir OUString aTargetLink;
2893cdf0e10cSrcweir sal_Int32 nFmlaSize = rStrm.readInt32();
2894cdf0e10cSrcweir sal_Int64 nFmlaEndPos = rStrm.tell() + ::std::max< sal_Int32 >( nFmlaSize, 0 );
2895cdf0e10cSrcweir if( (nFmlaSize == 7) && (rStrm.getRemaining() >= 7) )
2896cdf0e10cSrcweir {
2897cdf0e10cSrcweir sal_uInt8 nToken;
2898cdf0e10cSrcweir sal_Int16 nRefId;
2899cdf0e10cSrcweir sal_Int32 nNameId;
2900cdf0e10cSrcweir rStrm >> nToken >> nRefId >> nNameId;
2901cdf0e10cSrcweir if( nToken == (BIFF_TOKCLASS_VAL|BIFF_TOKID_NAMEX) )
2902cdf0e10cSrcweir aTargetLink = mxImpl->resolveOleTarget( nRefId, true );
2903cdf0e10cSrcweir }
2904cdf0e10cSrcweir rStrm.seek( nFmlaEndPos );
2905cdf0e10cSrcweir return aTargetLink;
2906cdf0e10cSrcweir }
2907cdf0e10cSrcweir
importOleTargetLink(BiffInputStream & rStrm,const sal_uInt16 * pnFmlaSize) const2908cdf0e10cSrcweir OUString FormulaParser::importOleTargetLink( BiffInputStream& rStrm, const sal_uInt16* pnFmlaSize ) const
2909cdf0e10cSrcweir {
2910cdf0e10cSrcweir OUString aTargetLink;
2911cdf0e10cSrcweir sal_uInt16 nFmlaSize = lclReadFmlaSize( rStrm, getBiff(), pnFmlaSize );
2912cdf0e10cSrcweir rStrm.skip( nFmlaSize );
2913cdf0e10cSrcweir return aTargetLink;
2914cdf0e10cSrcweir }
2915cdf0e10cSrcweir
importMacroName(const OUString & rFormulaString)2916cdf0e10cSrcweir OUString FormulaParser::importMacroName( const OUString& rFormulaString )
2917cdf0e10cSrcweir {
2918cdf0e10cSrcweir /* Valid macros are either sheet macros or VBA macros. OOXML and all BIFF
2919cdf0e10cSrcweir documents store defined names for sheet macros, but OOXML documents do
2920cdf0e10cSrcweir not store any defined name for VBA macros (while BIFF documents do).
2921cdf0e10cSrcweir Sheet macros may be defined locally to a sheet, or globally to the
2922cdf0e10cSrcweir document. As a result, all of the following macro specifiers are valid:
2923cdf0e10cSrcweir
2924cdf0e10cSrcweir 1) Macros located in the own document:
2925cdf0e10cSrcweir [0]!MySheetMacro (global sheet macro 'MySheetMacro')
2926cdf0e10cSrcweir Macro1!MyMacro (sheet-local sheet macro 'MyMacro')
2927cdf0e10cSrcweir [0]!MyVBAProc (VBA macro 'MyVBAProc')
2928cdf0e10cSrcweir [0]!Mod1.MyVBAProc (VBA macro 'MyVBAProc' from code module 'Mod1')
2929cdf0e10cSrcweir
2930cdf0e10cSrcweir 2) Macros from an external document:
2931cdf0e10cSrcweir [2]!MySheetMacro (global external sheet macro 'MySheetMacro')
2932cdf0e10cSrcweir [2]Macro1!MyMacro (sheet-local external sheet macro 'MyMacro')
2933cdf0e10cSrcweir [2]!MyVBAProc (external VBA macro 'MyVBAProc')
2934cdf0e10cSrcweir [2]!Mod1.MyVBAProc (external VBA macro from code module 'Mod1')
2935cdf0e10cSrcweir
2936cdf0e10cSrcweir This implementation is only interested in VBA macros from the own
2937cdf0e10cSrcweir document, ignoring the valid syntax 'Macro1!MyMacro' for sheet-local
2938cdf0e10cSrcweir sheet macros.
2939cdf0e10cSrcweir */
2940cdf0e10cSrcweir sal_Int32 nRefId = -1;
2941cdf0e10cSrcweir OUString aRemainder;
2942cdf0e10cSrcweir if( lclExtractRefId( nRefId, aRemainder, rFormulaString ) && (aRemainder.getLength() > 1) && (aRemainder[ 0 ] == '!') )
2943cdf0e10cSrcweir {
2944cdf0e10cSrcweir /* In BIFF12 documents, the reference identifier is always the
2945cdf0e10cSrcweir one-based index of the external link as it is in OOXML documents
2946cdf0e10cSrcweir (it is not an index into the list of reference sheets as used in
2947cdf0e10cSrcweir cell formulas). Index 0 is an implicit placeholder for the own
2948cdf0e10cSrcweir document. In BIFF12 documents, the reference to the own document is
2949cdf0e10cSrcweir stored explicitly, mostly at the top of the list, so index 1 may
2950cdf0e10cSrcweir resolve to the own document too.
2951cdf0e10cSrcweir Passing 'false' to getExternalLink() specifies to ignore the
2952cdf0e10cSrcweir reference sheets list (if existing) and to access the list of
2953cdf0e10cSrcweir external links directly. */
2954cdf0e10cSrcweir const ExternalLink* pExtLink = getExternalLinks().getExternalLink( nRefId, false ).get();
2955cdf0e10cSrcweir OSL_ENSURE( pExtLink, "FormulaParser::importMacroName - missing link" );
2956cdf0e10cSrcweir // do not accept macros in external documents (not supported)
2957cdf0e10cSrcweir if( pExtLink && (pExtLink->getLinkType() == LINKTYPE_SELF) )
2958cdf0e10cSrcweir {
2959cdf0e10cSrcweir // ignore sheet macros (defined name for VBA macros may not exist, see above)
2960cdf0e10cSrcweir OUString aMacroName = aRemainder.copy( 1 );
2961cdf0e10cSrcweir const DefinedName* pDefName = getDefinedNames().getByModelName( aMacroName ).get();
2962cdf0e10cSrcweir if( !pDefName || pDefName->isVBName() )
2963cdf0e10cSrcweir return aMacroName;
2964cdf0e10cSrcweir }
2965cdf0e10cSrcweir }
2966cdf0e10cSrcweir return OUString();
2967cdf0e10cSrcweir }
2968cdf0e10cSrcweir
2969cdf0e10cSrcweir // ============================================================================
2970cdf0e10cSrcweir
2971cdf0e10cSrcweir } // namespace xls
2972cdf0e10cSrcweir } // namespace oox
2973