Coverage Report

Created: 2026-06-13 06:44

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