Coverage Report

Created: 2026-09-14 06:37

next uncovered line (L), next uncovered region (R), next uncovered branch (B)
/src/libmwaw/src/lib/RagTime5StructManager.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 <cctype>
35
#include <iomanip>
36
#include <iostream>
37
#include <sstream>
38
39
#include "MWAWDebug.hxx"
40
#include "MWAWPrinter.hxx"
41
42
#include "RagTime5ClusterManager.hxx"
43
#include "RagTime5Document.hxx"
44
#include "RagTime5Formula.hxx"
45
#include "RagTime5Text.hxx"
46
47
#include "RagTime5StructManager.hxx"
48
49
namespace
50
{
51
//! the maximum recursion depth when reading nested fields
52
constexpr int MAX_RECORD_NESTING = 1 << 10;
53
}
54
55
////////////////////////////////////////////////////////////
56
// constructor/destructor, ...
57
////////////////////////////////////////////////////////////
58
RagTime5StructManager::RagTime5StructManager(RagTime5Document &doc)
59
81.1k
  : m_document(doc)
60
81.1k
{
61
81.1k
}
62
63
RagTime5StructManager::~RagTime5StructManager()
64
81.1k
{
65
81.1k
}
66
67
RagTime5StructManager::DataParser::DataParser(std::string const &zoneName)
68
339k
  : m_name(zoneName)
69
339k
{
70
339k
  if (!m_name.empty())
71
339k
    m_name[0]=char(std::toupper((unsigned char)(m_name[0])));
72
339k
}
73
74
RagTime5StructManager::DataParser::~DataParser()
75
339k
{
76
339k
}
77
78
RagTime5StructManager::FieldParser::~FieldParser()
79
236k
{
80
236k
}
81
////////////////////////////////////////////////////////////
82
// read basic structures
83
////////////////////////////////////////////////////////////
84
bool RagTime5StructManager::readCompressedLong(MWAWInputStreamPtr &input, long endPos, long &val)
85
12.9M
{
86
12.9M
  val=long(input->readULong(1));
87
12.9M
  if ((val&0xF0)==0xC0) {
88
2.55M
    input->seek(-1, librevenge::RVNG_SEEK_CUR);
89
2.55M
    val=long(MWAWInputStream::readULong(input->input().get(), 4, 0, false)&0xFFFFFFF);
90
2.55M
  }
91
10.3M
  else if (val>=0xD0) { // never seems, but may be ok
92
213k
    MWAW_DEBUG_MSG(("RagTime5Struct::readCompressedLong: can not read a long\n"));
93
213k
    return false;
94
213k
  }
95
10.1M
  else if (val>=0x80)
96
264k
    val=((val&0x7F)<<8)+long(input->readULong(1));
97
12.7M
  return input->tell()<=endPos;
98
12.9M
}
99
100
std::string RagTime5StructManager::printType(unsigned long fileType)
101
5.46M
{
102
5.46M
  static std::map<unsigned long, char const *> const s_typeToName = {
103
5.46M
    {0x145e042, "fillStyle[container]"},
104
5.46M
    {0x1460042, "lineStyle[container]"},
105
5.46M
    {0x146902a, "unit[base,from]"},
106
5.46M
    {0x146903a, "unit[base,to]"},
107
5.46M
    {0x146904a, "unit[base,id]"},
108
5.46M
    {0x146905a, "unit[name]"},
109
5.46M
    {0x146907a, "unit[second,id]"}, // rare
110
5.46M
    {0x146908a, "unit[digits,place]"},
111
5.46M
    {0x146a042, "unit[container]"},
112
5.46M
    {0x146e02a, "ruler[unit,id]"},
113
5.46M
    {0x146e03a, "ruler[step,major]"},
114
5.46M
    {0x146e04a, "ruler[step,minor]"},
115
5.46M
    {0x146e05a, "ruler[grid/major]"}, // a fraction or a fixed decimal?
116
5.46M
    {0x146e06a, "ruler[grid,line/gridPoint]"},
117
5.46M
    {0x146f042, "ruler[container]"},
118
5.46M
    {0x17d5042, "color[container]"},
119
120
    // functions collections
121
5.46M
    {0x14c2042, "functions[layout]"},
122
5.46M
    {0x1559842, "functions[standart]"},
123
5.46M
    {0x1663842, "functions[spreadsheet]"},
124
5.46M
    {0x1be5042, "functions[fax]"},
125
5.46M
    {0x1d50842, "functions[button]"},
126
5.46M
    {0x1e16842, "functions[slide]"},
127
5.46M
    {0x23aa042, "functions[calendar]"},
128
5.46M
    {0x23af042, "functions[serialNumber]"},
129
5.46M
    {0x23b4042, "functions[euro]"},
130
5.46M
  };
131
5.46M
  auto it=s_typeToName.find(fileType);
132
5.46M
  if (it!=s_typeToName.end())
133
37
    return it->second;
134
5.46M
  std::stringstream s;
135
5.46M
  s << (fileType>>11) << "-" << std::hex << (fileType&0x7ff) << std::dec;
136
5.46M
  return s.str();
137
5.46M
}
138
139
bool RagTime5StructManager::readTypeDefinitions(RagTime5Zone &zone)
140
8.58k
{
141
8.58k
  if (zone.m_entry.length()<26) return false;
142
8.53k
  MWAWInputStreamPtr input=zone.getInput();
143
8.53k
  long endPos=zone.m_entry.end();
144
8.53k
  input->setReadInverted(!zone.m_hiLoEndian);
145
8.53k
  input->seek(zone.m_entry.begin(), librevenge::RVNG_SEEK_SET);
146
147
8.53k
  libmwaw::DebugStream f;
148
8.53k
  f << "Entries(TypeDef):[" << zone << "]";
149
8.53k
  long N;
150
8.53k
  if (!input->checkPosition(endPos) || !RagTime5StructManager::readCompressedLong(input, endPos, N) || N<20 || 12+14*N>zone.m_entry.length()) {
151
854
    MWAW_DEBUG_MSG(("RagTime5StructManager::readTypeDefinitions: can not read the list type zone\n"));
152
854
    input->setReadInverted(false);
153
854
    return false;
154
854
  }
155
7.67k
  zone.m_isParsed=true;
156
7.67k
  libmwaw::DebugFile &ascFile=zone.ascii();
157
7.67k
  f << "N=" << N << ",";
158
7.67k
  int val;
159
23.0k
  for (int i=0; i<2; ++i) { // always 0,0
160
15.3k
    val=static_cast<int>(input->readLong(2));
161
15.3k
    if (val) f << "f" << i << "=" << val << ",";
162
15.3k
  }
163
7.67k
  auto sz=static_cast<int>(input->readULong(1));
164
7.67k
  if (input->tell()+sz>endPos) {
165
0
    MWAW_DEBUG_MSG(("RagTime5StructManager::readTypeDefinitions: can not find the data1 sz\n"));
166
0
    return false;
167
0
  }
168
7.67k
  if (sz) {
169
1.91k
    f << "data1=[" << std::hex;
170
250k
    for (int i=0; i<sz+1; ++i) {
171
248k
      val=static_cast<int>(input->readULong(1));
172
248k
      if (val) f << val << ",";
173
97.2k
      else f << "_,";
174
248k
    }
175
1.91k
    f << std::dec << "],";
176
1.91k
  }
177
7.67k
  long debDataPos=input->tell()+4*(N+1);
178
7.67k
  long remain=endPos-debDataPos;
179
7.67k
  if (remain<=0) {
180
0
    input->setReadInverted(false);
181
0
    return false;
182
0
  }
183
7.67k
  f << "ptr=[" << std::hex;
184
7.67k
  std::vector<long> listPtrs(size_t(N+1), -1);
185
7.67k
  long lastPtr=0;
186
7.67k
  int numOk=0;
187
813k
  for (size_t i=0; i<=size_t(N); ++i) {
188
806k
    auto ptr=long(input->readULong(4));
189
806k
    if (ptr<0 || ptr>remain || ptr<lastPtr) {
190
167k
      f << "###";
191
167k
      static bool first=true;
192
167k
      if (first) {
193
26
        first = false;
194
26
        MWAW_DEBUG_MSG(("RagTime5StructManager::readTypeDefinitions: problem reading some type position\n"));
195
26
      }
196
167k
      listPtrs[size_t(i)]=lastPtr;
197
167k
    }
198
638k
    else {
199
638k
      ++numOk;
200
638k
      lastPtr=listPtrs[size_t(i)]=ptr;
201
638k
    }
202
806k
    f << ptr << ",";
203
806k
  }
204
7.67k
  f << std::dec << "],";
205
7.67k
  ascFile.addPos(zone.m_entry.begin());
206
7.67k
  ascFile.addNote(f.str().c_str());
207
7.67k
  ascFile.addPos(endPos);
208
7.67k
  ascFile.addNote("_");
209
7.67k
  if (!numOk) {
210
586
    MWAW_DEBUG_MSG(("RagTime5StructManager::readTypeDefinitions: problem reading some type position\n"));
211
586
    input->setReadInverted(false);
212
586
    return false;
213
586
  }
214
215
  // first 10 main types are the same:
216
  //   0: 1451042, 1:6d042, 2:cf042, 3:1454042, 4:74040, 5:df842, 6:ce042, 7:3c042, 8:ce842, 9:67842, 10:6a842
217
  // Component correspondance
218
  // 14b5842: layout, 14b7842: master layout,
219
  // 14e6842: drawing
220
  // 15e0842: Text
221
  // 1645042: spreadsheet
222
  // 16a8842: Graph
223
  // 170c842: Picture
224
  // 1d4d042: Button
225
  // 1d7f842: Sound
226
  // 1db0842: Movie
227
769k
  for (size_t i=0; i+1<listPtrs.size(); ++i) {
228
762k
    if (listPtrs[i]<0 || listPtrs[i]==listPtrs[i+1]) continue;
229
625k
    if (listPtrs[i]==remain) break;
230
625k
    f.str("");
231
625k
    f << "TypeDef-" << i << "[head]:";
232
625k
    auto dSz=int(listPtrs[i+1]-listPtrs[i]);
233
625k
    long pos=debDataPos+listPtrs[i];
234
625k
    if (dSz<4+20) {
235
384
      f << "###";
236
384
      MWAW_DEBUG_MSG(("RagTime5StructManager::readTypeDefinitions: problem with some type size\n"));
237
384
      ascFile.addPos(pos);
238
384
      ascFile.addNote(f.str().c_str());
239
384
    }
240
625k
    input->seek(pos, librevenge::RVNG_SEEK_SET);
241
625k
    val=static_cast<int>(input->readLong(4));
242
625k
    if (val!=1) f << "num[used]=" << val << ",";
243
625k
    auto hSz=static_cast<int>(input->readULong(2));
244
625k
    int nData=(dSz-4-hSz)/12;
245
625k
    if (4+hSz>dSz || dSz!=4+hSz+12*nData || nData<0 || hSz<20) {
246
135k
      f << "###hSz=" << hSz << ",";
247
135k
      MWAW_DEBUG_MSG(("RagTime5StructManager::readTypeDefinitions: the header size seems bad\n"));
248
135k
      ascFile.addPos(pos);
249
135k
      ascFile.addNote(f.str().c_str());
250
135k
      continue;
251
135k
    }
252
490k
    val=static_cast<int>(input->readULong(2));
253
490k
    if (val) f << "fl=" << std::hex << val << std::dec << ",";
254
490k
    val=static_cast<int>(input->readULong(4));
255
490k
    if (val) f << "id?=" << std::hex << val << std::dec << ","; // maybe a date, origin?
256
490k
    auto type=input->readULong(4);
257
490k
    if (type) f << "type=" << printType(type) << ",";
258
1.47M
    for (int j=0; j<2; ++j) { // f1=0..12,
259
980k
      val=static_cast<int>(input->readLong(2));
260
980k
      if (val) f << "f" << j+1 << "=" << val << ",";
261
980k
    }
262
490k
    auto type2=input->readULong(4);
263
490k
    if (type2) f << "type2=" << printType(type2) << ",";
264
490k
    if (hSz>20) {
265
21.6k
      auto sSz=static_cast<int>(input->readULong(1));
266
21.6k
      if ((sSz%2)!=0 || 20+1+sSz>hSz) {
267
296
        f << "###sSz=" << sSz << ",";
268
296
        MWAW_DEBUG_MSG(("RagTime5StructManager::readTypeDefinitions: the string size seems bad\n"));
269
296
      }
270
21.3k
      else { // Layout, Text, Picture, .. a componant name
271
21.3k
        std::string name("");
272
154k
        for (int c=0; c<sSz/2; ++c)
273
133k
          name+=char(input->readULong(2));
274
21.3k
        f << "name=" << name << ",";
275
21.3k
        if (type2!=0x14a9842) {
276
227
          f << "###type2,";
277
227
          MWAW_DEBUG_MSG(("RagTime5StructManager::readTypeDefinitions: find odd type2 with a string size\n"));
278
227
        }
279
21.3k
      }
280
21.6k
    }
281
490k
    if (input->tell()!=pos+4+hSz)
282
628
      ascFile.addDelimiter(input->tell(),'|');
283
490k
    ascFile.addPos(pos);
284
490k
    ascFile.addNote(f.str().c_str());
285
286
490k
    input->seek(pos+4+hSz, librevenge::RVNG_SEEK_SET);
287
2.32M
    for (int j=0; j<nData; ++j) {
288
1.83M
      pos=input->tell();
289
1.83M
      f.str("");
290
1.83M
      f << "TypeDef-" << i << "[" << j << "]:";
291
1.83M
      f << "type=" << printType(input->readULong(4)) << ","; // a big number, ~type (but a multiple of 5)
292
1.83M
      f << "type2=" << printType(input->readULong(4)) << std::dec << ","; // a big number
293
5.50M
      for (int k=0; k<2; ++k) {
294
3.67M
        val=static_cast<int>(input->readULong(1));
295
3.67M
        if (val) f << "fl" << k << "=" << std::hex << val << std::dec << ",";
296
3.67M
      }
297
1.83M
      val=static_cast<int>(input->readLong(2));
298
1.83M
      if (val) f << "f0=" << val << ",";
299
1.83M
      ascFile.addPos(pos);
300
1.83M
      ascFile.addNote(f.str().c_str());
301
1.83M
      input->seek(pos+12, librevenge::RVNG_SEEK_SET);
302
1.83M
    }
303
490k
  }
304
7.09k
  if (!listPtrs.empty() && listPtrs.back()!=remain) {
305
1.97k
    ascFile.addPos(debDataPos+listPtrs.back());
306
1.97k
    ascFile.addNote("TypeDef-end");
307
1.97k
  }
308
7.09k
  input->setReadInverted(false);
309
7.09k
  return true;
310
7.67k
}
311
312
313
bool RagTime5StructManager::readUnicodeString(MWAWInputStreamPtr input, long endPos, librevenge::RVNGString &string)
314
573k
{
315
573k
  string="";
316
573k
  long pos=input->tell();
317
573k
  if (pos==endPos) return true;
318
573k
  long length=endPos-pos;
319
573k
  if (length<0 || (length%2)==1) {
320
3.24k
    MWAW_DEBUG_MSG(("RagTime5StructManager::readUnicodeString: find unexpected data length\n"));
321
3.24k
    return false;
322
3.24k
  }
323
570k
  length/=2;
324
570k
  int lEndian=0, hEndian=0; // for checking if little/big endian is set correctly
325
305M
  for (long i=0; i<length; ++i) {
326
304M
    auto c=static_cast<uint32_t>(input->readULong(2));
327
304M
    if ((c&0xFF00)==0) ++hEndian;
328
529k
    else if ((c&0xFF)==0) ++lEndian;
329
304M
    if (c!=0)
330
6.09M
      libmwaw::appendUnicode(c, string);
331
304M
  }
332
570k
  if (lEndian>hEndian) {
333
21.7k
    static bool first=true;
334
21.7k
    if (first) {
335
32
      first=false;
336
32
      MWAW_DEBUG_MSG(("RagTime5StructManager::readUnicodeString: the endian reading seems bad...\n"));
337
32
    }
338
21.7k
  }
339
570k
  return true;
340
573k
}
341
342
bool RagTime5StructManager::readDataIdList(MWAWInputStreamPtr input, int n, std::vector<int> &listIds)
343
184M
{
344
184M
  listIds.clear();
345
184M
  long pos=input->tell();
346
368M
  for (int i=0; i<n; ++i) {
347
185M
    int val=static_cast<int>(MWAWInputStream::readULong(input->input().get(), 2, 0, false));
348
185M
    if (val==0) {
349
182M
      listIds.push_back(0);
350
182M
      input->seek(2, librevenge::RVNG_SEEK_CUR);
351
182M
      continue;
352
182M
    }
353
2.72M
    if (val!=1) {
354
      // update the position
355
1.08M
      input->seek(pos+4*n, librevenge::RVNG_SEEK_SET);
356
1.08M
      return false;
357
1.08M
    }
358
1.63M
    listIds.push_back(static_cast<int>(MWAWInputStream::readULong(input->input().get(), 2, 0, false)));
359
1.63M
  }
360
183M
  return true;
361
184M
}
362
363
bool RagTime5StructManager::readField(MWAWInputStreamPtr input, long endPos, libmwaw::DebugFile &ascFile,
364
                                      RagTime5StructManager::Field &field, long fSz, int depth)
365
6.04M
{
366
6.04M
  if (depth >= MAX_RECORD_NESTING) {
367
0
    MWAW_DEBUG_MSG(("RagTime5StructManager::readField: nesting too deep\n"));
368
0
    return false;
369
0
  }
370
6.04M
  libmwaw::DebugStream f;
371
6.04M
  long debPos=input->tell();
372
6.04M
  if ((fSz>0 && (fSz<4 || debPos+fSz>endPos)) || (fSz<=0 && debPos+5>endPos)) {
373
22.0k
    MWAW_DEBUG_MSG(("RagTime5StructManager::readField: the zone seems too short\n"));
374
22.0k
    return false;
375
22.0k
  }
376
6.02M
  auto type=input->readULong(4);
377
6.02M
  if ((type>>16)==0) {
378
445k
    input->seek(debPos, librevenge::RVNG_SEEK_SET);
379
445k
    return false;
380
445k
  }
381
5.58M
  field.m_fileType=type;
382
5.58M
  bool complex=static_cast<int>(input->readULong(1))==0xc0;
383
5.58M
  input->seek(-1, librevenge::RVNG_SEEK_CUR);
384
5.58M
  if (fSz<=0) {
385
4.29M
    if (!readCompressedLong(input, endPos, fSz) || fSz<=0 || input->tell()+fSz>endPos) {
386
734k
      MWAW_DEBUG_MSG(("RagTime5StructManager::readField: can not read the data size\n"));
387
734k
      input->seek(debPos, librevenge::RVNG_SEEK_SET);
388
734k
      return false;
389
734k
    }
390
4.29M
  }
391
1.28M
  else
392
1.28M
    fSz-=4;
393
4.84M
  long debDataPos=input->tell();
394
4.84M
  long endDataPos=debDataPos+fSz;
395
4.84M
  switch (static_cast<unsigned long>(type)) {
396
40.2k
  case 0x360c0:
397
41.2k
  case 0x368c0:
398
41.2k
    if (fSz!=1) {
399
426
      MWAW_DEBUG_MSG(("RagTime5StructManager::readField: unexpected data fSz for bool\n"));
400
426
      f << "###bool,";
401
426
      break;
402
426
    }
403
40.8k
    field.m_type=Field::T_Bool;
404
405
40.8k
    field.m_name="bool";
406
40.8k
    field.m_longValue[0]=long(input->readLong(1));
407
40.8k
    return true;
408
409
384
  case 0x328c0:
410
384
    if (fSz!=1) {
411
22
      MWAW_DEBUG_MSG(("RagTime5StructManager::readField: unexpected data fSz for bInt\n"));
412
22
      f << "###bInt,";
413
22
      break;
414
22
    }
415
362
    field.m_type=Field::T_Long;
416
362
    field.m_name="bInt";
417
362
    field.m_longValue[0]=long(input->readLong(1));
418
362
    return true;
419
420
132k
  case 0x3b880:
421
160k
  case 0x1479080:
422
160k
  case 0x147b880:
423
286k
  case 0x147c080:
424
337k
  case 0x149d880:
425
390k
  case 0x149e080:
426
430k
  case 0x17d5880:
427
430k
    if (fSz!=2) {
428
1.51k
      MWAW_DEBUG_MSG(("RagTime5StructManager::readField: unexpected data fSz for int\n"));
429
1.51k
      f << "###int,";
430
1.51k
      break;
431
1.51k
    }
432
428k
    field.m_type=Field::T_Long;
433
428k
    field.m_name="int";
434
428k
    field.m_longValue[0]=long(input->readLong(2));
435
428k
    return true;
436
57.0k
  case 0x34080:
437
74.5k
  case 0xcf817: // bigger int dataId?: not in typedef
438
74.5k
    if (fSz!=2) {
439
603
      MWAW_DEBUG_MSG(("RagTime5StructManager::readField: unexpected data fSz for uint\n"));
440
603
      f << "###uint,";
441
603
      break;
442
603
    }
443
73.9k
    field.m_type=Field::T_Long;
444
73.9k
    field.m_name="uint";
445
73.9k
    field.m_longValue[0]=long(input->readULong(2));
446
73.9k
    return true;
447
4.83k
  case 0xb6000: // color percent
448
10.0k
  case 0x1493800: // checkme double(as int)
449
32.6k
  case 0x1494800: // checkme double(as int)
450
42.4k
  case 0x1495000:
451
44.8k
  case 0x1495800: // checkme double(as int)
452
44.8k
    if (fSz!=4) {
453
400
      MWAW_DEBUG_MSG(("RagTime5StructManager::readField: unexpected data fSz for double4\n"));
454
400
      f << "###float,";
455
400
      break;
456
400
    }
457
    // checkme if val=0xFFFFFFFF, inf?
458
44.4k
    field.m_type=Field::T_Double;
459
44.4k
    field.m_name="double4";
460
44.4k
    field.m_doubleValue=double(input->readLong(4))/65536;
461
44.4k
    return true;
462
42.0k
  case 0x45840: {
463
42.0k
    if (fSz!=8) {
464
365
      MWAW_DEBUG_MSG(("RagTime5StructManager::readField: unexpected data fSz for double\n"));
465
365
      f << "###double,";
466
365
      break;
467
365
    }
468
41.6k
    double res;
469
41.6k
    bool isNan;
470
41.6k
    if (!input->readDouble8(res, isNan)) {
471
361
      MWAW_DEBUG_MSG(("RagTime5StructManager::readField: can not read a double\n"));
472
361
      f << "###double";
473
361
      break;
474
361
    }
475
41.2k
    field.m_type=Field::T_Double;
476
41.2k
    field.m_name="double";
477
41.2k
    field.m_doubleValue=res;
478
41.2k
    return true;
479
41.6k
  }
480
7.31k
  case 0x14510b7: {
481
7.31k
    std::vector<int> listIds;
482
7.31k
    if (!readDataIdList(input, 1, listIds)) {
483
0
      MWAW_DEBUG_MSG(("RagTime5StructManager::readField: can not read the cluster id\n"));
484
0
      f << "###clustId,";
485
0
      break;
486
0
    }
487
7.31k
    field.m_name="colPatId";
488
7.31k
    field.m_type=Field::T_ZoneId;
489
7.31k
    field.m_longValue[0]=listIds[0];
490
7.31k
    return true;
491
7.31k
  }
492
825
  case 0x34800:
493
52.6k
  case 0x8c000: // a dim
494
52.6k
  case 0x234800:  // checkme, find always with 0x0
495
61.6k
  case 0x147415a: // checkme, find always with 0x0
496
80.4k
  case 0x15e3017: // 2 long, not in typedef
497
80.4k
    if (fSz!=4) {
498
151
      MWAW_DEBUG_MSG(("RagTime5StructManager::readField: unexpected data fSz for 2xint\n"));
499
151
      f << "###2xint,";
500
151
      break;
501
151
    }
502
80.2k
    field.m_type=Field::T_2Long;
503
80.2k
    field.m_name="2xint";
504
80.2k
    field.m_longValue[0]=long(input->readLong(2));
505
80.2k
    field.m_longValue[1]=long(input->readLong(2));
506
80.2k
    return true;
507
5.00k
  case 0x7d01a:
508
365k
  case 0xc8042: { // unicode
509
365k
    if (fSz<2) {
510
142
      MWAW_DEBUG_MSG(("RagTime5StructManager::readField: unexpected data fSz for unicode\n"));
511
142
      f << "###unicode";
512
142
      break;
513
142
    }
514
365k
    field.m_type=Field::T_Unicode;
515
365k
    field.m_name="unicode";
516
365k
    auto val=static_cast<int>(input->readULong(2));
517
365k
    if ((val&0x70FF)==0) {
518
222k
      if (val) f << "f1=" << ((val&0x7F00)>>8);
519
1.32M
      for (long i=2; i<fSz; ++i)
520
1.10M
        libmwaw::appendUnicode(static_cast<uint32_t>(input->readULong(1)), field.m_string);
521
222k
    }
522
142k
    else {
523
142k
      input->seek(debDataPos, librevenge::RVNG_SEEK_SET);
524
142k
      if (!readUnicodeString(input, endDataPos, field.m_string))
525
1.70k
        f << "###";
526
142k
    }
527
365k
    input->seek(endDataPos, librevenge::RVNG_SEEK_SET);
528
365k
    field.m_extra=f.str();
529
365k
    return true;
530
365k
  }
531
0
  case 0x1f6817:
532
0
  case 0x1f6827:
533
0
  case 0x1f7877: { // CHECKME: is this also valid for unicode ?
534
0
    if (fSz<2) {
535
0
      MWAW_DEBUG_MSG(("RagTime5StructManager::readField: unexpected data fSz for int+unicode\n"));
536
0
      f << "###int+unicode";
537
0
      break;
538
0
    }
539
0
    field.m_type=Field::T_Unicode;
540
0
    field.m_name="int+unicode";
541
0
    int val=int(input->readULong(2));
542
0
    if ((val&0xff) || val==0xff00) { // ff00 means list of {length+str} for normal string
543
0
      f << "multistring,";
544
0
      f << "val=" << std::hex << val << std::dec << ",";
545
0
      val=static_cast<int>(input->readULong(2));
546
0
    }
547
    //std::cout << "ICI1:" << std::hex << val << std::dec << "\n";
548
0
    if ((val&0x8000)==0) {
549
0
      if ((val>>8)>2) f << "f1=" << (val>>8);
550
0
      fSz=int(endDataPos-input->tell());
551
0
      for (long i=0; i<fSz; ++i) {
552
0
        auto c=static_cast<uint32_t>(input->readULong(1));
553
0
        if (c)
554
0
          libmwaw::appendUnicode(c, field.m_string);
555
0
        else
556
0
          field.m_string.append('#');
557
0
      }
558
0
    }
559
0
    else if (!readUnicodeString(input, endDataPos, field.m_string)) {
560
0
      field.m_string="###";
561
0
    }
562
0
    input->seek(endDataPos, librevenge::RVNG_SEEK_SET);
563
0
    field.m_extra=f.str();
564
0
    return true;
565
0
  }
566
600
  case 0x149a940: {
567
600
    if (fSz!=6) {
568
0
      MWAW_DEBUG_MSG(("RagTime5StructManager::readField: unexpected data fSz for interline\n"));
569
0
      f << "###interline";
570
0
      break;
571
0
    }
572
600
    field.m_type=Field::T_LongDouble;
573
600
    field.m_name="interline";
574
600
    field.m_longValue[0]=static_cast<int>(input->readLong(2));
575
600
    field.m_doubleValue=double(input->readLong(4))/65536.;
576
600
    return true;
577
600
  }
578
855
  case 0x149c940: { // checkme
579
855
    if (fSz!=6) {
580
0
      MWAW_DEBUG_MSG(("RagTime5StructManager::readField: unexpected data fSz for floatxint\n"));
581
0
      f << "###floatxint";
582
0
      break;
583
0
    }
584
855
    field.m_type=Field::T_LongDouble;
585
855
    field.m_name="floatxint";
586
855
    field.m_doubleValue=double(input->readLong(4))/65536.;
587
855
    field.m_longValue[0]=static_cast<int>(input->readLong(2));
588
855
    return true;
589
855
  }
590
23.0k
  case 0x74040: {
591
23.0k
    if (fSz!=8) {
592
702
      MWAW_DEBUG_MSG(("RagTime5StructManager::readField: unexpected data fSz for 2xfloat\n"));
593
702
      f << "###2xfloat";
594
702
      break;
595
702
    }
596
22.3k
    field.m_type=Field::T_DoubleList;
597
22.3k
    field.m_name="2xfloat";
598
67.1k
    for (int i=0; i<2; ++i)
599
44.7k
      field.m_doubleList.push_back(double(input->readLong(4))/65536);
600
22.3k
    return true;
601
23.0k
  }
602
5.30k
  case 0x1474040: // maybe one tab
603
6.02k
  case 0x81474040: {
604
6.02k
    if ((fSz%8)!=0) {
605
28
      MWAW_DEBUG_MSG(("RagTime5StructManager::readField: unexpected data fSz for tab\n"));
606
28
      f << "###tab[list]";
607
28
      break;
608
28
    }
609
5.99k
    field.m_type=Field::T_TabList;
610
5.99k
    field.m_name="tab";
611
5.99k
    auto N=int(fSz/8);
612
12.3k
    for (int i=0; i<N; ++i) {
613
6.36k
      TabStop tab;
614
6.36k
      tab.m_position=float(input->readLong(4))/65536.f;
615
6.36k
      tab.m_type=static_cast<int>(input->readLong(2));
616
6.36k
      tab.m_leaderChar=static_cast<uint16_t>(input->readULong(2));
617
6.36k
      field.m_tabList.push_back(tab);
618
6.36k
    }
619
5.99k
    return true;
620
6.02k
  }
621
40
  case 0x74840: // dimension
622
19.9k
  case 0x112040: // also some dimension ? ( often 0,0,0,1 but can be 0,-0.00564575,0,0.25 )
623
19.9k
    if (fSz!=16) {
624
94
      MWAW_DEBUG_MSG(("RagTime5StructManager::readField: unexpected data fSz for dim\n"));
625
94
      f << "###dim";
626
94
      break;
627
94
    }
628
19.8k
    field.m_type=Field::T_DoubleList;
629
19.8k
    field.m_name="dim";
630
99.3k
    for (long i=0; i<4; ++i)
631
79.4k
      field.m_doubleList.push_back(double(input->readLong(4))/65536.);
632
19.8k
    field.m_extra=f.str();
633
19.8k
    return true;
634
635
121
  case 0x1476840:
636
121
    if (fSz!=10) {
637
1
      MWAW_DEBUG_MSG(("RagTime5StructManager::readField: unexpected data fSz for 3intxfloat\n"));
638
1
      f << "###3intxfloat";
639
1
      break;
640
1
    }
641
120
    field.m_type=Field::T_Unstructured;
642
120
    field.m_name="3intxfloat";
643
120
    field.m_entry.setBegin(input->tell());
644
120
    field.m_entry.setEnd(endDataPos);
645
480
    for (long i=0; i<3; ++i) { // 1|3,1,1
646
360
      auto val=static_cast<int>(input->readLong(2));
647
360
      if (val) f << val << ":";
648
0
      else f << "_:";
649
360
    }
650
120
    f << double(input->readLong(4))/65536. << ",";
651
120
    field.m_extra=f.str();
652
120
    return true;
653
50.4k
  case 0x79040: { // checkme: unsure
654
50.4k
    if (fSz!=14) {
655
91
      MWAW_DEBUG_MSG(("RagTime5StructManager::readField: unexpected data fSz for 0x79040\n"));
656
91
      f << "###unstr";
657
91
      break;
658
91
    }
659
50.3k
    field.m_type=Field::T_Unstructured;
660
50.3k
    field.m_name="unstr";
661
50.3k
    field.m_entry.setBegin(input->tell());
662
50.3k
    field.m_entry.setEnd(endDataPos);
663
151k
    for (long i=0; i<2; ++i) { // something like 49c4x6c2b
664
100k
      f << std::hex << input->readULong(4) << std::dec;
665
100k
      if (i==0) f << "x";
666
50.3k
      else f << ",";
667
100k
    }
668
151k
    for (int i=0; i<2; ++i) { // often 4000, 3fed
669
100k
      f << std::hex << input->readULong(2) << std::dec;
670
100k
      if (i==0) f << "x";
671
50.3k
      else f << ",";
672
100k
    }
673
50.3k
    auto val=static_cast<int>(input->readLong(2));
674
50.3k
    if (val!=0x100) f << val << ":";
675
50.3k
    field.m_extra=f.str();
676
50.3k
    return true;
677
50.4k
  }
678
135k
  case 0x84040: {
679
135k
    if (fSz!=10) {
680
400
      MWAW_DEBUG_MSG(("RagTime5StructManager::readField: unexpected data fSz for rgba\n"));
681
400
      f << "###rgba";
682
400
      break;
683
400
    }
684
134k
    field.m_type=Field::T_Color;
685
134k
    field.m_name="rgba";
686
134k
    field.m_longValue[0]=long(input->readLong(2)); // id or numUsed
687
134k
    if (field.m_longValue[0]==50) {
688
54.6k
      field.m_longValue[1]=long(input->readULong(2));
689
54.6k
      field.m_color=MWAWColor(255,255,255);
690
54.6k
      input->seek(endDataPos, librevenge::RVNG_SEEK_SET);
691
54.6k
      return true;
692
54.6k
    }
693
79.9k
    unsigned char col[4];
694
319k
    for (auto &c : col) c=static_cast<unsigned char>(input->readULong(2)>>8); // rgba
695
79.9k
    field.m_color=MWAWColor(col[0],col[1],col[2],col[3]);
696
79.9k
    return true;
697
134k
  }
698
19.6k
  case 0x8d000: {
699
19.6k
    if (fSz!=4) {
700
952
      MWAW_DEBUG_MSG(("RagTime5StructManager::readField: unexpected data fSz for rsrcName\n"));
701
952
      f << "###rsrcName";
702
952
      break;
703
952
    }
704
18.6k
    field.m_type=Field::T_Code;
705
18.6k
    field.m_name="rsrcName";
706
18.6k
    auto cod=input->readULong(4);
707
93.2k
    for (int i=0; i<4; ++i) field.m_string.append(char(cod>>(24-8*i)));
708
18.6k
    return true;
709
19.6k
  }
710
0
  case 0x31e040:
711
    // <!DOCTYPE plist PUBLIC "-//Apple Computer//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
712
0
    if (fSz<30) {
713
0
      MWAW_DEBUG_MSG(("RagTime5StructManager::readField: unexpected data fSz for xml printer\n"));
714
0
      f << "###printInfoX";
715
0
      break;
716
0
    }
717
0
    field.m_type=Field::T_String;
718
0
    field.m_name="printInfoX";
719
0
    for (long i=0; i<fSz && i<30; ++i)
720
0
      field.m_string.append(char(input->readULong(1)));
721
0
    field.m_string.append("...");
722
0
    input->seek(endDataPos, librevenge::RVNG_SEEK_SET);
723
0
    return true;
724
0
  case 0x2fd040: {
725
0
    if (fSz<120) {
726
0
      MWAW_DEBUG_MSG(("RagTime5StructManager::readField: unexpected data fSz for printInfo\n"));
727
0
      f << "###printInfo";
728
0
      break;
729
0
    }
730
0
    libmwaw::PrinterInfo info;
731
0
    if (!info.read(input)) {
732
0
      MWAW_DEBUG_MSG(("RagTime5StructManager::readField: can not read printInfo\n"));
733
0
      f << "###printInfo";
734
0
      break;
735
0
    }
736
0
    field.m_type=Field::T_PrintInfo;
737
0
    field.m_name="printInfo";
738
0
    f << info << ",";
739
0
    field.m_extra=f.str();
740
    // then sometimes 4 string title, ...
741
0
    if (input->tell()!=endDataPos)
742
0
      ascFile.addDelimiter(input->tell(),'|');
743
0
    input->seek(endDataPos, librevenge::RVNG_SEEK_SET);
744
0
    return true;
745
0
  }
746
0
  case 0x333140: // AppleWriter pref, probably safe to ignore
747
0
    if (fSz!=908) {
748
0
      MWAW_DEBUG_MSG(("RagTime5StructManager::readField: unexpected data fSz for AppleWriter prefs\n"));
749
0
      f << "###appleWriterInfo";
750
0
      break;
751
0
    }
752
0
    field.m_type=Field::T_Unstructured;
753
0
    field.m_name="appleWriterInfo";
754
0
    field.m_entry.setBegin(input->tell());
755
0
    field.m_entry.setEnd(endDataPos);
756
    // name in lohi ?
757
0
    for (int i=0; i<32; ++i) {
758
0
      auto c=static_cast<int>(input->readULong(1));
759
0
      c+=static_cast<int>(input->readULong(1)<<8);
760
0
      if (c==0) break;
761
0
      f << char(c);
762
0
    }
763
0
    f << "...";
764
0
    field.m_extra=f.str();
765
0
    ascFile.addDelimiter(input->tell(),'|');
766
0
    input->seek(endDataPos, librevenge::RVNG_SEEK_SET);
767
0
    return true;
768
17.5k
  case 0x148c01a: // 2 int + 8 bytes for pat ?
769
17.5k
    if (fSz!=12) {
770
183
      MWAW_DEBUG_MSG(("RagTime5StructManager::readField: unexpected data fSz for pat\n"));
771
183
      f << "###pat";
772
183
      break;
773
183
    }
774
17.3k
    field.m_type=Field::T_Unstructured;
775
17.3k
    field.m_name="pat";
776
17.3k
    field.m_entry.setBegin(input->tell());
777
17.3k
    field.m_entry.setEnd(endDataPos);
778
17.3k
    field.m_extra="...";
779
17.3k
    input->seek(endDataPos, librevenge::RVNG_SEEK_SET);
780
17.3k
    return true;
781
17.8k
  case 0x226140:
782
17.8k
    if (fSz!=21) {
783
568
      MWAW_DEBUG_MSG(("RagTime5StructManager::readField: unexpected data fSz for font\n"));
784
568
      f << "###font";
785
568
      break;
786
568
    }
787
17.3k
    field.m_type=Field::T_Unstructured;
788
17.3k
    field.m_name="font";
789
17.3k
    field.m_entry.setBegin(input->tell());
790
17.3k
    field.m_entry.setEnd(endDataPos);
791
17.3k
    field.m_extra="...";
792
17.3k
    input->seek(endDataPos, librevenge::RVNG_SEEK_SET);
793
17.3k
    return true;
794
17.8k
  case 0x226940: { // checkme
795
17.8k
    if (fSz<262 || ((fSz-262)%6)!=0) {
796
228
      MWAW_DEBUG_MSG(("RagTime5StructManager::readField: unexpected data fSz for para\n"));
797
228
      f << "###para";
798
228
      break;
799
228
    }
800
17.6k
    field.m_type=Field::T_Unstructured;
801
17.6k
    field.m_name="para";
802
17.6k
    field.m_entry.setBegin(input->tell());
803
17.6k
    field.m_entry.setEnd(endDataPos);
804
17.6k
    field.m_extra="...";
805
17.6k
    ascFile.addPos(input->tell()+70);
806
17.6k
    ascFile.addNote("TextStyle-para-B0:");
807
17.6k
    ascFile.addPos(input->tell()+166);
808
17.6k
    ascFile.addNote("TextStyle-para-B1:");
809
17.6k
    if (fSz>262) {
810
4.05k
      ascFile.addPos(input->tell()+262);
811
4.05k
      ascFile.addNote("TextStyle-para-C:");
812
4.05k
    }
813
17.6k
    input->seek(endDataPos, librevenge::RVNG_SEEK_SET);
814
17.6k
    return true;
815
17.8k
  }
816
7.32k
  case 0x71940: // checkme: locale data ?
817
7.32k
    if (fSz!=108) {
818
426
      MWAW_DEBUG_MSG(("RagTime5StructManager::readField: unexpected data fSz for locale\n"));
819
426
      f << "###locale";
820
426
      break;
821
426
    }
822
6.89k
    field.m_type=Field::T_Unstructured;
823
6.89k
    field.m_name="locale";
824
6.89k
    field.m_entry.setBegin(input->tell());
825
6.89k
    field.m_entry.setEnd(endDataPos);
826
6.89k
    f << "fls=[" << std::hex;
827
62.0k
    for (long i=0; i<8; ++i) {
828
55.1k
      auto val=static_cast<int>(input->readLong(1));
829
55.1k
      if (val==1) f << "_,";
830
27.5k
      else f << val << ",";
831
55.1k
    }
832
6.89k
    f << "],";
833
6.89k
    f << "chars=[";
834
151k
    for (long i=0; i<21; ++i) {
835
144k
      auto val=static_cast<int>(input->readULong(2));
836
144k
      if (!val) f << "_,";
837
124k
      else if (val<128) f << char(val) << ",";
838
242
      else f << std::hex << val << std::dec << ",";
839
144k
    }
840
6.89k
    f << "],";
841
6.89k
    ascFile.addDelimiter(input->tell(),'|');
842
6.89k
    field.m_extra=f.str();
843
6.89k
    input->seek(endDataPos, librevenge::RVNG_SEEK_SET);
844
6.89k
    return true;
845
45
  case 0x32040:
846
45
    if (fSz<160) {
847
31
      MWAW_DEBUG_MSG(("RagTime5StructManager::readField: the data fSz for docInfo data seems too short\n"));
848
31
      f << "###docInfo";
849
31
      break;
850
31
    }
851
14
    else {
852
14
      field.m_type=Field::T_Unstructured;
853
14
      field.m_name="docInfo";
854
14
      field.m_entry.setBegin(input->tell());
855
14
      field.m_entry.setEnd(endDataPos);
856
14
      field.m_extra="...";
857
14
      input->seek(endDataPos, librevenge::RVNG_SEEK_SET);
858
14
      return true;
859
14
    }
860
17.5k
  case 0x227140: { // border checkme
861
17.5k
    if ((fSz%6)!=2) {
862
522
      MWAW_DEBUG_MSG(("RagTime5StructManager::readField: unexpected data fSz for list of border\n"));
863
522
      f << "###border";
864
522
      break;
865
522
    }
866
16.9k
    auto val=static_cast<int>(input->readULong(2)); // c000 or c1000
867
16.9k
    if (val!=0xc000) f << "f0=" << std::hex << val << std::dec << ",";
868
16.9k
    field.m_type=Field::T_LongList;
869
16.9k
    field.m_name="border";
870
16.9k
    field.m_numLongByData=3;
871
16.9k
    fSz/=6;
872
1.83M
    for (long i=0; i<fSz; ++i) {
873
1.81M
      field.m_longList.push_back(long(input->readLong(2))); // row?
874
1.81M
      field.m_longList.push_back(long(input->readLong(2))); // col?
875
1.81M
      field.m_longList.push_back(long(input->readULong(2))); // flags?
876
1.81M
    }
877
16.9k
    field.m_extra=f.str();
878
16.9k
    return true;
879
17.5k
  }
880
142
  case 0x64040: { // chart pref
881
142
    if (fSz<3) {
882
3
      MWAW_DEBUG_MSG(("RagTime5StructManager::readField: unexpected data fSz for chart pref\n"));
883
3
      f << "###chart pref";
884
3
      break;
885
3
    }
886
139
    field.m_type=Field::T_FieldList;
887
139
    field.m_entry.setBegin(input->tell());
888
139
    field.m_entry.setEnd(endDataPos);
889
556
    for (int i=0; i<3; ++i) { // f2=8|9
890
417
      auto val=static_cast<int>(input->readLong(1));
891
417
      if (val) f << "f" << i << "=" << val << ",";
892
417
    }
893
139
    bool ok=true;
894
139
    while (input->tell()<endDataPos) {
895
139
      Field child;
896
139
      long pos=input->tell();
897
139
      if (!readField(input, endDataPos, ascFile, child, 0, depth+1)) {
898
139
        ok=false;
899
139
        input->seek(pos, librevenge::RVNG_SEEK_SET);
900
139
        break;
901
139
      }
902
0
      field.m_fieldList.push_back(child);
903
0
    }
904
139
    if (!ok || input->tell() != endDataPos) {
905
139
      MWAW_DEBUG_MSG(("RagTime5StructManager::readField: can not read some charr pref list data\n"));
906
139
      f.str("");
907
139
      f << "###pos=" << input->tell()-debPos;
908
139
      input->seek(endDataPos, librevenge::RVNG_SEEK_SET);
909
139
    }
910
139
    field.m_extra=f.str();
911
139
    return true;
912
142
  }
913
13.5k
  case 0xce017: { // unstructured: not in typedef
914
13.5k
    if (fSz<5) {
915
2
      MWAW_DEBUG_MSG(("RagTime5StructManager::readField: unexpected data fSz for unstructured\n"));
916
2
      f << "###unstr";
917
2
      break;
918
2
    }
919
13.5k
    field.m_type=Field::T_Unstructured;
920
13.5k
    field.m_name="unstruct";
921
13.5k
    field.m_longValue[0]=input->readLong(4);
922
13.5k
    field.m_entry.setBegin(input->tell());
923
13.5k
    field.m_entry.setEnd(endDataPos);
924
13.5k
    f << "data=" << std::hex;
925
53.5k
    for (long i=0; i<fSz-4; ++i)
926
40.0k
      f << std::setfill('0') << std::setw(2) << static_cast<int>(input->readULong(1));
927
13.5k
    f << std::dec << ",";
928
13.5k
    field.m_extra=f.str();
929
13.5k
    return true;
930
13.5k
  }
931
1.12M
  case 0xce842:  // list of long : header fl=2000, f2=7
932
1.13M
  case 0x170c8e5: { // maybe list of color: f0=418,fl1=40,fl2=8
933
1.13M
    if ((fSz%4)!=0) {
934
1.20k
      MWAW_DEBUG_MSG(("RagTime5StructManager::readField: unexpected data fSz for list of long\n"));
935
1.20k
      f << "###";
936
1.20k
      break;
937
1.20k
    }
938
1.13M
    fSz/=4;
939
1.13M
    field.m_type=Field::T_LongList;
940
1.13M
    field.m_name="longList";
941
13.5M
    for (long i=0; i<fSz; ++i)
942
12.4M
      field.m_longList.push_back(long(input->readLong(4)));
943
1.13M
    return true;
944
1.13M
  }
945
59.5k
  case 0x3c057:
946
79.2k
  case 0x80045080: // child of 14741fa
947
131k
  case 0xcf042: { // list of small int: header fl=2000 with f2=9
948
131k
    if ((fSz%2)!=0) {
949
906
      MWAW_DEBUG_MSG(("RagTime5StructManager::readField: unexpected data fSz for list of long\n"));
950
906
      f << "###";
951
906
      break;
952
906
    }
953
131k
    fSz/=2;
954
131k
    field.m_type=Field::T_LongList;
955
131k
    field.m_name="intList";
956
353k
    for (long i=0; i<fSz; ++i)
957
222k
      field.m_longList.push_back(long(input->readLong(2)));
958
131k
    return true;
959
131k
  }
960
4
  case 0x154f017: // list of bytes
961
4
    field.m_type=Field::T_LongList;
962
4
    field.m_name="byteList";
963
12
    for (long i=0; i<fSz; ++i)
964
8
      field.m_longList.push_back(long(input->readLong(1)));
965
4
    return true;
966
413
  case 0x35000: // checkme find also a string code here...
967
20.7k
  case 0x35800: // unsure, ie small int
968
21.2k
  case 0x3e800: // unsure, find with 000af040, 00049840 or 0004c040
969
36.6k
  case 0xa4000:
970
36.6k
    if (fSz!=4) {
971
575
      MWAW_DEBUG_MSG(("RagTime5StructManager::readField: unexpected data fSz for list of uint32_t\n"));
972
575
      f << "###uint32";
973
575
      break;
974
575
    }
975
36.0k
    field.m_type=Field::T_Long;
976
36.0k
    field.m_longValue[0]=long(input->readULong(4));
977
36.0k
    return true;
978
16.3k
  case 0xa4840:
979
16.3k
    if (fSz!=8) {
980
200
      MWAW_DEBUG_MSG(("RagTime5StructManager::readField: unexpected data fSz for list of 2xuint32_t\n"));
981
200
      f << "###2xuint32";
982
200
      break;
983
200
    }
984
16.1k
    field.m_type=Field::T_2Long;
985
16.1k
    field.m_name="2xuint32";
986
16.1k
    for (long &i : field.m_longValue)
987
32.3k
      i=long(input->readULong(4));
988
16.1k
    return true;
989
990
20.7k
  case 0x33000: // maybe one 2xint
991
43.7k
  case 0x1671817:
992
43.7k
  case 0x16b491a: // in chart,
993
43.7k
  case 0x16b492a: // in chart, dim[4byte], id, 0
994
43.7k
  case 0x16b5aea: // chart preference, always 0,0,id,0
995
49.1k
  case 0x80033000:
996
49.1k
    if ((fSz%4)!=0) {
997
230
      MWAW_DEBUG_MSG(("RagTime5StructManager::readField: unexpected data fSz for list of 2xint\n"));
998
230
      f << "###";
999
230
      break;
1000
230
    }
1001
48.8k
    field.m_type=Field::T_LongList;
1002
48.8k
    field.m_name="2intList";
1003
48.8k
    field.m_numLongByData=2;
1004
48.8k
    fSz/=2;
1005
216k
    for (long i=0; i<fSz; ++i)
1006
168k
      field.m_longList.push_back(long(input->readLong(2)));
1007
48.8k
    return true;
1008
6.27k
  case 0x81452040: {
1009
6.27k
    if (fSz!=8) {
1010
136
      MWAW_DEBUG_MSG(("RagTime5StructManager::readField: unexpected data fSz for id+long\n"));
1011
136
      f << "###clustIdxlong";
1012
136
      break;
1013
136
    }
1014
6.14k
    field.m_type=Field::T_ZoneId;
1015
6.14k
    field.m_name="clustIdxlong";
1016
6.14k
    field.m_entry.setBegin(input->tell());
1017
6.14k
    field.m_entry.setEnd(endDataPos);
1018
6.14k
    std::vector<int> listIds;
1019
6.14k
    if (!readDataIdList(input, 1, listIds)) {
1020
53
      MWAW_DEBUG_MSG(("RagTime5StructManager::readField: can not read the cluster id for id+long\n"));
1021
53
      f << "###clustId,";
1022
53
      break;
1023
53
    }
1024
6.08k
    field.m_longValue[0]=listIds[0];
1025
6.08k
    unsigned long val= input->readULong(4); // always 90000001
1026
6.08k
    if (val!=0x90000001) f << std::hex << val << std::dec << ",";
1027
6.08k
    field.m_extra=f.str();
1028
6.08k
    return true;
1029
6.14k
  }
1030
15.6k
  case 0xa7017: // unicode
1031
15.7k
  case 0xa7027:
1032
32.0k
  case 0xa7037:
1033
48.4k
  case 0xa7047:
1034
64.7k
  case 0xa7057:
1035
80.6k
  case 0xa7067:
1036
101k
  case 0x146905a: // unicode
1037
1038
119k
  case 0x7a047: // font definition
1039
139k
  case 0x7a057: // ?? definition
1040
156k
  case 0x7a067: // ?? definition
1041
1042
160k
  case 0x146005a: // code
1043
160k
  case 0x146007a:
1044
160k
  case 0x14600aa:
1045
167k
  case 0x147403a:
1046
174k
  case 0x14740ba:
1047
174k
  case 0x147501a:
1048
177k
  case 0x148981a:
1049
1050
188k
  case 0x145e0ba: // bool
1051
194k
  case 0x147406a:
1052
194k
  case 0x147550a:
1053
209k
  case 0x17d486a:
1054
1055
209k
  case 0x147512a: // small int
1056
1057
225k
  case 0xa7077: // with type=3b880
1058
275k
  case 0x145e01a:
1059
296k
  case 0x146904a: // int with type=0x149d880
1060
296k
  case 0x146907a: // withe type = 149d880
1061
316k
  case 0x146908a: // with type=0x3b880
1062
316k
  case 0x1469840: // with type=147b88
1063
330k
  case 0x146e02a:
1064
344k
  case 0x146e03a:
1065
358k
  case 0x146e04a:
1066
372k
  case 0x146e06a:
1067
372k
  case 0x146e08a:
1068
412k
  case 0x145e11a: // with type=0x17d5880
1069
412k
  case 0x145e12a: // with type=017d5880
1070
419k
  case 0x147407a:
1071
425k
  case 0x147408a:
1072
435k
  case 0x1474042:
1073
435k
  case 0x147416a:
1074
441k
  case 0x14741ea:
1075
441k
  case 0x147420a: // with type=3b880
1076
441k
  case 0x14754aa: // with type=328c0
1077
441k
  case 0x147551a: // with type=1479080
1078
441k
  case 0x147e81a: // with type=3b880
1079
484k
  case 0x17d481a: // int
1080
1081
507k
  case 0x7d04a:
1082
508k
  case 0x147405a:
1083
508k
  case 0x14741ca: // 2 long
1084
511k
  case 0x145e02a: // with type=b600000
1085
511k
  case 0x14741ba: // with type=b600000
1086
513k
  case 0x145e0ea:
1087
513k
  case 0x146008a:
1088
513k
  case 0x14752da: // with type=1495000
1089
513k
  case 0x14740ea: // with type=b600000
1090
514k
  case 0x147536a: // with type=1495000
1091
514k
  case 0x147538a: // with type=1495000
1092
535k
  case 0x146902a: // double
1093
556k
  case 0x146903a: // double
1094
556k
  case 0x17d484a: // with type=34800
1095
556k
  case 0x147404a: // with type=149c94
1096
677k
  case 0x7d02a: // rgba color?
1097
694k
  case 0x145e05a:
1098
1099
694k
  case 0x14750ea: // keep with next para
1100
694k
  case 0x147530a: // break behavior
1101
694k
  case 0x14753aa: // min word spacing
1102
695k
  case 0x14753ca: // optimal word spacing
1103
695k
  case 0x14753ea: // max word spacing
1104
695k
  case 0x147546a: // number line in widows
1105
695k
  case 0x147548a: // number line in orphan
1106
695k
  case 0x147552a: // do not use spacing for single word
1107
695k
  case 0x147516a: // align paragraph on grid
1108
695k
  case 0x147418a: // small caps scaling x
1109
695k
  case 0x14741aa: // small caps scaling y
1110
1111
697k
  case 0x14c2042: /* function container*/
1112
700k
  case 0x1559842:
1113
700k
  case 0x1663842:
1114
700k
  case 0x1be5042:
1115
700k
  case 0x1d50842:
1116
700k
  case 0x1e16842:
1117
700k
  case 0x23aa042:
1118
700k
  case 0x23af042:
1119
700k
  case 0x23b4042:
1120
1121
734k
  case 0x7a09a: // with a4000 or a4840
1122
744k
  case 0x7a05a: // unknown
1123
762k
  case 0x7a0aa:
1124
768k
  case 0x14600ca: // with type=80033000
1125
782k
  case 0x146e05a: // with type=33000
1126
789k
  case 0x147402a:
1127
809k
  case 0x14741fa: // unsure find with type=80045080
1128
810k
  case 0x147502a: // with type=149a940
1129
810k
  case 0x147505a: // with type=1493800
1130
810k
  case 0x147506a: // with type=1493800
1131
810k
  case 0x147507a: // with type=1493800
1132
810k
  case 0x14750aa: // with type=149a940
1133
810k
  case 0x14750ba: // with type=149a940
1134
817k
  case 0x14750ca: // with type=1474040
1135
817k
  case 0x147510a: // with type=81474040 or 1474040
1136
823k
  case 0x147513a: // with type=1493800
1137
823k
  case 0x14754ba: // with type=1476840
1138
825k
  case 0x148983a: // with type=0074040
1139
827k
  case 0x148985a: // with type=1495800
1140
1141
827k
  case 0x16c1825: // chart pref with type=0042040 CHECKME
1142
827k
  case 0x16d5840: // chart main pref
1143
1144
  // docinfo zone
1145
827k
  case 0x1f7817:
1146
827k
  case 0x1f7827:
1147
827k
  case 0x1f7837:
1148
827k
  case 0x1f7847:
1149
827k
  case 0x1f7857:
1150
827k
  case 0x1f7887:
1151
1152
  // gobj property
1153
880k
  case 0x6615a:
1154
931k
  case 0x6616a:
1155
980k
  case 0x6617a:
1156
986k
  case 0x6619a:
1157
986k
  case 0xfd827:
1158
989k
  case 0x10581a:
1159
1.00M
  case 0x111817:
1160
1.00M
  case 0x111827:
1161
1.02M
  case 0x1467837:
1162
1.04M
  case 0x146789a:
1163
1.06M
  case 0x14678aa: {
1164
1.06M
    if (fSz<4) {
1165
312
      MWAW_DEBUG_MSG(("RagTime5StructManager::readField: unexpected list field size\n"));
1166
312
      f << "###list,";
1167
312
      break;
1168
312
    }
1169
1170
1.06M
    long pos=input->tell();
1171
1.06M
    Field child;
1172
1.06M
    if (!readField(input, endDataPos, ascFile, child, fSz, depth+1)) {
1173
1.48k
      f << "###pos=" << pos-debPos;
1174
1.48k
      input->seek(pos, librevenge::RVNG_SEEK_SET);
1175
1.48k
      break;
1176
1.48k
    }
1177
1.06M
    field.m_name="container";
1178
1179
1.06M
    field.m_type=Field::T_FieldList;
1180
1.06M
    field.m_fieldList.push_back(child);
1181
1.06M
    if (input->tell() != endDataPos) {
1182
4
      MWAW_DEBUG_MSG(("RagTime5StructManager::readField: can not read some field list data\n"));
1183
4
      f.str("");
1184
4
      f << "###pos=" << pos-debPos;
1185
4
      field.m_extra+=f.str();
1186
4
      input->seek(endDataPos, librevenge::RVNG_SEEK_SET);
1187
4
    }
1188
1.06M
    return true;
1189
1.06M
  }
1190
1191
  // condition, function, ...
1192
0
  case 0xe2c59:
1193
0
  case 0x1a473a:
1194
0
  case 0x1c58b1:
1195
0
  case 0x1d5ab5:
1196
0
  case 0x1dad60:
1197
0
  case 0x1e1c3b:
1198
0
  case 0x329eef:
1199
0
  case 0x6604ee:
1200
0
  case 0xcfdfc0:
1201
0
  case 0x1466794:
1202
0
  case 0x1468721:
1203
0
  case 0x1919327:
1204
0
  case 0x28b427c:
1205
0
  case 0x2a72e5f:
1206
0
  case 0x3217ef3: {
1207
0
    if (fSz!=12) {
1208
0
      MWAW_DEBUG_MSG(("RagTime5StructManager::readField: unexpected data fSz for condition\n"));
1209
0
      f << "###condition";
1210
0
      break;
1211
0
    }
1212
0
    field.m_type=Field::T_CondColor;
1213
0
    field.m_name="condition";
1214
0
    field.m_longValue[0]=long(input->readLong(2)); // numUsed ?
1215
0
    field.m_longValue[1]=long(input->readLong(2)); // formula id ?
1216
0
    unsigned char col[4];
1217
0
    for (auto &c : col) c=static_cast<unsigned char>(input->readULong(2)>>8); // rgba
1218
0
    field.m_color=MWAWColor(col[0],col[1],col[2],col[3]);
1219
0
    return true;
1220
0
  }
1221
1222
4.86k
  case 0x154a840: {
1223
4.86k
    if (fSz<6) {
1224
0
      MWAW_DEBUG_MSG(("RagTime5StructManager::readField: unexpected field size for functions def list\n"));
1225
0
      f << "###func[def],";
1226
0
      break;
1227
0
    }
1228
4.86k
    auto val=static_cast<int>(input->readLong(1)); // always 0?
1229
4.86k
    if (val) f << "f1=" << val << ",";
1230
4.86k
    auto N=static_cast<int>(input->readULong(1));
1231
4.86k
    if (6+N!=fSz) {
1232
0
      MWAW_DEBUG_MSG(("RagTime5StructManager::readField: unexpected field N for functions def list\n"));
1233
0
      f << "###func[def],N=" << N << ",";
1234
0
      break;
1235
0
    }
1236
19.4k
    for (int i=0; i<3; ++i) { // 0,-1|0|1,0
1237
14.5k
      val=static_cast<int>(input->readLong(1));
1238
14.5k
      if (!val) continue;
1239
4.98k
      f << "f" << i+2 << "=" << val << ",";
1240
4.98k
    }
1241
4.86k
    val=static_cast<int>(input->readULong(1)); //0|40|c0
1242
4.86k
    if (val) f << "f5=" << std::hex << val << std::dec << ",";
1243
    // list of [0|1|20]*
1244
4.86k
    field.m_type=Field::T_LongList;
1245
4.86k
    field.m_name="func[def]";
1246
8.10k
    for (int i=0; i<N; ++i)
1247
3.24k
      field.m_longList.push_back(static_cast<int>(input->readULong(1)));
1248
4.86k
    field.m_extra=f.str();
1249
4.86k
    return true;
1250
4.86k
  }
1251
31.2k
  case 0x42040: {
1252
31.2k
    if (fSz<10) {
1253
66
      MWAW_DEBUG_MSG(("RagTime5StructManager::readField: unexpected field size for day/month list\n"));
1254
66
      f << "###list[day/month],";
1255
66
      break;
1256
66
    }
1257
31.2k
    int val;
1258
93.6k
    for (int i=0; i<2; ++i) { // always 0?
1259
62.4k
      val=static_cast<int>(input->readULong(2));
1260
62.4k
      if (val) f << "f" << i+1 << "=" << val << ",";
1261
62.4k
    }
1262
31.2k
    auto N=static_cast<int>(input->readULong(2));
1263
31.2k
    val=static_cast<int>(input->readULong(2)); // always 20 ?
1264
31.2k
    if (val!=20) f << "f3=" << val << ",";
1265
31.2k
    val=static_cast<int>(input->readULong(2)); // always 0 ?
1266
31.2k
    if (val) f << "f4=" << val << ",";
1267
31.2k
    field.m_type=Field::T_FieldList;
1268
31.2k
    field.m_name="container[list]"; // can be day/month, ...
1269
31.2k
    bool ok=true;
1270
266k
    for (int i=0; i<N; ++i) {
1271
244k
      Field child;
1272
244k
      long pos=input->tell();
1273
244k
      if (!readField(input, endDataPos, ascFile, child, 0, depth+1)) {
1274
9.03k
        ok=false;
1275
9.03k
        input->seek(pos, librevenge::RVNG_SEEK_SET);
1276
9.03k
        break;
1277
9.03k
      }
1278
235k
      field.m_fieldList.push_back(child);
1279
235k
    }
1280
31.2k
    if (!ok || input->tell() != endDataPos) {
1281
9.20k
      MWAW_DEBUG_MSG(("RagTime5StructManager::readField: can not read some container list data\n"));
1282
9.20k
      f.str("");
1283
9.20k
      f << "###pos=" << input->tell()-debPos;
1284
9.20k
      input->seek(endDataPos, librevenge::RVNG_SEEK_SET);
1285
9.20k
    }
1286
31.2k
    field.m_extra+=f.str();
1287
31.2k
    return true;
1288
31.2k
  }
1289
18.3k
  case 0xd7842: { // list of ? : header fl=0|4000, f2=3
1290
18.3k
    if ((fSz%6)!=0) {
1291
208
      MWAW_DEBUG_MSG(("RagTime5StructManager::readField: unexpected data fSz for 0xd7842\n"));
1292
208
      f << "###";
1293
208
      break;
1294
208
    }
1295
18.1k
    fSz/=2;
1296
18.1k
    field.m_type=Field::T_LongList;
1297
18.1k
    field.m_name="3unknList";
1298
18.1k
    field.m_numLongByData=3;
1299
95.7k
    for (long i=0; i<fSz; ++i)
1300
77.5k
      field.m_longList.push_back(long(input->readLong(2)));
1301
18.1k
    return true;
1302
18.3k
  }
1303
919k
  default: {
1304
919k
    auto const &functIds=m_document.getFormulaParser()->getFunctionsId();
1305
919k
    if (functIds.find(static_cast<unsigned long>(type))!=functIds.end()) {
1306
4.90k
      if (fSz<14) {
1307
0
        MWAW_DEBUG_MSG(("RagTime5StructManager::readField: unexpected field size for functions name list\n"));
1308
0
        f << "###func[name],";
1309
0
        break;
1310
0
      }
1311
19.6k
      for (int i=0; i<3; ++i) { // f1=0|-1, f2=small number, other 0
1312
14.7k
        auto val=static_cast<int>(input->readLong(2));
1313
14.7k
        if (val) f << "f" << i+1 << "=" << val << ",";
1314
14.7k
      }
1315
4.90k
      field.m_type=Field::T_FieldList;
1316
4.90k
      field.m_name="func[name]";
1317
4.90k
      bool ok=true;
1318
14.6k
      for (int i=0; i<2; ++i) {
1319
9.77k
        Field child;
1320
9.77k
        long pos=input->tell();
1321
9.77k
        if (!readField(input, endDataPos, ascFile, child, 0, depth+1)) {
1322
44
          ok=false;
1323
44
          input->seek(pos, librevenge::RVNG_SEEK_SET);
1324
44
          break;
1325
44
        }
1326
9.72k
        field.m_fieldList.push_back(child);
1327
9.72k
      }
1328
4.90k
      if (!ok || input->tell() != endDataPos) {
1329
67
        MWAW_DEBUG_MSG(("RagTime5StructManager::readField: can not read some 2fields list data\n"));
1330
67
        f.str("");
1331
67
        f << "###pos=" << input->tell()-debPos;
1332
67
        input->seek(endDataPos, librevenge::RVNG_SEEK_SET);
1333
67
      }
1334
4.90k
      field.m_extra+=f.str();
1335
4.90k
      return true;
1336
4.90k
    }
1337
914k
    break;
1338
919k
  }
1339
4.84M
  }
1340
1341
927k
  input->seek(debDataPos, librevenge::RVNG_SEEK_SET);
1342
927k
  if (!complex) {
1343
646k
    static bool first=true;
1344
646k
    if (first) {
1345
37
      MWAW_DEBUG_MSG(("RagTime5StructManager::readField: find some unexpected data type=%lx, ...\n", static_cast<unsigned long>(type)));
1346
37
      first=false;
1347
37
    }
1348
646k
    field.m_name="#unknType";
1349
646k
    ascFile.addDelimiter(input->tell(),'|');
1350
646k
    input->seek(endDataPos, librevenge::RVNG_SEEK_SET);
1351
646k
    return true;
1352
646k
  }
1353
281k
  switch (type) {
1354
14.6k
  case 0x14b5815: // increasing list: with fl1=3, fl2=80, f1=29
1355
15.7k
  case 0x16be055: // fl1=f, fl2=80, f1=30
1356
16.9k
  case 0x16be065: // fl1=f, fl2=80, f1=30
1357
38.7k
  case 0x146e815: // maybe a list of dim: fl1=28-2a, fl2=80, f1=34
1358
170k
  case 0x1473815: // maybe a list of dim, fl2=80,f1=32
1359
189k
  case 0x14e6825: // maybe a list of coldim
1360
229k
  case 0x14eb015: // maybe a list of rowdim
1361
229k
  case 0x14f1825:
1362
229k
  case 0x15f4815: // maybe related to list
1363
229k
  case 0x160f815:
1364
252k
  case 0x1671845:
1365
252k
  case 0x17db015: // in group cluster
1366
252k
    field.m_name="longList";
1367
252k
    break;
1368
0
  case 0x1451025:
1369
187
  case 0x146c015: // with ce017
1370
187
  case 0x14e6875:
1371
187
  case 0x15f4015: // with ce017
1372
187
  case 0x15f6815:
1373
187
  case 0x15f9015: // sometimes a list of 15f6815
1374
187
    field.m_name="unstructList";
1375
187
    break;
1376
18.0k
  case 0x15e0825:
1377
18.0k
    field.m_name="3unknList";
1378
18.0k
    break;
1379
3
  case 0x14b4815: // with type=ce842
1380
3
    field.m_name="unknLayout";
1381
3
    break;
1382
0
  case 0x1715815: // with type=ce842
1383
0
    field.m_name="unknLstPict";
1384
0
    break;
1385
10.1k
  default:
1386
10.1k
    MWAW_DEBUG_MSG(("RagTime5StructManager::readField: unexpected list type=%lx\n", static_cast<unsigned long>(type)));
1387
10.1k
    field.m_name="#unknList";
1388
10.1k
    break;
1389
281k
  }
1390
281k
  field.m_type=Field::T_FieldList;
1391
554k
  while (input->tell()<endDataPos) {
1392
285k
    long pos=input->tell();
1393
285k
    Field child;
1394
285k
    if (!readField(input, endDataPos, ascFile, child, 0, depth+1)) {
1395
12.5k
      f << "###pos=" << pos-debPos;
1396
12.5k
      input->seek(pos, librevenge::RVNG_SEEK_SET);
1397
12.5k
      break;
1398
12.5k
    }
1399
272k
    field.m_fieldList.push_back(child);
1400
272k
  }
1401
281k
  if (input->tell()+4<endDataPos) {
1402
11.4k
    MWAW_DEBUG_MSG(("RagTime5StructManager::readField: can not read some data\n"));
1403
11.4k
    ascFile.addDelimiter(input->tell(),'|');
1404
11.4k
    input->seek(endDataPos, librevenge::RVNG_SEEK_SET);
1405
11.4k
    return true;
1406
11.4k
  }
1407
269k
  input->seek(endDataPos, librevenge::RVNG_SEEK_SET);
1408
269k
  field.m_extra=f.str();
1409
269k
  return true;
1410
281k
}
1411
1412
////////////////////////////////////////////////////////////
1413
// field function
1414
////////////////////////////////////////////////////////////
1415
std::ostream &operator<<(std::ostream &o, RagTime5StructManager::Field const &field)
1416
44.7k
{
1417
44.7k
  if (!field.m_name.empty())
1418
44.4k
    o << field.m_name << ":" << RagTime5StructManager::printType(field.m_fileType);
1419
256
  else
1420
256
    o << "T:" << RagTime5StructManager::printType(field.m_fileType);
1421
44.7k
  switch (field.m_type) {
1422
656
  case RagTime5StructManager::Field::T_Double:
1423
656
    o << "=" << field.m_doubleValue << ",";
1424
656
    break;
1425
166
  case RagTime5StructManager::Field::T_Bool:
1426
166
    if (field.m_longValue[0]==1)
1427
148
      o << ",";
1428
18
    else if (field.m_longValue[0]==0)
1429
10
      o << "=no,";
1430
8
    else
1431
8
      o << field.m_longValue[0] << ",";
1432
166
    break;
1433
2.58k
  case RagTime5StructManager::Field::T_Long:
1434
2.58k
    if (field.m_longValue[0]>1000)
1435
318
      o << "=0x" << std::hex << field.m_longValue[0] << std::dec << ",";
1436
2.26k
    else
1437
2.26k
      o << "=" << field.m_longValue[0] << ",";
1438
2.58k
    break;
1439
180
  case RagTime5StructManager::Field::T_2Long:
1440
180
    o << "=" << field.m_longValue[0] << ":" <<  field.m_longValue[1] << ",";
1441
180
    break;
1442
0
  case RagTime5StructManager::Field::T_LongDouble:
1443
0
    o << "=" << field.m_doubleValue << ":" <<  field.m_longValue[0] << ",";
1444
0
    break;
1445
282
  case RagTime5StructManager::Field::T_Color:
1446
282
    o << "=" << field.m_color;
1447
282
    if (field.m_longValue[0])
1448
230
      o << "[" << field.m_longValue[0] << "]";
1449
282
    o << ",";
1450
282
    return o;
1451
0
  case RagTime5StructManager::Field::T_CondColor:
1452
0
    o << "=" << field.m_color << "[" << field.m_longValue[0] << "," << field.m_longValue[1] << "],";
1453
0
    return o;
1454
0
  case RagTime5StructManager::Field::T_String:
1455
846
  case RagTime5StructManager::Field::T_Code:
1456
846
    o << "=" << field.m_string.cstr() << ",";
1457
846
    return o;
1458
0
  case RagTime5StructManager::Field::T_ZoneId:
1459
0
    if (field.m_longValue[0])
1460
0
      o << "=data" << field.m_longValue[0] << "A,";
1461
0
    return o;
1462
114
  case RagTime5StructManager::Field::T_Unicode:
1463
114
    o << "=\"" << field.m_string.cstr() << "\",";
1464
114
    return o;
1465
0
  case RagTime5StructManager::Field::T_PrintInfo:
1466
12
  case RagTime5StructManager::Field::T_Unstructured:
1467
12
    o << "=" << field.m_extra << ",";
1468
12
    return o;
1469
1.65k
  case RagTime5StructManager::Field::T_FieldList:
1470
1.65k
    if (!field.m_fieldList.empty()) {
1471
880
      o << "=[";
1472
880
      for (auto const &val : field.m_fieldList)
1473
880
        o << "[" << val << "],";
1474
880
      o << "]";
1475
880
    }
1476
1.65k
    o << ",";
1477
1.65k
    break;
1478
146
  case RagTime5StructManager::Field::T_DoubleList:
1479
146
    if (!field.m_doubleList.empty()) {
1480
146
      o << "=[";
1481
146
      for (auto const &val : field.m_doubleList)
1482
292
        o << val << ",";
1483
146
      o << "],";
1484
146
    }
1485
146
    break;
1486
458
  case RagTime5StructManager::Field::T_LongList:
1487
458
    if (!field.m_longList.empty() && field.m_numLongByData>0) {
1488
458
      o << "=[";
1489
458
      size_t pos=0;
1490
3.82k
      while (pos+size_t(field.m_numLongByData-1)<field.m_longList.size()) {
1491
7.04k
        for (int i=0; i<field.m_numLongByData; ++i) {
1492
3.68k
          long val=field.m_longList[pos++];
1493
3.68k
          if (!val)
1494
324
            o << "_";
1495
3.36k
          else if (val>-1000 && val <1000)
1496
2.86k
            o << val;
1497
494
          else if (val==long(0x80000000))
1498
0
            o << "inf";
1499
          // find sometime 0x3e7f0001
1500
494
          else
1501
494
            o << "0x" << std::hex << val << std::dec;
1502
3.68k
          o << ((i+1==field.m_numLongByData) ? "," : ":");
1503
3.68k
        }
1504
3.36k
      }
1505
458
      o << "]";
1506
458
    }
1507
458
    o << ",";
1508
458
    break;
1509
56
  case RagTime5StructManager::Field::T_TabList:
1510
56
    if (!field.m_tabList.empty()) {
1511
56
      o << "=[";
1512
56
      for (auto const &tab : field.m_tabList)
1513
70
        o << tab << ",";
1514
56
      o << "],";
1515
56
    }
1516
56
    break;
1517
37.5k
  case RagTime5StructManager::Field::T_Unknown:
1518
#if !defined(__clang__)
1519
  default:
1520
#endif
1521
37.5k
    o << "[###unkn],";
1522
37.5k
    break;
1523
44.7k
  }
1524
43.4k
  o << field.m_extra;
1525
43.4k
  return o;
1526
44.7k
}
1527
1528
////////////////////////////////////////////////////////////
1529
// parser function
1530
////////////////////////////////////////////////////////////
1531
bool RagTime5StructManager::GObjPropFieldParser::parseField(Field &field, RagTime5Zone &/*zone*/, int /*n*/, libmwaw::DebugStream &f)
1532
247k
{
1533
247k
  if (field.m_type==Field::T_FieldList) {
1534
236k
    switch (field.m_fileType) {
1535
52.0k
    case 0x6615a:
1536
52.0k
      for (auto const &child : field.m_fieldList) {
1537
52.0k
        if (child.m_type==Field::T_2Long && child.m_fileType==0x8c000) {
1538
51.8k
          f << "dim=" << child.m_longValue[0] << "x" << child.m_longValue[1] << ",";
1539
51.8k
          continue;
1540
51.8k
        }
1541
273
        MWAW_DEBUG_MSG(("RagTime5StructManager::GObjPropFieldParser::parseField: find unexpected dim field\n"));
1542
273
        f << "##dim=" << child << ",";
1543
273
      }
1544
52.0k
      break;
1545
51.2k
    case 0x6616a:
1546
51.2k
      for (auto const &child : field.m_fieldList) {
1547
51.2k
        if (child.m_type==Field::T_Unstructured && child.m_fileType==0x79040) {
1548
50.3k
          f << "data1=" << child << ",";
1549
50.3k
          continue;
1550
50.3k
        }
1551
942
        MWAW_DEBUG_MSG(("RagTime5StructManager::GObjPropFieldParser::parseField: find unexpected data1 field\n"));
1552
942
        f << "##data1=" << child << ",";
1553
942
      }
1554
51.2k
      break;
1555
48.9k
    case 0x6617a: // 0[13]0[01]
1556
48.9k
      for (auto const &child : field.m_fieldList) {
1557
48.9k
        if (child.m_type==Field::T_Long && child.m_fileType==0x34080) {
1558
48.6k
          f << "data2=" << std::hex << child.m_longValue[0] << std::dec << ",";
1559
48.6k
          continue;
1560
48.6k
        }
1561
298
        MWAW_DEBUG_MSG(("RagTime5StructManager::GObjPropFieldParser::parseField: find unexpected data2 field\n"));
1562
298
        f << "##data2=" << child << ",";
1563
298
      }
1564
48.9k
      break;
1565
6.28k
    case 0x6619a:
1566
6.28k
      for (auto const &child : field.m_fieldList) {
1567
6.28k
        if (child.m_type==Field::T_ZoneId && static_cast<unsigned long>(child.m_fileType)==0x81452040) {
1568
6.14k
          f << "cluster[id]=data" << child.m_longValue[0] << "A,";
1569
6.14k
          continue;
1570
6.14k
        }
1571
140
        MWAW_DEBUG_MSG(("RagTime5StructManager::GObjPropFieldParser::parseField: find unexpected cluster id field\n"));
1572
140
        f << "##cluster[id]=" << child << ",";
1573
140
      }
1574
6.28k
      break;
1575
0
    case 0xfd827: // rare with 0
1576
0
      for (auto const &child : field.m_fieldList) {
1577
0
        if (child.m_type==Field::T_Long && child.m_fileType==0x3b880) {
1578
0
          f << "data3=" << child.m_longValue[0] << ",";
1579
0
          continue;
1580
0
        }
1581
0
        MWAW_DEBUG_MSG(("RagTime5StructManager::GObjPropFieldParser::parseField: find unexpected data3 field\n"));
1582
0
        f << "##data3=" << child << ",";
1583
0
      }
1584
0
      break;
1585
2.21k
    case 0x10581a: // 1,_ or _,1 or 4000,1
1586
2.21k
      for (auto const &child : field.m_fieldList) {
1587
2.21k
        if (child.m_type==Field::T_LongList && child.m_fileType==0x33000) {
1588
2.18k
          f << "long[list]=[";
1589
4.37k
          for (auto val : child.m_longList) f << std::hex << val << std::dec << ",";
1590
2.18k
          f << "],";
1591
2.18k
          continue;
1592
2.18k
        }
1593
24
        MWAW_DEBUG_MSG(("RagTime5StructManager::GObjPropFieldParser::parseField: find long[list] field\n"));
1594
24
        f << "##long[list]=" << child << ",";
1595
24
      }
1596
2.21k
      break;
1597
19.8k
    case 0x111817: // margin in %
1598
19.8k
      for (auto const &child : field.m_fieldList) {
1599
19.8k
        if (child.m_type==Field::T_DoubleList && child.m_fileType==0x112040 && child.m_doubleList.size()==4) {
1600
19.8k
          f << "margins=" << MWAWBox2f(MWAWVec2f(float(child.m_doubleList[0]),float(child.m_doubleList[1])),
1601
19.8k
                                       MWAWVec2f(float(child.m_doubleList[2]),float(child.m_doubleList[3]))) << ",";
1602
19.8k
          continue;
1603
19.8k
        }
1604
15
        MWAW_DEBUG_MSG(("RagTime5StructManager::GObjPropFieldParser::parseField: find margins field\n"));
1605
15
        f << "##margins[list]=" << child << ",";
1606
15
      }
1607
19.8k
      break;
1608
5
    case 0x111827: // always 0,0
1609
5
      for (auto const &child : field.m_fieldList) {
1610
5
        if (child.m_type==Field::T_2Long && child.m_fileType==0x34800) {
1611
0
          f << "unknPos=" << child.m_longValue[0] << "x" << child.m_longValue[1] << ",";
1612
0
          continue;
1613
0
        }
1614
5
        MWAW_DEBUG_MSG(("RagTime5StructManager::GObjPropFieldParser::parseField: find unexpected unknPos field\n"));
1615
5
        f << "##unknPos=" << child << ",";
1616
5
      }
1617
5
      break;
1618
19.7k
    case 0x1467837: // always 0,0
1619
19.7k
      for (auto const &child : field.m_fieldList) {
1620
19.7k
        if (child.m_type==Field::T_DoubleList && child.m_fileType==0x74040) {
1621
19.6k
          f << "float[list]=[";
1622
39.3k
          for (auto const &val : child.m_doubleList) f << val << ",";
1623
19.6k
          f << "],";
1624
19.6k
          continue;
1625
19.6k
        }
1626
36
        MWAW_DEBUG_MSG(("RagTime5StructManager::GObjPropFieldParser::parseField: find unexpected float[list] field\n"));
1627
36
        f << "##float[list]=" << child << ",";
1628
36
      }
1629
19.7k
      break;
1630
19.8k
    case 0x146789a: // 1-2
1631
35.8k
    case 0x14678aa: // 1-2
1632
35.8k
      for (auto const &child : field.m_fieldList) {
1633
35.8k
        if (child.m_type==Field::T_Long && child.m_fileType==0x149e080) {
1634
35.6k
          f << "d" << ((field.m_fileType>>4)&0xf) << "=" << std::hex << child.m_longValue[0] << std::dec << ",";
1635
35.6k
          continue;
1636
35.6k
        }
1637
182
        MWAW_DEBUG_MSG(("RagTime5StructManager::GObjPropFieldParser::parseField: find unexpected data%ld field\n", ((field.m_fileType>>4)&0xf)));
1638
182
        f << "##d" << ((field.m_fileType>>4)&0xf) << "=" << child << ",";
1639
182
      }
1640
35.8k
      break;
1641
21
    default:
1642
21
      MWAW_DEBUG_MSG(("RagTime5StructManager::GObjPropFieldParser::parseField: find unexpected list field\n"));
1643
21
      f << "###field=" << field << ",";
1644
21
      break;
1645
236k
    }
1646
236k
  }
1647
10.9k
  else {
1648
10.9k
    MWAW_DEBUG_MSG(("RagTime5StructManager::GObjPropFieldParser::parseField: find unexpected field type\n"));
1649
10.9k
    f << "###field=" << field << ",";
1650
10.9k
  }
1651
247k
  return true;
1652
247k
}
1653
1654
////////////////////////////////////////////////////////////
1655
// zone function
1656
////////////////////////////////////////////////////////////
1657
RagTime5Zone::~RagTime5Zone()
1658
5.56M
{
1659
5.56M
}
1660
1661
void RagTime5Zone::createAsciiFile()
1662
677k
{
1663
677k
  if (!m_input)
1664
4
    return;
1665
677k
  if (m_asciiName.empty()) {
1666
0
    MWAW_DEBUG_MSG(("RagTime5Zone::createAsciiFile: can not find the ascii name\n"));
1667
0
    return;
1668
0
  }
1669
677k
  if (m_localAsciiFile) {
1670
0
    MWAW_DEBUG_MSG(("RagTime5Zone::createAsciiFile: the ascii file already exist\n"));
1671
0
  }
1672
677k
  m_localAsciiFile.reset(new libmwaw::DebugFile(m_input));
1673
677k
  m_asciiFile = m_localAsciiFile.get();
1674
677k
  m_asciiFile->open(m_asciiName);
1675
677k
}
1676
1677
std::string RagTime5Zone::getZoneName() const
1678
798k
{
1679
798k
  if (m_level==1) {
1680
789k
    if (m_ids[0]==0 && m_idsFlag[0]==1)
1681
1.01k
      return "FileHeader";
1682
788k
    else if (m_ids[0]==1 && m_idsFlag[0]==0)
1683
392k
      return "ZoneInfo";
1684
789k
  }
1685
404k
  std::stringstream s;
1686
404k
  if (m_level==1)
1687
396k
    s << "Data" << m_ids[0] << "A";
1688
8.51k
  else if (m_level<0 || m_level>3)
1689
0
    s << "###unknLevel" << m_level << "-" << m_ids[0];
1690
8.51k
  else if (!m_parentName.empty())
1691
835
    s << m_parentName << "-" << m_ids[0] << char('A'+m_level-1);
1692
7.67k
  else
1693
7.67k
    s << "###unknChild" << m_ids[0] << char('A'+m_level-1) ;
1694
404k
  return s.str();
1695
798k
}
1696
1697
void RagTime5Zone::addErrorInDebugFile(std::string const &zoneName)
1698
10.7k
{
1699
10.7k
  m_isParsed=true;
1700
10.7k
  if (m_entry.valid()) {
1701
5.83k
    libmwaw::DebugStream f;
1702
5.83k
    f << "Entries(" << zoneName << ")[" << *this << "]:###bad";
1703
5.83k
    ascii().addPos(m_entry.begin());
1704
5.83k
    ascii().addNote(f.str().c_str());
1705
5.83k
    ascii().addPos(m_entry.end());
1706
5.83k
    ascii().addNote("_");
1707
5.83k
  }
1708
10.7k
  libmwaw::DebugStream f;
1709
10.7k
  f << zoneName << ":###bad";
1710
10.7k
  m_mainAsciiFile->addPos(m_defPosition);
1711
10.7k
  m_mainAsciiFile->addNote(f.str().c_str());
1712
10.7k
}
1713
1714
std::ostream &operator<<(std::ostream &o, RagTime5Zone const &z)
1715
0
{
1716
0
  o << z.getZoneName();
1717
0
  if (z.m_idsFlag[0]==0)
1718
0
    o << "[head],";
1719
0
  else if (z.m_idsFlag[0]==1)
1720
0
    o << ",";
1721
0
  else
1722
0
    o << "[" << z.m_idsFlag[0] << "],";
1723
0
  for (int i=1; i<3; ++i) {
1724
0
    if (!z.m_kinds[i-1].empty()) {
1725
0
      o << z.m_kinds[i-1] << ",";
1726
0
      continue;
1727
0
    }
1728
0
    if (!z.m_ids[i] && !z.m_idsFlag[i]) continue;
1729
0
    o << "id" << i << "=" << z.m_ids[i];
1730
0
    if (z.m_idsFlag[i]==0)
1731
0
      o << "*";
1732
0
    else if (z.m_idsFlag[i]!=1)
1733
0
      o << ":" << z.m_idsFlag[i] << ",";
1734
0
    o << ",";
1735
0
  }
1736
0
  if (z.m_variableD[0] || z.m_variableD[1])
1737
0
    o << "varD=[" << z.m_variableD[0] << "," << z.m_variableD[1] << "],";
1738
0
  if (z.m_entry.valid())
1739
0
    o << z.m_entry.begin() << "<->" << z.m_entry.end() << ",";
1740
0
  else if (!z.m_entriesList.empty()) {
1741
0
    o << "ptr=" << std::hex;
1742
0
    for (size_t i=0; i< z.m_entriesList.size(); ++i) {
1743
0
      o << z.m_entriesList[i].begin() << "<->" << z.m_entriesList[i].end();
1744
0
      if (i+1<z.m_entriesList.size())
1745
0
        o << "+";
1746
0
    }
1747
0
    o << std::dec << ",";
1748
0
  }
1749
0
  if (!z.m_hiLoEndian) o << "loHi[endian],";
1750
0
  o << z.m_extra << ",";
1751
0
  return o;
1752
0
}
1753
1754
// vim: set filetype=cpp tabstop=2 shiftwidth=2 cindent autoindent smartindent noexpandtab: