LibreOffice Module sc (master)  1
qpro.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 <sal/config.h>
21 #include <sal/log.hxx>
22 
23 #include <qproform.hxx>
24 #include <qpro.hxx>
25 #include <qprostyle.hxx>
26 
27 #include <scerrors.hxx>
28 #include <ftools.hxx>
29 #include <document.hxx>
30 #include <formulacell.hxx>
31 #include <tools/stream.hxx>
32 #include <unotools/configmgr.hxx>
33 #include <docoptio.hxx>
34 #include <scdll.hxx>
35 #include <memory>
36 
38 {
39  ErrCode eRet = ERRCODE_NONE;
40  sal_uInt8 nCol, nDummy;
41  sal_uInt16 nRow;
42  sal_uInt16 nStyle;
43  bool bEndOfSheet = false;
44 
45  SAL_INFO("sc", "Read sheet " << nTab);
46 
47  while( ERRCODE_NONE == eRet && !bEndOfSheet && nextRecord() )
48  {
49  switch( getId() )
50  {
51  case 0x000f:{ // Label cell
52  mpStream->ReadUChar( nCol ).ReadUChar( nDummy ).ReadUInt16( nRow ).ReadUInt16( nStyle ).ReadUChar( nDummy );
53  sal_uInt16 nLen = getLength();
54  if (!mpStream->good() || nLen < 7)
55  eRet = SCERR_IMPORT_FORMAT;
56  else
57  {
58  OUString aLabel(readString(nLen - 7));
59  nStyle = nStyle >> 3;
60  pStyle->SetFormat( &rDoc, nCol, nRow, nTab, nStyle );
61  rDoc.EnsureTable(nTab);
62  rDoc.SetTextCell(ScAddress(nCol,nRow,nTab), aLabel);
63  }
64  }
65  break;
66 
67  case 0x00cb: // End of sheet
68  bEndOfSheet = true;
69  break;
70 
71  case 0x000c: // Blank cell
72  mpStream->ReadUChar( nCol ).ReadUChar( nDummy ).ReadUInt16( nRow ).ReadUInt16( nStyle );
73  if (!mpStream->good())
74  {
75  eRet = SCERR_IMPORT_FORMAT;
76  break;
77  }
78  nStyle = nStyle >> 3;
79  pStyle->SetFormat( &rDoc, nCol, nRow, nTab, nStyle );
80  break;
81 
82  case 0x000d:{ // Integer cell
83  sal_Int16 nValue;
84  mpStream->ReadUChar( nCol ).ReadUChar( nDummy ).ReadUInt16( nRow ).ReadUInt16( nStyle ).ReadInt16( nValue );
85  if (!mpStream->good())
86  {
87  eRet = SCERR_IMPORT_FORMAT;
88  break;
89  }
90  nStyle = nStyle >> 3;
91  pStyle->SetFormat( &rDoc, nCol, nRow, nTab, nStyle );
92  rDoc.EnsureTable(nTab);
93  rDoc.SetValue(ScAddress(nCol,nRow,nTab), static_cast<double>(nValue));
94  }
95  break;
96 
97  case 0x000e:{ // Floating point cell
98  double nValue;
99  mpStream->ReadUChar( nCol ).ReadUChar( nDummy ).ReadUInt16( nRow ).ReadUInt16( nStyle ).ReadDouble( nValue );
100  if (!mpStream->good())
101  {
102  eRet = SCERR_IMPORT_FORMAT;
103  break;
104  }
105  nStyle = nStyle >> 3;
106  pStyle->SetFormat( &rDoc, nCol, nRow, nTab, nStyle );
107  rDoc.EnsureTable(nTab);
108  rDoc.SetValue(ScAddress(nCol,nRow,nTab), nValue);
109  }
110  break;
111 
112  case 0x0010:
113  {
114  // Formula cell
115  double nValue;
116  sal_uInt16 nState, nLen;
117  mpStream->ReadUChar( nCol ).ReadUChar( nDummy ).ReadUInt16( nRow ).ReadUInt16( nStyle ).ReadDouble( nValue ).ReadUInt16( nState ).ReadUInt16( nLen );
118  if (!mpStream->good())
119  {
120  eRet = SCERR_IMPORT_FORMAT;
121  break;
122  }
123  ScAddress aAddr( nCol, nRow, nTab );
124  std::unique_ptr<ScTokenArray> pArray;
125 
126  QProToSc aConv(*mpStream, rDoc.GetSharedStringPool(), aAddr);
127  if (ConvErr::OK != aConv.Convert( rDoc, pArray ))
128  eRet = SCERR_IMPORT_FORMAT;
129  else
130  {
131  ScFormulaCell* pFormula = new ScFormulaCell(rDoc, aAddr, std::move(pArray));
132  nStyle = nStyle >> 3;
133  pFormula->AddRecalcMode( ScRecalcMode::ONLOAD_ONCE );
134  pStyle->SetFormat( &rDoc, nCol, nRow, nTab, nStyle );
135  rDoc.EnsureTable(nTab);
136  rDoc.SetFormulaCell(ScAddress(nCol,nRow,nTab), pFormula);
137  }
138  }
139  break;
140  }
141  }
142  return eRet;
143 }
144 
146 {
147  ScQProReader aReader(pStream);
148  ErrCode eRet = aReader.import(rDoc);
149  return eRet;
150 }
151 
153  : mnId(0)
154  , mnLength(0)
155  , mnOffset(0)
156  , mpStream(pStream)
157  , mbEndOfFile(false)
158  , mnMaxTab(utl::ConfigManager::IsFuzzing() ? 128 : MAXTAB)
159 {
160  if( mpStream )
161  {
162  mpStream->SetBufferSize( 65535 );
163  mpStream->SetStreamCharSet( RTL_TEXTENCODING_MS_1252 );
164  }
165 }
166 
168 {
169  if( mpStream )
170  mpStream->SetBufferSize( 0 );
171 }
172 
174 {
175  ErrCode eRet = ERRCODE_NONE;
176  sal_uInt16 nVersion;
177  sal_uInt16 i = 1, j = 1;
178  SCTAB nTab = 0;
179  SetEof( false );
180 
181  if( !recordsLeft() )
182  return SCERR_IMPORT_OPEN;
183 
184  std::unique_ptr<ScQProStyle> pStyleElement( new ScQProStyle );
185 
186  while( nextRecord() && eRet == ERRCODE_NONE)
187  {
188  switch( getId() )
189  {
190  case 0x0000: // Beginning of file
191  mpStream->ReadUInt16( nVersion );
192  break;
193 
194  case 0x00ca: // Beginning of sheet
195  if (nTab <= mnMaxTab)
196  {
197  if( nTab < 26 )
198  {
199  OUString aName = OUStringChar( sal_Unicode('A' + nTab) );
200  if (!nTab)
201  rDoc.RenameTab( nTab, aName );
202  else
203  rDoc.InsertTab( nTab, aName );
204  }
205  eRet = readSheet( nTab, rDoc, pStyleElement.get() );
206  nTab++;
207  }
208  break;
209 
210  case 0x0001: // End of file
211  SetEof( true );
212  break;
213 
214  case 0x00ce:{ // Attribute cell
215  sal_uInt8 nFormat, nAlign, nFont;
216  sal_Int16 nColor;
217  mpStream->ReadUChar( nFormat ).ReadUChar( nAlign ).ReadInt16( nColor ).ReadUChar( nFont );
218  pStyleElement->setAlign( i, nAlign );
219  pStyleElement->setFont( i, nFont );
220  i++;
221  }
222  break;
223 
224  case 0x00cf:{ // Font description
225  sal_uInt16 nPtSize, nFontAttr;
226  OUString aLabel;
227  mpStream->ReadUInt16( nPtSize ).ReadUInt16( nFontAttr );
228  pStyleElement->setFontRecord( j, nFontAttr, nPtSize );
229  sal_uInt16 nLen = getLength();
230  if (nLen >= 4)
231  aLabel = readString(nLen - 4);
232  else
233  eRet = SCERR_IMPORT_FORMAT;
234  pStyleElement->setFontType( j, aLabel );
235  j++;
236  }
237  break;
238  }
239  }
240  return eRet;
241 }
242 
244 {
245  ErrCode eRet = parse(rDoc);
246  rDoc.CalcAfterLoad();
247  return eRet;
248 }
249 
250 extern "C" SAL_DLLPUBLIC_EXPORT bool TestImportQPW(SvStream &rStream)
251 {
252  ScDLL::Init();
254  ScDocOptions aDocOpt = aDocument.GetDocOptions();
255  aDocOpt.SetLookUpColRowNames(false);
256  aDocument.SetDocOptions(aDocOpt);
257  aDocument.MakeTable(0);
258  aDocument.EnableExecuteLink(false);
259  aDocument.SetInsertingFromOtherDoc(true);
260  aDocument.SetImportingXML(true);
262 
263  ScQProReader aReader(&rStream);
264  ErrCode eRet = aReader.parse(aDocument);
265  return eRet == ERRCODE_NONE;
266 }
267 
269 {
270  return mpStream && mpStream->good();
271 }
272 
274 {
275  if( !recordsLeft() )
276  return false;
277 
278  if( mbEndOfFile )
279  return false;
280 
281  sal_uInt32 nPos = mpStream->Tell();
282  if( nPos != mnOffset + mnLength )
284 
285  mnLength = mnId = 0;
287 
288  mnOffset = mpStream->Tell();
289 #ifdef DEBUG_SC_QPRO
290  fprintf( stderr, "Read record 0x%x length 0x%x at offset 0x%x\n",
291  (unsigned)mnId, (unsigned)mnLength, (unsigned)mnOffset );
292 
293 #if 1 // rather verbose
294  int len = mnLength;
295  while (len > 0) {
296  int i, chunk = std::min(len, 16);
297  unsigned char data[16];
298  mpStream->Read( data, chunk );
299 
300  for (i = 0; i < chunk; i++)
301  fprintf( stderr, "%.2x ", data[i] );
302  fprintf( stderr, "| " );
303  for (i = 0; i < chunk; i++)
304  fprintf( stderr, "%c", data[i] < 127 && data[i] > 30 ? data[i] : '.' );
305  fprintf( stderr, "\n" );
306 
307  len -= chunk;
308  }
309  mpStream->Seek( mnOffset );
310 #endif
311 #endif
312  return true;
313 }
314 
315 OUString ScQProReader::readString(sal_uInt16 nLength)
316 {
318 }
319 
320 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */
sal_uInt32 mnOffset
Definition: qpro.hxx:36
SvStream & ReadInt16(sal_Int16 &rInt16)
OUString readString(sal_uInt16 nLength)
Definition: qpro.cxx:315
SC_DLLPUBLIC svl::SharedStringPool & GetSharedStringPool()
Definition: documen2.cxx:566
ScriptDocument aDocument
SvStream & ReadUInt16(sal_uInt16 &rUInt16)
~ScQProReader()
Definition: qpro.cxx:167
sal_uInt64 Seek(sal_uInt64 nPos)
virtual ErrCode ScImportQuattroPro(SvStream *pStream, ScDocument &rDoc) override
Definition: qpro.cxx:145
SC_DLLPUBLIC void SetValue(SCCOL nCol, SCROW nRow, SCTAB nTab, const double &rVal)
Definition: document.cxx:3489
sal_uInt16 mnId
void SetHardRecalcState(HardRecalcState eVal)
Definition: document.hxx:2314
SC_DLLPUBLIC void SetTextCell(const ScAddress &rPos, const OUString &rStr)
Call this if you are not sure whether to put this as an edit text or a simple text.
Definition: document.cxx:3462
SC_DLLPUBLIC void SetImportingXML(bool bVal)
Definition: documen9.cxx:592
sal_uInt16 sal_Unicode
SC_DLLPUBLIC bool RenameTab(SCTAB nTab, const OUString &rName, bool bExternalDocument=false)
Definition: document.cxx:853
SvStream * mpStream
Definition: qpro.hxx:37
ErrCode parse(ScDocument &rDoc)
Definition: qpro.cxx:173
void SetLookUpColRowNames(bool bVal)
Definition: docoptio.hxx:52
bool recordsLeft()
Definition: qpro.cxx:268
void SetInsertingFromOtherDoc(bool bVal)
Definition: document.hxx:2146
SC_DLLPUBLIC const ScDocOptions & GetDocOptions() const
Definition: documen3.cxx:1943
void EnableExecuteLink(bool bVal)
Definition: document.hxx:1543
int i
ErrCode import(ScDocument &rDoc)
Definition: qpro.cxx:243
static SC_DLLPUBLIC void Init()
DLL-init/exit-code must be linked to the DLL only.
Definition: scdll.cxx:99
ScQProReader(SvStream *pStream)
Definition: qpro.cxx:152
sal_uInt16 getLength() const
Definition: qpro.hxx:49
SC_DLLPUBLIC bool InsertTab(SCTAB nPos, const OUString &rName, bool bExternalDocument=false, bool bUndoDeleteTab=false)
Definition: document.cxx:504
ErrCode readSheet(SCTAB nTab, ScDocument &rDoc, ScQProStyle *pStyle)
Definition: qpro.cxx:37
void SetBufferSize(sal_uInt16 m_nBufSize)
SvStream & ReadUChar(unsigned char &rChar)
sal_uInt16 mnId
Definition: qpro.hxx:34
sal_Int16 nVersion
const SCTAB MAXTAB
Definition: address.hxx:70
SvStream & ReadDouble(double &rDouble)
sal_uInt16 mnLength
Definition: qpro.hxx:35
#define SCERR_IMPORT_OPEN
Definition: scerrors.hxx:26
exports com.sun.star.chart2. data
SC_DLLPUBLIC void EnsureTable(SCTAB nTab)
Definition: documen2.cxx:540
SC_DLLPUBLIC void CalcAfterLoad(bool bStartListening=true)
Definition: document.cxx:4040
void SetFormat(ScDocument *pDoc, sal_uInt8 nCol, sal_uInt16 nRow, SCTAB nTab, sal_uInt16 nStyle)
Definition: qprostyle.cxx:39
SC_DLLPUBLIC ScFormulaCell * SetFormulaCell(const ScAddress &rPos, ScFormulaCell *pCell)
Set formula cell, and transfer its ownership to the document.
Definition: documen2.cxx:1086
void SetEof(bool bValue)
Definition: qpro.hxx:46
SC_DLLPUBLIC void SetDocOptions(const ScDocOptions &rOpt)
Definition: documen3.cxx:1949
SAL_DLLPUBLIC_EXPORT bool TestImportQPW(SvStream &rStream)
Definition: qpro.cxx:250
bool mbEndOfFile
Definition: qpro.hxx:38
#define ERRCODE_NONE
unsigned char sal_uInt8
CalcAll() without broadcast/notify but setting up new listeners.
#define SAL_INFO(area, stream)
OUString aName
void SetStreamCharSet(rtl_TextEncoding eCharSet)
rtl_TextEncoding GetStreamCharSet() const
OUString aLabel
sal_uInt64 Tell() const
const SCTAB mnMaxTab
Definition: qpro.hxx:39
#define SCERR_IMPORT_FORMAT
Definition: scerrors.hxx:33
bool good() const
SC_DLLPUBLIC void MakeTable(SCTAB nTab, bool _bNeedsNameCheck=true)
Definition: document.cxx:168
OUString read_uInt8s_ToOUString(SvStream &rStrm, std::size_t nUnits, rtl_TextEncoding eEnc)
bool nextRecord()
Definition: qpro.cxx:273
void AddRecalcMode(ScRecalcMode)
sal_Int32 nState
sal_uInt16 nPos
sal_Int16 SCTAB
Definition: types.hxx:22
sal_Int16 nValue
sal_uInt16 getId() const
Definition: qpro.hxx:48