xref: /trunk/main/sc/source/filter/excel/excform8.cxx (revision b77af630)
1 /**************************************************************
2  *
3  * Licensed to the Apache Software Foundation (ASF) under one
4  * or more contributor license agreements.  See the NOTICE file
5  * distributed with this work for additional information
6  * regarding copyright ownership.  The ASF licenses this file
7  * to you under the Apache License, Version 2.0 (the
8  * "License"); you may not use this file except in compliance
9  * with the License.  You may obtain a copy of the License at
10  *
11  *   http://www.apache.org/licenses/LICENSE-2.0
12  *
13  * Unless required by applicable law or agreed to in writing,
14  * software distributed under the License is distributed on an
15  * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
16  * KIND, either express or implied.  See the License for the
17  * specific language governing permissions and limitations
18  * under the License.
19  *
20  *************************************************************/
21 
22 
23 
24 // MARKER(update_precomp.py): autogen include statement, do not remove
25 #include "precompiled_scfilt.hxx"
26 #include "excform.hxx"
27 
28 #include "cell.hxx"
29 #include "document.hxx"
30 #include "rangenam.hxx"
31 #include "xltracer.hxx"
32 #include "xistream.hxx"
33 #include "xihelper.hxx"
34 #include "xilink.hxx"
35 #include "xiname.hxx"
36 
37 #include "externalrefmgr.hxx"
38 
39 #include <vector>
40 
41 using ::std::vector;
42 
ExternalTabInfo()43 ExcelToSc8::ExternalTabInfo::ExternalTabInfo() :
44     mnFileId(0), mbExternal(false)
45 {
46 }
47 
48 // ============================================================================
49 
ExcelToSc8(const XclImpRoot & rRoot)50 ExcelToSc8::ExcelToSc8( const XclImpRoot& rRoot ) :
51     ExcelToSc( rRoot ),
52     rLinkMan( rRoot.GetLinkManager() )
53 {
54 }
55 
56 
~ExcelToSc8()57 ExcelToSc8::~ExcelToSc8()
58 {
59 }
60 
GetExternalFileIdFromXti(sal_uInt16 nIxti,sal_uInt16 & rFileId) const61 bool ExcelToSc8::GetExternalFileIdFromXti( sal_uInt16 nIxti, sal_uInt16& rFileId ) const
62 {
63     const String* pFileUrl = rLinkMan.GetSupbookUrl(nIxti);
64     if (!pFileUrl || pFileUrl->Len() == 0 || !GetDocShell())
65         return false;
66 
67     String aFileUrl = ScGlobal::GetAbsDocName(*pFileUrl, GetDocShell());
68     ScExternalRefManager* pRefMgr = GetDoc().GetExternalRefManager();
69     rFileId = pRefMgr->getExternalFileId(aFileUrl);
70 
71     return true;
72 }
73 
Read3DTabReference(sal_uInt16 nIxti,SCTAB & rFirstTab,SCTAB & rLastTab,ExternalTabInfo & rExtInfo)74 bool ExcelToSc8::Read3DTabReference( sal_uInt16 nIxti, SCTAB& rFirstTab, SCTAB& rLastTab, ExternalTabInfo& rExtInfo )
75 {
76 	rFirstTab = rLastTab = 0;
77     rExtInfo.mbExternal = !rLinkMan.IsSelfRef(nIxti);
78     bool bSuccess = rLinkMan.GetScTabRange(rFirstTab, rLastTab, nIxti);
79     if (!bSuccess)
80         return false;
81 
82     if (!rExtInfo.mbExternal)
83         // This is internal reference.  Stop here.
84         return true;
85 
86     rExtInfo.maTabName = rLinkMan.GetSupbookTabName(nIxti, rFirstTab);
87     return GetExternalFileIdFromXti(nIxti, rExtInfo.mnFileId);
88 }
89 
90 
91 // if bAllowArrays is false stream seeks to first byte after <nFormulaLen>
92 // otherwise it will seek to the first byte past additional content after <nFormulaLen>
Convert(const ScTokenArray * & rpTokArray,XclImpStream & aIn,sal_Size nFormulaLen,bool bAllowArrays,const FORMULA_TYPE eFT)93 ConvErr ExcelToSc8::Convert( const ScTokenArray*& rpTokArray, XclImpStream& aIn, sal_Size nFormulaLen, bool bAllowArrays, const FORMULA_TYPE eFT )
94 {
95 	sal_uInt8					nOp, nLen, nByte;
96     sal_uInt16                  nUINT16;
97 	double					fDouble;
98 	String					aString;
99 	sal_Bool					bError = sal_False;
100 	sal_Bool					bArrayFormula = sal_False;
101 	TokenId					nMerk0;
102 	const sal_Bool				bRangeName = eFT == FT_RangeName;
103 	const sal_Bool				bSharedFormula = eFT == FT_SharedFormula;
104 	const sal_Bool		        bConditional = eFT == FT_Conditional;
105 	const sal_Bool				bRNorSF = bRangeName || bSharedFormula || bConditional;
106 
107 	ScSingleRefData			aSRD;
108 	ScComplexRefData			aCRD;
109     ExtensionTypeVec		aExtensions;
110 
111 	if( eStatus != ConvOK )
112 	{
113         aIn.Ignore( nFormulaLen );
114 		return eStatus;
115 	}
116 
117 	if( nFormulaLen == 0 )
118 	{
119         aPool.Store( CREATE_STRING( "-/-" ) );
120 		aPool >> aStack;
121 		rpTokArray = aPool[ aStack.Get() ];
122 		return ConvOK;
123 	}
124 
125     sal_Size nEndPos = aIn.GetRecPos() + nFormulaLen;
126 
127     // #123870# Init members, they are on random values and not all will beinitialized in all cases below
128     aSRD.InitMembers();
129     aCRD.InitMembers();
130 
131     while( (aIn.GetRecPos() < nEndPos) && !bError )
132 	{
133 		aIn >> nOp;
134 
135         // #98524# always reset flags
136         aSRD.InitFlags();
137         aCRD.InitFlags();
138 
139 		switch( nOp )	//								Buch Seite:
140 		{			//										SDK4 SDK5
141 			case 0x01: // Array Formula							[325    ]
142 					   // Array Formula or Shared Formula		[    277]
143 			case 0x02: // Data Table							[325 277]
144                 aIn.Ignore( 4 );
145 
146 				bArrayFormula = sal_True;
147 				break;
148 			case 0x03: // Addition								[312 264]
149 				aStack >> nMerk0;
150 				aPool <<  aStack << ocAdd << nMerk0;
151 				aPool >> aStack;
152 				break;
153 			case 0x04: // Subtraction							[313 264]
154 				// SECOMD-TOP minus TOP
155 				aStack >> nMerk0;
156 				aPool << aStack << ocSub << nMerk0;
157 				aPool >> aStack;
158 				break;
159 			case 0x05: // Multiplication						[313 264]
160 				aStack >> nMerk0;
161 				aPool << aStack << ocMul << nMerk0;
162 				aPool >> aStack;
163 				break;
164 			case 0x06: // Division								[313 264]
165 				// divide TOP by SECOND-TOP
166 				aStack >> nMerk0;
167 				aPool << aStack << ocDiv << nMerk0;
168 				aPool >> aStack;
169 				break;
170 			case 0x07: // Exponetiation							[313 265]
171 				// raise SECOND-TOP to power of TOP
172 				aStack >> nMerk0;
173 				aPool << aStack << ocPow << nMerk0;
174 				aPool >> aStack;
175 				break;
176 			case 0x08: // Concatenation							[313 265]
177 				// append TOP to SECOND-TOP
178 				aStack >> nMerk0;
179 				aPool << aStack << ocAmpersand << nMerk0;
180 				aPool >> aStack;
181 				break;
182 			case 0x09: // Less Than								[313 265]
183 				// SECOND-TOP < TOP
184 				aStack >> nMerk0;
185 				aPool << aStack << ocLess << nMerk0;
186 				aPool >> aStack;
187 				break;
188 			case 0x0A: // Less Than or Equal					[313 265]
189 				// SECOND-TOP <= TOP
190 				aStack >> nMerk0;
191 				aPool << aStack << ocLessEqual << nMerk0;
192 				aPool >> aStack;
193 				break;
194 			case 0x0B: // Equal									[313 265]
195 				// SECOND-TOP == TOP
196 				aStack >> nMerk0;
197 				aPool << aStack << ocEqual << nMerk0;
198 				aPool >> aStack;
199 				break;
200 			case 0x0C: // Greater Than or Equal					[313 265]
201 				// SECOND-TOP == TOP
202 				aStack >> nMerk0;
203 				aPool << aStack << ocGreaterEqual << nMerk0;
204 				aPool >> aStack;
205 				break;
206 			case 0x0D: // Greater Than							[313 265]
207 				// SECOND-TOP == TOP
208 				aStack >> nMerk0;
209 				aPool << aStack << ocGreater << nMerk0;
210 				aPool >> aStack;
211 				break;
212 			case 0x0E: // Not Equal								[313 265]
213 				// SECOND-TOP == TOP
214 				aStack >> nMerk0;
215 				aPool << aStack << ocNotEqual << nMerk0;
216 				aPool >> aStack;
217 				break;
218 			case 0x0F: // Intersection							[314 265]
219 				aStack >> nMerk0;
220 				aPool << aStack << ocIntersect << nMerk0;
221 				aPool >> aStack;
222 				break;
223 			case 0x10: // Union									[314 265]
224 				// ocSep behelfsweise statt 'ocUnion'
225 				aStack >> nMerk0;
226 //#100928#      aPool << ocOpen << aStack << ocSep << nMerk0 << ocClose;
227                 aPool << aStack << ocSep << nMerk0;
228 					// doesn't fit exactly, but is more Excel-like
229 				aPool >> aStack;
230 				break;
231 			case 0x11: // Range									[314 265]
232 				aStack >> nMerk0;
233 				aPool << aStack << ocRange << nMerk0;
234 				aPool >> aStack;
235 				break;
236 			case 0x12: // Unary Plus							[312 264]
237                 aPool << ocAdd << aStack;
238                 aPool >> aStack;
239 				break;
240 			case 0x13: // Unary Minus							[312 264]
241 				aPool << ocNegSub << aStack;
242 				aPool >> aStack;
243 				break;
244 			case 0x14: // Percent Sign							[312 264]
245                 aPool << aStack << ocPercentSign;
246 				aPool >> aStack;
247 				break;
248 			case 0x15: // Parenthesis							[326 278]
249 				aPool << ocOpen << aStack << ocClose;
250 				aPool >> aStack;
251 				break;
252 			case 0x16: // Missing Argument						[314 266]
253 				aPool << ocMissing;
254 				aPool >> aStack;
255                 GetTracer().TraceFormulaMissingArg();
256 				break;
257 			case 0x17: // String Constant						[314 266]
258 				aIn >> nLen;		// und?
259                 aString = aIn.ReadUniString( nLen );            // reads Grbit even if nLen==0
260 
261 				aStack << aPool.Store( aString );
262 				break;
263 			case 0x18:											// natural language formula
264 				{
265 				sal_uInt8	nEptg;
266 				sal_uInt16	nCol, nRow;
267 				aIn >> nEptg;
268 				switch( nEptg )
269 				{							//	name		size	ext		type
270 					case 0x01:				//	Lel			4		-		err
271                         aIn.Ignore( 4 );
272                         aPool << ocBad;
273                         aPool >> aStack;
274                     break;
275 					case 0x02:				//	Rw			4		-		ref
276 					case 0x03:				//	Col			4		-		ref
277 					case 0x06:				//	RwV			4		-		val
278 					case 0x07:				//	ColV		4		-		val
279 						aIn >> nRow >> nCol;
280 
281                         aSRD.InitAddress( ScAddress( static_cast<SCCOL>(nCol & 0xFF), static_cast<SCROW>(nRow), aEingPos.Tab() ) );
282 
283 						if( nEptg == 0x02 || nEptg == 0x06 )
284 							aSRD.SetRowRel( sal_True );
285 						else
286 							aSRD.SetColRel( sal_True );
287 
288 						aSRD.CalcRelFromAbs( aEingPos );
289 
290 						aStack << aPool.StoreNlf( aSRD );
291 						break;
292 					case 0x0A:				//	Radical		13		-		ref
293 						aIn >> nRow >> nCol;
294                         aIn.Ignore( 9 );
295 
296                         aSRD.InitAddress( ScAddress( static_cast<SCCOL>(nCol & 0xFF), static_cast<SCROW>(nRow), aEingPos.Tab() ) );
297 
298 						aSRD.SetColRel( sal_True );
299 
300 						aSRD.CalcRelFromAbs( aEingPos );
301 
302 						aStack << aPool.StoreNlf( aSRD );
303 						break;
304 					case 0x0B:				//	RadicalS	13		x		ref
305                         aIn.Ignore( 13 );
306                         aExtensions.push_back( EXTENSION_NLR );
307                         aPool << ocBad;
308                         aPool >> aStack;
309                     break;
310 					case 0x0C:				//	RwS			4		x		ref
311                     case 0x0D:              //  ColS        4       x       ref
312                     case 0x0E:              //  RwSV        4       x       val
313                     case 0x0F:              //  ColSV       4       x       val
314                         aIn.Ignore( 4 );
315                         aExtensions.push_back( EXTENSION_NLR );
316                         aPool << ocBad;
317                         aPool >> aStack;
318                     break;
319 					case 0x10:				//	RadicalLel	4		-		err
320                     case 0x1D:              //  SxName      4       -       val
321                         aIn.Ignore( 4 );
322                         aPool << ocBad;
323                         aPool >> aStack;
324                     break;
325 					default:
326 						aPool << ocBad;
327 						aPool >> aStack;
328 				}
329 				}
330 				break;
331 			case 0x19: // Special Attribute						[327 279]
332 			{
333 				sal_uInt16 nData, nFakt;
334 				sal_uInt8 nOpt;
335 
336 				aIn >> nOpt >> nData;
337 				nFakt = 2;
338 
339 				if( nOpt & 0x04 )
340 				{// nFakt -> Bytes oder Words ueberlesen	AttrChoose
341 					nData++;
342                     aIn.Ignore( nData * nFakt );
343 				}
344 				else if( nOpt & 0x10 )						// AttrSum
345 					DoMulArgs( ocSum, 1 );
346 			}
347 				break;
348 			case 0x1C: // Error Value							[314 266]
349 			{
350 				aIn >> nByte;
351 #if 0   // erAck
352                 aPool.StoreError( XclTools::GetScErrorCode( nByte ) );
353 #else
354 				DefTokenId			eOc;
355 				switch( nByte )
356 				{
357                     case EXC_ERR_NULL:
358                     case EXC_ERR_DIV0:
359                     case EXC_ERR_VALUE:
360                     case EXC_ERR_REF:
361                     case EXC_ERR_NAME:
362                     case EXC_ERR_NUM:   eOc = ocStop;       break;
363                     case EXC_ERR_NA:    eOc = ocNotAvail;   break;
364                     default:            eOc = ocNoName;
365 				}
366 				aPool << eOc;
367 				if( eOc != ocStop )
368 					aPool << ocOpen << ocClose;
369 #endif
370 				aPool >> aStack;
371 			}
372 				break;
373 			case 0x1D: // Boolean								[315 266]
374 				aIn >> nByte;
375 				if( nByte == 0 )
376 					aPool << ocFalse << ocOpen << ocClose;
377 				else
378 					aPool << ocTrue << ocOpen << ocClose;
379 				aPool >> aStack;
380 				break;
381 			case 0x1E: // Integer								[315 266]
382 				aIn >> nUINT16;
383 				aStack << aPool.Store( ( double ) nUINT16 );
384 				break;
385 			case 0x1F: // Number								[315 266]
386 				aIn >> fDouble;
387 				aStack << aPool.Store( fDouble );
388 				break;
389 			case 0x40:
390 			case 0x60:
391             case 0x20: // Array Constant						[317 268]
392                 aIn >> nByte >> nUINT16;
393                 aIn.Ignore( 4 );
394                 if( bAllowArrays )
395                 {
396                     aStack << aPool.StoreMatrix();
397                     aExtensions.push_back( EXTENSION_ARRAY );
398                 }
399                 else
400                 {
401                     aPool << ocBad;
402                     aPool >> aStack;
403                 }
404                 break;
405 			case 0x41:
406 			case 0x61:
407 			case 0x21: // Function, Fixed Number of Arguments	[333 282]
408             {
409                 sal_uInt16 nXclFunc;
410                 aIn >> nXclFunc;
411                 if( const XclFunctionInfo* pFuncInfo = maFuncProv.GetFuncInfoFromXclFunc( nXclFunc ) )
412                     DoMulArgs( pFuncInfo->meOpCode, pFuncInfo->mnMaxParamCount );
413                 else
414                     DoMulArgs( ocNoName, 0 );
415             }
416             break;
417 			case 0x42:
418 			case 0x62:
419 			case 0x22: // Function, Variable Number of Arg.		[333 283]
420 			{
421                 sal_uInt16 nXclFunc;
422                 sal_uInt8 nParamCount;
423                 aIn >> nParamCount >> nXclFunc;
424                 nParamCount &= 0x7F;
425                 if( const XclFunctionInfo* pFuncInfo = maFuncProv.GetFuncInfoFromXclFunc( nXclFunc ) )
426                     DoMulArgs( pFuncInfo->meOpCode, nParamCount, pFuncInfo->mnMinParamCount );
427                 else
428                     DoMulArgs( ocNoName, 0 );
429 			}
430             break;
431 			case 0x43:
432 			case 0x63:
433 			case 0x23: // Name									[318 269]
434 				aIn >> nUINT16;
435 			{
436                 aIn.Ignore( 2 );
437 				//Determine if this is a user-defined Macro name.
438                 const XclImpName* pName = GetNameManager().GetName( nUINT16 );
439 				if(pName && !pName->GetScRangeData())
440 				    aStack << aPool.Store( ocMacro, pName->GetXclName() );
441 				else
442 				    aStack << aPool.Store( nUINT16 );
443 			}
444 			break;
445 			case 0x44:
446 			case 0x64:
447 			case 0x24: // Cell Reference						[319 270]
448 			case 0x4A:
449 			case 0x6A:
450 			case 0x2A: // Deleted Cell Reference				[323 273]
451 			{
452 				sal_uInt16			nCol, nRow;
453 
454 				aIn >> nRow >> nCol;
455 
456 				aSRD.nCol = static_cast<SCCOL>(nCol);
457 				aSRD.nRow = nRow & 0x3FFF;
458 				aSRD.nRelTab = 0;
459 				aSRD.SetTabRel( sal_True );
460 				aSRD.SetFlag3D( bRangeName );
461 
462                 ExcRelToScRel8( nRow, nCol, aSRD, bRangeName );
463 
464 				switch ( nOp )
465 				{
466 					case 0x4A:
467 					case 0x6A:
468 					case 0x2A: // Deleted Cell Reference	 	[323 273]
469 						// no information which part is deleted, set both
470 						aSRD.SetColDeleted( sal_True );
471 						aSRD.SetRowDeleted( sal_True );
472 				}
473 
474 				aStack << aPool.Store( aSRD );
475 			}
476 				break;
477 			case 0x45:
478 			case 0x65:
479 			case 0x25: // Area Reference						[320 270]
480 			case 0x4B:
481 			case 0x6B:
482 			case 0x2B: // Deleted Area Refernce					[323 273]
483 			{
484 				sal_uInt16			nRowFirst, nRowLast;
485 				sal_uInt16			nColFirst, nColLast;
486 				ScSingleRefData	&rSRef1 = aCRD.Ref1;
487 				ScSingleRefData	&rSRef2 = aCRD.Ref2;
488 
489 				aIn >> nRowFirst >> nRowLast >> nColFirst >> nColLast;
490 
491 				rSRef1.nRelTab = rSRef2.nRelTab = 0;
492 				rSRef1.SetTabRel( sal_True );
493 				rSRef2.SetTabRel( sal_True );
494 				rSRef1.SetFlag3D( bRangeName );
495 				rSRef2.SetFlag3D( bRangeName );
496 
497                 ExcRelToScRel8( nRowFirst, nColFirst, aCRD.Ref1, bRangeName );
498                 ExcRelToScRel8( nRowLast, nColLast, aCRD.Ref2, bRangeName );
499 
500 				if( IsComplColRange( nColFirst, nColLast ) )
501 					SetComplCol( aCRD );
502 				else if( IsComplRowRange( nRowFirst, nRowLast ) )
503 					SetComplRow( aCRD );
504 
505 				switch ( nOp )
506 				{
507 					case 0x4B:
508 					case 0x6B:
509 					case 0x2B: // Deleted Area Refernce			[323 273]
510 						// no information which part is deleted, set all
511 						rSRef1.SetColDeleted( sal_True );
512 						rSRef1.SetRowDeleted( sal_True );
513 						rSRef2.SetColDeleted( sal_True );
514 						rSRef2.SetRowDeleted( sal_True );
515 				}
516 
517 				aStack << aPool.Store( aCRD );
518 			}
519 				break;
520 			case 0x46:
521 			case 0x66:
522 			case 0x26: // Constant Reference Subexpression		[321 271]
523 				aExtensions.push_back( EXTENSION_MEMAREA );
524                 aIn.Ignore( 6 );       // mehr steht da nicht!
525 				break;
526 			case 0x47:
527 			case 0x67:
528 			case 0x27: // Erroneous Constant Reference Subexpr.	[322 272]
529                 aIn.Ignore( 6 );   // mehr steht da nicht!
530 //               aPool << ocBad;
531 //               aPool >> aStack;
532 				break;
533 			case 0x48:
534 			case 0x68:
535 			case 0x28: // Incomplete Constant Reference Subexpr.[331 281]
536                 aIn.Ignore( 6 );   // mehr steht da nicht!
537 //               aPool << ocBad;
538 //               aPool >> aStack;
539 				break;
540 			case 0x49:
541 			case 0x69:
542 			case 0x29: // Variable Reference Subexpression		[331 281]
543                 aIn.Ignore( 2 );   // mehr steht da nicht!
544 				break;
545 			case 0x4C:
546 			case 0x6C:
547 			case 0x2C: // Cell Reference Within a Name			[323    ]
548 					   // Cell Reference Within a Shared Formula[    273]
549 			{
550 				sal_uInt16		nRow, nCol;
551 
552 				aIn >> nRow >> nCol;
553 
554 				aSRD.nRelTab = 0;
555 				aSRD.SetTabRel( sal_True );
556 				aSRD.SetFlag3D( bRangeName );
557 
558                 ExcRelToScRel8( nRow, nCol, aSRD, bRNorSF );
559 
560 				aStack << aPool.Store( aSRD );
561 			}
562 				break;
563 			case 0x4D:
564 			case 0x6D:
565 			case 0x2D: // Area Reference Within a Name			[324    ]
566 			{	   // Area Reference Within a Shared Formula[    274]
567 				sal_uInt16					nRowFirst, nRowLast;
568 				sal_uInt16					nColFirst, nColLast;
569 
570 				aCRD.Ref1.nRelTab = aCRD.Ref2.nRelTab = 0;
571 				aCRD.Ref1.SetTabRel( sal_True );
572 				aCRD.Ref2.SetTabRel( sal_True );
573 				aCRD.Ref1.SetFlag3D( bRangeName );
574 				aCRD.Ref2.SetFlag3D( bRangeName );
575 
576 				aIn >> nRowFirst >> nRowLast >> nColFirst >> nColLast;
577 
578                 ExcRelToScRel8( nRowFirst, nColFirst, aCRD.Ref1, bRNorSF );
579                 ExcRelToScRel8( nRowLast, nColLast, aCRD.Ref2, bRNorSF );
580 
581 				if( IsComplColRange( nColFirst, nColLast ) )
582 					SetComplCol( aCRD );
583 				else if( IsComplRowRange( nRowFirst, nRowLast ) )
584 					SetComplRow( aCRD );
585 
586 				aStack << aPool.Store( aCRD );
587 			}
588 				break;
589 			case 0x4E:
590 			case 0x6E:
591 			case 0x2E: // Reference Subexpression Within a Name	[332 282]
592                 aIn.Ignore( 2 );   // mehr steht da nicht!
593 //               aPool << ocBad;
594 //               aPool >> aStack;
595 				break;
596 			case 0x4F:
597 			case 0x6F:
598 			case 0x2F: // Incomplete Reference Subexpression...	[332 282]
599                 aIn.Ignore( 2 );   // mehr steht da nicht!
600 //               aPool << ocBad;
601 //               aPool >> aStack;
602 				break;
603 			case 0x58:
604 			case 0x78:
605 			case 0x38: // Command-Equivalent Function			[333    ]
606 				aString.AssignAscii( "COMM_EQU_FUNC" );
607 				aIn >> nByte;
608 				aString += String::CreateFromInt32( nByte );
609 				aIn >> nByte;
610 				aStack << aPool.Store( aString );
611 				DoMulArgs( ocPush, nByte + 1 );
612 				break;
613 			case 0x59:
614 			case 0x79:
615 			case 0x39: // Name or External Name					[    275]
616             {
617                 sal_uInt16 nXtiIndex, nNameIdx;
618                 aIn >> nXtiIndex >> nNameIdx;
619                 aIn.Ignore( 2 );
620 
621                 if( rLinkMan.IsSelfRef( nXtiIndex ) )
622                 {
623                     // internal defined name with explicit sheet, i.e.: =Sheet1!AnyName
624                     const XclImpName* pName = GetNameManager().GetName( nNameIdx );
625                     if( pName && !pName->GetScRangeData() )
626                         aStack << aPool.Store( ocMacro, pName->GetXclName() );
627                     else
628                         aStack << aPool.Store( nNameIdx );
629                 }
630                 else if( const XclImpExtName* pExtName = rLinkMan.GetExternName( nXtiIndex, nNameIdx ) )
631                 {
632                     switch( pExtName->GetType() )
633                     {
634                         case xlExtName:
635                         {
636                             /* FIXME: enable this code for #i4385# once
637                              * external name reference can be stored in ODF,
638                              * which remains to be done for #i3740#. Until then
639                              * create a #NAME? token. */
640 #if 0
641                             sal_uInt16 nFileId;
642                             if (!GetExternalFileIdFromXti(nXtiIndex, nFileId) || !pExtName->HasFormulaTokens())
643                             {
644                                 aStack << aPool.Store(ocNoName, pExtName->GetName());
645                                 break;
646                             }
647 
648                             aStack << aPool.StoreExtName(nFileId, pExtName->GetName());
649                             pExtName->CreateExtNameData(GetDoc(), nFileId);
650 #else
651                             aStack << aPool.Store( ocNoName, pExtName->GetName() );
652 #endif
653                         }
654                         break;
655 
656                         case xlExtAddIn:
657                         {
658                             aStack << aPool.Store( ocExternal, pExtName->GetName() );
659                         }
660                         break;
661 
662                         case xlExtDDE:
663                         {
664                             String aApplic, aTopic;
665                             if( rLinkMan.GetLinkData( aApplic, aTopic, nXtiIndex ) )
666                             {
667                                 TokenId nPar1 = aPool.Store( aApplic );
668                                 TokenId nPar2 = aPool.Store( aTopic );
669                                 nMerk0 = aPool.Store( pExtName->GetName() );
670                                 aPool   << ocDde << ocOpen << nPar1 << ocSep << nPar2 << ocSep
671                                         << nMerk0 << ocClose;
672                                 aPool >> aStack;
673                                 pExtName->CreateDdeData( GetDoc(), aApplic, aTopic );
674                             }
675                         }
676                         break;
677 
678                         case xlExtEuroConvert:
679                             {
680                                 aStack << aPool.Store( ocEuroConvert, String() );
681                             }
682                         break;
683 
684                         default:    // OLE link
685                         {
686                             aPool << ocBad;
687                             aPool >> aStack;
688                         }
689                     }
690                 }
691                 else
692                 {
693                     //aStack << ocNoName;
694                     aPool << ocBad;
695                     aPool >> aStack;
696                 }
697             }
698                 break;
699 			case 0x5A:
700 			case 0x7A:
701 			case 0x3A: // 3-D Cell Reference					[    275]
702 			case 0x5C:
703 			case 0x7C:
704 			case 0x3C: // Deleted 3-D Cell Reference			[    277]
705 			{
706 				sal_uInt16 nIxti, nRw, nGrbitCol;
707 				SCTAB nTabFirst, nTabLast;
708 
709                 aIn >> nIxti >> nRw >> nGrbitCol;
710 
711                 ExternalTabInfo aExtInfo;
712                 if (!Read3DTabReference(nIxti, nTabFirst, nTabLast, aExtInfo))
713                 {
714                     aPool << ocBad;
715                     aPool >> aStack;
716                     break;
717                 }
718 
719                 aSRD.nTab = nTabFirst;
720                 aSRD.SetFlag3D( sal_True );
721                 aSRD.SetTabRel( sal_False );
722 
723                 ExcRelToScRel8( nRw, nGrbitCol, aSRD, bRangeName );
724 
725                 switch ( nOp )
726                 {
727                     case 0x5C:
728                     case 0x7C:
729                     case 0x3C: // Deleted 3-D Cell Reference	[    277]
730                         // no information which part is deleted, set both
731                         aSRD.SetColDeleted( sal_True );
732                         aSRD.SetRowDeleted( sal_True );
733                 }
734 
735                 if (aExtInfo.mbExternal)
736                 {
737                     // nTabFirst and nTabLast are the indices of the refernced
738                     // sheets in the SUPBOOK record, hence do not represent
739                     // the actual indices of the original sheets since the
740                     // SUPBOOK record only stores referenced sheets and skips
741                     // the ones that are not referenced.
742 
743                     if (nTabLast != nTabFirst)
744                     {
745                         aCRD.Ref1 = aCRD.Ref2 = aSRD;
746                         aCRD.Ref2.nTab = nTabLast;
747                         aStack << aPool.StoreExtRef(aExtInfo.mnFileId, aExtInfo.maTabName, aCRD);
748                     }
749                     else
750                         aStack << aPool.StoreExtRef(aExtInfo.mnFileId, aExtInfo.maTabName, aSRD);
751                 }
752                 else
753                 {
754                     if ( !ValidTab(nTabFirst))
755                         aSRD.SetTabDeleted( sal_True );
756 
757                     if( nTabLast != nTabFirst )
758                     {
759                         aCRD.Ref1 = aCRD.Ref2 = aSRD;
760                         aCRD.Ref2.nTab = nTabLast;
761                         aCRD.Ref2.SetTabDeleted( !ValidTab(nTabLast) );
762                         aStack << aPool.Store( aCRD );
763                     }
764                     else
765                         aStack << aPool.Store( aSRD );
766                 }
767 			}
768 				break;
769 			case 0x5B:
770 			case 0x7B:
771 			case 0x3B: // 3-D Area Reference					[    276]
772 			case 0x5D:
773 			case 0x7D:
774 			case 0x3D: // Deleted 3-D Area Reference			[    277]
775 			{
776 				sal_uInt16 nIxti, nRw1, nGrbitCol1, nRw2, nGrbitCol2;
777 				SCTAB nTabFirst, nTabLast;
778 				aIn >> nIxti >> nRw1 >> nRw2 >> nGrbitCol1 >> nGrbitCol2;
779 
780                 ExternalTabInfo aExtInfo;
781                 if (!Read3DTabReference(nIxti, nTabFirst, nTabLast, aExtInfo))
782 				{
783 					aPool << ocBad;
784 					aPool >> aStack;
785                     break;
786 				}
787 				ScSingleRefData	&rR1 = aCRD.Ref1;
788 				ScSingleRefData	&rR2 = aCRD.Ref2;
789 
790 
791                 rR1.nTab = nTabFirst;
792                 rR2.nTab = nTabLast;
793                 rR1.SetFlag3D( sal_True );
794                 rR1.SetTabRel( sal_False );
795                 rR2.SetFlag3D( nTabFirst != nTabLast );
796                 rR2.SetTabRel( sal_False );
797 
798                 ExcRelToScRel8( nRw1, nGrbitCol1, aCRD.Ref1, bRangeName );
799                 ExcRelToScRel8( nRw2, nGrbitCol2, aCRD.Ref2, bRangeName );
800 
801                 if( IsComplColRange( nGrbitCol1, nGrbitCol2 ) )
802                     SetComplCol( aCRD );
803                 else if( IsComplRowRange( nRw1, nRw2 ) )
804                     SetComplRow( aCRD );
805 
806                 switch ( nOp )
807                 {
808                     case 0x5D:
809                     case 0x7D:
810                     case 0x3D: // Deleted 3-D Area Reference	[    277]
811                         // no information which part is deleted, set all
812                         rR1.SetColDeleted( sal_True );
813                         rR1.SetRowDeleted( sal_True );
814                         rR2.SetColDeleted( sal_True );
815                         rR2.SetRowDeleted( sal_True );
816                 }
817 
818                 if (aExtInfo.mbExternal)
819                 {
820                     aStack << aPool.StoreExtRef(aExtInfo.mnFileId, aExtInfo.maTabName, aCRD);
821                 }
822                 else
823                 {
824                     if ( !ValidTab(nTabFirst) )
825                         rR1.SetTabDeleted( sal_True );
826                     if ( !ValidTab(nTabLast) )
827                         rR2.SetTabDeleted( sal_True );
828 
829                     aStack << aPool.Store( aCRD );
830                 }
831 			}
832 				break;
833 			default: bError = sal_True;
834 		}
835 		bError |= !aIn.IsValid();
836 	}
837 
838 	ConvErr eRet;
839 
840 	if( bError )
841 	{
842 		aPool << ocBad;
843 		aPool >> aStack;
844 		rpTokArray = aPool[ aStack.Get() ];
845 		eRet = ConvErrNi;
846 	}
847     else if( aIn.GetRecPos() != nEndPos )
848 	{
849 		aPool << ocBad;
850 		aPool >> aStack;
851 		rpTokArray = aPool[ aStack.Get() ];
852 		eRet = ConvErrCount;
853 	}
854 	else if( bArrayFormula )
855 	{
856 		rpTokArray = NULL;
857 		eRet = ConvOK;
858 	}
859 	else
860 	{
861 		rpTokArray = aPool[ aStack.Get() ];
862 		eRet = ConvOK;
863 	}
864 
865     aIn.Seek( nEndPos );
866 
867 	if( eRet == ConvOK)
868 		ReadExtensions( aExtensions, aIn );
869 
870 	return eRet;
871 }
872 
873 
874 // stream seeks to first byte after <nFormulaLen>
Convert(_ScRangeListTabs & rRangeList,XclImpStream & aIn,sal_Size nFormulaLen,const FORMULA_TYPE eFT)875 ConvErr ExcelToSc8::Convert( _ScRangeListTabs& rRangeList, XclImpStream& aIn, sal_Size nFormulaLen, const FORMULA_TYPE eFT )
876 {
877 	sal_uInt8					nOp, nLen;//, nByte;
878 	sal_Bool					bError = sal_False;
879 	sal_Bool					bArrayFormula = sal_False;
880 	const sal_Bool				bRangeName = eFT == FT_RangeName;
881 	const sal_Bool				bSharedFormula = eFT == FT_SharedFormula;
882 	const sal_Bool				bRNorSF = bRangeName || bSharedFormula;
883 
884 	ScSingleRefData			aSRD;
885 	ScComplexRefData			aCRD;
886 
887 	bExternName = sal_False;
888 
889 	if( eStatus != ConvOK )
890 	{
891         aIn.Ignore( nFormulaLen );
892 		return eStatus;
893 	}
894 
895 	if( nFormulaLen == 0 )
896 		return ConvOK;
897 
898     sal_Size nEndPos = aIn.GetRecPos() + nFormulaLen;
899 
900     while( (aIn.GetRecPos() < nEndPos) && !bError )
901 	{
902 		aIn >> nOp;
903 
904         // #98524# always reset flags
905         aSRD.InitFlags();
906         aCRD.InitFlags();
907 
908 		switch( nOp )	//								Buch Seite:
909 		{			//										SDK4 SDK5
910 			case 0x01: // Array Formula							[325    ]
911 					   // Array Formula or Shared Formula		[    277]
912                 aIn.Ignore( 4 );
913 
914 				bArrayFormula = sal_True;
915 				break;
916 			case 0x02: // Data Table							[325 277]
917                 aIn.Ignore( 4 );
918 				break;
919 			case 0x03: // Addition								[312 264]
920 			case 0x04: // Subtraction							[313 264]
921 			case 0x05: // Multiplication						[313 264]
922 			case 0x06: // Division								[313 264]
923 			case 0x07: // Exponetiation							[313 265]
924 			case 0x08: // Concatenation							[313 265]
925 			case 0x09: // Less Than								[313 265]
926 			case 0x0A: // Less Than or Equal					[313 265]
927 			case 0x0B: // Equal									[313 265]
928 			case 0x0C: // Greater Than or Equal					[313 265]
929 			case 0x0D: // Greater Than							[313 265]
930 			case 0x0E: // Not Equal								[313 265]
931 			case 0x0F: // Intersection							[314 265]
932 			case 0x10: // Union									[314 265]
933 			case 0x11: // Range									[314 265]
934 			case 0x12: // Unary Plus							[312 264]
935 			case 0x13: // Unary Minus							[312 264]
936 			case 0x14: // Percent Sign							[312 264]
937 			case 0x15: // Parenthesis							[326 278]
938 			case 0x16: // Missing Argument						[314 266]
939 				break;
940 			case 0x17: // String Constant						[314 266]
941 				aIn >> nLen;		// und?
942 
943 				aIn.IgnoreUniString( nLen );		// reads Grbit even if nLen==0
944 				break;
945 			case 0x19: // Special Attribute						[327 279]
946 			{
947 				sal_uInt16 nData, nFakt;
948 				sal_uInt8 nOpt;
949 
950 				aIn >> nOpt >> nData;
951 				nFakt = 2;
952 
953 				if( nOpt & 0x04 )
954 				{// nFakt -> Bytes oder Words ueberlesen	AttrChoose
955 					nData++;
956                     aIn.Ignore( nData * nFakt );
957 				}
958 			}
959 				break;
960 			case 0x1C: // Error Value							[314 266]
961 			case 0x1D: // Boolean								[315 266]
962                 aIn.Ignore( 1 );
963 				break;
964 			case 0x1E: // Integer								[315 266]
965                 aIn.Ignore( 2 );
966 				break;
967 			case 0x1F: // Number								[315 266]
968                 aIn.Ignore( 8 );
969 				break;
970 			case 0x40:
971 			case 0x60:
972 			case 0x20: // Array Constant						[317 268]
973                 aIn.Ignore( 7 );
974 				break;
975 			case 0x41:
976 			case 0x61:
977 			case 0x21: // Function, Fixed Number of Arguments	[333 282]
978                 aIn.Ignore( 2 );
979 				break;
980 			case 0x42:
981 			case 0x62:
982 			case 0x22: // Function, Variable Number of Arg.		[333 283]
983                 aIn.Ignore( 3 );
984 				break;
985 			case 0x43:
986 			case 0x63:
987 			case 0x23: // Name									[318 269]
988                 aIn.Ignore( 4 );
989 				break;
990 			case 0x44:
991 			case 0x64:
992 			case 0x24: // Cell Reference						[319 270]
993 			{
994 				sal_uInt16			nCol, nRow;
995 
996 				aIn >> nRow >> nCol;
997 
998 				aSRD.nCol = static_cast<SCCOL>(nCol);
999 				aSRD.nRow = nRow & 0x3FFF;
1000 				aSRD.nRelTab = 0;
1001 				aSRD.SetTabRel( sal_True );
1002 				aSRD.SetFlag3D( bRangeName );
1003 
1004                 ExcRelToScRel8( nRow, nCol, aSRD, bRangeName );
1005 
1006 				rRangeList.Append( aSRD );
1007 			}
1008 				break;
1009 			case 0x45:
1010 			case 0x65:
1011 			case 0x25: // Area Reference						[320 270]
1012 			{
1013 				sal_uInt16			nRowFirst, nRowLast;
1014 				sal_uInt16			nColFirst, nColLast;
1015 				ScSingleRefData	&rSRef1 = aCRD.Ref1;
1016 				ScSingleRefData	&rSRef2 = aCRD.Ref2;
1017 
1018 				aIn >> nRowFirst >> nRowLast >> nColFirst >> nColLast;
1019 
1020 				rSRef1.nRelTab = rSRef2.nRelTab = 0;
1021 				rSRef1.SetTabRel( sal_True );
1022 				rSRef2.SetTabRel( sal_True );
1023 				rSRef1.SetFlag3D( bRangeName );
1024 				rSRef2.SetFlag3D( bRangeName );
1025 
1026                 ExcRelToScRel8( nRowFirst, nColFirst, aCRD.Ref1, bRangeName );
1027                 ExcRelToScRel8( nRowLast, nColLast, aCRD.Ref2, bRangeName );
1028 
1029 				if( IsComplColRange( nColFirst, nColLast ) )
1030 					SetComplCol( aCRD );
1031 				else if( IsComplRowRange( nRowFirst, nRowLast ) )
1032 					SetComplRow( aCRD );
1033 
1034 				rRangeList.Append( aCRD );
1035 			}
1036 				break;
1037 			case 0x46:
1038 			case 0x66:
1039 			case 0x26: // Constant Reference Subexpression		[321 271]
1040 			case 0x47:
1041 			case 0x67:
1042 			case 0x27: // Erroneous Constant Reference Subexpr.	[322 272]
1043 			case 0x48:
1044 			case 0x68:
1045 			case 0x28: // Incomplete Constant Reference Subexpr.[331 281]
1046                 aIn.Ignore( 6 );   // mehr steht da nicht!
1047 				break;
1048 			case 0x49:
1049 			case 0x69:
1050 			case 0x29: // Variable Reference Subexpression		[331 281]
1051                 aIn.Ignore( 2 );   // mehr steht da nicht!
1052 				break;
1053 			case 0x4A:
1054 			case 0x6A:
1055 			case 0x2A: // Deleted Cell Reference				[323 273]
1056                 aIn.Ignore( 3 );
1057 				break;
1058 			case 0x4B:
1059 			case 0x6B:
1060 			case 0x2B: // Deleted Area Refernce					[323 273]
1061                 aIn.Ignore( 6 );
1062 				break;
1063 			case 0x4C:
1064 			case 0x6C:
1065 			case 0x2C: // Cell Reference Within a Name			[323    ]
1066 					   // Cell Reference Within a Shared Formula[    273]
1067 			{
1068 				sal_uInt16		nRow, nCol;
1069 
1070 				aIn >> nRow >> nCol;
1071 
1072 				aSRD.nRelTab = 0;
1073 				aSRD.SetTabRel( sal_True );
1074 				aSRD.SetFlag3D( bRangeName );
1075 
1076                 ExcRelToScRel8( nRow, nCol, aSRD, bRNorSF );
1077 
1078 				rRangeList.Append( aSRD );
1079 			}
1080 				break;
1081 			case 0x4D:
1082 			case 0x6D:
1083 			case 0x2D: // Area Reference Within a Name			[324    ]
1084 			{	   // Area Reference Within a Shared Formula[    274]
1085 				sal_uInt16					nRowFirst, nRowLast;
1086 				sal_uInt16					nColFirst, nColLast;
1087 
1088 				aCRD.Ref1.nRelTab = aCRD.Ref2.nRelTab = 0;
1089 				aCRD.Ref1.SetTabRel( sal_True );
1090 				aCRD.Ref2.SetTabRel( sal_True );
1091 				aCRD.Ref1.SetFlag3D( bRangeName );
1092 				aCRD.Ref2.SetFlag3D( bRangeName );
1093 
1094 				aIn >> nRowFirst >> nRowLast >> nColFirst >> nColLast;
1095 
1096                 ExcRelToScRel8( nRowFirst, nColFirst, aCRD.Ref1, bRNorSF );
1097                 ExcRelToScRel8( nRowLast, nColLast, aCRD.Ref2, bRNorSF );
1098 
1099 				if( IsComplColRange( nColFirst, nColLast ) )
1100 					SetComplCol( aCRD );
1101 				else if( IsComplRowRange( nRowFirst, nRowLast ) )
1102 					SetComplRow( aCRD );
1103 
1104 				rRangeList.Append( aCRD );
1105 			}
1106 				break;
1107 			case 0x4E:
1108 			case 0x6E:
1109 			case 0x2E: // Reference Subexpression Within a Name	[332 282]
1110 			case 0x4F:
1111 			case 0x6F:
1112 			case 0x2F: // Incomplete Reference Subexpression...	[332 282]
1113 			case 0x58:
1114 			case 0x78:
1115 			case 0x38: // Command-Equivalent Function			[333    ]
1116                 aIn.Ignore( 2 );
1117 				break;
1118 			case 0x59:
1119 			case 0x79:
1120 			case 0x39: // Name or External Name					[    275]
1121                 aIn.Ignore( 24 );
1122 				break;
1123 			case 0x5A:
1124 			case 0x7A:
1125 			case 0x3A: // 3-D Cell Reference					[    275]
1126 			{
1127 				sal_uInt16			nIxti, nRw, nGrbitCol;
1128 
1129 				aIn >> nIxti >> nRw >> nGrbitCol;
1130 
1131                 SCTAB nFirstScTab, nLastScTab;
1132                 if( rLinkMan.GetScTabRange( nFirstScTab, nLastScTab, nIxti ) )
1133                 {
1134                     aSRD.nTab = nFirstScTab;
1135                     aSRD.SetFlag3D( sal_True );
1136 					aSRD.SetTabRel( sal_False );
1137 
1138                     ExcRelToScRel8( nRw, nGrbitCol, aSRD, bRangeName );
1139 
1140                     if( nFirstScTab != nLastScTab )
1141 					{
1142 						aCRD.Ref1 = aSRD;
1143 						aCRD.Ref2.nCol = aSRD.nCol;
1144 						aCRD.Ref2.nRow = aSRD.nRow;
1145                         aCRD.Ref2.nTab = nLastScTab;
1146 						rRangeList.Append( aCRD );
1147 					}
1148 					else
1149 						rRangeList.Append( aSRD );
1150 				}
1151 			}
1152 				break;
1153 			case 0x5B:
1154 			case 0x7B:
1155 			case 0x3B: // 3-D Area Reference					[    276]
1156 			{
1157 				sal_uInt16			nIxti, nRw1, nGrbitCol1, nRw2, nGrbitCol2;
1158 
1159 				aIn >> nIxti >> nRw1 >> nRw2 >> nGrbitCol1 >> nGrbitCol2;
1160 
1161                 SCTAB nFirstScTab, nLastScTab;
1162                 if( rLinkMan.GetScTabRange( nFirstScTab, nLastScTab, nIxti ) )
1163 				{
1164 					ScSingleRefData	&rR1 = aCRD.Ref1;
1165 					ScSingleRefData	&rR2 = aCRD.Ref2;
1166 
1167                     rR1.nTab = nFirstScTab;
1168                     rR2.nTab = nLastScTab;
1169                     rR1.SetFlag3D( sal_True );
1170 					rR1.SetTabRel( sal_False );
1171                     rR2.SetFlag3D( nFirstScTab != nLastScTab );
1172 					rR2.SetTabRel( sal_False );
1173 
1174                     ExcRelToScRel8( nRw1, nGrbitCol1, aCRD.Ref1, bRangeName );
1175                     ExcRelToScRel8( nRw2, nGrbitCol2, aCRD.Ref2, bRangeName );
1176 
1177 					if( IsComplColRange( nGrbitCol1, nGrbitCol2 ) )
1178 						SetComplCol( aCRD );
1179 					else if( IsComplRowRange( nRw1, nRw2 ) )
1180 						SetComplRow( aCRD );
1181 
1182 					rRangeList.Append( aCRD );
1183 				}
1184 			}
1185 				break;
1186 			case 0x5C:
1187 			case 0x7C:
1188 			case 0x3C: // Deleted 3-D Cell Reference			[    277]
1189                 aIn.Ignore( 6 );
1190 				break;
1191 			case 0x5D:
1192 			case 0x7D:
1193 			case 0x3D: // Deleted 3-D Area Reference			[    277]
1194                 aIn.Ignore( 10 );
1195 				break;
1196 			default:
1197 				bError = sal_True;
1198 		}
1199 		bError |= !aIn.IsValid();
1200 	}
1201 
1202 	ConvErr eRet;
1203 
1204 	if( bError )
1205 		eRet = ConvErrNi;
1206     else if( aIn.GetRecPos() != nEndPos )
1207 		eRet = ConvErrCount;
1208 	else if( bExternName )
1209 		eRet = ConvErrExternal;
1210 	else
1211 		eRet = ConvOK;
1212 
1213     aIn.Seek( nEndPos );
1214 	return eRet;
1215 }
1216 
ConvertExternName(const ScTokenArray * & rpArray,XclImpStream & rStrm,sal_Size nFormulaLen,const String & rUrl,const vector<String> & rTabNames)1217 ConvErr ExcelToSc8::ConvertExternName( const ScTokenArray*& rpArray, XclImpStream& rStrm, sal_Size nFormulaLen,
1218                                        const String& rUrl, const vector<String>& rTabNames )
1219 {
1220     if( !GetDocShell() )
1221         return ConvErrNi;
1222 
1223     String aFileUrl = ScGlobal::GetAbsDocName(rUrl, GetDocShell());
1224 
1225     sal_uInt8               nOp, nByte;
1226     bool                    bError = false;
1227 
1228     ScSingleRefData           aSRD;
1229     ScComplexRefData            aCRD;
1230 
1231     if (eStatus != ConvOK)
1232     {
1233         rStrm.Ignore(nFormulaLen);
1234         return eStatus;
1235     }
1236 
1237     if (nFormulaLen == 0)
1238     {
1239         aPool.Store(CREATE_STRING("-/-"));
1240         aPool >> aStack;
1241         rpArray = aPool[aStack.Get()];
1242         return ConvOK;
1243     }
1244 
1245     ScExternalRefManager* pRefMgr = GetDoc().GetExternalRefManager();
1246     sal_uInt16 nFileId = pRefMgr->getExternalFileId(aFileUrl);
1247     sal_uInt16 nTabCount = static_cast< sal_uInt16 >( rTabNames.size() );
1248 
1249     sal_Size nEndPos = rStrm.GetRecPos() + nFormulaLen;
1250 
1251     // #123870# Init members, they are on random values and not all will beinitialized in all cases below
1252     aSRD.InitMembers();
1253     aCRD.InitMembers();
1254 
1255     while( (rStrm.GetRecPos() < nEndPos) && !bError )
1256     {
1257         rStrm >> nOp;
1258 
1259         // #98524# always reset flags
1260         aSRD.InitFlags();
1261         aCRD.InitFlags();
1262 
1263         switch( nOp )
1264         {
1265             case 0x1C: // Error Value
1266             {
1267                 rStrm >> nByte;
1268                 DefTokenId eOc;
1269                 switch( nByte )
1270                 {
1271                     case EXC_ERR_NULL:
1272                     case EXC_ERR_DIV0:
1273                     case EXC_ERR_VALUE:
1274                     case EXC_ERR_REF:
1275                     case EXC_ERR_NAME:
1276                     case EXC_ERR_NUM:   eOc = ocStop;       break;
1277                     case EXC_ERR_NA:    eOc = ocNotAvail;   break;
1278                     default:            eOc = ocNoName;
1279                 }
1280                 aPool << eOc;
1281                 if( eOc != ocStop )
1282                     aPool << ocOpen << ocClose;
1283                 aPool >> aStack;
1284             }
1285             break;
1286             case 0x3A:
1287             {
1288                 // cell reference in external range name
1289                 sal_uInt16 nExtTab1, nExtTab2, nRow, nGrbitCol;
1290                 rStrm >> nExtTab1 >> nExtTab2 >> nRow >> nGrbitCol;
1291                 if (nExtTab1 >= nTabCount || nExtTab2 >= nTabCount)
1292                 {
1293                     bError = true;
1294                     break;
1295                 }
1296 
1297                 aSRD.nTab = nExtTab1;
1298                 aSRD.SetFlag3D(true);
1299                 aSRD.SetTabRel(false);
1300                 ExcRelToScRel8(nRow, nGrbitCol, aSRD, true);
1301                 aCRD.Ref1 = aCRD.Ref2 = aSRD;
1302                 String aTabName = rTabNames[nExtTab1];
1303 
1304                 if (nExtTab1 == nExtTab2)
1305                 {
1306                     // single cell reference
1307                     aStack << aPool.StoreExtRef(nFileId, aTabName, aSRD);
1308                 }
1309                 else
1310                 {
1311                     // area reference
1312                     aCRD.Ref2.nTab = nExtTab2;
1313                     aStack << aPool.StoreExtRef(nFileId, aTabName, aCRD);
1314                 }
1315             }
1316             break;
1317             case 0x3B:
1318             {
1319                 // area reference
1320 				sal_uInt16 nExtTab1, nExtTab2, nRow1, nRow2, nGrbitCol1, nGrbitCol2;
1321 				rStrm >> nExtTab1 >> nExtTab2 >> nRow1 >> nRow2 >> nGrbitCol1 >> nGrbitCol2;
1322                 ScSingleRefData& rR1 = aCRD.Ref1;
1323                 ScSingleRefData& rR2 = aCRD.Ref2;
1324 
1325                 rR1.nTab = nExtTab1;
1326                 rR1.SetFlag3D(true);
1327                 rR1.SetTabRel(false);
1328                 ExcRelToScRel8(nRow1, nGrbitCol1, rR1, true);
1329 
1330                 rR2.nTab = nExtTab2;
1331                 rR2.SetFlag3D(true);
1332                 rR2.SetTabRel(false);
1333                 ExcRelToScRel8(nRow2, nGrbitCol2, rR2, true);
1334 
1335                 String aTabName = rTabNames[nExtTab1];
1336                 aStack << aPool.StoreExtRef(nFileId, aTabName, aCRD);
1337             }
1338             break;
1339             default:
1340                 bError = true;
1341         }
1342         bError |= !rStrm.IsValid();
1343     }
1344 
1345     ConvErr eRet;
1346 
1347     if( bError )
1348     {
1349         aPool << ocBad;
1350         aPool >> aStack;
1351         rpArray = aPool[ aStack.Get() ];
1352         eRet = ConvErrNi;
1353     }
1354     else if( rStrm.GetRecPos() != nEndPos )
1355     {
1356         aPool << ocBad;
1357         aPool >> aStack;
1358         rpArray = aPool[ aStack.Get() ];
1359         eRet = ConvErrCount;
1360     }
1361     else
1362     {
1363         rpArray = aPool[ aStack.Get() ];
1364         eRet = ConvOK;
1365     }
1366 
1367     rStrm.Seek(nEndPos);
1368     return eRet;
1369 }
1370 
ExcRelToScRel8(sal_uInt16 nRow,sal_uInt16 nC,ScSingleRefData & rSRD,const sal_Bool bName)1371 void ExcelToSc8::ExcRelToScRel8( sal_uInt16 nRow, sal_uInt16 nC, ScSingleRefData &rSRD, const sal_Bool bName )
1372 {
1373 	const sal_Bool		bColRel = ( nC & 0x4000 ) != 0;
1374 	const sal_Bool		bRowRel = ( nC & 0x8000 ) != 0;
1375 	const sal_uInt8		nCol = static_cast<sal_uInt8>(nC);
1376 
1377 	rSRD.SetColRel( bColRel );
1378 	rSRD.SetRowRel( bRowRel );
1379 
1380 	if( bName )
1381 	{
1382 		// C O L
1383 		if( bColRel )
1384 			//															rel Col
1385 			rSRD.nRelCol = static_cast<SCsCOL>(static_cast<sal_Int8>(nC));
1386 		else
1387 			//															abs Col
1388 			rSRD.nCol = static_cast<SCCOL>(nCol);
1389 
1390 		// R O W
1391 		if( bRowRel )
1392 			//															rel Row
1393 			rSRD.nRelRow = static_cast<SCsROW>(static_cast<sal_Int16>(nRow));
1394 		else
1395 			//															abs Row
1396             rSRD.nRow = Min( static_cast<SCROW>(nRow), MAXROW);
1397 
1398 		// T A B
1399 		// #67965# abs needed if rel in shared formula for ScCompiler UpdateNameReference
1400 		if ( rSRD.IsTabRel() && !rSRD.IsFlag3D() )
1401             rSRD.nTab = GetCurrScTab();
1402 	}
1403 	else
1404 	{
1405 		// C O L
1406 		if ( bColRel )
1407 			rSRD.nRelCol = static_cast<SCsCOL>(nCol) - aEingPos.Col();
1408 		else
1409 			rSRD.nCol = static_cast<SCCOL>(nCol);
1410 
1411 		// R O W
1412 		if ( bRowRel )
1413 			rSRD.nRelRow = static_cast<SCsROW>(nRow) - aEingPos.Row();
1414 		else
1415 			rSRD.nRow = static_cast<SCROW>(nRow);
1416 
1417         // T A B
1418         // #i10184# abs needed if rel in shared formula for ScCompiler UpdateNameReference
1419         if ( rSRD.IsTabRel() && !rSRD.IsFlag3D() )
1420             rSRD.nTab = GetCurrScTab() + rSRD.nRelTab;
1421 	}
1422 }
1423 
1424 
1425 // stream seeks to first byte after <nLen>
GetAbsRefs(ScRangeList & r,XclImpStream & aIn,sal_Size nLen)1426 sal_Bool ExcelToSc8::GetAbsRefs( ScRangeList& r, XclImpStream& aIn, sal_Size nLen )
1427 {
1428 	sal_uInt8					nOp;
1429 	sal_uInt16					nRow1, nRow2, nCol1, nCol2;
1430 	SCTAB                                   nTab1, nTab2;
1431 	sal_uInt16					nIxti;
1432 
1433     sal_Size nSeek;
1434 
1435     sal_Size nEndPos = aIn.GetRecPos() + nLen;
1436 
1437     while( aIn.IsValid() && (aIn.GetRecPos() < nEndPos) )
1438 	{
1439 		aIn >> nOp;
1440 		nSeek = 0;
1441 
1442 		switch( nOp )
1443 		{
1444 			case 0x44:
1445 			case 0x64:
1446 			case 0x24: // Cell Reference						[319 270]
1447 			case 0x4C:
1448 			case 0x6C:
1449 			case 0x2C: // Cell Reference Within a Name			[323    ]
1450 					   // Cell Reference Within a Shared Formula[    273]
1451 				aIn >> nRow1 >> nCol1;
1452 
1453 				nRow2 = nRow1;
1454 				nCol2 = nCol1;
1455                 nTab1 = nTab2 = GetCurrScTab();
1456 				goto _common;
1457 			case 0x45:
1458 			case 0x65:
1459 			case 0x25: // Area Reference						[320 270]
1460 			case 0x4D:
1461 			case 0x6D:
1462 			case 0x2D: // Area Reference Within a Name			[324    ]
1463 					   // Area Reference Within a Shared Formula[    274]
1464 				aIn >> nRow1 >> nRow2 >> nCol1 >> nCol2;
1465 
1466                 nTab1 = nTab2 = GetCurrScTab();
1467 				goto _common;
1468 			case 0x5A:
1469 			case 0x7A:
1470 			case 0x3A: // 3-D Cell Reference					[    275]
1471 				aIn >> nIxti >> nRow1 >> nCol1;
1472 
1473 				nRow2 = nRow1;
1474 				nCol2 = nCol1;
1475 
1476 				goto _3d_common;
1477 			case 0x5B:
1478 			case 0x7B:
1479 			case 0x3B: // 3-D Area Reference					[    276]
1480 				aIn >> nIxti >> nRow1 >> nRow2 >> nCol1 >> nCol2;
1481 
1482 	_3d_common:
1483                 // #122885# skip references to deleted sheets
1484                 if( !rLinkMan.GetScTabRange( nTab1, nTab2, nIxti ) || !ValidTab( nTab1 ) || !ValidTab( nTab2 ) )
1485 					break;
1486 
1487 				goto _common;
1488 	_common:
1489                 // do not check abs/rel flags, linked controls have set them!
1490 //               if( !(( nCol1 & 0xC000 ) || ( nCol2 & 0xC000 )) )
1491                 {
1492                     ScRange aScRange;
1493                     nCol1 &= 0x3FFF;
1494                     nCol2 &= 0x3FFF;
1495                     if( GetAddressConverter().ConvertRange( aScRange, XclRange( nCol1, nRow1, nCol2, nRow2 ), nTab1, nTab2, true ) )
1496                         r.Append( aScRange );
1497                 }
1498 				break;
1499 			case 0x1C: // Error Value							[314 266]
1500 			case 0x1D: // Boolean								[315 266]
1501 				nSeek = 1;
1502 				break;
1503 			case 0x1E: // Integer								[315 266]
1504 			case 0x41:
1505 			case 0x61:
1506 			case 0x21: // Function, Fixed Number of Arguments	[333 282]
1507 			case 0x49:
1508 			case 0x69:
1509 			case 0x29: // Variable Reference Subexpression		[331 281]
1510 			case 0x4E:
1511 			case 0x6E:
1512 			case 0x2E: // Reference Subexpression Within a Name	[332 282]
1513 			case 0x4F:
1514 			case 0x6F:
1515 			case 0x2F: // Incomplete Reference Subexpression...	[332 282]
1516 			case 0x58:
1517 			case 0x78:
1518 			case 0x38: // Command-Equivalent Function			[333    ]
1519 				nSeek = 2;
1520 				break;
1521 			case 0x42:
1522 			case 0x62:
1523 			case 0x22: // Function, Variable Number of Arg.		[333 283]
1524 				nSeek = 3;
1525 				break;
1526 			case 0x01: // Array Formula							[325    ]
1527 			case 0x02: // Data Table							[325 277]
1528 			case 0x43:
1529 			case 0x63:
1530 			case 0x23: // Name									[318 269]
1531 			case 0x4A:
1532 			case 0x6A:
1533 			case 0x2A: // Deleted Cell Reference				[323 273]
1534 				nSeek = 4;
1535 				break;
1536 			case 0x46:
1537 			case 0x66:
1538 			case 0x26: // Constant Reference Subexpression		[321 271]
1539 			case 0x47:
1540 			case 0x67:
1541 			case 0x27: // Erroneous Constant Reference Subexpr.	[322 272]
1542 			case 0x48:
1543 			case 0x68:
1544 			case 0x28: // Incomplete Constant Reference Subexpr.[331 281]
1545 			case 0x5C:
1546 			case 0x7C:
1547 			case 0x3C: // Deleted 3-D Cell Reference			[    277]
1548             case 0x59:
1549             case 0x79:
1550             case 0x39: // Name or External Name                 [    275]
1551 				nSeek = 6;
1552 				break;
1553 			case 0x40:
1554 			case 0x60:
1555 			case 0x20: // Array Constant						[317 268]
1556 				nSeek = 7;
1557 				break;
1558 			case 0x1F: // Number								[315 266]
1559 			case 0x4B:
1560 			case 0x6B:
1561 			case 0x2B: // Deleted Area Refernce					[323 273]
1562 				nSeek = 8;
1563 				break;
1564 			case 0x5D:
1565 			case 0x7D:
1566 			case 0x3D: // Deleted 3-D Area Reference			[    277]
1567 				nSeek = 10;
1568 				break;
1569 			case 0x17: // String Constant						[314 266]
1570 			{
1571                 sal_uInt8 nStrLen;
1572                 aIn >> nStrLen;
1573                 aIn.IgnoreUniString( nStrLen );     // reads Grbit even if nLen==0
1574 				nSeek = 0;
1575 			}
1576 				break;
1577 			case 0x19: // Special Attribute						[327 279]
1578 			{
1579 				sal_uInt16	nData;
1580 				sal_uInt8	nOpt;
1581 				aIn >> nOpt >> nData;
1582 				if( nOpt & 0x04 )
1583 				{// nFakt -> Bytes oder Words ueberlesen	AttrChoose
1584 					nData++;
1585 					nSeek = nData * 2;
1586 			}
1587 			}
1588 				break;
1589 		}
1590 
1591         aIn.Ignore( nSeek );
1592 	}
1593     aIn.Seek( nEndPos );
1594 
1595 	return r.Count() != 0;
1596 }
1597 
1598 
1599 
1600 
1601 
1602