Coverage Report

Created: 2026-09-06 07:18

next uncovered line (L), next uncovered region (R), next uncovered branch (B)
/src/libmwaw/src/lib/ClarisWksSSParser.cxx
Line
Count
Source
1
/* -*- Mode: C++; c-default-style: "k&r"; indent-tabs-mode: nil; tab-width: 2; c-basic-offset: 2 -*- */
2
3
/* libmwaw
4
* Version: MPL 2.0 / LGPLv2+
5
*
6
* The contents of this file are subject to the Mozilla Public License Version
7
* 2.0 (the "License"); you may not use this file except in compliance with
8
* the License or as specified alternatively below. You may obtain a copy of
9
* the License at http://www.mozilla.org/MPL/
10
*
11
* Software distributed under the License is distributed on an "AS IS" basis,
12
* WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
13
* for the specific language governing rights and limitations under the
14
* License.
15
*
16
* Major Contributor(s):
17
* Copyright (C) 2002 William Lachance (wrlach@gmail.com)
18
* Copyright (C) 2002,2004 Marc Maurer (uwog@uwog.net)
19
* Copyright (C) 2004-2006 Fridrich Strba (fridrich.strba@bluewin.ch)
20
* Copyright (C) 2006, 2007 Andrew Ziem
21
* Copyright (C) 2011, 2012 Alonso Laurent (alonso@loria.fr)
22
*
23
*
24
* All Rights Reserved.
25
*
26
* For minor contributions see the git repository.
27
*
28
* Alternatively, the contents of this file may be used under the terms of
29
* the GNU Lesser General Public License Version 2 or later (the "LGPLv2+"),
30
* in which case the provisions of the LGPLv2+ are applicable
31
* instead of those above.
32
*/
33
34
#include <algorithm>
35
#include <cstring>
36
#include <iomanip>
37
#include <iostream>
38
#include <limits>
39
#include <map>
40
#include <sstream>
41
42
#include <librevenge/librevenge.h>
43
44
#include "MWAWFont.hxx"
45
#include "MWAWFontConverter.hxx"
46
#include "MWAWHeader.hxx"
47
#include "MWAWPosition.hxx"
48
#include "MWAWPictMac.hxx"
49
#include "MWAWPrinter.hxx"
50
#include "MWAWSection.hxx"
51
#include "MWAWSpreadsheetListener.hxx"
52
53
#include "ClarisWksDatabase.hxx"
54
#include "ClarisWksDocument.hxx"
55
#include "ClarisWksGraph.hxx"
56
#include "ClarisWksPresentation.hxx"
57
#include "ClarisWksSpreadsheet.hxx"
58
#include "ClarisWksStruct.hxx"
59
#include "ClarisWksStyleManager.hxx"
60
#include "ClarisWksTable.hxx"
61
#include "ClarisWksText.hxx"
62
63
#include "ClarisWksSSParser.hxx"
64
65
/** Internal: the structures of a ClarisWksSSParser */
66
namespace ClarisWksSSParserInternal
67
{
68
69
////////////////////////////////////////
70
//! Internal: the state of a ClarisWksSSParser
71
struct State {
72
  //! constructor
73
  State()
74
78.2k
    : m_actPage(0)
75
78.2k
    , m_numPages(0)
76
78.2k
  {
77
78.2k
  }
78
79
  int m_actPage /** the actual page */, m_numPages /** the number of page of the final document */;
80
};
81
82
////////////////////////////////////////
83
//! Internal: the subdocument of a ClarisWksSSParser
84
class SubDocument final : public MWAWSubDocument
85
{
86
public:
87
  SubDocument(ClarisWksSSParser &pars, MWAWInputStreamPtr const &input, int zoneId, MWAWPosition const &pos=MWAWPosition())
88
3.29k
    : MWAWSubDocument(&pars, input, MWAWEntry())
89
3.29k
    , m_id(zoneId)
90
3.29k
    , m_position(pos) {}
91
92
  //! destructor
93
3.29k
  ~SubDocument() final {}
94
95
  //! operator!=
96
  bool operator!=(MWAWSubDocument const &doc) const final
97
3.06k
  {
98
3.06k
    if (MWAWSubDocument::operator!=(doc)) return true;
99
0
    auto const *sDoc = dynamic_cast<SubDocument const *>(&doc);
100
0
    if (!sDoc) return true;
101
0
    if (m_id != sDoc->m_id) return true;
102
0
    return false;
103
0
  }
104
105
  //! the parser function
106
  void parse(MWAWListenerPtr &listener, libmwaw::SubDocumentType type) final;
107
108
protected:
109
  //! the subdocument id
110
  int m_id;
111
  //! the subdocument position if defined
112
  MWAWPosition m_position;
113
};
114
115
void SubDocument::parse(MWAWListenerPtr &listener, libmwaw::SubDocumentType)
116
3.06k
{
117
3.06k
  if (!listener.get()) {
118
0
    MWAW_DEBUG_MSG(("ClarisWksSSParserInternal::SubDocument::parse: no listener\n"));
119
0
    return;
120
0
  }
121
3.06k
  if (m_id == -1) { // a number used to send linked frame
122
0
    listener->insertChar(' ');
123
0
    return;
124
0
  }
125
3.06k
  if (m_id == 0) {
126
0
    MWAW_DEBUG_MSG(("ClarisWksSSParserInternal::SubDocument::parse: unknown zone\n"));
127
0
    return;
128
0
  }
129
3.06k
  auto *parser=dynamic_cast<ClarisWksSSParser *>(m_parser);
130
3.06k
  if (!parser) {
131
0
    MWAW_DEBUG_MSG(("ClarisWksSSParserInternal::SubDocument::parse: can not find parser\n"));
132
0
    return;
133
0
  }
134
3.06k
  parser->m_document->sendZone(m_id, listener, m_position);
135
3.06k
}
136
}
137
138
////////////////////////////////////////////////////////////
139
// constructor/destructor, ...
140
////////////////////////////////////////////////////////////
141
ClarisWksSSParser::ClarisWksSSParser(MWAWInputStreamPtr const &input, MWAWRSRCParserPtr const &rsrcParser, MWAWHeader *header)
142
31.6k
  : MWAWSpreadsheetParser(input, rsrcParser, header)
143
31.6k
  , m_state()
144
31.6k
  , m_document()
145
31.6k
{
146
31.6k
  init();
147
31.6k
}
148
149
ClarisWksSSParser::~ClarisWksSSParser()
150
31.6k
{
151
31.6k
}
152
153
void ClarisWksSSParser::init()
154
31.6k
{
155
31.6k
  resetSpreadsheetListener();
156
31.6k
  setAsciiName("main-1");
157
158
31.6k
  m_state.reset(new ClarisWksSSParserInternal::State);
159
31.6k
  m_document.reset(new ClarisWksDocument(*this));
160
31.6k
  m_document->m_sendFootnote=static_cast<ClarisWksDocument::SendFootnote>(&ClarisWksSSParser::sendFootnote);
161
  // reduce the margin (in case, the page is not defined)
162
31.6k
  getPageSpan().setMargins(0.1);
163
31.6k
}
164
165
////////////////////////////////////////////////////////////
166
// interface with the different parser
167
////////////////////////////////////////////////////////////
168
void ClarisWksSSParser::sendFootnote(int zoneId)
169
3.29k
{
170
3.29k
  if (!getSpreadsheetListener()) return;
171
172
3.29k
  MWAWSubDocumentPtr subdoc(new ClarisWksSSParserInternal::SubDocument(*this, getInput(), zoneId));
173
3.29k
  getSpreadsheetListener()->insertNote(MWAWNote(MWAWNote::FootNote), subdoc);
174
3.29k
}
175
176
bool ClarisWksSSParser::checkHeader(MWAWHeader *header, bool strict)
177
46.6k
{
178
46.6k
  *m_state = ClarisWksSSParserInternal::State();
179
46.6k
  if (!m_document->checkHeader(header, strict))
180
249
    return false;
181
46.4k
  return getParserState()->m_kind==MWAWDocument::MWAW_K_SPREADSHEET ||
182
30.1k
         getParserState()->m_kind==MWAWDocument::MWAW_K_DATABASE;
183
46.6k
}
184
185
////////////////////////////////////////////////////////////
186
// the parser
187
////////////////////////////////////////////////////////////
188
void ClarisWksSSParser::parse(librevenge::RVNGSpreadsheetInterface *docInterface)
189
15.0k
{
190
15.0k
  if (!getInput().get() || !checkHeader(nullptr))  throw(libmwaw::ParseException());
191
15.0k
  bool ok = true;
192
15.0k
  try {
193
    // create the asciiFile
194
15.0k
    ascii().setStream(getInput());
195
15.0k
    ascii().open(asciiName());
196
197
15.0k
    checkHeader(nullptr);
198
15.0k
    ok = m_document->createZones();
199
    // check that we have at least read the main zone
200
15.0k
    if (ok) {
201
13.9k
      auto zMap = m_document->getZone(1);
202
13.9k
      if (!zMap)
203
5.97k
        ok = false;
204
7.99k
      else if (getParserState()->m_kind==MWAWDocument::MWAW_K_SPREADSHEET)
205
1.52k
        ok = zMap->m_fileType==2;
206
6.47k
      else
207
6.47k
        ok = zMap->m_fileType==3;
208
13.9k
    }
209
15.0k
    if (ok) {
210
7.01k
      createDocument(docInterface);
211
7.01k
      m_document->sendZone(1);
212
7.01k
    }
213
15.0k
    ascii().reset();
214
15.0k
  }
215
15.0k
  catch (...) {
216
13
    MWAW_DEBUG_MSG(("ClarisWksSSParser::parse: exception catched when parsing\n"));
217
13
    ok = false;
218
13
  }
219
220
15.0k
  resetSpreadsheetListener();
221
15.0k
  if (!ok) throw(libmwaw::ParseException());
222
15.0k
}
223
224
////////////////////////////////////////////////////////////
225
// create the document
226
////////////////////////////////////////////////////////////
227
void ClarisWksSSParser::createDocument(librevenge::RVNGSpreadsheetInterface *documentInterface)
228
7.01k
{
229
7.01k
  if (!documentInterface) return;
230
7.01k
  if (getSpreadsheetListener()) {
231
0
    MWAW_DEBUG_MSG(("ClarisWksSSParser::createDocument: listener already exist\n"));
232
0
    return;
233
0
  }
234
235
7.01k
  m_document->m_graphParser->computePositions();
236
237
  // update the page
238
7.01k
  m_state->m_actPage = 0;
239
7.01k
  m_state->m_numPages=1;
240
241
7.01k
  std::vector<MWAWPageSpan> pageList;
242
7.01k
  m_document->updatePageSpanList(pageList);
243
  //
244
7.01k
  MWAWSpreadsheetListenerPtr listen(new MWAWSpreadsheetListener(*getParserState(), pageList, documentInterface));
245
7.01k
  setSpreadsheetListener(listen);
246
7.01k
  listen->setDocumentMetaData(m_document->getDocumentMetaData());
247
7.01k
  listen->startDocument();
248
7.01k
}
249
250
// vim: set filetype=cpp tabstop=2 shiftwidth=2 cindent autoindent smartindent noexpandtab: