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 #ifndef INCLUDED_SC_SOURCE_FILTER_INC_FORMEL_HXX
21 #define INCLUDED_SC_SOURCE_FILTER_INC_FORMEL_HXX
22
23 #include <tools/stream.hxx>
24
25 #include "tokstack.hxx"
26
27 #include <memory>
28 #include <vector>
29 #include <map>
30
31 namespace svl {
32
33 class SharedStringPool;
34
35 }
36
37 class XclImpStream;
38 class ScTokenArray;
39
40 enum class ConvErr
41 {
42 OK = 0,
43 Ni, // unimplemented/unknown opcode occurred
44 Count // did not get all bytes of formula
45 };
46
47 enum FORMULA_TYPE
48 {
49 FT_CellFormula,
50 FT_RangeName,
51 FT_SharedFormula,
52 FT_CondFormat
53 };
54
55 class ScRangeListTabs
56 {
57 typedef ::std::vector<ScRange> RangeListType;
58 typedef ::std::map<SCTAB, std::unique_ptr<RangeListType>> TabRangeType;
59 TabRangeType m_TabRanges;
60 RangeListType::const_iterator maItrCur;
61 RangeListType::const_iterator maItrCurEnd;
62
63 public:
64 ScRangeListTabs ();
65 ~ScRangeListTabs();
66
67 void Append( const ScAddress& aSRD, SCTAB nTab );
68 void Append( const ScRange& aCRD, SCTAB nTab );
69
70 const ScRange* First ( SCTAB nTab );
71 const ScRange* Next ();
72
HasRanges() const73 bool HasRanges () const { return !m_TabRanges.empty(); }
74 };
75
76 class ConverterBase
77 {
78 protected:
79 TokenPool aPool; // user token + predefined token
80 TokenStack aStack;
81 ScAddress aEingPos;
82
83 ConverterBase( svl::SharedStringPool& rSPool );
84 virtual ~ConverterBase();
85
86 void Reset();
87 };
88
89 class ExcelConverterBase : public ConverterBase
90 {
91 protected:
92 ExcelConverterBase( svl::SharedStringPool& rSPool );
93 virtual ~ExcelConverterBase() override;
94
95 public:
96 void Reset();
97 void Reset( const ScAddress& rEingPos );
98
99 virtual ConvErr Convert( std::unique_ptr<ScTokenArray>& rpErg, XclImpStream& rStrm, std::size_t nFormulaLen,
100 bool bAllowArrays, const FORMULA_TYPE eFT = FT_CellFormula ) = 0;
101 virtual ConvErr Convert( ScRangeListTabs&, XclImpStream& rStrm, std::size_t nFormulaLen, SCTAB nTab,
102 const FORMULA_TYPE eFT = FT_CellFormula ) = 0;
103 };
104
105 class LotusConverterBase : public ConverterBase
106 {
107 protected:
108 SvStream& aIn;
109 sal_Int32 nBytesLeft;
110
111 inline void Ignore( const long nSeekRel );
112 inline void Read( sal_uInt8& nByte );
113 inline void Read( sal_uInt16& nUINT16 );
114 inline void Read( sal_Int16& nINT16 );
115 inline void Read( double& fDouble );
116 inline void Read( sal_uInt32& nUINT32 );
117
118 LotusConverterBase( SvStream& rStr, svl::SharedStringPool& rSPool );
119 virtual ~LotusConverterBase() override;
120
121 public:
122 void Reset( const ScAddress& rEingPos );
123
124 virtual void Convert( std::unique_ptr<ScTokenArray>& rpErg, sal_Int32& nRest ) = 0;
125
good() const126 bool good() const { return aIn.good(); }
127
128 protected:
129 using ConverterBase::Reset;
130 };
131
Ignore(const long nSeekRel)132 inline void LotusConverterBase::Ignore( const long nSeekRel )
133 {
134 aIn.SeekRel( nSeekRel );
135 nBytesLeft -= nSeekRel;
136 }
137
Read(sal_uInt8 & nByte)138 inline void LotusConverterBase::Read( sal_uInt8& nByte )
139 {
140 aIn.ReadUChar( nByte );
141 if (aIn.good())
142 nBytesLeft--;
143 else
144 {
145 // SvStream::ReadUChar() does not init a single char on failure. This
146 // behaviour is even tested in a unit test.
147 nByte = 0;
148 nBytesLeft = -1; // bail out early
149 }
150 }
151
Read(sal_uInt16 & nUINT16)152 inline void LotusConverterBase::Read( sal_uInt16& nUINT16 )
153 {
154 aIn.ReadUInt16( nUINT16 );
155 if (aIn.good())
156 nBytesLeft -= 2;
157 else
158 nBytesLeft = -1; // bail out early
159 }
160
Read(sal_Int16 & nINT16)161 inline void LotusConverterBase::Read( sal_Int16& nINT16 )
162 {
163 aIn.ReadInt16( nINT16 );
164 if (aIn.good())
165 nBytesLeft -= 2;
166 else
167 nBytesLeft = -1; // bail out early
168 }
169
Read(double & fDouble)170 inline void LotusConverterBase::Read( double& fDouble )
171 {
172 aIn.ReadDouble( fDouble );
173 if (aIn.good())
174 nBytesLeft -= 8;
175 else
176 nBytesLeft = -1; // bail out early
177 }
178
Read(sal_uInt32 & nUINT32)179 inline void LotusConverterBase::Read( sal_uInt32& nUINT32 )
180 {
181 aIn.ReadUInt32( nUINT32 );
182 if (aIn.good())
183 nBytesLeft -= 4;
184 else
185 nBytesLeft = -1; // bail out early
186 }
187
188 #endif
189
190 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */
191