Version 6.4.0.3, tag libreoffice-6.4.0.3
[LibreOffice.git] / sc / source / filter / lotus / filter.cxx
blob9746a6807a93eca3ffe32b35e5336f4e4917b35e
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 // Discover WKS, WK1 and WK3; s.a op.cpp
22 #include <map>
24 #include <filter.hxx>
25 #include <document.hxx>
26 #include <scerrors.hxx>
28 #include <optab.h>
29 #include <op.h>
30 #include <scmem.h>
31 #include <decl.h>
32 #include <fprogressbar.hxx>
33 #include "lotfilter.hxx"
34 #include <tools/stream.hxx>
36 static ErrCode
37 generate_Opcodes(LotusContext &rContext, SvStream& aStream,
38 ScfStreamProgressBar& aPrgrsBar)
40 OPCODE_FKT *pOps = nullptr;
41 int nOps = 0;
43 ErrCode nErr = ERRCODE_NONE;
45 switch (rContext.eTyp)
47 case eWK_1:
48 case eWK_2:
49 pOps = LotusContext::pOpFkt;
50 nOps = FKT_LIMIT;
51 break;
52 case eWK123:
53 pOps = LotusContext::pOpFkt123;
54 nOps = FKT_LIMIT123;
55 break;
56 case eWK3:
57 nErr = SCERR_IMPORT_NI;
58 break;
59 case eWK_Error:
60 nErr = SCERR_IMPORT_FORMAT;
61 break;
62 default:
63 nErr = SCERR_IMPORT_UNKNOWN_WK;
64 break;
67 if (nErr != ERRCODE_NONE)
69 MemDelete(rContext);
70 return nErr;
73 // #i76299# seems that SvStream::IsEof() does not work correctly
74 sal_uInt64 const nStrmSize = aStream.TellEnd();
75 aStream.Seek( STREAM_SEEK_TO_BEGIN );
76 while (!rContext.bEOF && aStream.good() && (aStream.Tell() < nStrmSize))
78 sal_uInt16 nOpcode(LOTUS_EOF), nLength(0);
80 aStream.ReadUInt16(nOpcode).ReadUInt16(nLength);
81 if (!aStream.good())
82 break;
84 aPrgrsBar.Progress();
85 if( nOpcode == LOTUS_EOF )
86 rContext.bEOF = true;
87 else if( nOpcode == LOTUS_FILEPASSWD )
89 nErr = SCERR_IMPORT_FILEPASSWD;
90 break;
92 else if( nOpcode < nOps )
93 pOps[ nOpcode ] (rContext, aStream, nLength);
94 else if (rContext.eTyp == eWK123 && nOpcode == LOTUS_PATTERN)
96 // This is really ugly - needs re-factoring ...
97 aStream.SeekRel(nLength);
98 aStream.ReadUInt16( nOpcode ).ReadUInt16( nLength );
99 if ( nOpcode == 0x29a)
101 aStream.SeekRel(nLength);
102 aStream.ReadUInt16( nOpcode ).ReadUInt16( nLength );
103 if ( nOpcode == 0x804 )
105 aStream.SeekRel(nLength);
106 OP_ApplyPatternArea123(rContext, aStream);
108 else
109 aStream.SeekRel(nLength);
111 else
112 aStream.SeekRel(nLength);
114 else
115 aStream.SeekRel( nLength );
118 MemDelete(rContext);
120 if (!aStream.good())
121 nErr = SCERR_IMPORT_FORMAT;
122 else if (nErr == ERRCODE_NONE)
123 rContext.pDoc->CalcAfterLoad();
125 return nErr;
128 static WKTYP ScanVersion(SvStream& aStream)
130 // PREC: pWKFile: pointer to open file
131 // POST: return: type of file
132 sal_uInt16 nOpcode(0), nVersNr(0), nRecLen(0);
134 // first byte has to be 0 because of BOF!
135 aStream.ReadUInt16( nOpcode );
136 if (nOpcode != LotusContext::nBOF)
137 return eWK_UNKNOWN;
139 aStream.ReadUInt16( nRecLen ).ReadUInt16( nVersNr );
141 if (!aStream.good())
142 return eWK_Error;
144 switch( nVersNr )
146 case 0x0404:
147 if( nRecLen == 2 )
148 return eWK_1;
149 else
150 return eWK_UNKNOWN;
152 case 0x0406:
153 if( nRecLen == 2 )
154 return eWK_2;
155 else
156 return eWK_UNKNOWN;
158 case 0x1000:
159 aStream.ReadUInt16( nVersNr );
160 if (!aStream.good())
161 return eWK_Error;
162 if( nVersNr == 0x0004 && nRecLen == 26 )
164 // 4 bytes of 26 read => skip 22 (read instead of seek to make IsEof() work just in case)
165 sal_Char aDummy[22];
166 aStream.ReadBytes(aDummy, 22);
167 return !aStream.good() ? eWK_Error : eWK3;
169 break;
170 case 0x1003:
171 if( nRecLen == 0x1a )
172 return eWK123;
173 else
174 return eWK_UNKNOWN;
175 case 0x1005:
176 if( nRecLen == 0x1a )
177 return eWK123;
178 else
179 return eWK_UNKNOWN;
182 return eWK_UNKNOWN;
185 ErrCode ScImportLotus123old(LotusContext& rContext, SvStream& aStream, ScDocument* pDocument, rtl_TextEncoding eSrc )
187 aStream.Seek( 0 );
189 // make document pointer global
190 rContext.pDoc = pDocument;
191 rContext.bEOF = false;
192 rContext.eCharVon = eSrc;
194 // allocate memory
195 if( !MemNew(rContext) )
196 return SCERR_IMPORT_OUTOFMEM;
198 // initialize page format (only Tab 0!)
199 // initialize page format; meaning: get defaults from SC TODO:
200 //scGetPageFormat( 0, &aPage );
202 // start progressbar
203 ScfStreamProgressBar aPrgrsBar( aStream, pDocument->GetDocumentShell() );
205 // detect file type
206 rContext.eTyp = ScanVersion(aStream);
207 rContext.aLotusPatternPool.clear();
209 return generate_Opcodes(rContext, aStream, aPrgrsBar);
212 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */