Coverage Report

Created: 2026-07-20 07:04

next uncovered line (L), next uncovered region (R), next uncovered branch (B)
/src/libetonyek/src/lib/IWAParser.h
Line
Count
Source
1
/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
2
/*
3
 * This file is part of the libetonyek 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
10
#ifndef IWAPARSER_H_INCLUDED
11
#define IWAPARSER_H_INCLUDED
12
13
#include <deque>
14
#include <functional>
15
#include <map>
16
#include <memory>
17
#include <string>
18
#include <unordered_map>
19
20
#include <boost/optional.hpp>
21
#include <boost/variant.hpp>
22
23
#if defined(__GNUC__) && !defined(__clang__)
24
#pragma GCC diagnostic push
25
#pragma GCC diagnostic ignored "-Weffc++"
26
#endif
27
#include <mdds/flat_segment_tree.hpp>
28
#if defined(__GNUC__) && !defined(__clang__)
29
#pragma GCC diagnostic pop
30
#endif
31
32
#include "libetonyek_utils.h"
33
#include "IWAMessage.h"
34
#include "IWAObjectIndex.h"
35
#include "IWORKLanguageManager.h"
36
#include "IWORKOutputElements.h"
37
#include "IWORKStyle_fwd.h"
38
#include "IWORKTypes.h"
39
40
namespace libetonyek
41
{
42
43
class IWORKCollector;
44
class IWAObjectIndex;
45
class IWORKPropertyMap;
46
class IWORKTable;
47
class IWORKText;
48
49
class IWAParser
50
{
51
  friend class IWAObjectIndex; // for readColor
52
53
  // disable copying
54
  IWAParser(const IWAParser &);
55
  IWAParser &operator=(const IWAParser &);
56
public:
57
  IWAParser(const RVNGInputStreamPtr_t &fragments, const RVNGInputStreamPtr_t &package, IWORKCollector &collector);
58
  virtual ~IWAParser()
59
2.14k
  {
60
2.14k
  }
61
62
  bool parse();
63
64
protected:
65
  class ObjectMessage
66
  {
67
  public:
68
    ObjectMessage(IWAParser &parser, unsigned id, unsigned type = 0);
69
    ~ObjectMessage();
70
71
    operator bool() const;
72
    const IWAMessage &get() const;
73
74
    unsigned getType() const;
75
76
    friend const IWAMessage &get(const ObjectMessage &msg)
77
264k
    {
78
264k
      return msg.get();
79
264k
    }
80
81
  private:
82
    IWAParser &m_parser;
83
    boost::optional<IWAMessage> m_message;
84
    const unsigned m_id;
85
    unsigned m_type;
86
  };
87
  friend class ObjectMessage;
88
89
  typedef std::map<unsigned, IWORKStylePtr_t> StyleMap_t;
90
  typedef std::function<void(unsigned, IWORKStylePtr_t &)> StyleParseFun_t;
91
92
protected:
93
  static boost::optional<unsigned> readRef(const IWAMessage &msg, unsigned field);
94
  static std::deque<unsigned> readRefs(const IWAMessage &msg, unsigned field);
95
  static boost::optional<IWORKPosition> readPosition(const IWAMessage &msg, unsigned field);
96
  static boost::optional<IWORKSize> readSize(const IWAMessage &msg, unsigned field);
97
  static boost::optional<IWORKColor> readColor(const IWAMessage &msg, unsigned field);
98
  static boost::optional<std::string> readUUID(const IWAMessage &msg, unsigned field);
99
  static boost::optional<uint64_t> readUID(const IWAMessage &msg, unsigned field);
100
  static std::deque<uint64_t> readUIDs(const IWAMessage &msg, unsigned field);
101
  static void readStroke(const IWAMessage &msg, IWORKStroke &stroke);
102
  bool readFill(const IWAMessage &msg, IWORKFill &fill);
103
  static void readGradient(const IWAMessage &msg, IWORKGradient &gradient);
104
  static void readShadow(const IWAMessage &msg, IWORKShadow &shadow);
105
  static void readPadding(const IWAMessage &msg, IWORKPadding &padding);
106
  static void readDropCap(const IWAMessage &msg, IWORKDropCap &cap);
107
108
  bool dispatchShape(unsigned id);
109
  bool dispatchShapeWithMessage(const IWAMessage &msg, unsigned type);
110
  bool parseText(unsigned id, bool createNoteAsFootnote=true, const std::function<void(unsigned, IWORKStylePtr_t)> &openPageSpan=nullptr);
111
  void parseComment(unsigned id);
112
  void parseAuthorInComment(unsigned id);
113
  void parseCustomFormat(unsigned id);
114
115
  virtual bool parseShapePlacement(const IWAMessage &msg, IWORKGeometryPtr_t &geometry, boost::optional<unsigned> &flags);
116
  void parseMask(unsigned id, IWORKGeometryPtr_t &geometry, IWORKPathPtr_t &path);
117
  void updateGeometryUsingTextRef(unsigned id, IWORKGeometry &geometry, unsigned flags);
118
119
  const IWORKStylePtr_t queryCharacterStyle(unsigned id) const;
120
  const IWORKStylePtr_t queryDropCapStyle(unsigned id) const;
121
  const IWORKStylePtr_t queryParagraphStyle(unsigned id) const;
122
  const IWORKStylePtr_t querySectionStyle(unsigned id) const;
123
124
  const IWORKStylePtr_t queryGraphicStyle(unsigned id) const;
125
  const IWORKStylePtr_t queryMediaStyle(unsigned id) const;
126
  const IWORKStylePtr_t queryCellStyle(unsigned id) const;
127
  const IWORKStylePtr_t queryTableStyle(unsigned id) const;
128
  const IWORKStylePtr_t queryListStyle(unsigned id) const;
129
130
  const IWORKStylePtr_t queryStyle(unsigned id, StyleMap_t &styleMap, StyleParseFun_t parse) const;
131
  boost::optional<unsigned> getObjectType(unsigned id) const;
132
133
protected:
134
  IWORKFormatNameMap m_formatNameMap;
135
  IWORKLanguageManager m_langManager;
136
  IWORKTableNameMapPtr_t m_tableNameMap;
137
  std::shared_ptr<IWORKText> m_currentText;
138
139
private:
140
  struct Format
141
  {
142
    Format();
143
    boost::optional<IWORKCellType> m_type;
144
    boost::variant<IWORKNumberFormat,IWORKDateTimeFormat,IWORKDurationFormat> m_format;
145
  };
146
147
  struct PageMaster
148
  {
149
    PageMaster();
150
    IWORKStylePtr_t m_style;
151
    bool m_headerFootersSameAsPrevious;
152
  };
153
154
  struct TableHeader
155
  {
156
    TableHeader(unsigned count, float defValue=0);
157
158
    mdds::flat_segment_tree<unsigned, float> m_sizes;
159
    mdds::flat_segment_tree<unsigned, bool> m_hidden;
160
  };
161
162
  typedef std::map<unsigned, boost::variant<std::string, unsigned, IWORKFormulaPtr_t, Format> > DataList_t;
163
164
  struct ConditionRule
165
  {
166
    ConditionRule();
167
168
    IWORKFormulaPtr_t m_formula;
169
    boost::optional<unsigned> m_cellStyleRef;
170
    boost::optional<unsigned> m_paragraphStyleRef;
171
  };
172
173
  typedef std::deque<ConditionRule> ConditionRule_t;
174
  typedef std::map<unsigned, ConditionRule_t> ConditionRuleList_t;
175
176
  struct TableInfo
177
  {
178
    TableInfo(const std::shared_ptr<IWORKTable> &table, unsigned columns, unsigned rows);
179
180
    std::shared_ptr<IWORKTable> m_table;
181
182
    const unsigned m_columns;
183
    const unsigned m_rows;
184
185
    IWORKStylePtr_t m_style;
186
187
    TableHeader m_columnHeader;
188
    TableHeader m_rowHeader;
189
190
    DataList_t m_simpleTextList;
191
    DataList_t m_cellStyleList;
192
    ConditionRuleList_t m_conditionStyleList;
193
    DataList_t m_formattedTextList;
194
    DataList_t m_formulaList;
195
    DataList_t m_formatList;
196
    DataList_t m_newFormatList;
197
    DataList_t m_commentList;
198
  };
199
200
private:
201
  virtual bool parseDocument() = 0;
202
203
private:
204
  void queryObject(unsigned id, unsigned &type, boost::optional<IWAMessage> &msg) const;
205
  const RVNGInputStreamPtr_t queryFile(unsigned id) const;
206
207
  void parseObjectIndex();
208
209
  void parseCharacterStyle(unsigned id, IWORKStylePtr_t &style);
210
  void parseDropCapStyle(unsigned id, IWORKStylePtr_t &style);
211
  void parseParagraphStyle(unsigned id, IWORKStylePtr_t &style);
212
  void parseSectionStyle(unsigned id, IWORKStylePtr_t &style);
213
214
  void parseGraphicStyle(unsigned id, IWORKStylePtr_t &style);
215
  void parseMediaStyle(unsigned id, IWORKStylePtr_t &style);
216
  void parseCellStyle(unsigned id, IWORKStylePtr_t &style);
217
  void parseTableStyle(unsigned id, IWORKStylePtr_t &style);
218
  void parseListStyle(unsigned id, IWORKStylePtr_t &style);
219
220
  void parseHeaderAndFooter(unsigned id, IWORKPageMaster &hf);
221
  void parsePageMaster(unsigned id, PageMaster &pageMaster);
222
223
  void parseTabularModel(unsigned id);
224
  void parseDataList(unsigned id, DataList_t &dataList);
225
  void parseTile(unsigned id, unsigned decalY);
226
  void parseTileDefinition(unsigned row, unsigned col, RVNGInputStreamPtr_t &input, unsigned endPos, bool oldFormat);
227
  void parseTableHeaders(unsigned id, TableHeader &header);
228
  void parseTableGridLines(unsigned id, IWORKGridLineMap_t (&gridLines)[4]);
229
  void parseTableGridLine(unsigned id, IWORKGridLineMap_t &gridLines);
230
  void parseLink(unsigned id, std::string &url);
231
232
  bool parseAttachment(unsigned id);
233
  bool parseConditionRules(unsigned id, ConditionRule_t &rules);
234
  bool parseDrawableShape(const IWAMessage &msg, bool isConnectionLine=false);
235
  bool parseGroup(const IWAMessage &msg);
236
  bool parseShapePlacement(const IWAMessage &msg);
237
  bool parseImage(const IWAMessage &msg);
238
  bool parseTabularInfo(const IWAMessage &msg);
239
  bool parsePath(const IWAMessage &msg, IWORKPathPtr_t &path);
240
  bool parseFormula(const IWAMessage &msg, IWORKFormulaPtr_t &formula);
241
  bool parseFormat(const IWAMessage &msg, Format &format);
242
  virtual bool parseStickyNote(const IWAMessage &msg);
243
244
  bool parseArrowProperties(const IWAMessage &msg, IWORKPropertyMap &props, bool headArrow);
245
  void parseCharacterProperties(const IWAMessage &msg, IWORKPropertyMap &props);
246
  void parseColumnsProperties(const IWAMessage &msg, IWORKPropertyMap &props);
247
248
private:
249
  IWORKCollector &m_collector;
250
251
  IWAObjectIndex m_index;
252
253
  std::deque<unsigned> m_visited;
254
255
  mutable StyleMap_t m_charStyles;
256
  mutable StyleMap_t m_dropCapStyles;
257
  mutable StyleMap_t m_paraStyles;
258
  mutable StyleMap_t m_sectionStyles;
259
260
  mutable StyleMap_t m_graphicStyles;
261
  mutable StyleMap_t m_mediaStyles;
262
  mutable StyleMap_t m_cellStyles;
263
  mutable StyleMap_t m_tableStyles;
264
  mutable StyleMap_t m_listStyles;
265
266
  std::shared_ptr<TableInfo> m_currentTable;
267
  std::map<uint64_t,Format> m_uidFormatMap;
268
};
269
270
}
271
272
#endif
273
274
/* vim:set shiftwidth=2 softtabstop=2 expandtab: */