Coverage Report

Created: 2026-09-14 06:37

next uncovered line (L), next uncovered region (R), next uncovered branch (B)
/src/libmwaw/src/lib/RagTime5Chart.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 <cmath>
35
#include <iomanip>
36
#include <iostream>
37
#include <limits>
38
#include <map>
39
#include <set>
40
#include <sstream>
41
42
#include <librevenge/librevenge.h>
43
44
#include "MWAWFont.hxx"
45
#include "MWAWListener.hxx"
46
#include "MWAWPosition.hxx"
47
#include "MWAWSubDocument.hxx"
48
49
#include "RagTime5Document.hxx"
50
#include "RagTime5StructManager.hxx"
51
#include "RagTime5ClusterManager.hxx"
52
53
#include "RagTime5Chart.hxx"
54
55
#include "libmwaw_internal.hxx"
56
57
/** Internal: the structures of a RagTime5Chart */
58
namespace RagTime5ChartInternal
59
{
60
//! the setting zone
61
struct SettingZone {
62
  //! constructor
63
  SettingZone()
64
1.04k
  {
65
1.04k
  }
66
  /** three list of long: first zone of type?, second list pos to id?, main data link
67
      the 0 and 1 data zone are directly stored in link.m_longList is data are short, if not in the link
68
      the 2 zone only contains a link to the settings zone
69
   */
70
  RagTime5ClusterManager::Link m_listLinkId[3];
71
};
72
73
//! the unknown third chart zone
74
struct UnknownZone3 {
75
  //! constructor
76
  UnknownZone3()
77
2.09k
  {
78
2.09k
  }
79
  /** three list of long: first zone of type?, second list pos to id?, third list of flag
80
      the data zone are directly stored in link.m_longList is data are short, if not in the link
81
   */
82
  RagTime5ClusterManager::Link m_listLinkId[3];
83
};
84
85
//! the unknown ten chart zone
86
struct UnknownZone10 {
87
  //! constructor
88
  UnknownZone10()
89
0
  {
90
0
  }
91
  /** three list of long: first zone of type?, second list pos to id?, third list of sub zones
92
      the data zone are directly stored in link.m_longList is data are short, if not in the link
93
   */
94
  RagTime5ClusterManager::Link m_listLinkId[3];
95
};
96
97
//! structure to store chart information in RagTime5ChartInternal
98
struct Chart {
99
  //! constructor
100
  Chart()
101
1.04k
    : m_numSeries(0)
102
1.04k
    , m_settingZone()
103
1.04k
    , m_zone3()
104
1.04k
    , m_zone10()
105
1.04k
  {
106
1.04k
  }
107
  //! the number of series
108
  int m_numSeries;
109
  //! the setting zone
110
  SettingZone m_settingZone;
111
  //! the unknown zone3
112
  UnknownZone3 m_zone3;
113
  //! the unknown zone10
114
  UnknownZone3 m_zone10;
115
};
116
//
117
// parser
118
//
119
120
//! Internal: the helper to read a clustList
121
struct ClustListParser final : public RagTime5StructManager::DataParser {
122
  //! constructor
123
  ClustListParser(RagTime5ClusterManager &clusterManager, int fieldSize, std::string const &zoneName)
124
943
    : RagTime5StructManager::DataParser(zoneName)
125
943
    , m_clusterList()
126
943
    , m_fieldSize(fieldSize)
127
943
    , m_clusterManager(clusterManager)
128
943
  {
129
943
    if (fieldSize!=24 && fieldSize!=60) {
130
0
      MWAW_DEBUG_MSG(("RagTime5ChartInternal::ClustListParser::ClustListParser: bad data size\n"));
131
0
      m_fieldSize=0;
132
0
    }
133
943
  }
134
  //! destructor
135
  ~ClustListParser() final;
136
  //! returns a cluster name
137
  std::string getClusterDebugName(int id) const
138
674
  {
139
674
    return m_clusterManager.getClusterDebugName(id);
140
674
  }
141
142
  //! try to parse a data
143
  bool parseData(MWAWInputStreamPtr &input, long endPos, RagTime5Zone &/*zone*/, int /*n*/, libmwaw::DebugStream &f) final
144
674
  {
145
674
    long pos=input->tell();
146
674
    if (!m_fieldSize || endPos-pos!=m_fieldSize) {
147
0
      MWAW_DEBUG_MSG(("RagTime5ChartInternal::ClustListParser::parse: bad data size\n"));
148
0
      return false;
149
0
    }
150
151
674
    std::vector<int> listIds;
152
674
    if (!RagTime5StructManager::readDataIdList(input, 1, listIds)) {
153
0
      MWAW_DEBUG_MSG(("RagTime5ChartInternal::ClustListParser::parse: can not read an cluster id\n"));
154
0
      f << "##clusterIds,";
155
0
      return false;
156
0
    }
157
674
    if (listIds[0]) {
158
674
      m_clusterList.push_back(listIds[0]);
159
      // a e,2003,200b, ... cluster
160
674
      f << getClusterDebugName(listIds[0]) << ",";
161
674
    }
162
674
    unsigned long lVal=input->readULong(4); // c00..small number
163
674
    if ((lVal&0xc0000000)==0xc0000000)
164
674
      f << "f0=" << (lVal&0x3fffffff) << ",";
165
0
    else
166
0
      f << "f0*" << lVal << ",";
167
674
    if (m_fieldSize==24) {
168
0
      for (int i=0; i<8; ++i) { // f1=0|1, f2=f3=f4=0, f5=0|c, f6=0|d|e
169
0
        auto val=static_cast<int>(input->readLong(2));
170
0
        if (val) f << "f" << i << "=" << val << ",";
171
0
      }
172
0
      return true;
173
0
    }
174
674
    auto val=static_cast<int>(input->readLong(4)); // small int
175
674
    if (val) f << "f0=" << val << ",";
176
2.69k
    for (int i=0; i<3; ++i) {
177
2.02k
      float dim[4];
178
8.08k
      for (auto &d : dim) d=float(input->readLong(4))/65536.f;
179
2.02k
      MWAWBox2f box(MWAWVec2f(dim[0],dim[1]), MWAWVec2f(dim[2],dim[3]));
180
2.02k
      if (box!=MWAWBox2f(MWAWVec2f(0,0),MWAWVec2f(0,0)))
181
674
        f << "dim" << i << "=" << box << ",";
182
2.02k
    }
183
674
    return true;
184
674
  }
185
186
  //! the list of read cluster
187
  std::vector<int> m_clusterList;
188
private:
189
  //! the field size
190
  int m_fieldSize;
191
  //! the main zone manager
192
  RagTime5ClusterManager &m_clusterManager;
193
  //! copy constructor, not implemented
194
  ClustListParser(ClustListParser &orig);
195
  //! copy operator, not implemented
196
  ClustListParser &operator=(ClustListParser &orig);
197
};
198
199
ClustListParser::~ClustListParser()
200
943
{
201
943
}
202
203
//! Internal: the helper to read a double's cell double
204
struct DoubleParser final : public RagTime5StructManager::DataParser {
205
  //! constructor
206
  DoubleParser()
207
0
    : RagTime5StructManager::DataParser("ChartValueDouble")
208
0
  {
209
0
  }
210
  //! destructor
211
  ~DoubleParser() final;
212
  //! try to parse a data
213
  bool parseData(MWAWInputStreamPtr &input, long endPos, RagTime5Zone &/*zone*/, int /*n*/, libmwaw::DebugStream &f) final
214
0
  {
215
0
    long pos=input->tell();
216
0
    long fSz=endPos-pos;
217
0
    if (fSz!=8) {
218
0
      MWAW_DEBUG_MSG(("RagTime5ChartInternal::DoubleParser::parse: bad data size\n"));
219
0
      return false;
220
0
    }
221
0
    double res;
222
0
    bool isNan;
223
0
    if (input->readDouble8(res, isNan)) {
224
0
      f << res;
225
0
      return true;
226
0
    }
227
0
    input->seek(pos, librevenge::RVNG_SEEK_SET);
228
0
    if (input->readULong(4)==0x7ff01fe0 && input->readULong(4)==0) {
229
      // some kind of nan ?
230
0
      f << "undef,";
231
0
      return true;
232
0
    }
233
0
    MWAW_DEBUG_MSG(("RagTime5ChartInternal::DoubleParser::parse: can not read a double\n"));
234
0
    f << "##double";
235
0
    return true;
236
0
  }
237
};
238
239
DoubleParser::~DoubleParser()
240
0
{
241
0
}
242
243
//! Internal: the helper to read a serieType's cell serieType
244
struct SerieTypeParser final : public RagTime5StructManager::DataParser {
245
  //! constructor
246
  SerieTypeParser()
247
0
    : RagTime5StructManager::DataParser("ChartSerieType")
248
0
  {
249
0
  }
250
  //! destructor
251
  ~SerieTypeParser() final;
252
  //! try to parse a data
253
  bool parseData(MWAWInputStreamPtr &input, long endPos, RagTime5Zone &/*zone*/, int /*n*/, libmwaw::DebugStream &f) final
254
0
  {
255
0
    long pos=input->tell();
256
0
    long fSz=endPos-pos;
257
0
    if (fSz!=8) {
258
0
      MWAW_DEBUG_MSG(("RagTime5ChartInternal::SerieTypeParser::parse: bad data size\n"));
259
0
      return false;
260
0
    }
261
0
    long val=static_cast<int>(input->readULong(4)); // always 1
262
0
    if (val!=1) {
263
0
      MWAW_DEBUG_MSG(("RagTime5ChartInternal::SerieTypeParser::parse: find unknown f0 value\n"));
264
0
      f << "##f0=" << val << ",";
265
0
    }
266
0
    auto type=input->readULong(4);
267
0
    switch (type) { // todo: find meaning
268
0
    case 0x7d01a:
269
0
    case 0x16b481a:
270
0
    case 0x16b482a:
271
0
    case 0x16b48fa:
272
0
    case 0x16b601a:
273
0
      f << "type=" << RagTime5StructManager::printType(type) << ",";
274
0
      break;
275
0
    default:
276
0
      MWAW_DEBUG_MSG(("RagTime5ChartInternal::SerieTypeParser::parse: find unknown type\n"));
277
0
      f << "##type=" << RagTime5StructManager::printType(type) << ",";
278
0
      break;
279
0
    }
280
0
    return true;
281
0
  }
282
};
283
284
SerieTypeParser::~SerieTypeParser()
285
0
{
286
0
}
287
288
//! Internal: the helper to read child text box value(title+label)
289
struct ChildTZoneParser final : public RagTime5StructManager::DataParser {
290
  //! constructor
291
  ChildTZoneParser()
292
0
    : RagTime5StructManager::DataParser("ChartValueTZone")
293
0
  {
294
0
  }
295
  //! destructor
296
  ~ChildTZoneParser() final;
297
  //! try to parse a data
298
  bool parseData(MWAWInputStreamPtr &input, long endPos, RagTime5Zone &/*zone*/, int /*n*/, libmwaw::DebugStream &f) final
299
0
  {
300
0
    long pos=input->tell();
301
0
    long fSz=endPos-pos;
302
0
    if (fSz!=14) {
303
0
      MWAW_DEBUG_MSG(("RagTime5ChartInternal::ChildTZoneParser::parse: bad data size\n"));
304
0
      return false;
305
0
    }
306
0
    for (int i=0; i<5; ++i) { // f0=403d, f5=1|8
307
0
      auto val=static_cast<int>(input->readLong(2));
308
0
      if (val) f << "f" << i << "=" << val << ",";
309
0
    }
310
0
    unsigned long id= input->readULong(4);
311
0
    if ((id&0xfc000000) != 0x4000000) {
312
0
      MWAW_DEBUG_MSG(("RagTime5ChartInternal::ChildTZoneParser::parse: textbox sub[id] seems bad\n"));
313
0
      f << "#partId[h]=" << (id>>26) << ",";
314
0
    }
315
0
    id &= 0x3ffffff;
316
0
    if (id) f << "subId=" << id << ",";
317
0
    return true;
318
0
  }
319
};
320
321
ChildTZoneParser::~ChildTZoneParser()
322
0
{
323
0
}
324
325
//! Internal: the helper to read a ZoneUnknown1's cell ZoneUnknown1
326
struct ZoneUnknown1Parser final : public RagTime5StructManager::DataParser {
327
  //! constructor
328
  ZoneUnknown1Parser()
329
0
    : RagTime5StructManager::DataParser("ChartUnknown1")
330
0
  {
331
0
  }
332
  //! destructor
333
  ~ZoneUnknown1Parser() final;
334
  //! try to parse a data
335
  bool parseData(MWAWInputStreamPtr &input, long endPos, RagTime5Zone &/*zone*/, int /*n*/, libmwaw::DebugStream &f) final
336
0
  {
337
0
    long pos=input->tell();
338
0
    long fSz=endPos-pos;
339
0
    if (fSz!=6) {
340
0
      MWAW_DEBUG_MSG(("RagTime5ChartInternal::ZoneUnknown1Parser::parse: bad data size\n"));
341
0
      return false;
342
0
    }
343
0
    for (int i=0; i<2; ++i) { // f0: constant in the zone 1|18, f1=10..25
344
0
      auto val=static_cast<int>(input->readLong(2));
345
0
      if (val) f << "f" << i << "=" << val << ",";
346
0
    }
347
0
    auto val=static_cast<int>(input->readULong(2)); // always 0|4
348
0
    if (val!=4)
349
0
      f << "f2=" << val << ",";
350
0
    return true;
351
0
  }
352
};
353
354
ZoneUnknown1Parser::~ZoneUnknown1Parser()
355
0
{
356
0
}
357
358
//! Internal: the helper to read a ZoneUnknown3's cell ZoneUnknown3
359
struct ZoneUnknown3Parser final : public RagTime5StructManager::DataParser {
360
  //! constructor
361
0
  ZoneUnknown3Parser() : RagTime5StructManager::DataParser("ChartUnknown3")
362
0
  {
363
0
  }
364
  //! destructor
365
  ~ZoneUnknown3Parser() final;
366
  //! try to parse a data
367
  bool parseData(MWAWInputStreamPtr &input, long endPos, RagTime5Zone &/*zone*/, int /*n*/, libmwaw::DebugStream &f) final
368
0
  {
369
0
    long pos=input->tell();
370
0
    long fSz=endPos-pos;
371
0
    if (fSz!=32) {
372
0
      MWAW_DEBUG_MSG(("RagTime5ChartInternal::ZoneUnknown3Parser::parse: bad data size\n"));
373
0
      return false;
374
0
    }
375
0
    for (int i=0; i<16; ++i) { // f1=1, f3=800, f8=9
376
0
      auto val=static_cast<int>(input->readLong(2));
377
0
      if (val) f << "f" << i << "=" << val << ",";
378
0
    }
379
0
    return true;
380
0
  }
381
};
382
383
ZoneUnknown3Parser::~ZoneUnknown3Parser()
384
0
{
385
0
}
386
387
////////////////////////////////////////
388
//! Internal: the state of a RagTime5Chart
389
struct State {
390
  //! constructor
391
  State()
392
81.1k
    : m_numPages(0)
393
81.1k
  {
394
81.1k
  }
395
  //! the number of pages
396
  int m_numPages;
397
};
398
399
}
400
401
////////////////////////////////////////////////////////////
402
// constructor/destructor, ...
403
////////////////////////////////////////////////////////////
404
RagTime5Chart::RagTime5Chart(RagTime5Document &doc)
405
81.1k
  : m_document(doc)
406
81.1k
  , m_structManager(m_document.getStructManager())
407
81.1k
  , m_styleManager(m_document.getStyleManager())
408
81.1k
  , m_parserState(m_document.getParserState())
409
81.1k
  , m_state(new RagTime5ChartInternal::State)
410
81.1k
{
411
81.1k
}
412
413
RagTime5Chart::~RagTime5Chart()
414
81.1k
{ }
415
416
int RagTime5Chart::version() const
417
0
{
418
0
  return m_parserState->m_version;
419
0
}
420
421
int RagTime5Chart::numPages() const
422
0
{
423
  // TODO IMPLEMENT ME
424
0
  MWAW_DEBUG_MSG(("RagTime5Chart::numPages: is not implemented\n"));
425
0
  return 0;
426
0
}
427
428
////////////////////////////////////////////////////////////
429
//
430
// Intermediate level
431
//
432
////////////////////////////////////////////////////////////
433
434
////////////////////////////////////////////////////////////
435
//
436
// Low level
437
//
438
////////////////////////////////////////////////////////////
439
440
////////////////////////////////////////////////////////////
441
// interface send function
442
////////////////////////////////////////////////////////////
443
444
void RagTime5Chart::flushExtra()
445
0
{
446
0
  MWAW_DEBUG_MSG(("RagTime5Chart::flushExtra: is not implemented\n"));
447
0
}
448
449
////////////////////////////////////////////////////////////
450
// cluster parser
451
////////////////////////////////////////////////////////////
452
453
namespace RagTime5ChartInternal
454
{
455
//! low level: the chart cluster data
456
struct ClusterChart final : public RagTime5ClusterManager::Cluster {
457
  //! constructor
458
  ClusterChart()
459
1.04k
    : RagTime5ClusterManager::Cluster(C_ChartZone)
460
1.04k
    , m_typesLink()
461
1.04k
    , m_unknownLink1()
462
1.04k
    , m_unknownLink3()
463
1.04k
  {
464
1.04k
  }
465
  //! destructor
466
  ~ClusterChart() final;
467
  //! some content zone: first a double zone, second link to sub text zone data
468
  std::vector<RagTime5ClusterManager::Link> m_valuesLink[2];
469
  //! list of type link
470
  RagTime5ClusterManager::Link m_typesLink;
471
  //! unknown link of size 6
472
  RagTime5ClusterManager::Link m_unknownLink1;
473
  //! unknown link of size 32
474
  RagTime5ClusterManager::Link m_unknownLink3;
475
};
476
477
ClusterChart::~ClusterChart()
478
1.04k
{
479
1.04k
}
480
481
//
482
//! low level: parser of chart cluster
483
//
484
struct ChartCParser final : public RagTime5ClusterManager::ClusterParser {
485
  //! the different field types
486
  enum Type {
487
    F_ParentLink, F_Prefs, F_Pref, F_Series, F_Series2, F_Serie, F_SerieTypes, F_Settings, F_Setting, F_Values, F_Values2, F_Value,
488
    F_DZone1, F_DZones3, F_DZone3, F_DZone5, F_DZone8, F_DZone9, F_DZones10, F_DZone10,
489
    F_DZoneF12, F_DZoneF70, F_DZoneF226,
490
    F_ChartList,
491
    F_UnknZone1, F_UnknZone2,
492
    F_Unknown
493
  };
494
  //! a small structure used to stored a field type
495
  struct ZoneType {
496
    //! constructor
497
    ZoneType()
498
80.7k
      : m_type(F_Unknown)
499
80.7k
      , m_id(-1)
500
80.7k
    {
501
80.7k
    }
502
    //! return the zone type name
503
    std::string getName() const
504
36.8k
    {
505
36.8k
      std::stringstream s;
506
36.8k
      switch (m_type) {
507
969
      case F_ParentLink:
508
969
        s << "parent[list]";
509
969
        break;
510
0
      case F_Prefs: // unsure
511
0
        s << "pref[list]";
512
0
        break;
513
0
      case F_Pref: // unsure
514
0
        s << "pref";
515
0
        break;
516
2.04k
      case F_Series:
517
2.04k
        s << "serie[list1]";
518
2.04k
        break;
519
805
      case F_Series2:
520
805
        s << "serie[list2]";
521
805
        break;
522
2.05k
      case F_Serie:
523
2.05k
        s << "serie";
524
2.05k
        break;
525
2.04k
      case F_SerieTypes:
526
2.04k
        s << "serie[types]";
527
2.04k
        break;
528
2.05k
      case F_Settings:
529
2.05k
        s << "setting[list]";
530
2.05k
        break;
531
2.50k
      case F_Setting:
532
2.50k
        s << "setting";
533
2.50k
        break;
534
0
      case F_ChartList:
535
0
        s << "charList";
536
0
        break;
537
1.93k
      case F_Values:
538
1.93k
        s << "value[list1]";
539
1.93k
        break;
540
0
      case F_Values2: // column value size 18 or 22 or 24 ?
541
0
        s << "value[list2]";
542
0
        break;
543
0
      case F_Value:
544
0
        s << "value";
545
0
        break;
546
2.05k
      case F_DZone1:
547
2.05k
        s << "dZone1";
548
2.05k
        break;
549
2.01k
      case F_DZone5:
550
2.01k
        s << "dZone5";
551
2.01k
        break;
552
2.04k
      case F_DZones3:
553
2.04k
        s << "dZone3[list]";
554
2.04k
        break;
555
2.49k
      case F_DZone3:
556
2.49k
        s << "dZone3";
557
2.49k
        break;
558
2.03k
      case F_DZone8:
559
2.03k
        s << "dZone8";
560
2.03k
        break;
561
2.05k
      case F_DZone9:
562
2.05k
        s << "dZone9";
563
2.05k
        break;
564
2.05k
      case F_DZones10:
565
2.05k
        s << "dZone10[list]";
566
2.05k
        break;
567
2.49k
      case F_DZone10:
568
2.49k
        s << "dZone10";
569
2.49k
        break;
570
2.45k
      case F_DZoneF12: // size 12 or 20
571
2.45k
        s << "dZone12";
572
2.45k
        break;
573
0
      case F_DZoneF70:
574
0
        s << "dZone70";
575
0
        break;
576
2.72k
      case F_DZoneF226:
577
2.72k
        s << "dZone226";
578
2.72k
        break;
579
0
      case F_UnknZone1:
580
0
        s << "unkZone1";
581
0
        break;
582
0
      case F_UnknZone2:
583
0
        s << "unkZone2";
584
0
        break;
585
0
      case F_Unknown:
586
#if !defined(__clang__)
587
      default:
588
#endif
589
0
        s << "unknown";
590
0
        break;
591
36.8k
      }
592
36.8k
      if (m_id>=0) s << "[" << m_id << "]";
593
36.8k
      return s.str();
594
36.8k
    }
595
    //! the field type
596
    Type m_type;
597
    //! the field local id
598
    int m_id;
599
  };
600
  //! constructor
601
  ChartCParser(RagTime5ClusterManager &parser, int type, libmwaw::DebugFile &ascii)
602
1.04k
    : ClusterParser(parser, type, "ClustChart")
603
1.04k
    , m_cluster(new ClusterChart)
604
1.04k
    , m_chart(new Chart)
605
1.04k
    , m_what(-1)
606
1.04k
    , m_linkId(-1)
607
1.04k
    , m_fieldName("")
608
1.04k
    , m_zoneType()
609
1.04k
    , m_fieldIdToZoneTypeMap()
610
1.04k
    , m_zoneToParseSet()
611
1.04k
    , m_asciiFile(ascii)
612
1.04k
  {
613
1.04k
  }
614
  //! destructor
615
  ~ChartCParser() final;
616
  //! return the current cluster
617
  std::shared_ptr<RagTime5ClusterManager::Cluster> getCluster() final
618
1.04k
  {
619
1.04k
    return m_cluster;
620
1.04k
  }
621
  //! return the current cluster
622
  std::shared_ptr<ClusterChart> getChartCluster()
623
2.09k
  {
624
2.09k
    return m_cluster;
625
2.09k
  }
626
  //! return the chart
627
  std::shared_ptr<Chart> getChart()
628
2.09k
  {
629
2.09k
    return m_chart;
630
2.09k
  }
631
  //! insert a new zone to be parsed
632
  void insertZoneToBeParsed(int id, ZoneType const &type, bool canBeDuplicated=false)
633
33.6k
  {
634
33.6k
    if (canBeDuplicated && m_fieldIdToZoneTypeMap.find(id)!=m_fieldIdToZoneTypeMap.end() &&
635
5.43k
        m_fieldIdToZoneTypeMap.find(id)->second.m_type==type.m_type)
636
5.42k
      return;
637
28.2k
    if (id<0 || m_fieldIdToZoneTypeMap.find(id)!=m_fieldIdToZoneTypeMap.end()) {
638
225
      MWAW_DEBUG_MSG(("RagTime5ChartInternal::ChartCParser::insertZoneToParse: oops the zone %d seems bad\n", id));
639
225
      return;
640
225
    }
641
28.0k
    m_fieldIdToZoneTypeMap[id]=type;
642
28.0k
    m_zoneToParseSet.insert(id);
643
28.0k
  }
644
  //! try to check the father type
645
  bool checkFatherType(int id, Type type) const
646
2.45k
  {
647
2.45k
    if (m_fieldIdToZoneTypeMap.find(id)==m_fieldIdToZoneTypeMap.end() ||
648
2.45k
        m_fieldIdToZoneTypeMap.find(id)->second.m_type!=type) {
649
0
      MWAW_DEBUG_MSG(("RagTime5ChartInternal::ChartCParser::insertZoneToParse: can not check the father type for %d\n", id));
650
0
      return false;
651
0
    }
652
2.45k
    return true;
653
2.45k
  }
654
  /** returns to new zone to parse. -1: means no preference, 0: means first zone, ...
655
   */
656
  int getNewZoneToParse() final
657
27.1k
  {
658
27.1k
    if (m_zoneToParseSet.empty())
659
1.11k
      return -1;
660
26.0k
    int id=*(m_zoneToParseSet.begin());
661
26.0k
    m_zoneToParseSet.erase(id);
662
26.0k
    return id;
663
27.1k
  }
664
  //! end of a start zone call
665
  void endZone() final
666
26.6k
  {
667
26.6k
    if (m_link.empty())
668
18.1k
      return;
669
8.54k
    switch (m_zoneType.m_type) {
670
2.48k
    case F_Setting:
671
2.48k
      if (m_zoneType.m_id<0 || m_zoneType.m_id>=3 ||
672
2.48k
          !m_chart->m_settingZone.m_listLinkId[m_zoneType.m_id].empty()) {
673
0
        MWAW_DEBUG_MSG(("RagTime5ChartInternal::ChartCParser::endZone: oops setting%d link is already set\n", m_zoneType.m_id));
674
0
        m_cluster->m_linksList.push_back(m_link);
675
0
        return;
676
0
      }
677
2.48k
      m_link.m_name=std::string("ChartSetting_")+char('0'+m_zoneType.m_id);
678
2.48k
      m_chart->m_settingZone.m_listLinkId[m_zoneType.m_id]=m_link;
679
2.48k
      return;
680
2.47k
    case F_DZone3:
681
2.47k
      if (m_zoneType.m_id<0 || m_zoneType.m_id>=3 ||
682
2.47k
          !m_chart->m_zone3.m_listLinkId[m_zoneType.m_id].empty()) {
683
0
        MWAW_DEBUG_MSG(("RagTime5ChartInternal::ChartCParser::endZone: oops zone3%d link is already set\n", m_zoneType.m_id));
684
0
        m_cluster->m_linksList.push_back(m_link);
685
0
        return;
686
0
      }
687
2.47k
      m_link.m_name=std::string("ChartDZone3_")+char('0'+m_zoneType.m_id);
688
2.47k
      m_chart->m_zone3.m_listLinkId[m_zoneType.m_id]=m_link;
689
2.47k
      return;
690
1.66k
    case F_DZone10:
691
1.66k
      if (m_zoneType.m_id<0 || m_zoneType.m_id>=2 ||
692
1.66k
          !m_chart->m_zone10.m_listLinkId[m_zoneType.m_id].empty()) {
693
0
        MWAW_DEBUG_MSG(("RagTime5ChartInternal::ChartCParser::endZone: oops zone10%d link is already set\n", m_zoneType.m_id));
694
0
        m_cluster->m_linksList.push_back(m_link);
695
0
        return;
696
0
      }
697
1.66k
      m_link.m_name=std::string("ChartDZone10_")+char('0'+m_zoneType.m_id);
698
1.66k
      m_chart->m_zone10.m_listLinkId[m_zoneType.m_id]=m_link;
699
1.66k
      return;
700
943
    case F_ParentLink:
701
943
      if (m_cluster->m_parentLink.empty())
702
943
        m_cluster->m_parentLink=m_link;
703
0
      else {
704
0
        MWAW_DEBUG_MSG(("RagTime5ChartInternal::ChartCParser::endZone: oops parent link is already set\n"));
705
0
        m_cluster->m_linksList.push_back(m_link);
706
0
      }
707
943
      return;
708
0
    case F_SerieTypes:
709
0
      if (m_cluster->m_typesLink.empty())
710
0
        m_cluster->m_typesLink=m_link;
711
0
      else {
712
0
        MWAW_DEBUG_MSG(("RagTime5ChartInternal::ChartCParser::endZone: oops serie types link is already set\n"));
713
0
        m_cluster->m_linksList.push_back(m_link);
714
0
      }
715
0
      return;
716
981
    case F_DZone5: // a link to some data but never fills in my file
717
981
      if (m_link.m_fieldSize>0) {
718
0
        MWAW_DEBUG_MSG(("RagTime5ChartInternal::ChartCParser::endZone: find unexpected not empty zone 5's link\n"));
719
0
      }
720
981
      m_cluster->m_linksList.push_back(m_link);
721
981
      return;
722
0
    case F_UnknZone1:
723
0
      if (m_cluster->m_unknownLink1.empty())
724
0
        m_cluster->m_unknownLink1=m_link;
725
0
      else {
726
0
        MWAW_DEBUG_MSG(("RagTime5ChartInternal::ChartCParser::endZone: oops unknown1 link is already set\n"));
727
0
        m_cluster->m_linksList.push_back(m_link);
728
0
      }
729
0
      return;
730
0
    case F_DZoneF70:
731
0
      if (m_cluster->m_unknownLink3.empty())
732
0
        m_cluster->m_unknownLink3=m_link;
733
0
      else {
734
0
        MWAW_DEBUG_MSG(("RagTime5ChartInternal::ChartCParser::endZone: oops unknown1 link is already set\n"));
735
0
        m_cluster->m_linksList.push_back(m_link);
736
0
      }
737
0
      return;
738
0
    case F_Pref:
739
0
    case F_Prefs:
740
0
    case F_Series:
741
0
    case F_Series2:
742
0
    case F_Settings:
743
0
    case F_Values:
744
0
    case F_DZone1:
745
0
    case F_DZones3:
746
0
    case F_DZone8:
747
0
    case F_DZone9:
748
0
    case F_DZones10:
749
0
    case F_DZoneF12:
750
0
    case F_Values2:
751
0
      MWAW_DEBUG_MSG(("RagTime5ChartInternal::ChartCParser::endZone: oops find unexpected link for zone %s\n", m_zoneType.getName().c_str()));
752
0
      m_cluster->m_linksList.push_back(m_link);
753
0
      return;
754
0
    case F_ChartList:
755
0
    case F_DZoneF226:
756
0
    case F_UnknZone2:
757
0
    case F_Serie:
758
0
    case F_Value:
759
0
    case F_Unknown:
760
#if !defined(__clang__)
761
    default:
762
#endif
763
0
      break;
764
8.54k
    }
765
766
0
    switch (m_linkId) {
767
0
    case 1:
768
0
    case 2:
769
0
      m_cluster->m_valuesLink[m_linkId-1].push_back(m_link);
770
0
      break;
771
0
    default:
772
0
      m_cluster->m_linksList.push_back(m_link);
773
0
      break;
774
0
    }
775
0
  }
776
  //! parse a zone
777
  bool parseZone(MWAWInputStreamPtr &input, long fSz, int N, int flag, libmwaw::DebugStream &f) final
778
26.6k
  {
779
26.6k
    m_linkId=-1;
780
26.6k
    m_fieldName="";
781
26.6k
    if (N==-5)
782
1.04k
      return parseHeaderZone(input,fSz,N,flag,f);
783
25.6k
    if (N<0) {
784
90
      MWAW_DEBUG_MSG(("RagTime5ChartInternal::ChartCParser::parseZone: expected N value\n"));
785
90
      f << "###N=" << N << ",";
786
90
      return true;
787
90
    }
788
25.5k
    m_what=1;
789
25.5k
    return parseDataZone(input, fSz, N, flag, f);
790
25.6k
  }
791
  //! parse a field
792
  bool parseField(RagTime5StructManager::Field const &field, int /*m*/, libmwaw::DebugStream &f) final
793
9.78k
  {
794
9.78k
    if (!m_fieldName.empty())
795
9.47k
      f << m_fieldName << ",";
796
797
9.78k
    switch (m_what) {
798
0
    case 0: // header
799
0
      if (field.m_type==RagTime5StructManager::Field::T_LongList && field.m_fileType==0x3c057) {
800
0
        f << "unkn0=[";
801
0
        for (auto const id : field.m_longList)
802
0
          f << id << ","; // 15
803
0
        f << "],";
804
0
        break;
805
0
      }
806
0
      break;
807
8.58k
    case 2: // list link
808
8.58k
      if (field.m_type==RagTime5StructManager::Field::T_LongList && field.m_fileType==0xce842) {
809
8.53k
        f << "pos=[";
810
95.1k
        for (auto const &val : field.m_longList) {
811
95.1k
          if (val>1000)
812
10.8k
            f << std::hex << val << std::dec << ",";
813
84.3k
          else
814
84.3k
            f << val << ",";
815
95.1k
        }
816
8.53k
        f << "],";
817
8.53k
        m_link.m_longList=field.m_longList;
818
8.53k
        break;
819
8.53k
      }
820
50
      if (m_zoneType.m_type==F_Setting || m_zoneType.m_type==F_DZone3 ||
821
50
          m_zoneType.m_type==F_DZone5 || m_zoneType.m_type==F_DZone10) {
822
50
        MWAW_DEBUG_MSG(("RagTime5ChartInternal::ChartCParser::parseField: find unexpected list link field\n"));
823
50
        f << "###" << field;
824
50
        break;
825
50
      }
826
0
      if (field.m_type==RagTime5StructManager::Field::T_Unstructured && field.m_fileType==0xce017) {
827
        // a small value 2|4|a|1c|40
828
0
        f << "unkn="<<field.m_extra << ",";
829
0
        break;
830
0
      }
831
0
      if (m_zoneType.m_type==F_ParentLink) {
832
0
        MWAW_DEBUG_MSG(("RagTime5ChartInternal::ChartCParser::parseField: find unexpected list link field\n"));
833
0
        f << "###" << field;
834
0
        break;
835
0
      }
836
0
      if (field.m_type==RagTime5StructManager::Field::T_LongList && field.m_fileType==0xcf042) {
837
0
        f << "unkn=[";
838
0
        for (auto val : field.m_longList) {
839
0
          if (val==0)
840
0
            f << "_,";
841
0
          else
842
0
            f << val << ",";
843
0
        }
844
0
        break;
845
0
      }
846
0
      MWAW_DEBUG_MSG(("RagTime5ChartInternal::ChartCParser::parseField: find unexpected list link field\n"));
847
0
      f << "###" << field;
848
0
      break;
849
831
    case 3:
850
831
      if (field.m_type==RagTime5StructManager::Field::T_LongList && field.m_fileType==0xcf042) {
851
831
        bool listPos=false, canBeDupplicated=false;
852
831
        ZoneType zoneType;
853
831
        if (m_zoneType.m_type==F_Series || m_zoneType.m_type==F_Series2) {
854
0
          listPos=true;
855
0
          zoneType.m_type=F_Serie;
856
0
          canBeDupplicated=true;
857
0
        }
858
831
        else if (m_zoneType.m_type==F_Values) {
859
0
          listPos=true;
860
0
          zoneType.m_type=F_Value;
861
0
          canBeDupplicated=true;
862
0
        }
863
831
        else if (m_zoneType.m_type==F_DZone10 && m_zoneType.m_id==2) {
864
831
          listPos=true;
865
831
          zoneType.m_type=F_DZoneF226;
866
831
          canBeDupplicated=true;
867
831
        }
868
0
        else if (m_zoneType.m_type==F_Prefs) {
869
0
          listPos=true;
870
0
          zoneType.m_type=F_Pref;
871
0
        }
872
831
        if (listPos)
873
831
          f << "child=[";
874
0
        else
875
0
          f << "unkn=[";
876
3.32k
        for (size_t j=0; j<field.m_longList.size(); ++j) {
877
2.49k
          if (field.m_longList[j]==0)
878
0
            f << "_,";
879
2.49k
          else if (listPos) {
880
2.49k
            f << "F" << field.m_longList[j]-1 << ",";
881
2.49k
            zoneType.m_id=int(j);
882
2.49k
            insertZoneToBeParsed(int(field.m_longList[j])-1, zoneType,canBeDupplicated);
883
2.49k
          }
884
0
          else
885
0
            f << field.m_longList[j] << ",";
886
2.49k
        }
887
831
        f << "],";
888
831
        break;
889
831
      }
890
0
      MWAW_DEBUG_MSG(("RagTime5ChartInternal::ChartCParser::parseField: find unexpected data4 field\n"));
891
0
      f << "###" << field;
892
0
      break;
893
0
    case 4: // UnknZone1
894
0
      if (field.m_type==RagTime5StructManager::Field::T_Long && field.m_fileType==0xcf817) {
895
0
        f << "unkn=" << field.m_longValue[0]; // 56|87
896
0
        break;
897
0
      }
898
0
      MWAW_DEBUG_MSG(("RagTime5ChartInternal::ChartCParser::parseField: find unexpected what=4 field\n"));
899
0
      f << "###" << field;
900
0
      break;
901
0
    case 5: // Pref
902
0
      if (field.m_type==RagTime5StructManager::Field::T_FieldList && field.m_fileType==0x16c1825) {
903
0
        for (auto const &child : field.m_fieldList) {
904
0
          if (child.m_type==RagTime5StructManager::Field::T_FieldList && child.m_fileType==0x42040) {
905
0
            f << child;
906
0
            continue;
907
0
          }
908
0
          MWAW_DEBUG_MSG(("RagTime5GraphInternal::SpreadsheetCParser::parseField: find unexpected child[fSz=91]\n"));
909
0
          f << "##[" << child << "],";
910
0
        }
911
0
        break;
912
0
      }
913
0
      MWAW_DEBUG_MSG(("RagTime5ChartInternal::ChartCParser::parseField: find unexpected preferences field\n"));
914
0
      f << "###" << field;
915
0
      break;
916
366
    default:
917
366
      MWAW_DEBUG_MSG(("RagTime5ChartInternal::ChartCParser::parseField: find unexpected field\n"));
918
366
      f << "###" << field;
919
366
      break;
920
9.78k
    }
921
9.78k
    return true;
922
9.78k
  }
923
protected:
924
  //! parse a data block
925
  bool parseDataZone(MWAWInputStreamPtr &input, long fSz, int N, int flag, libmwaw::DebugStream &f)
926
25.5k
  {
927
25.5k
    f << "fl=" << std::hex << flag << std::dec << ",";
928
25.5k
    m_zoneType=ZoneType();
929
25.5k
    if (m_fieldIdToZoneTypeMap.find(m_dataId)!=m_fieldIdToZoneTypeMap.end())
930
25.3k
      m_zoneType=m_fieldIdToZoneTypeMap.find(m_dataId)->second;
931
25.5k
    long pos=input->tell();
932
25.5k
    m_link.m_N=N;
933
25.5k
    int val;
934
25.5k
    long linkValues[4];
935
25.5k
    std::string mess("");
936
25.5k
    if (m_zoneType.m_type==F_Unknown)
937
199
      f << "@";
938
25.3k
    else
939
25.3k
      f << "[F" << m_dataId << "],";
940
25.5k
    switch (m_zoneType.m_type) {
941
969
    case F_ParentLink:
942
969
      if (fSz!=36 || !readLinkHeader(input, fSz, m_link, linkValues, mess)) {
943
26
        MWAW_DEBUG_MSG(("RagTime5ChartInternal::ChartCParser::parseDataZone: can not read a link for parent list\n"));
944
26
        f << "###";
945
26
        break;
946
26
      }
947
943
      if ((m_link.m_fileType[1]&0xFFD7)!=0x10) {
948
0
        MWAW_DEBUG_MSG(("RagTime5ChartInternal::ChartCParser::parseDataZone: the fileType1 seems bad\n"));
949
0
        f << "###fileType1=" << std::hex << m_link.m_fileType[1] << std::dec << ",";
950
0
      }
951
      // a cluster zone with field of size 60...
952
943
      m_link.m_name="ChartParentLst";
953
943
      m_what=2;
954
943
      f << m_link << "," << mess;
955
      // now 2 int
956
2.82k
      for (int i=0; i<2; ++i) {
957
1.88k
        val=static_cast<int>(input->readLong(2));
958
1.88k
        if (val) f << "f" << i << "=" << val << ",";
959
1.88k
      }
960
943
      break;
961
0
    case F_Prefs:
962
0
      if (fSz==36) {
963
0
        val=static_cast<int>(input->readLong(4));
964
0
        if (val) f << "#f0=" << val << ",";
965
0
        val=static_cast<int>(input->readLong(4));
966
0
        if (val!=0x17db042) {
967
0
          MWAW_DEBUG_MSG(("RagTime5ChartInternal::ChartCParser::parseZone: find unexpected type0\n"));
968
0
          f << "#fileType0=" << std::hex << val << std::dec << ",";
969
0
        }
970
0
        for (int i=0; i<2; ++i) {
971
0
          val=static_cast<int>(input->readLong(4));
972
0
          if (val) f << "f" << i+1 << "=" << val << ",";
973
0
        }
974
0
        val=static_cast<int>(input->readULong(2));
975
0
        if ((val&0xFFD7)!=0x10) {
976
0
          MWAW_DEBUG_MSG(("RagTime5ChartInternal::ChartCParser::parseZone: find unexpected type1[fSz36]\n"));
977
0
          f << "#fileType1=" << std::hex << val << std::dec << ",";
978
0
        }
979
0
        ZoneType zoneType;
980
0
        zoneType.m_type=F_ChartList;
981
0
        f << "ids=[";
982
0
        for (int i=0; i<3; ++i) {
983
0
          val=static_cast<int>(input->readLong(4));
984
0
          if (!val) {
985
0
            f << "_,";
986
0
            continue;
987
0
          }
988
0
          zoneType.m_id=i;
989
0
          insertZoneToBeParsed(val-1, zoneType);
990
0
          f << "F" << val-1 << ",";
991
0
        }
992
0
        f << "],";
993
0
        break;
994
0
      }
995
0
      if (fSz!=29 || !readLinkHeader(input, fSz, m_link, linkValues, mess)) {
996
0
        MWAW_DEBUG_MSG(("RagTime5ChartInternal::ChartCParser::parseDataZone: can not read a link for prefs list\n"));
997
0
        f << "###";
998
0
        break;
999
0
      }
1000
0
      m_what=3;
1001
0
      if (m_link.m_fileType[0]!=0x3c052) {
1002
0
        MWAW_DEBUG_MSG(("RagTime5ChartInternal::ChartCParser::parseDataZone: fileType0 seems odd for prefs list\n"));
1003
0
        f << "###fileType0=" << RagTime5StructManager::printType(m_link.m_fileType[0]) << std::dec << ",";
1004
0
      }
1005
0
      if ((m_link.m_fileType[1]&0xFFD7)!=0x50) {
1006
0
        MWAW_DEBUG_MSG(("RagTime5ChartInternal::ChartCParser::parseDataZone: fileType1 seems odd for prefs list\n"));
1007
0
        f << "###fileType1=" << std::hex << m_link.m_fileType[1] << std::dec << ",";
1008
0
      }
1009
0
      val=static_cast<int>(input->readLong(1)); // always 1
1010
0
      if (val!=1)
1011
0
        f << "f0=" << val << ",";
1012
0
      break;
1013
1.00k
    case F_Series: {
1014
1.00k
      if (fSz!=35 && fSz!=40) {
1015
20
        MWAW_DEBUG_MSG(("RagTime5ChartInternal::ChartCParser::parseDataZone: find unexpected size for series list1\n"));
1016
20
        f << "###";
1017
20
        break;
1018
20
      }
1019
981
      m_what=3;
1020
981
      if (m_dataId!=4) {
1021
0
        MWAW_DEBUG_MSG(("RagTime5ChartInternal::ChartCParser::parseDataZone: the zone id seems bad\n"));
1022
0
        f << "##zoneId=" << m_dataId << ",";
1023
0
      }
1024
981
      auto type=input->readULong(4);
1025
981
      if (type && type!=0x3c052) {
1026
0
        MWAW_DEBUG_MSG(("RagTime5ChartInternal::ChartCParser::parseDataZone:fileType0 seems bad\n"));
1027
0
        f << "##fileType0=" << RagTime5StructManager::printType(type) << ",";
1028
0
      }
1029
3.92k
      for (int i=0; i<3; ++i) { // f2=0|16a88a7
1030
2.94k
        type=input->readULong(4);
1031
2.94k
        if (type) f << "f" << i << "=" << RagTime5StructManager::printType(type) << ",";
1032
2.94k
      }
1033
981
      val=static_cast<int>(input->readULong(2)); // 67|6f
1034
981
      if ((val&0xFFF7)!=0x67)
1035
0
        f << "f3=" << val << ",";
1036
3.92k
      for (int i=0; i<3; ++i) { // always 0,0,0x100
1037
2.94k
        val=static_cast<int>(input->readULong(2));
1038
2.94k
        if (val) f << "f" << i+4 << "=" << val << ",";
1039
2.94k
      }
1040
981
      if (fSz==40) {
1041
0
        for (int i=0; i<5; ++i) { // always 0
1042
0
          val=static_cast<int>(input->readULong(1));
1043
0
          if (val) f << "f" << i+7 << "=" << val << ",";
1044
0
        }
1045
0
      }
1046
981
      val=static_cast<int>(input->readULong(1)); // always 0
1047
981
      if (val) f << "g0=" << val << ",";
1048
2.94k
      for (int i=0; i<2; ++i) { // 1,1-4
1049
1.96k
        val=static_cast<int>(input->readULong(2));
1050
1.96k
        if (val) f << "f" << i+4 << "=" << val << ",";
1051
1.96k
      }
1052
981
      break;
1053
1.00k
    }
1054
805
    case F_Series2: {
1055
805
      if (fSz!=29 && fSz!=34) {
1056
0
        MWAW_DEBUG_MSG(("RagTime5ChartInternal::ChartCParser::parseDataZone: find unexpected size for series list 2\n"));
1057
0
        f << "###";
1058
0
        break;
1059
0
      }
1060
805
      f << "father=A" << N-1 << ",";
1061
805
      m_what=3;
1062
805
      auto type=input->readULong(4);
1063
805
      if (type!=0x16c2042) {
1064
0
        MWAW_DEBUG_MSG(("RagTime5ChartInternal::ChartCParser::parseDataZone: filetype0 seems bad\n"));
1065
0
        f << "###fileType0=" << RagTime5StructManager::printType(type) << ",";
1066
0
      }
1067
5.63k
      for (int i=0; i<6; ++i) { // always 0
1068
4.83k
        val=static_cast<int>(input->readLong(2));
1069
4.83k
        if (val) f << "f" << i << "=" << val << ",";
1070
4.83k
      }
1071
805
      val=static_cast<int>(input->readULong(2));
1072
805
      if (val!=0x70) {
1073
0
        MWAW_DEBUG_MSG(("RagTime5ChartInternal::ChartCParser::parseDataZone: the filetype1  seems bad\n"));
1074
0
        f << "###fileType1=" << std::hex << val << std::dec << ",";
1075
0
      }
1076
4.83k
      for (int i=0; i<5; ++i) { //g2=0|256
1077
4.02k
        val=static_cast<int>(input->readLong(fSz==29 ? 1 : 2));
1078
4.02k
        if (val) f << "g" << i << "=" << val << ",";
1079
4.02k
      }
1080
805
      break;
1081
805
    }
1082
1.00k
    case F_Settings: { // second zone, no auxiliar data
1083
1.00k
      if (fSz!=38) {
1084
20
        MWAW_DEBUG_MSG(("RagTime5ChartInternal::ChartCParser::parseDataZone: the settings size seems bad\n"));
1085
20
        f << "###";
1086
20
        break;
1087
20
      }
1088
988
      auto type=input->readULong(4);
1089
988
      if (type!=0x47040) {
1090
0
        MWAW_DEBUG_MSG(("RagTime5ChartInternal::ChartCParser::parseDataZone:fileType0 seems bad\n"));
1091
0
        f << "##fileType0=" << RagTime5StructManager::printType(type) << ",";
1092
0
      }
1093
5.92k
      for (int i=0; i<5; ++i) { // always 0
1094
4.94k
        val=static_cast<int>(input->readLong(2));
1095
4.94k
        if (val) f << "f" << i << "=" << val << ",";
1096
4.94k
      }
1097
1098
988
      val=static_cast<int>(input->readLong(4)); // often 16
1099
988
      if (val!=16) f << "unk=" << val << ",";
1100
988
      ZoneType zoneType;
1101
988
      zoneType.m_type=F_Setting;
1102
988
      int listIds[3];
1103
2.96k
      for (auto &id : listIds) id=static_cast<int>(input->readLong(4));
1104
3.95k
      for (int i=0; i<3; ++i) {
1105
2.96k
        if (!listIds[i]) {
1106
0
          f << "_,";
1107
0
          continue;
1108
0
        }
1109
2.96k
        f << "F" << listIds[i]-1 << ",";
1110
2.96k
        zoneType.m_id=i;
1111
2.96k
        insertZoneToBeParsed(listIds[i]-1, zoneType);
1112
2.96k
      }
1113
1114
988
      val=static_cast<int>(input->readLong(2)); // always 1
1115
988
      if (val!=1)
1116
0
        f << "f10=" << val << ",";
1117
988
      break;
1118
1.00k
    }
1119
1.00k
    case F_DZones3:
1120
2.00k
    case F_DZones10: {
1121
2.00k
      if (fSz!=36) {
1122
40
        MWAW_DEBUG_MSG(("RagTime5ChartInternal::ChartCParser::parseDataZone: the zone 3 seems odd\n"));
1123
40
        f << "###";
1124
40
        break;
1125
40
      }
1126
1.96k
      input->seek(pos, librevenge::RVNG_SEEK_SET);
1127
1.96k
      auto fType=input->readULong(4);
1128
1.96k
      if (fType && fType!=0x35800) {
1129
25
        MWAW_DEBUG_MSG(("RagTime5ChartInternal::ChartCParser::parseDataZone: the file type 0 seems bad\n"));
1130
25
        f << "##fileType0=" << RagTime5StructManager::printType(fType) << ",";
1131
25
      }
1132
5.88k
      for (int i=0; i<2; ++i) {
1133
3.92k
        val=static_cast<int>(input->readULong(4));
1134
3.92k
        if (val) f << "f" << i << "=" << std::hex << val << std::dec << ",";
1135
3.92k
      }
1136
1.96k
      fType=input->readULong(4);
1137
1.96k
      unsigned long const expectedFileType=m_zoneType.m_type==F_DZones3 ? 0 : 0x16a88a7;
1138
1.96k
      if (fType!=expectedFileType) {
1139
0
        MWAW_DEBUG_MSG(("RagTime5ChartInternal::ChartCParser::parseDataZone: the file type1 seems bad\n"));
1140
0
        f << "##fileType1=" << RagTime5StructManager::printType(fType) << ",";
1141
0
      }
1142
1.96k
      val=static_cast<int>(input->readULong(2));
1143
1.96k
      if (val!=0x10)
1144
0
        f << "f3=" << val << ",";
1145
1.96k
      ZoneType zoneType;
1146
1.96k
      zoneType.m_type= m_zoneType.m_type==F_DZones3 ? F_DZone3 : F_DZone10;
1147
7.85k
      for (int i=0; i<3; ++i) {
1148
5.88k
        val=static_cast<int>(input->readULong(4));
1149
5.88k
        if (!val)
1150
0
          continue;
1151
5.88k
        f << "F" << val-1 << ",";
1152
5.88k
        zoneType.m_id=i;
1153
5.88k
        insertZoneToBeParsed(val-1, zoneType);
1154
5.88k
      }
1155
1.96k
      break;
1156
2.00k
    }
1157
889
    case F_Values: {
1158
889
      if (fSz!=29 && fSz!=34) {
1159
0
        MWAW_DEBUG_MSG(("RagTime5ChartInternal::ChartCParser::parseDataZone: find unexpected size for values list 1\n"));
1160
0
        f << "###";
1161
0
        break;
1162
0
      }
1163
889
      if (!readLinkHeader(input, fSz, m_link, linkValues, mess)) {
1164
0
        MWAW_DEBUG_MSG(("RagTime5ChartInternal::ChartCParser::parseDataZone: can not read the values link\n"));
1165
0
        f << "###link";
1166
0
        break;
1167
0
      }
1168
889
      m_what=3;
1169
889
      if (m_link.m_fileType[0]!=0x3c052) {
1170
0
        MWAW_DEBUG_MSG(("RagTime5ChartInternal::ChartCParser::parseDataZone: find unexpected fieldType0\n"));
1171
0
        f << "###fileType0=" << RagTime5StructManager::printType(m_link.m_fileType[0]) << ",";
1172
0
      }
1173
889
      if ((m_link.m_fileType[1]&0xFFD7)!=0x40) {
1174
0
        MWAW_DEBUG_MSG(("RagTime5ChartInternal::ChartCParser::parseDataZone: find unexpected fieldType1\n"));
1175
0
        f << "###fileType1=" << std::hex << m_link.m_fileType[1] << std::dec << ",";
1176
0
      }
1177
889
      if (fSz==34) {
1178
0
        for (int i=0; i<3; ++i) { // f0=100
1179
0
          val=static_cast<int>(input->readLong(2));
1180
0
          if (val) f << "f" << i << "=" << val << ",";
1181
0
        }
1182
0
      }
1183
889
      val=static_cast<int>(input->readLong(1)); // always 1
1184
889
      if (val!=1)
1185
0
        f << "f0=" << val << ",";
1186
889
      f << m_link << "," << mess;
1187
889
      break;
1188
889
    }
1189
0
    case F_Values2: { // 18, 22 or 24
1190
0
      if (fSz<18) {
1191
0
        MWAW_DEBUG_MSG(("RagTime5ChartInternal::ChartCParser::parseDataZone: find unexpected size for values list2\n"));
1192
0
        f << "###";
1193
0
        break;
1194
0
      }
1195
0
      if (!checkFatherType(N-1, F_Serie))
1196
0
        f << "###";
1197
0
      f << "father=A" << N-1 << ",";
1198
0
      auto type=input->readULong(4);
1199
0
      if (type!=0x7a4a9d && (type&0xFFF00E0)!=0x1fa0000) { // find 0x1fa601e, 0x1fa421c, 0x1faa21d
1200
0
        MWAW_DEBUG_MSG(("RagTime5ChartInternal::ChartCParser::parseDataZone: filetype0 seems bad\n"));
1201
0
        f << "###";
1202
0
      }
1203
0
      f << "fileType0=" << RagTime5StructManager::printType(type) << ",";
1204
0
      int numExtra=int(fSz-10)/4;
1205
0
      f << "child=[";
1206
0
      ZoneType zoneType;
1207
0
      zoneType.m_type=F_Value;
1208
0
      zoneType.m_id=m_zoneType.m_id;
1209
0
      for (int i=0; i<numExtra; ++i) {
1210
0
        val=static_cast<int>(input->readLong(4));
1211
0
        if (!val) {
1212
0
          f << "_,";
1213
0
          continue;
1214
0
        }
1215
0
        f << "F" << val-1 << ",";
1216
0
        insertZoneToBeParsed(val-1, zoneType, true);
1217
0
      }
1218
0
      f << "],";
1219
0
      if ((fSz%4)==0) {
1220
0
        val=static_cast<int>(input->readLong(2));
1221
0
        if (val) f << "g0=" << val << ",";
1222
0
      }
1223
0
      break;
1224
0
    }
1225
    // simple data
1226
0
    case F_Pref: {
1227
0
      if (fSz!=30) {
1228
0
        MWAW_DEBUG_MSG(("RagTime5ChartInternal::ChartCParser::parseDataZone: can not read pref link\n"));
1229
0
        f << "###link";
1230
0
        break;
1231
0
      }
1232
0
      m_what=5;
1233
0
      for (int i=0; i<6; ++i) { // f3=1
1234
0
        val=static_cast<int>(input->readLong(2));
1235
0
        if (val) f << "f" << i << "=" << val << ",";
1236
0
      }
1237
0
      auto type=input->readULong(4);
1238
0
      if (type!=0x16a8842) {
1239
0
        MWAW_DEBUG_MSG(("RagTime5ChartInternal::ChartCParser::parseDataZone: the filetype0 seems bad\n"));
1240
0
        f << "###fileType0=" << RagTime5StructManager::printType(type) << ",";
1241
0
      }
1242
0
      for (int i=0; i<4; ++i) { // g0=1
1243
0
        val=static_cast<int>(input->readLong(2));
1244
0
        if (val) f << "g" << i << "=" << val << ",";
1245
0
      }
1246
0
      break;
1247
0
    }
1248
0
    case F_ChartList: {
1249
0
      if (fSz!=28 && fSz!=30) {
1250
0
        MWAW_DEBUG_MSG(("RagTime5ChartInternal::ChartCParser::parseDataZone: find unexpected size for chart list link\n"));
1251
0
        f << "###";
1252
0
        break;
1253
0
      }
1254
0
      if (!readLinkHeader(input, fSz, m_link, linkValues, mess)) {
1255
0
        MWAW_DEBUG_MSG(("RagTime5ChartInternal::ChartCParser::parseDataZone: can not read the chart list link\n"));
1256
0
        f << "###link";
1257
0
        break;
1258
0
      }
1259
0
      m_what=2;
1260
0
      if ((m_zoneType.m_id==0 &&  m_link.m_fileType[0]!=0x3e800) ||
1261
0
          (m_zoneType.m_id==1 &&  m_link.m_fileType[0]!=0x35800) ||
1262
0
          (m_zoneType.m_id==2 &&  m_link.m_fileType[0]!=0x45080)) {
1263
0
        MWAW_DEBUG_MSG(("RagTime5ChartInternal::ChartCParser::parseDataZone: find unexpected fieldType0\n"));
1264
0
        f << "###fileType0=" << RagTime5StructManager::printType(m_link.m_fileType[0]) << ",";
1265
0
      }
1266
0
      if ((m_link.m_fileType[1]&0xFFD7)!=0) {
1267
0
        MWAW_DEBUG_MSG(("RagTime5ChartInternal::ChartCParser::parseDataZone: find unexpected fieldType1\n"));
1268
0
        f << "###fileType1=" << std::hex << m_link.m_fileType[1] << std::dec << ",";
1269
0
      }
1270
0
      break;
1271
0
    }
1272
1.00k
    case F_Serie: {
1273
1.00k
      if (fSz!=14 && fSz!=116) {
1274
20
        MWAW_DEBUG_MSG(("RagTime5ChartInternal::ChartCParser::parseDataZone: unexpected series field size\n"));
1275
20
        f << "###";
1276
20
        break;
1277
20
      }
1278
4.91k
      for (int i=0; i<4; ++i) { // f2=0|1000
1279
3.92k
        val=static_cast<int>(input->readULong(2));
1280
3.92k
        static int const expected[]= {0,0,0,0x400};
1281
3.92k
        if (val!=expected[i]) f << "f" << i << "=" << std::hex << val << std::dec << ",";
1282
3.92k
      }
1283
982
      if (fSz==14) { // empty
1284
982
        f << "empty,";
1285
982
        break;
1286
982
      }
1287
0
      for (int i=0; i<3; ++i) { // f4=1-23,
1288
0
        val=static_cast<int>(input->readLong(2));
1289
0
        if (val) f << "f" << i+4 << "=" << val << ",";
1290
0
      }
1291
0
      auto zoneId=static_cast<int>(input->readLong(4));
1292
0
      if (zoneId) {
1293
0
        f << "F" << zoneId-1 << ",";
1294
0
        ZoneType zoneType;
1295
0
        zoneType.m_type=F_Values2;
1296
0
        zoneType.m_id=m_zoneType.m_id;
1297
0
        insertZoneToBeParsed(zoneId-1, zoneType);
1298
0
      }
1299
0
      for (int i=0; i<3; ++i) { // f4=1-23,
1300
0
        val=static_cast<int>(input->readLong(2));
1301
0
        if (val) f << "f" << i+7 << "=" << val << ",";
1302
0
      }
1303
0
      f << "num=[";
1304
0
      for (int i=0; i<5; ++i) {
1305
0
        val=static_cast<int>(input->readLong(2));
1306
0
        if (val)
1307
0
          f << val << ",";
1308
0
        else
1309
0
          f << "_,";
1310
0
      }
1311
0
      f << "],";
1312
0
      f << "fl=[";
1313
0
      for (int i=0; i<6; ++i) { // 0|4,1,0|1|e|68,0|1|6|55,2,8
1314
0
        val=static_cast<int>(input->readULong(1));
1315
0
        if (val)
1316
0
          f << std::hex << val << std::dec << ",";
1317
0
        else
1318
0
          f << "_,";
1319
0
      }
1320
0
      f << "],";
1321
0
      double res;
1322
0
      bool isNan;
1323
0
      long actPos;
1324
0
      f << "dim=";
1325
0
      for (int i=0; i<2; ++i) { // always Xx0.2?
1326
0
        actPos=input->tell();
1327
0
        if (!input->readDouble8(res, isNan)) {
1328
0
          MWAW_DEBUG_MSG(("RagTime5ChartInternal::ChartCParser::parseDataZone: can not read a double\n"));
1329
0
          f << "###double";
1330
0
          input->seek(actPos+8, librevenge::RVNG_SEEK_SET);
1331
0
        }
1332
0
        else
1333
0
          f << res;
1334
0
        f << (i==0 ? "x" : ",");
1335
0
      }
1336
0
      val=static_cast<int>(input->readLong(4));
1337
0
      if (val) f << "f12=" << val << ",";
1338
0
      actPos=input->tell();
1339
0
      if (!input->readDouble8(res, isNan)) {
1340
0
        MWAW_DEBUG_MSG(("RagTime5ChartInternal::ChartCParser::parseDataZone: can not read a double\n"));
1341
0
        f << "###double,";
1342
0
        input->seek(actPos+8, librevenge::RVNG_SEEK_SET);
1343
0
      }
1344
0
      else
1345
0
        f << "dim1=" << res << ","; // always 6?
1346
0
      f << "fl2=[";
1347
0
      for (int i=0; i<4; ++i) { // 0|10, 0|80, 8,0|20
1348
0
        val=static_cast<int>(input->readULong(1));
1349
0
        if (val)
1350
0
          f << std::hex << val << std::dec << ",";
1351
0
        else
1352
0
          f << "_,";
1353
0
      }
1354
0
      f << "],";
1355
0
      val=static_cast<int>(input->readLong(2)); // always 0
1356
0
      if (val) f << "g0=" << val << ",";
1357
0
      for (int i=0; i<2; ++i) {
1358
0
        f << "unk" << i << "=[";
1359
0
        for (int j=0; j<3; ++j) { // always _,_,1d8-218,[138]0
1360
0
          val=static_cast<int>(input->readULong(j==1 ? 4 : 2));
1361
0
          if (!val) {
1362
0
            f << "_,";
1363
0
            continue;
1364
0
          }
1365
0
          if (j==1 && m_zoneType.m_type==F_Serie) {
1366
0
            f << "F" << val-1 << ",";
1367
0
            if (i==0 && val==zoneId) continue;
1368
0
            ZoneType zoneType;
1369
0
            zoneType.m_type=i==0 ? F_Values2 :  F_Values;
1370
0
            zoneType.m_id=m_zoneType.m_id;
1371
0
            insertZoneToBeParsed(val-1, zoneType);
1372
0
          }
1373
0
          else
1374
0
            f << std::hex << val << std::dec << ",";
1375
1376
0
        }
1377
0
        f << "],";
1378
0
      }
1379
0
      val=static_cast<int>(input->readLong(4));
1380
0
      if (val) f << "id=" << val << ",";
1381
0
      val=static_cast<int>(input->readLong(4));
1382
0
      if (val) {
1383
0
        f << "unknZone2=F" << val-1 << ",";
1384
0
        ZoneType zoneType;
1385
0
        zoneType.m_type=F_UnknZone2;
1386
0
        zoneType.m_id=m_zoneType.m_id;
1387
0
        insertZoneToBeParsed(val-1, zoneType);
1388
0
      }
1389
0
      for (int i=0; i<6; ++i) {
1390
0
        val=static_cast<int>(input->readLong(2));
1391
0
        if (!val) continue;
1392
0
        f << "g" << i+1 << "=" << val << ",";
1393
0
      }
1394
0
      break;
1395
982
    }
1396
1.00k
    case F_SerieTypes:
1397
1.00k
      if (fSz!=34 || !readLinkHeader(input, fSz, m_link, linkValues, mess)) {
1398
22
        MWAW_DEBUG_MSG(("RagTime5ChartInternal::ChartCParser::parseDataZone: can not read series type link\n"));
1399
22
        f << "###";
1400
22
        break;
1401
22
      }
1402
980
      if (m_link.m_fileType[0]!=0x3e800) {
1403
0
        MWAW_DEBUG_MSG(("RagTime5ChartInternal::ChartCParser::parseDataZone: unexpected fileType0\n"));
1404
0
        f << "###fileType0=" << RagTime5StructManager::printType(m_link.m_fileType[0]) << ",";
1405
0
      }
1406
980
      if ((m_link.m_fileType[1]&0xFFD7)!=0x10) {
1407
0
        MWAW_DEBUG_MSG(("RagTime5ChartInternal::ChartCParser::parseDataZone: unexpected fileType1\n"));
1408
0
        f << "###fileType1=" << std::hex << m_link.m_fileType[1] << std::dec << ",";
1409
0
      }
1410
980
      m_link.m_name="ChartSerieType";
1411
980
      f << m_link << "," << mess;
1412
980
      val=static_cast<int>(input->readLong(4));
1413
980
      if (val) {
1414
980
        ZoneType zoneType;
1415
980
        zoneType.m_type=F_Series2;
1416
980
        f << "serie[list]=F" << val-1 << ",";
1417
980
        insertZoneToBeParsed(val-1, zoneType);
1418
980
      }
1419
980
      break;
1420
2.50k
    case F_Setting: {
1421
2.50k
      if (((fSz!=28 || m_zoneType.m_id>=2) && (fSz!=32 || m_zoneType.m_id!=2)) ||
1422
2.50k
          !readLinkHeader(input, fSz, m_link, linkValues, mess)) {
1423
0
        MWAW_DEBUG_MSG(("RagTime5ChartInternal::ChartCParser::parseDataZone: can not read a setting link\n"));
1424
0
        f << "###link,";
1425
0
        break;
1426
0
      }
1427
2.50k
      m_what=2;
1428
2.50k
      unsigned long const expectedType=m_zoneType.m_id==0 ? 0x3e800 : m_zoneType.m_id==1 ? 0x35800 : 0x47040;
1429
2.50k
      if (m_link.m_fileType[0]!=expectedType) {
1430
0
        MWAW_DEBUG_MSG(("RagTime5ChartInternal::ChartCParser::parseDataZone: unexpected fileType0\n"));
1431
0
        f << "###fileType0=" << RagTime5StructManager::printType(m_link.m_fileType[0]) << ",";
1432
0
      }
1433
2.50k
      if (m_zoneType.m_id==2)
1434
836
        m_link.m_name="settings";
1435
2.50k
      f << m_link << "," << mess;
1436
2.50k
      break;
1437
2.50k
    }
1438
2.49k
    case F_DZone3: {
1439
2.49k
      if (fSz!=28 || !readLinkHeader(input, fSz, m_link, linkValues, mess)) {
1440
1
        MWAW_DEBUG_MSG(("RagTime5ChartInternal::ChartCParser::parseDataZone: can not read a dZone3 link\n"));
1441
1
        f << "###link,";
1442
1
        break;
1443
1
      }
1444
2.49k
      m_what=2;
1445
2.49k
      unsigned long const expectedType=m_zoneType.m_id==0 ? 0x3e800 : 0x35800;
1446
2.49k
      if (m_link.m_fileType[0]!=expectedType) {
1447
0
        MWAW_DEBUG_MSG(("RagTime5ChartInternal::ChartCParser::parseDataZone: unexpected fileType0\n"));
1448
0
        f << "###fileType0=" << RagTime5StructManager::printType(m_link.m_fileType[0]) << ",";
1449
0
      }
1450
2.49k
      f << m_link << "," << mess;
1451
2.49k
      break;
1452
2.49k
    }
1453
2.49k
    case F_DZone10:
1454
2.49k
      if (m_zoneType.m_id==2) {
1455
832
        if (fSz!=29 && fSz!=34) {
1456
0
          MWAW_DEBUG_MSG(("RagTime5ChartInternal::ChartCParser::parseDataZone: the size dzone10[2] of seems odd\n"));
1457
0
          f << "###fSz,";
1458
0
          break;
1459
0
        }
1460
832
        auto type=input->readULong(4);
1461
832
        if (type!=0x16aa842) {
1462
0
          MWAW_DEBUG_MSG(("RagTime5ChartInternal::ChartCParser::parseDataZone: the filetype0 seems bad\n"));
1463
0
          f << "##fileType0=" << RagTime5StructManager::printType(type) << ",";
1464
0
        }
1465
832
        m_what=3;
1466
5.82k
        for (int i=0; i<6; ++i) { // always 0
1467
4.99k
          val=static_cast<int>(input->readLong(2));
1468
4.99k
          if (val) f << "f" << i << "=" << val << ",";
1469
4.99k
        }
1470
832
        val=static_cast<int>(input->readULong(2));
1471
832
        if (val!=0x60 && val!=0x70) {
1472
0
          MWAW_DEBUG_MSG(("RagTime5ChartInternal::ChartCParser::parseDataZone: the filetype1  seems bad\n"));
1473
0
          f << "##fileType1=" << std::hex << val << std::dec << ",";
1474
0
        }
1475
4.99k
        for (int i=0; i<5; ++i) { //g2=0|256
1476
4.16k
          val=static_cast<int>(input->readLong(fSz==29 ? 1 : 2));
1477
4.16k
          if (val) f << "g" << i << "=" << val << ",";
1478
4.16k
        }
1479
832
        break;
1480
832
      }
1481
1.66k
      if (fSz!=28 || !readLinkHeader(input, fSz, m_link, linkValues, mess)) {
1482
1
        MWAW_DEBUG_MSG(("RagTime5ChartInternal::ChartCParser::parseDataZone: can not read a dZone10 link\n"));
1483
1
        f << "###link,";
1484
1
        break;
1485
1
      }
1486
1.66k
      m_what=2;
1487
1.66k
      if (m_link.m_fileType[0]!=(m_zoneType.m_id==0 ? 0x3e800 : 0x35800)) {
1488
0
        MWAW_DEBUG_MSG(("RagTime5ChartInternal::ChartCParser::parseDataZone: unexpected fileType0\n"));
1489
0
        f << "###fileType0=" << RagTime5StructManager::printType(m_link.m_fileType[0]) << ",";
1490
0
      }
1491
1.66k
      f << m_link << "," << mess;
1492
1.66k
      break;
1493
0
    case F_Value: {
1494
0
      if (fSz!=50 || !readLinkHeader(input, fSz, m_link, linkValues, mess)) {
1495
0
        MWAW_DEBUG_MSG(("RagTime5ChartInternal::ChartCParser::parseDataZone: can not read a value link\n"));
1496
0
        f << "###link,";
1497
0
        break;
1498
0
      }
1499
0
      if (m_link.m_fieldSize==8) {
1500
0
        f << "double,";
1501
0
        m_link.m_name="ChartValueDouble";
1502
0
        m_linkId=1;
1503
0
      }
1504
0
      else if (m_link.m_fieldSize==14) {
1505
0
        f << "text[zone],";
1506
0
        m_link.m_name="ChartValueTZone";
1507
0
        m_linkId=2;
1508
0
      }
1509
0
      else {
1510
0
        MWAW_DEBUG_MSG(("RagTime5ChartInternal::ChartCParser::parseDataZone: find unknown link\n"));
1511
0
        f << "###unknown,";
1512
0
      }
1513
0
      f << m_link << "," << mess;
1514
0
      auto type=input->readULong(4);
1515
0
      if (type && (type&0xFFFD70F)!=0x16b400a) {
1516
0
        MWAW_DEBUG_MSG(("RagTime5ChartInternal::ChartCParser::parseDataZone: find unknown fileType2\n"));
1517
0
        f << "###";
1518
0
      }
1519
0
      if (type)
1520
0
        f << "fileType2=" << RagTime5StructManager::printType(type) << ",";
1521
0
      for (int i=0; i<3; ++i) { // g0=1, g1,g2 small number
1522
0
        val=static_cast<int>(input->readLong(4));
1523
0
        if (!val) continue;
1524
0
        if (i==1) {
1525
0
          f << "serie=A" << val-1 << ",";
1526
0
          if (!checkFatherType(val-1, F_Serie))
1527
0
            f << "###";
1528
0
        }
1529
0
        else f << "g" << i << "=" << val << ",";
1530
0
      }
1531
0
      val=static_cast<int>(input->readULong(2)); // 0|21|40|4000
1532
0
      if (val) f << "fl=" << std::hex << val << std::dec << ",";
1533
0
      val=static_cast<int>(input->readULong(2)); // 1-4
1534
0
      if (val) f << "g3=" << val << ",";
1535
0
      break;
1536
0
    }
1537
1.00k
    case F_DZone1: // fSz=74|117|119
1538
1.00k
      if (fSz!=74 && fSz!=117 && fSz!=119) {
1539
20
        MWAW_DEBUG_MSG(("RagTime5ChartInternal::ChartCParser::parseDataZone: the first zone size seems bad\n"));
1540
20
        f << "###sz";
1541
20
        break;
1542
20
      }
1543
1.97k
      for (int step=0; step<2; ++step) {
1544
1.97k
        f << "data" << step << "=[";
1545
7.90k
        for (int i=0; i<3; ++i) { // f2=0|1000
1546
5.92k
          val=static_cast<int>(input->readLong(2));
1547
5.92k
          if (val) f << "f" << i << "=" << std::hex << val << std::dec << ",";
1548
5.92k
        }
1549
7.90k
        for (int i=0; i<3; ++i) { // f3=0|d|e, f4=e|f, f5=0|f|10
1550
5.92k
          val=static_cast<int>(input->readLong(4));
1551
5.92k
          if (!val) continue;
1552
5.92k
          ZoneType zoneType;
1553
5.92k
          zoneType.m_type=F_DZoneF226;
1554
5.92k
          zoneType.m_id=m_zoneType.m_id;
1555
5.92k
          insertZoneToBeParsed(val-1, zoneType, true);
1556
5.92k
          f << "zone226=F" << val-1 << ",";
1557
5.92k
        }
1558
1.97k
        if (step==1)
1559
988
          break;
1560
2.96k
        for (int i=0; i<2; ++i) { // always 0
1561
1.97k
          val=static_cast<int>(input->readLong(2));
1562
1.97k
          if (val) f << "f" << i+5 << "=" << std::hex << val << std::dec << ",";
1563
1.97k
        }
1564
4.94k
        for (int i=0; i<4; ++i) {
1565
3.95k
          auto lVal=long(input->readULong(4));
1566
3.95k
          static long const expected[]= {0x5ab56, 0x2d5ab, 0x8000, 0x7162c};
1567
3.95k
          if (lVal!=expected[i])
1568
25
            f << "#fileType" << i << "=" << std::hex << lVal << std::dec << ",";
1569
3.95k
        }
1570
4.94k
        for (int i=0; i<4; ++i) { // g0=-1|0|1d,1e, g1=-1|0|9|a|d, g2=1
1571
3.95k
          val=static_cast<int>(input->readLong(2));
1572
3.95k
          if (val) f << "g" << i << "=" << val << ",";
1573
3.95k
        }
1574
2.96k
        for (int i=0; i<2; ++i) { // always ccd
1575
1.97k
          val=static_cast<int>(input->readLong(4));
1576
1.97k
          if (val!=0xccd) f << "g" << i+3 << "=" << val << ",";
1577
1.97k
        }
1578
988
        val=static_cast<int>(input->readULong(2)); // [04]1[01][137]
1579
988
        if (val) f<<"fl=" << std::hex << val << std::dec << ",";
1580
988
        val=static_cast<int>(input->readULong(2));
1581
988
        if (val!=0xe07) f<<"fl2=" << std::hex << val << std::dec << ",";
1582
988
        val=static_cast<int>(input->readULong(4));
1583
988
        if (val) {
1584
25
          f << "unknZone1=F" << val-1 << ",";
1585
25
          ZoneType zoneType;
1586
25
          zoneType.m_type=F_UnknZone1;
1587
25
          zoneType.m_id=m_zoneType.m_id;
1588
25
          insertZoneToBeParsed(val-1, zoneType);
1589
25
        }
1590
2.96k
        for (int i=0; i<2; ++i) {
1591
1.97k
          val=static_cast<int>(input->readLong(2));
1592
1.97k
          if (val) f << "g" << i+5 << "=" << val << ",";
1593
1.97k
        }
1594
988
        val=static_cast<int>(input->readULong(2));
1595
988
        if (val==0xc000)
1596
0
          f << "fl3*";
1597
988
        else if (val)
1598
0
          f << "fl3=" << std::hex << val << std::dec << ",";
1599
988
        f << "],";
1600
988
        if (fSz==74)
1601
0
          break;
1602
988
      }
1603
988
      if (fSz==74)
1604
0
        break;
1605
988
      f << "num=[";
1606
12.8k
      for (int i=0; i<12; ++i) { // a decreasing sequence
1607
11.8k
        val=static_cast<int>(input->readLong(2));
1608
11.8k
        if (val)
1609
2.05k
          f << val << ",";
1610
9.80k
        else
1611
9.80k
          f << "_,";
1612
11.8k
      }
1613
988
      f << "],";
1614
988
      val=static_cast<int>(input->readLong(1)); // alway 1 ?
1615
988
      if (val!=1)
1616
0
        f << "f0=" << val << ",";
1617
988
      if (fSz==117)
1618
0
        break;
1619
988
      val=static_cast<int>(input->readULong(2)); // 0[01][01]2
1620
988
      if (val)
1621
988
        f << "fl2=" << std::hex << val << std::dec << ",";
1622
988
      break;
1623
982
    case F_DZone5:
1624
982
      if (fSz!=32 || !readLinkHeader(input, fSz, m_link, linkValues, mess)) {
1625
1
        MWAW_DEBUG_MSG(("RagTime5ChartInternal::ChartCParser::parseDataZone: can not read the zone5 link\n"));
1626
1
        f << "###link";
1627
1
        break;
1628
1
      }
1629
981
      m_what=2;
1630
981
      m_link.m_type=RagTime5ClusterManager::Link::L_List;
1631
981
      m_link.m_name="ChartUnknLink5";
1632
981
      m_link.m_N=N;
1633
981
      if ((m_link.m_fileType[1]&0xFFD7)!=0x210) {
1634
0
        MWAW_DEBUG_MSG(("RagTime5ChartInternal::ChartCParser::parseDataZone: unexpected file type 1\n"));
1635
0
        f << "###fileType1=" << std::hex << m_link.m_fileType[1] << std::dec << ",";
1636
0
      }
1637
981
      f << m_link << "," << mess;
1638
981
      break;
1639
986
    case F_DZone8: // fSz=20
1640
1.98k
    case F_DZone9: // fSz=18
1641
1.98k
      if ((fSz!=20 || m_zoneType.m_type!=F_DZone8) &&
1642
1.02k
          (fSz!=18 || m_zoneType.m_type!=F_DZone9)) {
1643
40
        MWAW_DEBUG_MSG(("RagTime5ChartInternal::ChartCParser::parseDataZone: can not read a data8 or 9 zone\n"));
1644
40
        f << "###";
1645
40
        break;
1646
40
      }
1647
1.94k
      val=static_cast<int>(input->readULong(4));
1648
1.94k
      if (val)
1649
25
        f << "f0=" << val << ",";
1650
1.94k
      val=static_cast<int>(input->readULong(2)); // 0|b00|1000
1651
1.94k
      if (val) f << "fl=" << std::hex << val << std::dec << ",";
1652
7.77k
      for (int i=0; i<4; ++i) { // small number
1653
6.81k
        val=static_cast<int>(input->readLong(2));
1654
6.81k
        if (val) f << "f" << i+1 << "=" << val << ",";
1655
6.81k
        if (fSz==18 && i==2)
1656
982
          break;
1657
6.81k
      }
1658
1.94k
      break;
1659
2.45k
    case F_DZoneF12: { // find with size 12 or 20
1660
2.45k
      if (fSz<12) {
1661
0
        MWAW_DEBUG_MSG(("RagTime5ChartInternal::ChartCParser::parseDataZone: find unexpected size for zone 12\n"));
1662
0
        f << "###";
1663
0
        break;
1664
0
      }
1665
2.45k
      val=static_cast<int>(input->readLong(4));
1666
2.45k
      if (!checkFatherType(val-1, F_DZoneF226))
1667
0
        f << "###";
1668
2.45k
      f << "father=A" << val-1 << ",";
1669
2.45k
      val=static_cast<int>(input->readLong(2)); //  0|300|b00|1000 ...
1670
2.45k
      if (val) f << "fl=" << std::hex << val << std::dec << ",";
1671
2.45k
      int extra=int(fSz-12)/2;
1672
2.45k
      for (int i=0; i<extra; ++i) { // smal number
1673
0
        val=static_cast<int>(input->readLong(2));
1674
0
        if (val) f << "f" << i << "=" << val << ",";
1675
0
      }
1676
2.45k
      break;
1677
2.45k
    }
1678
2.72k
    case F_DZoneF226: {
1679
2.72k
      if (fSz!=226) {
1680
0
        MWAW_DEBUG_MSG(("RagTime5ChartInternal::ChartCParser::parseDataZone: can not read a zone 226\n"));
1681
0
        f << "###sz";
1682
0
        break;
1683
0
      }
1684
10.9k
      for (int i=0; i<3; ++i) { // f2=0|1000
1685
8.18k
        val=static_cast<int>(input->readULong(2));
1686
8.18k
        static int const expected[]= {0,0,0,0x400};
1687
8.18k
        if (val!=expected[i]) f << "f" << i << "=" << std::hex << val << std::dec << ",";
1688
8.18k
      }
1689
2.72k
      bool isType2=false;
1690
8.18k
      for (int i=0; i<2; ++i) {
1691
5.45k
        auto type=input->readULong(4);
1692
5.45k
        if (type && (type&0xFFF000F)!=0x16b000a && (i!=0 || (type&0xFFF000F)!=0x196000a)) {
1693
0
          MWAW_DEBUG_MSG(("RagTime5ChartInternal::ChartCParser::parseDataZone: find unknown fileType%d\n", i));
1694
0
          f << "###";
1695
0
        }
1696
5.45k
        f << "fileType" << i << "=" << RagTime5StructManager::printType(type) << ",";
1697
5.45k
        if (i==1 && type==0x16b684a) {
1698
          // the second seems quite differents
1699
0
          isType2=true;
1700
0
          f << "type2,";
1701
0
        }
1702
5.45k
      }
1703
8.18k
      for (int i=0; i<2; ++i) {
1704
5.45k
        val=static_cast<int>(input->readULong(2));
1705
5.45k
        if (val)
1706
5.45k
          f << "fl" << i << "=" << std::hex << val << std::dec << ",";
1707
5.45k
      }
1708
2.72k
      float dim[2];
1709
5.45k
      for (auto &d : dim) d=float(input->readLong(4))/65536.f;
1710
2.72k
      f << "dim=" << MWAWVec2f(dim[0], dim[1]) << ",";
1711
16.3k
      for (int i=0; i<5; ++i) { // f3=1, f4=0|400, f5=0-f
1712
13.6k
        val=static_cast<int>(input->readLong(2));
1713
13.6k
        if (val)
1714
2.85k
          f << "f" << i+3 << "=" << val << ',';
1715
13.6k
      }
1716
2.72k
      f << "num0=[";
1717
13.6k
      for (int i=0; i<4; ++i) { // 1|12, 1-6, 3, 3
1718
10.9k
        val=static_cast<int>(input->readLong(2));
1719
10.9k
        if (val)
1720
10.9k
          f << val << ',';
1721
0
        else
1722
0
          f << ",";
1723
10.9k
      }
1724
2.72k
      f << "],";
1725
2.72k
      val=static_cast<int>(input->readLong(4));
1726
2.72k
      if (val) {
1727
2.72k
        f << "F" << val-1 << ",";
1728
2.72k
        ZoneType zoneType;
1729
2.72k
        zoneType.m_type=F_DZoneF12;
1730
2.72k
        zoneType.m_id=m_zoneType.m_id;
1731
2.72k
        insertZoneToBeParsed(val-1, zoneType);
1732
2.72k
      }
1733
2.72k
      f << "num1=[";
1734
13.6k
      for (int i=0; i<4; ++i) { // X1, X1, X1,5
1735
10.9k
        val=static_cast<int>(input->readLong(2));
1736
10.9k
        if (val)
1737
10.9k
          f << val << ',';
1738
0
        else
1739
0
          f << ",";
1740
10.9k
      }
1741
2.72k
      f << "],";
1742
2.72k
      int n=isType2 ? 1 : 5;
1743
16.3k
      for (int i=0; i<n; ++i) {
1744
13.6k
        f << "unkn" << i << "=[";
1745
150k
        for (int j=0; j<10; ++j) {
1746
136k
          val=static_cast<int>(input->readULong(1));
1747
136k
          if (val)
1748
95.3k
            f << std::hex << val << std::dec << ',';
1749
41.0k
          else
1750
41.0k
            f << "_,";
1751
136k
        }
1752
13.6k
        val=static_cast<int>(input->readLong(2)); // 1|5
1753
13.6k
        if (val!=1)
1754
8
          f << val << "],";
1755
13.6k
        else
1756
13.6k
          f << "_],";
1757
13.6k
      }
1758
2.72k
      input->seek(pos+116,librevenge::RVNG_SEEK_SET);
1759
2.72k
      double res;
1760
2.72k
      bool isNan;
1761
2.72k
      f << "val0=[";
1762
10.8k
      for (int i=0; i<3; ++i) { // checkme: sometimes double sometimes not double...
1763
8.18k
        if (!input->readDouble8(res, isNan))
1764
25
          break;
1765
8.15k
        f << res << ",";
1766
8.15k
      }
1767
2.72k
      f << "],";
1768
2.72k
      input->seek(pos+140,librevenge::RVNG_SEEK_SET);
1769
13.6k
      for (int i=0; i<4; ++i) {
1770
10.9k
        val=static_cast<int>(input->readULong(1)); // 0|4
1771
10.9k
        if (val)
1772
2.72k
          f << "fl" << i+2 << "=" << val << ",";
1773
10.9k
      }
1774
2.72k
      f << "val1=[";
1775
13.5k
      for (int i=0; i<4; ++i) { // often 0,1,1,1
1776
10.8k
        if (!input->readDouble8(res, isNan))
1777
25
          break;
1778
10.8k
        f << res << ",";
1779
10.8k
      }
1780
2.72k
      input->seek(pos+176,librevenge::RVNG_SEEK_SET);
1781
2.72k
      f << "],";
1782
2.72k
      int lDim[4];
1783
10.9k
      for (auto &d : lDim) d=static_cast<int>(input->readLong(4));
1784
2.72k
      MWAWBox2i box(MWAWVec2i(lDim[0],lDim[1]),MWAWVec2i(lDim[1],lDim[2]));
1785
2.72k
      if (box!=MWAWBox2i(MWAWVec2i(0,0),MWAWVec2i(0,0)))
1786
75
        f << "dim1=" << box << ",";
1787
10.9k
      for (int i=0; i<3; ++i) { // g0=1-5, g1=1-14, g2=13|19|fa
1788
8.18k
        val=static_cast<int>(input->readULong(2));
1789
8.18k
        if (val)
1790
8.09k
          f << "g" << i << "=" << val << ",";
1791
8.18k
      }
1792
2.72k
      f << "unkn2=[";
1793
32.7k
      for (int i=0; i<11; ++i) {
1794
30.0k
        val=static_cast<int>(input->readULong(2));
1795
30.0k
        if (val)
1796
242
          f << std::hex << val << std::dec << ",";
1797
29.7k
        else
1798
29.7k
          f << "_,";
1799
30.0k
      }
1800
2.72k
      f << "],";
1801
2.72k
      break;
1802
2.72k
    }
1803
0
    case F_DZoneF70: // see only in one file, so ...
1804
0
      if (fSz!=70 || !readLinkHeader(input, fSz, m_link, linkValues, mess)) {
1805
0
        MWAW_DEBUG_MSG(("RagTime5ChartInternal::ChartCParser::parseDataZone: unexpected zoneF70 size\n"));
1806
0
        f << "###fSz,";
1807
0
        break;
1808
0
      }
1809
0
      m_link.m_name="ChartUnknown3";
1810
0
      f << m_link << "," << mess;
1811
0
      if ((m_link.m_fileType[1]&0xFFD7)!=0x50) {
1812
0
        MWAW_DEBUG_MSG(("RagTime5ChartInternal::ChartCParser::parseDataZone: find unknown fileType1\n"));
1813
0
        f << "###fileType1="<<std::hex << m_link.m_fileType[1] << std::dec << ",";;
1814
0
      }
1815
0
      for (int i=0; i<2; ++i) {
1816
0
        val=static_cast<int>(input->readLong(2));
1817
0
        if (val) f << "f" << i << "=" << val << ",";
1818
0
      }
1819
0
      val=static_cast<int>(input->readULong(4));
1820
0
      if (val && val!=0x25544f2c) // %To, ?
1821
0
        f << "#f2="<<std::hex << val << std::dec << ",";;
1822
0
      val=static_cast<int>(input->readULong(2)); // 9
1823
0
      if (val!=9) f << "f3=" << val << ",";
1824
0
      for (int i=0; i<9; ++i) {
1825
0
        val=static_cast<int>(input->readULong(2));
1826
0
        static int const expected[]= {0x6443,0x2554,0x3ee4,0,0,0,0,0x58a5,0x5c85,};
1827
0
        if (val!=expected[i]) f << "g" << i << "=" << std::hex << val << std::dec << ",";
1828
0
      }
1829
0
      for (int i=0; i<6; ++i) { // h3=1, h5=0|800
1830
0
        val=static_cast<int>(input->readLong(2));
1831
0
        if (val)
1832
0
          f << "h" << i << "=" << val << ",";
1833
0
      }
1834
0
      break;
1835
0
    case F_UnknZone1:
1836
0
      if (fSz!=30 || !readLinkHeader(input, fSz, m_link, linkValues, mess)) {
1837
0
        MWAW_DEBUG_MSG(("RagTime5ChartInternal::ChartCParser::parseDataZone: can not read the unknownZone1 link\n"));
1838
0
        f << "###link";
1839
0
        break;
1840
0
      }
1841
0
      if (m_link.m_fileType[0]!=0x16cd840) {
1842
0
        MWAW_DEBUG_MSG(("RagTime5ChartInternal::ChartCParser::parseDataZone: find odd fileType0\n"));
1843
0
        f << "###fileType0=" << RagTime5StructManager::printType(m_link.m_fileType[0]) << ",";
1844
0
      }
1845
0
      if (m_link.m_fieldSize!=6) {
1846
0
        MWAW_DEBUG_MSG(("RagTime5ChartInternal::ChartCParser::parseDataZone: find unexpected field size\n"));
1847
0
        f << "###field[size]=" << m_link.m_fieldSize << ",";
1848
0
      }
1849
0
      m_link.m_name="ChartUnknown1";
1850
0
      m_what=4;
1851
0
      f << m_link << "," << mess;
1852
0
      break;
1853
0
    case F_UnknZone2:
1854
0
      if (fSz!=28 || !readLinkHeader(input, fSz, m_link, linkValues, mess)) {
1855
0
        MWAW_DEBUG_MSG(("RagTime5ChartInternal::ChartCParser::parseDataZone: can not read the unknownZone1 link\n"));
1856
0
        f << "###link";
1857
0
        break;
1858
0
      }
1859
0
      if (m_link.m_fileType[0]!=0x34800) {
1860
0
        MWAW_DEBUG_MSG(("RagTime5ChartInternal::ChartCParser::parseDataZone: find odd fileType0\n"));
1861
0
        f << "###fileType0=" << RagTime5StructManager::printType(m_link.m_fileType[0]) << ",";
1862
0
      }
1863
0
      f << m_link << "," << mess;
1864
0
      m_what=2;
1865
0
      break;
1866
199
    case F_Unknown:
1867
#if !defined(__clang__)
1868
    default:
1869
#endif
1870
199
      MWAW_DEBUG_MSG(("RagTime5ChartInternal::ChartCParser::parseDataZone: find unknown zone type\n"));
1871
199
      f << "###fSz,";
1872
199
      break;
1873
25.5k
    }
1874
25.5k
    if (m_zoneType.m_type!=F_Unknown)
1875
25.3k
      m_fieldName=m_zoneType.getName();
1876
25.5k
    if (!m_fieldName.empty())
1877
25.3k
      f << m_fieldName << ",";
1878
25.5k
    return true;
1879
25.5k
  }
1880
  //! parse the header zone
1881
  bool parseHeaderZone(MWAWInputStreamPtr &input, long fSz, int N, int flag, libmwaw::DebugStream &f)
1882
1.04k
  {
1883
1.04k
    f << "header, fl=" << std::hex << flag << std::dec << ",";
1884
1.04k
    m_fieldName="header";
1885
1.04k
    m_what=0;
1886
1.04k
    if (N!=-5 || m_dataId!=0 || (fSz!=331 && fSz!=339)) {
1887
0
      f << "###N=" << N << ",fSz=" << fSz << ",";
1888
0
      MWAW_DEBUG_MSG(("RagTime5ChartInternal::ChartCParser::parseHeaderZone: find unexpected main field\n"));
1889
0
      return true;
1890
0
    }
1891
1.04k
    int val;
1892
3.14k
    for (int i=0; i<2; ++i) { // always 0?
1893
2.09k
      val=static_cast<int>(input->readLong(2));
1894
2.09k
      if (val) f << "f" << i << "=" << val << ",";
1895
2.09k
    }
1896
1.04k
    val=static_cast<int>(input->readLong(2));
1897
1.04k
    f << "id=" << val << ",";
1898
1.04k
    val=static_cast<int>(input->readULong(2));
1899
1.04k
    if (m_type>0 && val!=m_type) {
1900
0
      MWAW_DEBUG_MSG(("RagTime5ChartInternal::ChartCParser::parseHeaderZone: unexpected zone type\n"));
1901
0
      f << "##zoneType=" << std::hex << val << std::dec << ",";
1902
0
    }
1903
3.14k
    for (int i=0; i<2; ++i) {
1904
2.09k
      val=static_cast<int>(input->readLong(4));
1905
2.09k
      if (!val) continue;
1906
1.10k
      ZoneType zoneType;
1907
1.10k
      zoneType.m_type=i==0 ? F_ParentLink : F_Prefs;
1908
1.10k
      if (i==0)
1909
1.04k
        f << "parent=F" << val-1 << ",";
1910
61
      else
1911
61
        f << "prefs=F" << val-1 << ",";
1912
1.10k
      insertZoneToBeParsed(val-1, zoneType);
1913
1.10k
    }
1914
9.43k
    for (int i=0; i<8; ++i) { // f3=0|d, f7=0|1|2|3|7, f8=3|4, f9=2
1915
8.38k
      val=static_cast<int>(input->readLong(2));
1916
8.38k
      if (!val) continue;
1917
2.38k
      if (i==1) {
1918
61
        f << "num[series]=" << val << ",";
1919
61
        m_chart->m_numSeries=val;
1920
61
      }
1921
2.32k
      else
1922
2.32k
        f << "f" << i+2 << "=" << val << ",";
1923
2.38k
    }
1924
1.04k
    val=static_cast<int>(input->readLong(2)); // always 10
1925
1.04k
    if (val!=0x10)
1926
61
      f << "fl0=" << val << ",";
1927
1.04k
    f << "double0=[";
1928
7.33k
    for (int i=0; i<6; ++i) { // something like [200,150,200,0,0,500,]
1929
6.28k
      double res;
1930
6.28k
      bool isNan;
1931
6.28k
      long actPos=input->tell();
1932
6.28k
      if (!input->readDouble8(res, isNan)) {
1933
50
        MWAW_DEBUG_MSG(("RagTime5ChartInternal::ChartCParser::parseHeaderZone: can not read a double0\n"));
1934
50
        f << "##double" << i << ",";
1935
50
        input->seek(actPos+8, librevenge::RVNG_SEEK_SET);
1936
50
      }
1937
6.23k
      else f << res << ",";
1938
6.28k
    }
1939
1.04k
    f << "],";
1940
1.04k
    val=static_cast<int>(input->readLong(1)); // always f
1941
1.04k
    if (val!=0xf)
1942
20
      f << "fl1=" << val << ",";
1943
1.04k
    f << "double1=[";
1944
3.14k
    for (int i=0; i<2; ++i) { // small number between 0 et 2: some angle?
1945
2.09k
      double res;
1946
2.09k
      bool isNan;
1947
2.09k
      long actPos=input->tell();
1948
2.09k
      if (!input->readDouble8(res, isNan)) {
1949
0
        MWAW_DEBUG_MSG(("RagTime5ChartInternal::ChartCParser::parseHeaderZone: can not read a double1\n"));
1950
0
        f << "##double" << i << ",";
1951
0
        input->seek(actPos+8, librevenge::RVNG_SEEK_SET);
1952
0
      }
1953
2.09k
      else f << res << ",";
1954
2.09k
    }
1955
1.04k
    f << "],";
1956
1.04k
    float dim[4];
1957
3.14k
    for (int i=0; i<2; ++i) dim[i]=float(input->readLong(4))/65536.f;
1958
1.04k
    f << "dim?=" << MWAWVec2f(dim[0],dim[1]) << ",";
1959
1.04k
    f << "double2=[";
1960
1.04k
    int numData=fSz==331 ? 11 : 12;
1961
14.6k
    for (int i=0; i<1+numData; ++i) { // checkme 500+a matrix (without the last line and/or column)
1962
13.6k
      double res;
1963
13.6k
      bool isNan;
1964
13.6k
      long actPos=input->tell();
1965
13.6k
      if (!input->readDouble8(res, isNan)) {
1966
0
        MWAW_DEBUG_MSG(("RagTime5ChartInternal::ChartCParser::parseHeaderZone: can not read a double1\n"));
1967
0
        f << "##double" << i << ",";
1968
0
        input->seek(actPos+8, librevenge::RVNG_SEEK_SET);
1969
0
      }
1970
13.6k
      else f << res << ",";
1971
13.6k
    }
1972
1.04k
    f << "],";
1973
1.04k
    long pos=input->tell();
1974
1.04k
    libmwaw::DebugStream f2;
1975
1.04k
    f2 << "ClustChart-0-A:headerB,";
1976
1.04k
    f2 << "child=[";
1977
13.6k
    for (int i=0; i<12; ++i) {
1978
12.5k
      val=static_cast<int>(input->readLong(4));
1979
12.5k
      static Type const wh[]= {
1980
12.5k
        F_DZone1, F_Settings, F_DZones3, F_Series,
1981
12.5k
        F_DZone5, F_Unknown/*never seen*/, F_SerieTypes,  F_Serie,
1982
12.5k
        F_DZone8, F_DZone9, F_DZones10, F_Values
1983
12.5k
      };
1984
12.5k
      if (!val) continue;
1985
11.5k
      if (wh[i]!=F_Unknown) {
1986
11.5k
        ZoneType zoneType;
1987
11.5k
        zoneType.m_type=wh[i];
1988
11.5k
        insertZoneToBeParsed(val-1, zoneType);
1989
11.5k
        f2 << zoneType.getName() << "=F" << val-1 << ",";
1990
11.5k
      }
1991
85
      else {
1992
85
        MWAW_DEBUG_MSG(("RagTime5ChartInternal::ChartCParser::parseHeaderZone: find unknown zone\n"));
1993
85
        f2 << "###unk" << i << "=F" << val-1 << ",";
1994
85
      }
1995
11.5k
    }
1996
1.04k
    f2 << "],";
1997
1.04k
    val=static_cast<int>(input->readULong(2)); // [128][8c][045]
1998
1.04k
    if (val) f2 << "fl2=" << std::hex << val << std::dec << ",";
1999
4.19k
    for (int i=0; i<3; ++i) { // never seems dim3 so unsure ...
2000
12.5k
      for (auto &d : dim) d=float(input->readLong(4))/65536.f;
2001
3.14k
      MWAWBox2f bdbox(MWAWVec2f(dim[0],dim[1]),MWAWVec2f(dim[2],dim[3]));
2002
3.14k
      if (bdbox!=MWAWBox2f(MWAWVec2f(0,0),MWAWVec2f(0,0)))
2003
1.19k
        f2 << "dim" << i+1 << "?=" << bdbox << ",";
2004
3.14k
    }
2005
1.04k
    val=static_cast<int>(input->readLong(2)); // always 0?
2006
1.04k
    if (val) f2 << "h0=" << val << ",";
2007
1.04k
    f2 << "ID?=[";
2008
3.14k
    for (int i=0; i<2; ++i) f2 << std::hex << input->readULong(4) << std::dec << ",";
2009
1.04k
    f2 << "],";
2010
1.04k
    val=static_cast<int>(input->readLong(2)); // 1|6|7
2011
1.04k
    if (val) f2 << "h1=" << val << ",";
2012
3.14k
    for (int i=0; i<2; ++i) {
2013
2.09k
      val=static_cast<int>(input->readULong(2));
2014
2.09k
      if (val) f2 << "fl" << i+2 << "=" << std::hex << val << std::dec << ",";
2015
2.09k
    }
2016
1.04k
    val=static_cast<int>(input->readULong(4));
2017
1.04k
    if (val) {
2018
56
      f2 << "dZone70=F" << val-1 << ",";
2019
56
      ZoneType zoneType;
2020
56
      zoneType.m_type=F_DZoneF70;
2021
56
      insertZoneToBeParsed(val-1, zoneType);
2022
56
    }
2023
3.14k
    for (int i=0; i<2; ++i) { // h2=small number, h3:1
2024
2.09k
      val=static_cast<int>(input->readULong(2));
2025
2.09k
      if (val) f2 << "h" << i+2 << "=" << val << ",";
2026
2.09k
    }
2027
1.04k
    m_asciiFile.addPos(pos);
2028
1.04k
    m_asciiFile.addNote(f2.str().c_str());
2029
1.04k
    return true;
2030
1.04k
  }
2031
2032
  //! the current cluster
2033
  std::shared_ptr<ClusterChart> m_cluster;
2034
  //! the chart
2035
  std::shared_ptr<Chart> m_chart;
2036
  //! a index to know which field is parsed :  0: main, 1: common data, 2: list, 3: sub zone position, 4: unknown1, 5: the preferences
2037
  int m_what;
2038
  //! the link id: 1: value double, 2: value text zone
2039
  int m_linkId;
2040
  //! the actual field name
2041
  std::string m_fieldName;
2042
  //! the current zone type
2043
  ZoneType m_zoneType;
2044
  //! the list of id to zone type map
2045
  std::map<int, ZoneType> m_fieldIdToZoneTypeMap;
2046
  //! the list of know zone remaining to be parsed
2047
  std::set<int> m_zoneToParseSet;
2048
  //! the ascii file
2049
  libmwaw::DebugFile &m_asciiFile;
2050
private:
2051
  //! copy constructor (not implemented)
2052
  ChartCParser(ChartCParser const &orig) = delete;
2053
  //! copy operator (not implemented)
2054
  ChartCParser &operator=(ChartCParser const &orig) = delete;
2055
};
2056
2057
ChartCParser::~ChartCParser()
2058
1.04k
{
2059
1.04k
}
2060
2061
}
2062
2063
std::shared_ptr<RagTime5ClusterManager::Cluster> RagTime5Chart::readChartCluster(RagTime5Zone &zone, int zoneType)
2064
1.04k
{
2065
1.04k
  std::shared_ptr<RagTime5ClusterManager> clusterManager=m_document.getClusterManager();
2066
1.04k
  if (!clusterManager) {
2067
0
    MWAW_DEBUG_MSG(("RagTime5Chart::readChartCluster: oops can not find the cluster manager\n"));
2068
0
    return std::shared_ptr<RagTime5ClusterManager::Cluster>();
2069
0
  }
2070
1.04k
  RagTime5ChartInternal::ChartCParser parser(*clusterManager, zoneType, zone.ascii());
2071
1.04k
  if (!clusterManager->readCluster(zone, parser) || !parser.getChartCluster() || !parser.getChart()) {
2072
0
    MWAW_DEBUG_MSG(("RagTime5Chart::readChartCluster: oops can not find the cluster\n"));
2073
0
    return std::shared_ptr<RagTime5ClusterManager::Cluster>();
2074
0
  }
2075
1.04k
  auto cluster=parser.getChartCluster();
2076
1.04k
  auto chart=parser.getChart();
2077
1.04k
  m_document.checkClusterList(cluster->m_clusterIdsList);
2078
2079
  // setting zone
2080
4.19k
  for (int i=0; i<3; ++i) {
2081
3.14k
    RagTime5ClusterManager::Link &link=chart->m_settingZone.m_listLinkId[i];
2082
3.14k
    if (link.empty())
2083
661
      continue;
2084
2.48k
    if (i<2)
2085
1.64k
      m_document.readLongList(link, link.m_longList);
2086
836
    else {
2087
836
      RagTime5StructManager::FieldParser defaultParser("Settings");
2088
836
      m_document.readStructZone(link, defaultParser, 0);
2089
836
    }
2090
2.48k
  }
2091
  // unknown zone3
2092
3.14k
  for (auto &link : chart->m_zone3.m_listLinkId) {
2093
3.14k
    if (link.empty())
2094
672
      continue;
2095
2.47k
    m_document.readLongList(link, link.m_longList);
2096
2.47k
  }
2097
  // unknown zone10
2098
3.14k
  for (int i=0; i<2; ++i) { // normally, we must already have use listLinkId[2]
2099
2.09k
    auto &link=chart->m_zone10.m_listLinkId[i];
2100
2.09k
    if (link.empty())
2101
434
      continue;
2102
1.66k
    m_document.readLongList(link, link.m_longList);
2103
1.66k
  }
2104
1.04k
  if (!cluster->m_dataLink.empty()) {
2105
0
    MWAW_DEBUG_MSG(("RagTime5Chart::readChartCluster: oops do not how to parse the main data\n"));
2106
0
  }
2107
1.04k
  if (!cluster->m_parentLink.empty()) {
2108
943
    RagTime5ChartInternal::ClustListParser linkParser(*clusterManager, 60, "ChartParentLst");
2109
943
    m_document.readListZone(cluster->m_parentLink, linkParser);
2110
943
    m_document.checkClusterList(linkParser.m_clusterList);
2111
943
  }
2112
1.04k
  if (!cluster->m_typesLink.empty()) {
2113
0
    RagTime5ChartInternal::SerieTypeParser serieTypeParser;
2114
0
    m_document.readFixedSizeZone(cluster->m_typesLink, serieTypeParser);
2115
0
  }
2116
3.14k
  for (int i=0; i<2; ++i) {
2117
2.09k
    for (auto const &lnk : cluster->m_valuesLink[i]) {
2118
0
      if (i==0) {
2119
0
        RagTime5ChartInternal::DoubleParser doubleParser;
2120
0
        m_document.readFixedSizeZone(lnk, doubleParser);
2121
0
      }
2122
0
      else { // argh, where is the textZoneId ?
2123
0
        RagTime5ChartInternal::ChildTZoneParser textParser;
2124
0
        m_document.readFixedSizeZone(lnk, textParser);
2125
0
      }
2126
0
    }
2127
2.09k
  }
2128
1.04k
  if (!cluster->m_unknownLink1.empty()) {
2129
0
    RagTime5ChartInternal::ZoneUnknown1Parser zone1Parser;
2130
0
    m_document.readFixedSizeZone(cluster->m_unknownLink1, zone1Parser);
2131
0
  }
2132
1.04k
  if (!cluster->m_unknownLink3.empty()) {
2133
0
    RagTime5ChartInternal::ZoneUnknown3Parser zone3Parser;
2134
0
    m_document.readFixedSizeZone(cluster->m_unknownLink3, zone3Parser);
2135
0
  }
2136
2137
1.04k
  if (!cluster->m_nameLink.empty()) {
2138
0
    std::map<int, librevenge::RVNGString> idToStringMap;
2139
0
    m_document.readUnicodeStringList(cluster->m_nameLink, idToStringMap);
2140
0
  }
2141
2142
1.04k
  for (auto const &lnk : cluster->m_linksList) {
2143
981
    if (lnk.m_type==RagTime5ClusterManager::Link::L_List) {
2144
981
      m_document.readListZone(lnk);
2145
981
      continue;
2146
981
    }
2147
0
    std::stringstream s;
2148
0
    s << "Chart_data" << lnk.m_fieldSize;
2149
0
    RagTime5StructManager::DataParser defaultParser(lnk.m_name.empty() ? s.str() : lnk.m_name);
2150
0
    m_document.readFixedSizeZone(lnk, defaultParser);
2151
0
  }
2152
2153
1.04k
  return cluster;
2154
1.04k
}
2155
// vim: set filetype=cpp tabstop=2 shiftwidth=2 cindent autoindent smartindent noexpandtab: