LibreOffice Module sc (master)  1
lotimpop.cxx
Go to the documentation of this file.
1 /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
2 /*
3  * This file is part of the LibreOffice project.
4  *
5  * This Source Code Form is subject to the terms of the Mozilla Public
6  * License, v. 2.0. If a copy of the MPL was not distributed with this
7  * file, You can obtain one at http://mozilla.org/MPL/2.0/.
8  *
9  * This file incorporates work covered by the following license notice:
10  *
11  * Licensed to the Apache Software Foundation (ASF) under one or more
12  * contributor license agreements. See the NOTICE file distributed
13  * with this work for additional information regarding copyright
14  * ownership. The ASF licenses this file to you under the Apache
15  * License, Version 2.0 (the "License"); you may not use this file
16  * except in compliance with the License. You may obtain a copy of
17  * the License at http://www.apache.org/licenses/LICENSE-2.0 .
18  */
19 
20 #include "lotfilter.hxx"
21 #include <lotimpop.hxx>
22 #include <osl/mutex.hxx>
23 #include <sal/log.hxx>
24 
25 #include <document.hxx>
26 #include <formulacell.hxx>
27 #include <global.hxx>
28 
29 #include <root.hxx>
30 #include <lotfntbf.hxx>
31 #include <lotform.hxx>
32 #include <tool.h>
33 #include <namebuff.hxx>
34 #include <lotattr.hxx>
35 #include <stringutil.hxx>
36 #include <config_fuzzers.h>
37 
38 #include <unotools/configmgr.hxx>
39 
40 
41 static osl::Mutex aLotImpSemaphore;
42 
43 ImportLotus::ImportLotus(LotusContext &rContext, SvStream& aStream, ScDocument* pDoc, rtl_TextEncoding eQ)
44  : ImportTyp(pDoc, eQ)
45  , pIn(&aStream)
46  , aConv(rContext, *pIn, pDoc->GetSharedStringPool(), eQ, false)
47  , nTab(0)
48  , nExtTab(0)
49 {
50  // good point to start locking of import lotus
51  aLotImpSemaphore.acquire();
52 }
53 
55 {
56  // no need 4 pLotusRoot anymore
57  aLotImpSemaphore.release();
58 }
59 
61 {
62  sal_uInt16 nFileCode, nFileSub, nSaveCnt;
63  sal_uInt8 nMajorId, nMinorId, nFlags;
64 
65  Read( nFileCode );
66  Read( nFileSub );
67  LotusContext &rContext = aConv.getContext();
68  Read( rContext.aActRange );
69  Read( nSaveCnt );
70  Read( nMajorId );
71  Read( nMinorId );
72  Skip( 1 );
73  Read( nFlags );
74 
75  if( nFileSub == 0x0004 )
76  {
77  if( nFileCode == 0x1000 )
78  {// <= WK3
79  rContext.eFirstType = rContext.eActType = Lotus123Typ::WK3;
80  }
81  else if( nFileCode == 0x1002 )
82  {// WK4
83  rContext.eFirstType = rContext.eActType = Lotus123Typ::WK4;
84  }
85  }
86 }
87 
89 {
90  sal_uInt16 nFileCode, nFileSub;
91 
92  Read( nFileCode );
93  Read( nFileSub );
94 
95  return ( nFileCode == 0x8007 && ( nFileSub == 0x0000 || nFileSub == 0x00001 ) );
96 }
97 
98 void ImportLotus::Columnwidth( sal_uInt16 nRecLen )
99 {
100  SAL_WARN_IF( nRecLen < 4, "sc.filter", "*ImportLotus::Columnwidth(): Record too short!" );
101 
102  sal_uInt8 nLTab, nWindow2;
103  sal_uInt16 nCnt = (nRecLen < 4) ? 0 : ( nRecLen - 4 ) / 2;
104 
105  Read( nLTab );
106  Read( nWindow2 );
107 
108  if( !pD->HasTable( static_cast<SCTAB> (nLTab) ) )
109  pD->MakeTable( static_cast<SCTAB> (nLTab) );
110 
111  if( !nWindow2 )
112  {
113  Skip( 2 );
114 
115  sal_uInt8 nCol, nSpaces;
116 
117  while( nCnt )
118  {
119  Read( nCol );
120  Read( nSpaces );
121  // Attention: ambiguous Correction factor!
122  pD->SetColWidth( static_cast<SCCOL> (nCol), static_cast<SCTAB> (nLTab), static_cast<sal_uInt16>( TWIPS_PER_CHAR * 1.28 * nSpaces ) );
123 
124  nCnt--;
125  }
126  }
127 }
128 
129 void ImportLotus::Hiddencolumn( sal_uInt16 nRecLen )
130 {
131  SAL_WARN_IF( nRecLen < 4, "sc.filter", "*ImportLotus::Hiddencolumn(): Record too short!" );
132 
133  sal_uInt8 nLTab, nWindow2;
134  sal_uInt16 nCnt = (nRecLen < 4) ? 0 : ( nRecLen - 4 ) / 2;
135 
136  Read( nLTab );
137  Read( nWindow2 );
138 
139  if( !nWindow2 )
140  {
141  Skip( 2 );
142 
143  sal_uInt8 nCol;
144 
145  while( nCnt )
146  {
147  Read( nCol );
148 
149  pD->SetColHidden(static_cast<SCCOL>(nCol), static_cast<SCCOL>(nCol), static_cast<SCTAB>(nLTab), true);
150  nCnt--;
151  }
152  }
153 }
154 
156 {
157  sal_uInt16 nRangeType;
158  ScRange aScRange;
159 
160  Read( nRangeType );
161 
162  char aBuffer[ 17 ];
163  pIn->ReadBytes(aBuffer, 16);
164  aBuffer[ 16 ] = 0;
165  OUString aName( aBuffer, strlen(aBuffer), eQuellChar );
166 
167  Read( aScRange );
168 
169  LotusContext &rContext = aConv.getContext();
170  rContext.pRngNmBffWK3->Add( rContext.pDoc, aName, aScRange );
171 }
172 
174 {
175  ScAddress aA;
176 
177  Read( aA );
178 
179  ScSetStringParam aParam;
180  aParam.setTextInput();
181  pD->EnsureTable(aA.Tab());
182  pD->SetString(aA, "#ERR!", &aParam);
183 }
184 
186 {
187  ScAddress aA;
188 
189  Read( aA );
190 
191  ScSetStringParam aParam;
192  aParam.setTextInput();
193  pD->EnsureTable(aA.Tab());
194  pD->SetString(aA, "#NA!", &aParam);
195 }
196 
198 {
199  ScAddress aA;
200  OUString aLabel;
201  char cAlign;
202 
203  Read( aA );
204  Read( cAlign );
205  Read( aLabel );
206 
207  ScSetStringParam aParam;
208  aParam.setTextInput();
209  pD->EnsureTable(aA.Tab());
210  pD->SetString(aA, aLabel, &aParam);
211 }
212 
214 {
215  ScAddress aAddr;
216  double fVal;
217 
218  Read( aAddr );
219  Read( fVal );
220 
221  pD->EnsureTable(aAddr.Tab());
222  pD->SetValue(aAddr, fVal);
223 }
224 
226 {
227  ScAddress aAddr;
228  sal_Int16 nVal;
229 
230  Read( aAddr );
231  Read( nVal );
232 
233  pD->EnsureTable(aAddr.Tab());
234  pD->SetValue(aAddr, SnumToDouble(nVal));
235 }
236 
237 void ImportLotus::Formulacell( sal_uInt16 n )
238 {
239  SAL_WARN_IF( !pIn, "sc.filter", "-ImportLotus::Formulacell(): Null-Stream!" );
240 
241  ScAddress aAddr;
242 
243  Read( aAddr );
244  Skip( 10 );
245 
246  n -= std::min<sal_uInt16>(n, 14);
247 
248  std::unique_ptr<ScTokenArray> pErg;
249  sal_Int32 nRest = n;
250 
251  aConv.Reset( aAddr );
252  aConv.SetWK3();
253  aConv.Convert( pErg, nRest );
254  if (!aConv.good())
255  return;
256 
257  ScFormulaCell* pCell = pErg ? new ScFormulaCell(pD, aAddr, std::move(pErg)) : new ScFormulaCell(pD, aAddr);
258  pCell->AddRecalcMode( ScRecalcMode::ONLOAD_ONCE );
259  pD->EnsureTable(aAddr.Tab());
260  pD->SetFormulaCell(aAddr, pCell);
261 }
262 
263 void ImportLotus::Read( OUString &r )
264 {
266 }
267 
268 void ImportLotus::RowPresentation( sal_uInt16 nRecLen )
269 {
270  SAL_WARN_IF( nRecLen < 5, "sc.filter", "*ImportLotus::RowPresentation(): Record too short!" );
271 
272  sal_uInt8 nLTab, nFlags;
273  sal_uInt16 nRow, nHeight;
274  sal_uInt16 nCnt = (nRecLen < 4) ? 0 : ( nRecLen - 4 ) / 8;
275 
276  Read( nLTab );
277  Skip( 1 );
278 
279  while( nCnt )
280  {
281  Read( nRow );
282  Read( nHeight );
283  Skip( 2 );
284  Read( nFlags );
285  Skip( 1 );
286 
287  if( nFlags & 0x02 ) // Fixed / Stretch to fit fonts
288  { // fixed
289  // Height in Lotus in 1/32 Points
290  nHeight *= 20; // -> 32 * TWIPS
291  nHeight /= 32; // -> TWIPS
292 
293  pD->SetRowFlags( static_cast<SCROW> (nRow), static_cast<SCTAB> (nLTab), pD->GetRowFlags( static_cast<SCROW> (nRow), static_cast<SCTAB> (nLTab) ) | CRFlags::ManualSize );
294 
295  pD->SetRowHeight( static_cast<SCROW> (nRow), static_cast<SCTAB> (nLTab), nHeight );
296  }
297 
298  nCnt--;
299  }
300 }
301 
303 {
304  sal_uInt16 nTmpTab(0);
305  Read(nTmpTab);
306  OUString aName;
307  Read(aName);
308 
309  SCTAB nLTab(SanitizeTab(static_cast<SCTAB>(nTmpTab)));
310 #if ENABLE_FUZZERS
311  //ofz#14167 arbitrary sheet limit to make fuzzing useful
312  if (nLTab > 5)
313  nLTab = 5;
314 #endif
315 
316  if (pD->HasTable(nLTab))
317  pD->RenameTab(nLTab, aName);
318  else
319  pD->InsertTab(nLTab, aName);
320 }
321 
323 {
324  sal_uInt8 nNum;
325  OUString aName;
326 
327  Read( nNum );
328 
329  if( nNum >= LotusFontBuffer::nSize )
330  return; // nonsense
331 
332  Read( aName );
333 
334  LotusContext &rContext = aConv.getContext();
335  rContext.maFontBuff.SetName( nNum, aName );
336 }
337 
339 {
340  LotusContext &rContext = aConv.getContext();
341  for( sal_uInt16 nCnt = 0 ; nCnt < LotusFontBuffer::nSize ; nCnt++ )
342  {
343  sal_uInt16 nType;
344  Read( nType );
345  rContext.maFontBuff.SetType( nCnt, nType );
346  }
347 }
348 
350 {
351  LotusContext &rContext = aConv.getContext();
352  for( sal_uInt16 nCnt = 0 ; nCnt < LotusFontBuffer::nSize ; nCnt++ )
353  {
354  sal_uInt16 nSize;
355  Read( nSize );
356  rContext.maFontBuff.SetHeight( nCnt, nSize );
357  }
358 }
359 
360 void ImportLotus::Row_( const sal_uInt16 nRecLen )
361 {
362  SAL_WARN_IF( nExtTab < 0, "sc.filter", "*ImportLotus::Row_(): not possible!" );
363 
364  sal_uInt16 nCntDwn = (nRecLen < 4) ? 0 : ( nRecLen - 4 ) / 5;
365  SCCOL nColCnt = 0;
366  sal_uInt8 nRepeats;
367  LotAttrWK3 aAttr;
368 
369  bool bCenter = false;
370  SCCOL nCenterStart = 0, nCenterEnd = 0;
371  LotusContext &rContext = aConv.getContext();
372 
373  sal_uInt16 nTmpRow(0);
374  Read(nTmpRow);
375  SCROW nRow(rContext.pDoc->SanitizeRow(static_cast<SCROW>(nTmpRow)));
376  sal_uInt16 nHeight(0);
377  Read(nHeight);
378 
379  nHeight &= 0x0FFF;
380  nHeight *= 22;
381 
382  SCTAB nDestTab(static_cast<SCTAB>(nExtTab));
383 
384  if( nHeight )
385  pD->SetRowHeight(nRow, nDestTab, nHeight);
386 
387  while( nCntDwn )
388  {
389  Read( aAttr );
390  Read( nRepeats );
391 
392  if( aAttr.HasStyles() )
393  rContext.maAttrTable.SetAttr(
394  rContext, nColCnt, static_cast<SCCOL> ( nColCnt + nRepeats ), nRow, aAttr );
395 
396  // Do this here and NOT in class LotAttrTable, as we only add attributes if the other
397  // attributes are set
398  // -> for Center-Attribute default is centered
399  if( aAttr.IsCentered() )
400  {
401  if( bCenter )
402  {
403  if (pD->HasData(nColCnt, nRow, nDestTab))
404  {
405  // new Center after previous Center
406  pD->DoMerge(nDestTab, nCenterStart, nRow, nCenterEnd, nRow);
407  nCenterStart = nColCnt;
408  }
409  }
410  else
411  {
412  // fully new Center
413  bCenter = true;
414  nCenterStart = nColCnt;
415  }
416  nCenterEnd = nColCnt + static_cast<SCCOL>(nRepeats);
417  }
418  else
419  {
420  if( bCenter )
421  {
422  // possibly reset old Center
423  pD->DoMerge(nDestTab, nCenterStart, nRow, nCenterEnd, nRow);
424  bCenter = false;
425  }
426  }
427 
428  nColCnt = nColCnt + static_cast<SCCOL>(nRepeats);
429  nColCnt++;
430 
431  nCntDwn--;
432  }
433 
434  if( bCenter )
435  // possibly reset old Center
436  pD->DoMerge(nDestTab, nCenterStart, nRow, nCenterEnd, nRow);
437 }
438 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */
static void AppendCString(SvStream &rStrm, OUString &rString, rtl_TextEncoding eTextEnc)
Appends a zero terminated byte string.
Definition: ftools.cxx:274
void NamedSheet()
Definition: lotimpop.cxx:302
void Font_Ysize()
Definition: lotimpop.cxx:349
Store parameters used in the ScDocument::SetString() method.
Definition: stringutil.hxx:35
ScRange aActRange
Definition: lotfilter.hxx:55
void setTextInput()
Call this whenever you need to unconditionally set input as text, no matter what the input is...
Definition: stringutil.cxx:38
virtual ~ImportLotus() override
Definition: lotimpop.cxx:54
SC_DLLPUBLIC void SetColHidden(SCCOL nStartCol, SCCOL nEndCol, SCTAB nTab, bool bHidden)
Definition: document.cxx:4469
void Row_(const sal_uInt16 nRecLen)
Definition: lotimpop.cxx:360
double SnumToDouble(sal_Int16 nVal)
Definition: tool.cxx:104
void Skip(const sal_uInt16 nNumBytes)
Definition: lotimpop.hxx:132
void RowPresentation(sal_uInt16 nRecLen)
Definition: lotimpop.cxx:268
SC_DLLPUBLIC void SetValue(SCCOL nCol, SCROW nRow, SCTAB nTab, const double &rVal)
Definition: document.cxx:3460
LotAttrTable maAttrTable
Definition: lotfilter.hxx:58
#define TWIPS_PER_CHAR
Definition: global.hxx:89
void Reset(const ScAddress &rEingPos)
Definition: lotform.cxx:357
void Nacell()
Definition: lotimpop.cxx:185
void Userrange()
Definition: lotimpop.cxx:155
std::unique_ptr< RangeNameBufferWK3 > pRngNmBffWK3
Definition: lotfilter.hxx:56
void Formulacell(sal_uInt16 nRecLen)
Definition: lotimpop.cxx:237
SC_DLLPUBLIC bool RenameTab(SCTAB nTab, const OUString &rName, bool bExternalDocument=false)
Definition: document.cxx:852
SC_DLLPUBLIC void SetColWidth(SCCOL nCol, SCTAB nTab, sal_uInt16 nNewWidth)
Definition: document.cxx:4085
void SetName(const sal_uInt16 nIndex, const OUString &rName)
Definition: fontbuff.cxx:70
ScDocument * pD
Definition: imp_op.hxx:47
rtl_TextEncoding eQuellChar
Definition: imp_op.hxx:46
void Numbercell()
Definition: lotimpop.cxx:213
SC_DLLPUBLIC bool HasTable(SCTAB nTab) const
Definition: document.cxx:190
SCTAB Tab() const
Definition: address.hxx:271
SC_DLLPUBLIC bool SetString(SCCOL nCol, SCROW nRow, SCTAB nTab, const OUString &rString, const ScSetStringParam *pParam=nullptr)
Definition: document.cxx:3365
static const sal_uInt16 nSize
Definition: lotfntbf.hxx:51
void Font_Type()
Definition: lotimpop.cxx:338
void Labelcell()
Definition: lotimpop.cxx:197
bool HasStyles() const
Definition: lotattr.hxx:43
sal_Int16 SCCOL
Definition: types.hxx:22
void Bof()
Definition: lotimpop.cxx:60
SvStream * pIn
Definition: lotimpop.hxx:35
SC_DLLPUBLIC void SetRowHeight(SCROW nRow, SCTAB nTab, sal_uInt16 nNewHeight)
Definition: document.cxx:4097
SC_DLLPUBLIC bool InsertTab(SCTAB nPos, const OUString &rName, bool bExternalDocument=false, bool bUndoDeleteTab=false)
Definition: document.cxx:503
bool BofFm3()
Definition: lotimpop.cxx:88
void Hiddencolumn(sal_uInt16 nRecLen)
Definition: lotimpop.cxx:129
void Smallnumcell()
Definition: lotimpop.cxx:225
SC_DLLPUBLIC void DoMerge(SCTAB nTab, SCCOL nStartCol, SCROW nStartRow, SCCOL nEndCol, SCROW nEndRow, bool bDeleteCaptions=true)
Definition: documen3.cxx:2033
bool IsCentered() const
Definition: lotattr.hxx:49
void Font_Face()
Definition: lotimpop.cxx:322
SC_DLLPUBLIC void EnsureTable(SCTAB nTab)
Definition: documen2.cxx:537
std::size_t ReadBytes(void *pData, std::size_t nSize)
ImportLotus(LotusContext &rContext, SvStream &, ScDocument *, rtl_TextEncoding eSrc)
Definition: lotimpop.cxx:43
LotusFontBuffer maFontBuff
Definition: lotfilter.hxx:57
SCROW SanitizeRow(SCROW nRow) const
Definition: document.hxx:876
virtual void Convert(std::unique_ptr< ScTokenArray > &rpErg, sal_Int32 &nRest) override
Definition: lotform.cxx:385
SCTAB SanitizeTab(SCTAB nTab)
Definition: address.hxx:139
sal_Int32 SCROW
Definition: types.hxx:18
void SetType(const sal_uInt16 nIndex, const sal_uInt16 nType)
Definition: fontbuff.cxx:90
std::unique_ptr< char[]> aBuffer
SC_DLLPUBLIC ScFormulaCell * SetFormulaCell(const ScAddress &rPos, ScFormulaCell *pCell)
Set formula cell, and transfer its ownership to the document.
Definition: documen2.cxx:1081
ErrCode Read()
Definition: lotread.cxx:227
Lotus123Typ eActType
Definition: lotfilter.hxx:54
#define SAL_WARN_IF(condition, area, stream)
unsigned char sal_uInt8
OUString aName
sal_Int32 nExtTab
Definition: lotimpop.hxx:38
void SetWK3()
Definition: lotform.hxx:110
SC_DLLPUBLIC bool HasData(SCCOL nCol, SCROW nRow, SCTAB nTab)
Definition: documen5.cxx:525
OUString aLabel
ScDocument * pDoc
Definition: lotfilter.hxx:45
QPRO_FUNC_TYPE nType
Definition: qproform.cxx:401
bool good() const
Definition: formel.hxx:126
Lotus123Typ eFirstType
Definition: lotfilter.hxx:53
static osl::Mutex aLotImpSemaphore
Definition: lotimpop.cxx:41
LotusContext & getContext()
Definition: lotform.hxx:95
SC_DLLPUBLIC void MakeTable(SCTAB nTab, bool _bNeedsNameCheck=true)
Definition: document.cxx:167
SC_DLLPUBLIC void SetRowFlags(SCROW nRow, SCTAB nTab, CRFlags nNewFlags)
Definition: document.cxx:4318
void SetAttr(LotusContext &rContext, const SCCOL nColFirst, const SCCOL nColLast, const SCROW nRow, const LotAttrWK3 &)
Definition: lotattr.cxx:231
void AddRecalcMode(ScRecalcMode)
void SetHeight(const sal_uInt16 nIndex, const sal_uInt16 nHeight)
Definition: fontbuff.cxx:83
LotusToSc aConv
Definition: lotimpop.hxx:36
void Errcell()
Definition: lotimpop.cxx:173
sal_Int16 SCTAB
Definition: types.hxx:23
SC_DLLPUBLIC CRFlags GetRowFlags(SCROW nRow, SCTAB nTab) const
Definition: document.cxx:4338
void Columnwidth(sal_uInt16 nRecLen)
Definition: lotimpop.cxx:98