LanguageTool: don't crash if REST protocol isn't set
[LibreOffice.git] / sc / source / filter / qpro / qpro.cxx
blob5ee451af9aef7c9933b95b8d15c32292ada3b388
1 /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
2 /*
3 * This file is part of the LibreOffice project.
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/.
9 * This file incorporates work covered by the following license notice:
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 .
20 #include <sal/config.h>
21 #include <sal/log.hxx>
23 #include <qproform.hxx>
24 #include <qpro.hxx>
25 #include <qprostyle.hxx>
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>
37 ErrCode ScQProReader::readSheet( SCTAB nTab, ScDocument& rDoc, ScQProStyle *pStyle )
39 ErrCode eRet = ERRCODE_NONE;
40 sal_uInt8 nCol, nDummy;
41 sal_uInt16 nRow;
42 sal_uInt16 nStyle;
43 bool bEndOfSheet = false;
45 SAL_INFO("sc", "Read sheet " << nTab);
47 while( ERRCODE_NONE == eRet && !bEndOfSheet && nextRecord() )
49 switch( getId() )
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
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);
65 break;
67 case 0x00cb: // End of sheet
68 bEndOfSheet = true;
69 break;
71 case 0x000c: // Blank cell
72 mpStream->ReadUChar( nCol ).ReadUChar( nDummy ).ReadUInt16( nRow ).ReadUInt16( nStyle );
73 if (!mpStream->good())
75 eRet = SCERR_IMPORT_FORMAT;
76 break;
78 nStyle = nStyle >> 3;
79 pStyle->SetFormat( &rDoc, nCol, nRow, nTab, nStyle );
80 break;
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())
87 eRet = SCERR_IMPORT_FORMAT;
88 break;
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));
95 break;
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())
102 eRet = SCERR_IMPORT_FORMAT;
103 break;
105 nStyle = nStyle >> 3;
106 pStyle->SetFormat( &rDoc, nCol, nRow, nTab, nStyle );
107 rDoc.EnsureTable(nTab);
108 rDoc.SetValue(ScAddress(nCol,nRow,nTab), nValue);
110 break;
112 case 0x0010:
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())
120 eRet = SCERR_IMPORT_FORMAT;
121 break;
123 ScAddress aAddr( nCol, nRow, nTab );
124 std::unique_ptr<ScTokenArray> pArray;
126 QProToSc aConv(*mpStream, rDoc.GetSharedStringPool(), aAddr);
127 if (ConvErr::OK != aConv.Convert( rDoc, pArray ))
128 eRet = SCERR_IMPORT_FORMAT;
129 else
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);
139 break;
142 return eRet;
145 ErrCode ScFormatFilterPluginImpl::ScImportQuattroPro(SvStream *pStream, ScDocument& rDoc)
147 ScQProReader aReader(pStream);
148 ErrCode eRet = aReader.import(rDoc);
149 return eRet;
152 ScQProReader::ScQProReader(SvStream* pStream)
153 : mnId(0)
154 , mnLength(0)
155 , mnOffset(0)
156 , mpStream(pStream)
157 , mbEndOfFile(false)
158 , mnMaxTab(utl::ConfigManager::IsFuzzing() ? 128 : MAXTAB)
160 if( mpStream )
162 mpStream->SetBufferSize( 65535 );
163 mpStream->SetStreamCharSet( RTL_TEXTENCODING_MS_1252 );
167 ScQProReader::~ScQProReader()
169 if( mpStream )
170 mpStream->SetBufferSize( 0 );
173 ErrCode ScQProReader::parse(ScDocument& rDoc)
175 ErrCode eRet = ERRCODE_NONE;
176 sal_uInt16 nVersion;
177 sal_uInt16 i = 1, j = 1;
178 SCTAB nTab = 0;
179 SetEof( false );
181 if( !recordsLeft() )
182 return SCERR_IMPORT_OPEN;
184 std::unique_ptr<ScQProStyle> pStyleElement( new ScQProStyle );
186 while( nextRecord() && eRet == ERRCODE_NONE)
188 switch( getId() )
190 case 0x0000: // Beginning of file
191 mpStream->ReadUInt16( nVersion );
192 break;
194 case 0x00ca: // Beginning of sheet
195 if (nTab <= mnMaxTab)
197 if( nTab < 26 )
199 OUString aName = OUStringChar( sal_Unicode('A' + nTab) );
200 if (!nTab)
201 rDoc.RenameTab( nTab, aName );
202 else
203 rDoc.InsertTab( nTab, aName );
205 eRet = readSheet( nTab, rDoc, pStyleElement.get() );
206 nTab++;
208 break;
210 case 0x0001: // End of file
211 SetEof( true );
212 break;
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++;
222 break;
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++;
237 break;
240 return eRet;
243 ErrCode ScQProReader::import( ScDocument& rDoc)
245 ErrCode eRet = parse(rDoc);
246 rDoc.CalcAfterLoad();
247 return eRet;
250 extern "C" SAL_DLLPUBLIC_EXPORT bool TestImportQPW(SvStream &rStream)
252 ScDLL::Init();
253 ScDocument aDocument;
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);
261 aDocument.SetHardRecalcState(ScDocument::HardRecalcState::ETERNAL);
263 ScQProReader aReader(&rStream);
264 ErrCode eRet = aReader.parse(aDocument);
265 return eRet == ERRCODE_NONE;
268 bool ScQProReader::recordsLeft()
270 return mpStream && mpStream->good();
273 bool ScQProReader::nextRecord()
275 if( !recordsLeft() )
276 return false;
278 if( mbEndOfFile )
279 return false;
281 sal_uInt32 nPos = mpStream->Tell();
282 if( nPos != mnOffset + mnLength )
283 mpStream->Seek( mnOffset + mnLength );
285 mnLength = mnId = 0;
286 mpStream->ReadUInt16( mnId ).ReadUInt16( mnLength );
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 );
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 );
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" );
307 len -= chunk;
309 mpStream->Seek( mnOffset );
310 #endif
311 #endif
312 return true;
315 OUString ScQProReader::readString(sal_uInt16 nLength)
317 return read_uInt8s_ToOUString(*mpStream, nLength, mpStream->GetStreamCharSet());
320 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */