Coverage Report

Created: 2026-10-28 06:34

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
91.6k
  : m_document(doc)
60
91.6k
{
61
91.6k
}
62
63
RagTime5StructManager::~RagTime5StructManager()
64
91.6k
{
65
91.6k
}
66
67
RagTime5StructManager::DataParser::DataParser(std::string const &zoneName)
68
304k
  : m_name(zoneName)
69
304k
{
70
304k
  if (!m_name.empty())
71
304k
    m_name[0]=char(std::toupper((unsigned char)(m_name[0])));
72
304k
}
73
74
RagTime5StructManager::DataParser::~DataParser()
75
304k
{
76
304k
}
77
78
RagTime5StructManager::FieldParser::~FieldParser()
79
230k
{
80
230k
}
81
////////////////////////////////////////////////////////////
82
// read basic structures
83
////////////////////////////////////////////////////////////
84
bool RagTime5StructManager::readCompressedLong(MWAWInputStreamPtr &input, long endPos, long &val)
85
10.4M
{
86
10.4M
  val=long(input->readULong(1));
87
10.4M
  if ((val&0xF0)==0xC0) {
88
2.56M
    input->seek(-1, librevenge::RVNG_SEEK_CUR);
89
2.56M
    val=long(MWAWInputStream::readULong(input->input().get(), 4, 0, false)&0xFFFFFFF);
90
2.56M
  }
91
7.92M
  else if (val>=0xD0) { // never seems, but may be ok
92
57.7k
    MWAW_DEBUG_MSG(("RagTime5Struct::readCompressedLong: can not read a long\n"));
93
57.7k
    return false;
94
57.7k
  }
95
7.86M
  else if (val>=0x80)
96
196k
    val=((val&0x7F)<<8)+long(input->readULong(1));
97
10.4M
  return input->tell()<=endPos;
98
10.4M
}
99
100
std::string RagTime5StructManager::printType(unsigned long fileType)
101
3.88M
{
102
3.88M
  static std::map<unsigned long, char const *> const s_typeToName = {
103
3.88M
    {0x145e042, "fillStyle[container]"},
104
3.88M
    {0x1460042, "lineStyle[container]"},
105
3.88M
    {0x146902a, "unit[base,from]"},
106
3.88M
    {0x146903a, "unit[base,to]"},
107
3.88M
    {0x146904a, "unit[base,id]"},
108
3.88M
    {0x146905a, "unit[name]"},
109
3.88M
    {0x146907a, "unit[second,id]"}, // rare
110
3.88M
    {0x146908a, "unit[digits,place]"},
111
3.88M
    {0x146a042, "unit[container]"},
112
3.88M
    {0x146e02a, "ruler[unit,id]"},
113
3.88M
    {0x146e03a, "ruler[step,major]"},
114
3.88M
    {0x146e04a, "ruler[step,minor]"},
115
3.88M
    {0x146e05a, "ruler[grid/major]"}, // a fraction or a fixed decimal?
116
3.88M
    {0x146e06a, "ruler[grid,line/gridPoint]"},
117
3.88M
    {0x146f042, "ruler[container]"},
118
3.88M
    {0x17d5042, "color[container]"},
119
120
    // functions collections
121
3.88M
    {0x14c2042, "functions[layout]"},
122
3.88M
    {0x1559842, "functions[standart]"},
123
3.88M
    {0x1663842, "functions[spreadsheet]"},
124
3.88M
    {0x1be5042, "functions[fax]"},
125
3.88M
    {0x1d50842, "functions[button]"},
126
3.88M
    {0x1e16842, "functions[slide]"},
127
3.88M
    {0x23aa042, "functions[calendar]"},
128
3.88M
    {0x23af042, "functions[serialNumber]"},
129
3.88M
    {0x23b4042, "functions[euro]"},
130
3.88M
  };
131
3.88M
  auto it=s_typeToName.find(fileType);
132
3.88M
  if (it!=s_typeToName.end())
133
75
    return it->second;
134
3.88M
  std::stringstream s;
135
3.88M
  s << (fileType>>11) << "-" << std::hex << (fileType&0x7ff) << std::dec;
136
3.88M
  return s.str();
137
3.88M
}
138
139
bool RagTime5StructManager::readTypeDefinitions(RagTime5Zone &zone)
140
7.52k
{
141
7.52k
  if (zone.m_entry.length()<26) return false;
142
7.44k
  MWAWInputStreamPtr input=zone.getInput();
143
7.44k
  long endPos=zone.m_entry.end();
144
7.44k
  input->setReadInverted(!zone.m_hiLoEndian);
145
7.44k
  input->seek(zone.m_entry.begin(), librevenge::RVNG_SEEK_SET);
146
147
7.44k
  libmwaw::DebugStream f;
148
7.44k
  f << "Entries(TypeDef):[" << zone << "]";
149
7.44k
  long N;
150
7.44k
  if (!input->checkPosition(endPos) || !RagTime5StructManager::readCompressedLong(input, endPos, N) || N<20 || 12+14*N>zone.m_entry.length()) {
151
622
    MWAW_DEBUG_MSG(("RagTime5StructManager::readTypeDefinitions: can not read the list type zone\n"));
152
622
    input->setReadInverted(false);
153
622
    return false;
154
622
  }
155
6.82k
  zone.m_isParsed=true;
156
6.82k
  libmwaw::DebugFile &ascFile=zone.ascii();
157
6.82k
  f << "N=" << N << ",";
158
6.82k
  int val;
159
20.4k
  for (int i=0; i<2; ++i) { // always 0,0
160
13.6k
    val=static_cast<int>(input->readLong(2));
161
13.6k
    if (val) f << "f" << i << "=" << val << ",";
162
13.6k
  }
163
6.82k
  auto sz=static_cast<int>(input->readULong(1));
164
6.82k
  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
6.82k
  if (sz) {
169
1.41k
    f << "data1=[" << std::hex;
170
240k
    for (int i=0; i<sz+1; ++i) {
171
239k
      val=static_cast<int>(input->readULong(1));
172
239k
      if (val) f << val << ",";
173
104k
      else f << "_,";
174
239k
    }
175
1.41k
    f << std::dec << "],";
176
1.41k
  }
177
6.82k
  long debDataPos=input->tell()+4*(N+1);
178
6.82k
  long remain=endPos-debDataPos;
179
6.82k
  if (remain<=0) {
180
0
    input->setReadInverted(false);
181
0
    return false;
182
0
  }
183
6.82k
  f << "ptr=[" << std::hex;
184
6.82k
  std::vector<long> listPtrs(size_t(N+1), -1);
185
6.82k
  long lastPtr=0;
186
6.82k
  int numOk=0;
187
557k
  for (size_t i=0; i<=size_t(N); ++i) {
188
550k
    auto ptr=long(input->readULong(4));
189
550k
    if (ptr<0 || ptr>remain || ptr<lastPtr) {
190
151k
      f << "###";
191
151k
      static bool first=true;
192
151k
      if (first) {
193
26
        first = false;
194
26
        MWAW_DEBUG_MSG(("RagTime5StructManager::readTypeDefinitions: problem reading some type position\n"));
195
26
      }
196
151k
      listPtrs[size_t(i)]=lastPtr;
197
151k
    }
198
398k
    else {
199
398k
      ++numOk;
200
398k
      lastPtr=listPtrs[size_t(i)]=ptr;
201
398k
    }
202
550k
    f << ptr << ",";
203
550k
  }
204
6.82k
  f << std::dec << "],";
205
6.82k
  ascFile.addPos(zone.m_entry.begin());
206
6.82k
  ascFile.addNote(f.str().c_str());
207
6.82k
  ascFile.addPos(endPos);
208
6.82k
  ascFile.addNote("_");
209
6.82k
  if (!numOk) {
210
298
    MWAW_DEBUG_MSG(("RagTime5StructManager::readTypeDefinitions: problem reading some type position\n"));
211
298
    input->setReadInverted(false);
212
298
    return false;
213
298
  }
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
535k
  for (size_t i=0; i+1<listPtrs.size(); ++i) {
228
528k
    if (listPtrs[i]<0 || listPtrs[i]==listPtrs[i+1]) continue;
229
387k
    if (listPtrs[i]==remain) break;
230
387k
    f.str("");
231
387k
    f << "TypeDef-" << i << "[head]:";
232
387k
    auto dSz=int(listPtrs[i+1]-listPtrs[i]);
233
387k
    long pos=debDataPos+listPtrs[i];
234
387k
    if (dSz<4+20) {
235
579
      f << "###";
236
579
      MWAW_DEBUG_MSG(("RagTime5StructManager::readTypeDefinitions: problem with some type size\n"));
237
579
      ascFile.addPos(pos);
238
579
      ascFile.addNote(f.str().c_str());
239
579
    }
240
387k
    input->seek(pos, librevenge::RVNG_SEEK_SET);
241
387k
    val=static_cast<int>(input->readLong(4));
242
387k
    if (val!=1) f << "num[used]=" << val << ",";
243
387k
    auto hSz=static_cast<int>(input->readULong(2));
244
387k
    int nData=(dSz-4-hSz)/12;
245
387k
    if (4+hSz>dSz || dSz!=4+hSz+12*nData || nData<0 || hSz<20) {
246
54.6k
      f << "###hSz=" << hSz << ",";
247
54.6k
      MWAW_DEBUG_MSG(("RagTime5StructManager::readTypeDefinitions: the header size seems bad\n"));
248
54.6k
      ascFile.addPos(pos);
249
54.6k
      ascFile.addNote(f.str().c_str());
250
54.6k
      continue;
251
54.6k
    }
252
332k
    val=static_cast<int>(input->readULong(2));
253
332k
    if (val) f << "fl=" << std::hex << val << std::dec << ",";
254
332k
    val=static_cast<int>(input->readULong(4));
255
332k
    if (val) f << "id?=" << std::hex << val << std::dec << ","; // maybe a date, origin?
256
332k
    auto type=input->readULong(4);
257
332k
    if (type) f << "type=" << printType(type) << ",";
258
997k
    for (int j=0; j<2; ++j) { // f1=0..12,
259
665k
      val=static_cast<int>(input->readLong(2));
260
665k
      if (val) f << "f" << j+1 << "=" << val << ",";
261
665k
    }
262
332k
    auto type2=input->readULong(4);
263
332k
    if (type2) f << "type2=" << printType(type2) << ",";
264
332k
    if (hSz>20) {
265
12.4k
      auto sSz=static_cast<int>(input->readULong(1));
266
12.4k
      if ((sSz%2)!=0 || 20+1+sSz>hSz) {
267
478
        f << "###sSz=" << sSz << ",";
268
478
        MWAW_DEBUG_MSG(("RagTime5StructManager::readTypeDefinitions: the string size seems bad\n"));
269
478
      }
270
12.0k
      else { // Layout, Text, Picture, .. a componant name
271
12.0k
        std::string name("");
272
80.6k
        for (int c=0; c<sSz/2; ++c)
273
68.6k
          name+=char(input->readULong(2));
274
12.0k
        f << "name=" << name << ",";
275
12.0k
        if (type2!=0x14a9842) {
276
154
          f << "###type2,";
277
154
          MWAW_DEBUG_MSG(("RagTime5StructManager::readTypeDefinitions: find odd type2 with a string size\n"));
278
154
        }
279
12.0k
      }
280
12.4k
    }
281
332k
    if (input->tell()!=pos+4+hSz)
282
934
      ascFile.addDelimiter(input->tell(),'|');
283
332k
    ascFile.addPos(pos);
284
332k
    ascFile.addNote(f.str().c_str());
285
286
332k
    input->seek(pos+4+hSz, librevenge::RVNG_SEEK_SET);
287
1.48M
    for (int j=0; j<nData; ++j) {
288
1.15M
      pos=input->tell();
289
1.15M
      f.str("");
290
1.15M
      f << "TypeDef-" << i << "[" << j << "]:";
291
1.15M
      f << "type=" << printType(input->readULong(4)) << ","; // a big number, ~type (but a multiple of 5)
292
1.15M
      f << "type2=" << printType(input->readULong(4)) << std::dec << ","; // a big number
293
3.45M
      for (int k=0; k<2; ++k) {
294
2.30M
        val=static_cast<int>(input->readULong(1));
295
2.30M
        if (val) f << "fl" << k << "=" << std::hex << val << std::dec << ",";
296
2.30M
      }
297
1.15M
      val=static_cast<int>(input->readLong(2));
298
1.15M
      if (val) f << "f0=" << val << ",";
299
1.15M
      ascFile.addPos(pos);
300
1.15M
      ascFile.addNote(f.str().c_str());
301
1.15M
      input->seek(pos+12, librevenge::RVNG_SEEK_SET);
302
1.15M
    }
303
332k
  }
304
6.52k
  if (!listPtrs.empty() && listPtrs.back()!=remain) {
305
1.81k
    ascFile.addPos(debDataPos+listPtrs.back());
306
1.81k
    ascFile.addNote("TypeDef-end");
307
1.81k
  }
308
6.52k
  input->setReadInverted(false);
309
6.52k
  return true;
310
6.82k
}
311
312
313
bool RagTime5StructManager::readUnicodeString(MWAWInputStreamPtr input, long endPos, librevenge::RVNGString &string)
314
537k
{
315
537k
  string="";
316
537k
  long pos=input->tell();
317
537k
  if (pos==endPos) return true;
318
537k
  long length=endPos-pos;
319
537k
  if (length<0 || (length%2)==1) {
320
4.41k
    MWAW_DEBUG_MSG(("RagTime5StructManager::readUnicodeString: find unexpected data length\n"));
321
4.41k
    return false;
322
4.41k
  }
323
532k
  length/=2;
324
532k
  int lEndian=0, hEndian=0; // for checking if little/big endian is set correctly
325
6.25M
  for (long i=0; i<length; ++i) {
326
5.72M
    auto c=static_cast<uint32_t>(input->readULong(2));
327
5.72M
    if ((c&0xFF00)==0) ++hEndian;
328
406k
    else if ((c&0xFF)==0) ++lEndian;
329
5.72M
    if (c!=0)
330
5.70M
      libmwaw::appendUnicode(c, string);
331
5.72M
  }
332
532k
  if (lEndian>hEndian) {
333
18.5k
    static bool first=true;
334
18.5k
    if (first) {
335
33
      first=false;
336
33
      MWAW_DEBUG_MSG(("RagTime5StructManager::readUnicodeString: the endian reading seems bad...\n"));
337
33
    }
338
18.5k
  }
339
532k
  return true;
340
537k
}
341
342
bool RagTime5StructManager::readDataIdList(MWAWInputStreamPtr input, int n, std::vector<int> &listIds)
343
2.29M
{
344
2.29M
  listIds.clear();
345
2.29M
  long pos=input->tell();
346
5.45M
  for (int i=0; i<n; ++i) {
347
3.47M
    int val=static_cast<int>(MWAWInputStream::readULong(input->input().get(), 2, 0, false));
348
3.47M
    if (val==0) {
349
1.63M
      listIds.push_back(0);
350
1.63M
      input->seek(2, librevenge::RVNG_SEEK_CUR);
351
1.63M
      continue;
352
1.63M
    }
353
1.84M
    if (val!=1) {
354
      // update the position
355
321k
      input->seek(pos+4*n, librevenge::RVNG_SEEK_SET);
356
321k
      return false;
357
321k
    }
358
1.52M
    listIds.push_back(static_cast<int>(MWAWInputStream::readULong(input->input().get(), 2, 0, false)));
359
1.52M
  }
360
1.97M
  return true;
361
2.29M
}
362
363
bool RagTime5StructManager::readField(MWAWInputStreamPtr input, long endPos, libmwaw::DebugFile &ascFile,
364
                                      RagTime5StructManager::Field &field, long fSz, int depth)
365
4.79M
{
366
4.79M
  if (depth >= MAX_RECORD_NESTING) {
367
0
    MWAW_DEBUG_MSG(("RagTime5StructManager::readField: nesting too deep\n"));
368
0
    return false;
369
0
  }
370
4.79M
  libmwaw::DebugStream f;
371
4.79M
  long debPos=input->tell();
372
4.79M
  if ((fSz>0 && (fSz<4 || debPos+fSz>endPos)) || (fSz<=0 && debPos+5>endPos)) {
373
15.0k
    MWAW_DEBUG_MSG(("RagTime5StructManager::readField: the zone seems too short\n"));
374
15.0k
    return false;
375
15.0k
  }
376
4.77M
  auto type=input->readULong(4);
377
4.77M
  if ((type>>16)==0) {
378
90.2k
    input->seek(debPos, librevenge::RVNG_SEEK_SET);
379
90.2k
    return false;
380
90.2k
  }
381
4.68M
  field.m_fileType=type;
382
4.68M
  bool complex=static_cast<int>(input->readULong(1))==0xc0;
383
4.68M
  input->seek(-1, librevenge::RVNG_SEEK_CUR);
384
4.68M
  if (fSz<=0) {
385
3.42M
    if (!readCompressedLong(input, endPos, fSz) || fSz<=0 || input->tell()+fSz>endPos) {
386
263k
      MWAW_DEBUG_MSG(("RagTime5StructManager::readField: can not read the data size\n"));
387
263k
      input->seek(debPos, librevenge::RVNG_SEEK_SET);
388
263k
      return false;
389
263k
    }
390
3.42M
  }
391
1.25M
  else
392
1.25M
    fSz-=4;
393
4.42M
  long debDataPos=input->tell();
394
4.42M
  long endDataPos=debDataPos+fSz;
395
4.42M
  switch (static_cast<unsigned long>(type)) {
396
45.8k
  case 0x360c0:
397
45.9k
  case 0x368c0:
398
45.9k
    if (fSz!=1) {
399
224
      MWAW_DEBUG_MSG(("RagTime5StructManager::readField: unexpected data fSz for bool\n"));
400
224
      f << "###bool,";
401
224
      break;
402
224
    }
403
45.7k
    field.m_type=Field::T_Bool;
404
405
45.7k
    field.m_name="bool";
406
45.7k
    field.m_longValue[0]=long(input->readLong(1));
407
45.7k
    return true;
408
409
42
  case 0x328c0:
410
42
    if (fSz!=1) {
411
21
      MWAW_DEBUG_MSG(("RagTime5StructManager::readField: unexpected data fSz for bInt\n"));
412
21
      f << "###bInt,";
413
21
      break;
414
21
    }
415
21
    field.m_type=Field::T_Long;
416
21
    field.m_name="bInt";
417
21
    field.m_longValue[0]=long(input->readLong(1));
418
21
    return true;
419
420
154k
  case 0x3b880:
421
188k
  case 0x1479080:
422
189k
  case 0x147b880:
423
330k
  case 0x147c080:
424
391k
  case 0x149d880:
425
422k
  case 0x149e080:
426
460k
  case 0x17d5880:
427
460k
    if (fSz!=2) {
428
2.93k
      MWAW_DEBUG_MSG(("RagTime5StructManager::readField: unexpected data fSz for int\n"));
429
2.93k
      f << "###int,";
430
2.93k
      break;
431
2.93k
    }
432
457k
    field.m_type=Field::T_Long;
433
457k
    field.m_name="int";
434
457k
    field.m_longValue[0]=long(input->readLong(2));
435
457k
    return true;
436
51.4k
  case 0x34080:
437
70.8k
  case 0xcf817: // bigger int dataId?: not in typedef
438
70.8k
    if (fSz!=2) {
439
118
      MWAW_DEBUG_MSG(("RagTime5StructManager::readField: unexpected data fSz for uint\n"));
440
118
      f << "###uint,";
441
118
      break;
442
118
    }
443
70.7k
    field.m_type=Field::T_Long;
444
70.7k
    field.m_name="uint";
445
70.7k
    field.m_longValue[0]=long(input->readULong(2));
446
70.7k
    return true;
447
0
  case 0xb6000: // color percent
448
6.20k
  case 0x1493800: // checkme double(as int)
449
18.8k
  case 0x1494800: // checkme double(as int)
450
27.6k
  case 0x1495000:
451
27.6k
  case 0x1495800: // checkme double(as int)
452
27.6k
    if (fSz!=4) {
453
434
      MWAW_DEBUG_MSG(("RagTime5StructManager::readField: unexpected data fSz for double4\n"));
454
434
      f << "###float,";
455
434
      break;
456
434
    }
457
    // checkme if val=0xFFFFFFFF, inf?
458
27.2k
    field.m_type=Field::T_Double;
459
27.2k
    field.m_name="double4";
460
27.2k
    field.m_doubleValue=double(input->readLong(4))/65536;
461
27.2k
    return true;
462
44.8k
  case 0x45840: {
463
44.8k
    if (fSz!=8) {
464
510
      MWAW_DEBUG_MSG(("RagTime5StructManager::readField: unexpected data fSz for double\n"));
465
510
      f << "###double,";
466
510
      break;
467
510
    }
468
44.3k
    double res;
469
44.3k
    bool isNan;
470
44.3k
    if (!input->readDouble8(res, isNan)) {
471
595
      MWAW_DEBUG_MSG(("RagTime5StructManager::readField: can not read a double\n"));
472
595
      f << "###double";
473
595
      break;
474
595
    }
475
43.7k
    field.m_type=Field::T_Double;
476
43.7k
    field.m_name="double";
477
43.7k
    field.m_doubleValue=res;
478
43.7k
    return true;
479
44.3k
  }
480
0
  case 0x14510b7: {
481
0
    std::vector<int> listIds;
482
0
    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
0
    field.m_name="colPatId";
488
0
    field.m_type=Field::T_ZoneId;
489
0
    field.m_longValue[0]=listIds[0];
490
0
    return true;
491
0
  }
492
927
  case 0x34800:
493
44.6k
  case 0x8c000: // a dim
494
44.6k
  case 0x234800:  // checkme, find always with 0x0
495
54.5k
  case 0x147415a: // checkme, find always with 0x0
496
69.3k
  case 0x15e3017: // 2 long, not in typedef
497
69.3k
    if (fSz!=4) {
498
312
      MWAW_DEBUG_MSG(("RagTime5StructManager::readField: unexpected data fSz for 2xint\n"));
499
312
      f << "###2xint,";
500
312
      break;
501
312
    }
502
69.0k
    field.m_type=Field::T_2Long;
503
69.0k
    field.m_name="2xint";
504
69.0k
    field.m_longValue[0]=long(input->readLong(2));
505
69.0k
    field.m_longValue[1]=long(input->readLong(2));
506
69.0k
    return true;
507
347
  case 0x7d01a:
508
450k
  case 0xc8042: { // unicode
509
450k
    if (fSz<2) {
510
244
      MWAW_DEBUG_MSG(("RagTime5StructManager::readField: unexpected data fSz for unicode\n"));
511
244
      f << "###unicode";
512
244
      break;
513
244
    }
514
450k
    field.m_type=Field::T_Unicode;
515
450k
    field.m_name="unicode";
516
450k
    auto val=static_cast<int>(input->readULong(2));
517
450k
    if ((val&0x70FF)==0) {
518
273k
      if (val) f << "f1=" << ((val&0x7F00)>>8);
519
1.58M
      for (long i=2; i<fSz; ++i)
520
1.31M
        libmwaw::appendUnicode(static_cast<uint32_t>(input->readULong(1)), field.m_string);
521
273k
    }
522
176k
    else {
523
176k
      input->seek(debDataPos, librevenge::RVNG_SEEK_SET);
524
176k
      if (!readUnicodeString(input, endDataPos, field.m_string))
525
2.70k
        f << "###";
526
176k
    }
527
450k
    input->seek(endDataPos, librevenge::RVNG_SEEK_SET);
528
450k
    field.m_extra=f.str();
529
450k
    return true;
530
450k
  }
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
0
  case 0x149a940: {
567
0
    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
0
    field.m_type=Field::T_LongDouble;
573
0
    field.m_name="interline";
574
0
    field.m_longValue[0]=static_cast<int>(input->readLong(2));
575
0
    field.m_doubleValue=double(input->readLong(4))/65536.;
576
0
    return true;
577
0
  }
578
0
  case 0x149c940: { // checkme
579
0
    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
0
    field.m_type=Field::T_LongDouble;
585
0
    field.m_name="floatxint";
586
0
    field.m_doubleValue=double(input->readLong(4))/65536.;
587
0
    field.m_longValue[0]=static_cast<int>(input->readLong(2));
588
0
    return true;
589
0
  }
590
6.29k
  case 0x74040: {
591
6.29k
    if (fSz!=8) {
592
967
      MWAW_DEBUG_MSG(("RagTime5StructManager::readField: unexpected data fSz for 2xfloat\n"));
593
967
      f << "###2xfloat";
594
967
      break;
595
967
    }
596
5.32k
    field.m_type=Field::T_DoubleList;
597
5.32k
    field.m_name="2xfloat";
598
15.9k
    for (int i=0; i<2; ++i)
599
10.6k
      field.m_doubleList.push_back(double(input->readLong(4))/65536);
600
5.32k
    return true;
601
6.29k
  }
602
7.09k
  case 0x1474040: // maybe one tab
603
7.09k
  case 0x81474040: {
604
7.09k
    if ((fSz%8)!=0) {
605
87
      MWAW_DEBUG_MSG(("RagTime5StructManager::readField: unexpected data fSz for tab\n"));
606
87
      f << "###tab[list]";
607
87
      break;
608
87
    }
609
7.01k
    field.m_type=Field::T_TabList;
610
7.01k
    field.m_name="tab";
611
7.01k
    auto N=int(fSz/8);
612
14.1k
    for (int i=0; i<N; ++i) {
613
7.14k
      TabStop tab;
614
7.14k
      tab.m_position=float(input->readLong(4))/65536.f;
615
7.14k
      tab.m_type=static_cast<int>(input->readLong(2));
616
7.14k
      tab.m_leaderChar=static_cast<uint16_t>(input->readULong(2));
617
7.14k
      field.m_tabList.push_back(tab);
618
7.14k
    }
619
7.01k
    return true;
620
7.09k
  }
621
73
  case 0x74840: // dimension
622
5.43k
  case 0x112040: // also some dimension ? ( often 0,0,0,1 but can be 0,-0.00564575,0,0.25 )
623
5.43k
    if (fSz!=16) {
624
161
      MWAW_DEBUG_MSG(("RagTime5StructManager::readField: unexpected data fSz for dim\n"));
625
161
      f << "###dim";
626
161
      break;
627
161
    }
628
5.27k
    field.m_type=Field::T_DoubleList;
629
5.27k
    field.m_name="dim";
630
26.3k
    for (long i=0; i<4; ++i)
631
21.0k
      field.m_doubleList.push_back(double(input->readLong(4))/65536.);
632
5.27k
    field.m_extra=f.str();
633
5.27k
    return true;
634
635
24
  case 0x1476840:
636
24
    if (fSz!=10) {
637
24
      MWAW_DEBUG_MSG(("RagTime5StructManager::readField: unexpected data fSz for 3intxfloat\n"));
638
24
      f << "###3intxfloat";
639
24
      break;
640
24
    }
641
0
    field.m_type=Field::T_Unstructured;
642
0
    field.m_name="3intxfloat";
643
0
    field.m_entry.setBegin(input->tell());
644
0
    field.m_entry.setEnd(endDataPos);
645
0
    for (long i=0; i<3; ++i) { // 1|3,1,1
646
0
      auto val=static_cast<int>(input->readLong(2));
647
0
      if (val) f << val << ":";
648
0
      else f << "_:";
649
0
    }
650
0
    f << double(input->readLong(4))/65536. << ",";
651
0
    field.m_extra=f.str();
652
0
    return true;
653
42.9k
  case 0x79040: { // checkme: unsure
654
42.9k
    if (fSz!=14) {
655
188
      MWAW_DEBUG_MSG(("RagTime5StructManager::readField: unexpected data fSz for 0x79040\n"));
656
188
      f << "###unstr";
657
188
      break;
658
188
    }
659
42.7k
    field.m_type=Field::T_Unstructured;
660
42.7k
    field.m_name="unstr";
661
42.7k
    field.m_entry.setBegin(input->tell());
662
42.7k
    field.m_entry.setEnd(endDataPos);
663
128k
    for (long i=0; i<2; ++i) { // something like 49c4x6c2b
664
85.4k
      f << std::hex << input->readULong(4) << std::dec;
665
85.4k
      if (i==0) f << "x";
666
42.7k
      else f << ",";
667
85.4k
    }
668
128k
    for (int i=0; i<2; ++i) { // often 4000, 3fed
669
85.4k
      f << std::hex << input->readULong(2) << std::dec;
670
85.4k
      if (i==0) f << "x";
671
42.7k
      else f << ",";
672
85.4k
    }
673
42.7k
    auto val=static_cast<int>(input->readLong(2));
674
42.7k
    if (val!=0x100) f << val << ":";
675
42.7k
    field.m_extra=f.str();
676
42.7k
    return true;
677
42.9k
  }
678
122k
  case 0x84040: {
679
122k
    if (fSz!=10) {
680
710
      MWAW_DEBUG_MSG(("RagTime5StructManager::readField: unexpected data fSz for rgba\n"));
681
710
      f << "###rgba";
682
710
      break;
683
710
    }
684
121k
    field.m_type=Field::T_Color;
685
121k
    field.m_name="rgba";
686
121k
    field.m_longValue[0]=long(input->readLong(2)); // id or numUsed
687
121k
    if (field.m_longValue[0]==50) {
688
52.8k
      field.m_longValue[1]=long(input->readULong(2));
689
52.8k
      field.m_color=MWAWColor(255,255,255);
690
52.8k
      input->seek(endDataPos, librevenge::RVNG_SEEK_SET);
691
52.8k
      return true;
692
52.8k
    }
693
68.9k
    unsigned char col[4];
694
275k
    for (auto &c : col) c=static_cast<unsigned char>(input->readULong(2)>>8); // rgba
695
68.9k
    field.m_color=MWAWColor(col[0],col[1],col[2],col[3]);
696
68.9k
    return true;
697
121k
  }
698
15.8k
  case 0x8d000: {
699
15.8k
    if (fSz!=4) {
700
1.00k
      MWAW_DEBUG_MSG(("RagTime5StructManager::readField: unexpected data fSz for rsrcName\n"));
701
1.00k
      f << "###rsrcName";
702
1.00k
      break;
703
1.00k
    }
704
14.8k
    field.m_type=Field::T_Code;
705
14.8k
    field.m_name="rsrcName";
706
14.8k
    auto cod=input->readULong(4);
707
74.0k
    for (int i=0; i<4; ++i) field.m_string.append(char(cod>>(24-8*i)));
708
14.8k
    return true;
709
15.8k
  }
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
2
  case 0x2fd040: {
725
2
    if (fSz<120) {
726
2
      MWAW_DEBUG_MSG(("RagTime5StructManager::readField: unexpected data fSz for printInfo\n"));
727
2
      f << "###printInfo";
728
2
      break;
729
2
    }
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
12.8k
  case 0x148c01a: // 2 int + 8 bytes for pat ?
769
12.8k
    if (fSz!=12) {
770
224
      MWAW_DEBUG_MSG(("RagTime5StructManager::readField: unexpected data fSz for pat\n"));
771
224
      f << "###pat";
772
224
      break;
773
224
    }
774
12.5k
    field.m_type=Field::T_Unstructured;
775
12.5k
    field.m_name="pat";
776
12.5k
    field.m_entry.setBegin(input->tell());
777
12.5k
    field.m_entry.setEnd(endDataPos);
778
12.5k
    field.m_extra="...";
779
12.5k
    input->seek(endDataPos, librevenge::RVNG_SEEK_SET);
780
12.5k
    return true;
781
19.2k
  case 0x226140:
782
19.2k
    if (fSz!=21) {
783
794
      MWAW_DEBUG_MSG(("RagTime5StructManager::readField: unexpected data fSz for font\n"));
784
794
      f << "###font";
785
794
      break;
786
794
    }
787
18.4k
    field.m_type=Field::T_Unstructured;
788
18.4k
    field.m_name="font";
789
18.4k
    field.m_entry.setBegin(input->tell());
790
18.4k
    field.m_entry.setEnd(endDataPos);
791
18.4k
    field.m_extra="...";
792
18.4k
    input->seek(endDataPos, librevenge::RVNG_SEEK_SET);
793
18.4k
    return true;
794
19.6k
  case 0x226940: { // checkme
795
19.6k
    if (fSz<262 || ((fSz-262)%6)!=0) {
796
386
      MWAW_DEBUG_MSG(("RagTime5StructManager::readField: unexpected data fSz for para\n"));
797
386
      f << "###para";
798
386
      break;
799
386
    }
800
19.2k
    field.m_type=Field::T_Unstructured;
801
19.2k
    field.m_name="para";
802
19.2k
    field.m_entry.setBegin(input->tell());
803
19.2k
    field.m_entry.setEnd(endDataPos);
804
19.2k
    field.m_extra="...";
805
19.2k
    ascFile.addPos(input->tell()+70);
806
19.2k
    ascFile.addNote("TextStyle-para-B0:");
807
19.2k
    ascFile.addPos(input->tell()+166);
808
19.2k
    ascFile.addNote("TextStyle-para-B1:");
809
19.2k
    if (fSz>262) {
810
5.61k
      ascFile.addPos(input->tell()+262);
811
5.61k
      ascFile.addNote("TextStyle-para-C:");
812
5.61k
    }
813
19.2k
    input->seek(endDataPos, librevenge::RVNG_SEEK_SET);
814
19.2k
    return true;
815
19.6k
  }
816
8.96k
  case 0x71940: // checkme: locale data ?
817
8.96k
    if (fSz!=108) {
818
699
      MWAW_DEBUG_MSG(("RagTime5StructManager::readField: unexpected data fSz for locale\n"));
819
699
      f << "###locale";
820
699
      break;
821
699
    }
822
8.26k
    field.m_type=Field::T_Unstructured;
823
8.26k
    field.m_name="locale";
824
8.26k
    field.m_entry.setBegin(input->tell());
825
8.26k
    field.m_entry.setEnd(endDataPos);
826
8.26k
    f << "fls=[" << std::hex;
827
74.4k
    for (long i=0; i<8; ++i) {
828
66.1k
      auto val=static_cast<int>(input->readLong(1));
829
66.1k
      if (val==1) f << "_,";
830
33.0k
      else f << val << ",";
831
66.1k
    }
832
8.26k
    f << "],";
833
8.26k
    f << "chars=[";
834
181k
    for (long i=0; i<21; ++i) {
835
173k
      auto val=static_cast<int>(input->readULong(2));
836
173k
      if (!val) f << "_,";
837
148k
      else if (val<128) f << char(val) << ",";
838
298
      else f << std::hex << val << std::dec << ",";
839
173k
    }
840
8.26k
    f << "],";
841
8.26k
    ascFile.addDelimiter(input->tell(),'|');
842
8.26k
    field.m_extra=f.str();
843
8.26k
    input->seek(endDataPos, librevenge::RVNG_SEEK_SET);
844
8.26k
    return true;
845
108
  case 0x32040:
846
108
    if (fSz<160) {
847
73
      MWAW_DEBUG_MSG(("RagTime5StructManager::readField: the data fSz for docInfo data seems too short\n"));
848
73
      f << "###docInfo";
849
73
      break;
850
73
    }
851
35
    else {
852
35
      field.m_type=Field::T_Unstructured;
853
35
      field.m_name="docInfo";
854
35
      field.m_entry.setBegin(input->tell());
855
35
      field.m_entry.setEnd(endDataPos);
856
35
      field.m_extra="...";
857
35
      input->seek(endDataPos, librevenge::RVNG_SEEK_SET);
858
35
      return true;
859
35
    }
860
19.9k
  case 0x227140: { // border checkme
861
19.9k
    if ((fSz%6)!=2) {
862
604
      MWAW_DEBUG_MSG(("RagTime5StructManager::readField: unexpected data fSz for list of border\n"));
863
604
      f << "###border";
864
604
      break;
865
604
    }
866
19.3k
    auto val=static_cast<int>(input->readULong(2)); // c000 or c1000
867
19.3k
    if (val!=0xc000) f << "f0=" << std::hex << val << std::dec << ",";
868
19.3k
    field.m_type=Field::T_LongList;
869
19.3k
    field.m_name="border";
870
19.3k
    field.m_numLongByData=3;
871
19.3k
    fSz/=6;
872
2.07M
    for (long i=0; i<fSz; ++i) {
873
2.05M
      field.m_longList.push_back(long(input->readLong(2))); // row?
874
2.05M
      field.m_longList.push_back(long(input->readLong(2))); // col?
875
2.05M
      field.m_longList.push_back(long(input->readULong(2))); // flags?
876
2.05M
    }
877
19.3k
    field.m_extra=f.str();
878
19.3k
    return true;
879
19.9k
  }
880
365
  case 0x64040: { // chart pref
881
365
    if (fSz<3) {
882
8
      MWAW_DEBUG_MSG(("RagTime5StructManager::readField: unexpected data fSz for chart pref\n"));
883
8
      f << "###chart pref";
884
8
      break;
885
8
    }
886
357
    field.m_type=Field::T_FieldList;
887
357
    field.m_entry.setBegin(input->tell());
888
357
    field.m_entry.setEnd(endDataPos);
889
1.42k
    for (int i=0; i<3; ++i) { // f2=8|9
890
1.07k
      auto val=static_cast<int>(input->readLong(1));
891
1.07k
      if (val) f << "f" << i << "=" << val << ",";
892
1.07k
    }
893
357
    bool ok=true;
894
358
    while (input->tell()<endDataPos) {
895
358
      Field child;
896
358
      long pos=input->tell();
897
358
      if (!readField(input, endDataPos, ascFile, child, 0, depth+1)) {
898
357
        ok=false;
899
357
        input->seek(pos, librevenge::RVNG_SEEK_SET);
900
357
        break;
901
357
      }
902
1
      field.m_fieldList.push_back(child);
903
1
    }
904
357
    if (!ok || input->tell() != endDataPos) {
905
357
      MWAW_DEBUG_MSG(("RagTime5StructManager::readField: can not read some charr pref list data\n"));
906
357
      f.str("");
907
357
      f << "###pos=" << input->tell()-debPos;
908
357
      input->seek(endDataPos, librevenge::RVNG_SEEK_SET);
909
357
    }
910
357
    field.m_extra=f.str();
911
357
    return true;
912
365
  }
913
14
  case 0xce017: { // unstructured: not in typedef
914
14
    if (fSz<5) {
915
14
      MWAW_DEBUG_MSG(("RagTime5StructManager::readField: unexpected data fSz for unstructured\n"));
916
14
      f << "###unstr";
917
14
      break;
918
14
    }
919
0
    field.m_type=Field::T_Unstructured;
920
0
    field.m_name="unstruct";
921
0
    field.m_longValue[0]=input->readLong(4);
922
0
    field.m_entry.setBegin(input->tell());
923
0
    field.m_entry.setEnd(endDataPos);
924
0
    f << "data=" << std::hex;
925
0
    for (long i=0; i<fSz-4; ++i)
926
0
      f << std::setfill('0') << std::setw(2) << static_cast<int>(input->readULong(1));
927
0
    f << std::dec << ",";
928
0
    field.m_extra=f.str();
929
0
    return true;
930
14
  }
931
1.13M
  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.93k
      MWAW_DEBUG_MSG(("RagTime5StructManager::readField: unexpected data fSz for list of long\n"));
935
1.93k
      f << "###";
936
1.93k
      break;
937
1.93k
    }
938
1.13M
    fSz/=4;
939
1.13M
    field.m_type=Field::T_LongList;
940
1.13M
    field.m_name="longList";
941
14.1M
    for (long i=0; i<fSz; ++i)
942
13.0M
      field.m_longList.push_back(long(input->readLong(4)));
943
1.13M
    return true;
944
1.13M
  }
945
75.3k
  case 0x3c057:
946
93.6k
  case 0x80045080: // child of 14741fa
947
152k
  case 0xcf042: { // list of small int: header fl=2000 with f2=9
948
152k
    if ((fSz%2)!=0) {
949
1.22k
      MWAW_DEBUG_MSG(("RagTime5StructManager::readField: unexpected data fSz for list of long\n"));
950
1.22k
      f << "###";
951
1.22k
      break;
952
1.22k
    }
953
151k
    fSz/=2;
954
151k
    field.m_type=Field::T_LongList;
955
151k
    field.m_name="intList";
956
415k
    for (long i=0; i<fSz; ++i)
957
264k
      field.m_longList.push_back(long(input->readLong(2)));
958
151k
    return true;
959
152k
  }
960
0
  case 0x154f017: // list of bytes
961
0
    field.m_type=Field::T_LongList;
962
0
    field.m_name="byteList";
963
0
    for (long i=0; i<fSz; ++i)
964
0
      field.m_longList.push_back(long(input->readLong(1)));
965
0
    return true;
966
274
  case 0x35000: // checkme find also a string code here...
967
17.5k
  case 0x35800: // unsure, ie small int
968
17.8k
  case 0x3e800: // unsure, find with 000af040, 00049840 or 0004c040
969
38.2k
  case 0xa4000:
970
38.2k
    if (fSz!=4) {
971
867
      MWAW_DEBUG_MSG(("RagTime5StructManager::readField: unexpected data fSz for list of uint32_t\n"));
972
867
      f << "###uint32";
973
867
      break;
974
867
    }
975
37.3k
    field.m_type=Field::T_Long;
976
37.3k
    field.m_longValue[0]=long(input->readULong(4));
977
37.3k
    return true;
978
20.4k
  case 0xa4840:
979
20.4k
    if (fSz!=8) {
980
269
      MWAW_DEBUG_MSG(("RagTime5StructManager::readField: unexpected data fSz for list of 2xuint32_t\n"));
981
269
      f << "###2xuint32";
982
269
      break;
983
269
    }
984
20.1k
    field.m_type=Field::T_2Long;
985
20.1k
    field.m_name="2xuint32";
986
20.1k
    for (long &i : field.m_longValue)
987
40.3k
      i=long(input->readULong(4));
988
20.1k
    return true;
989
990
17.6k
  case 0x33000: // maybe one 2xint
991
17.6k
  case 0x1671817:
992
17.6k
  case 0x16b491a: // in chart,
993
17.6k
  case 0x16b492a: // in chart, dim[4byte], id, 0
994
17.6k
  case 0x16b5aea: // chart preference, always 0,0,id,0
995
17.6k
  case 0x80033000:
996
17.6k
    if ((fSz%4)!=0) {
997
394
      MWAW_DEBUG_MSG(("RagTime5StructManager::readField: unexpected data fSz for list of 2xint\n"));
998
394
      f << "###";
999
394
      break;
1000
394
    }
1001
17.2k
    field.m_type=Field::T_LongList;
1002
17.2k
    field.m_name="2intList";
1003
17.2k
    field.m_numLongByData=2;
1004
17.2k
    fSz/=2;
1005
53.1k
    for (long i=0; i<fSz; ++i)
1006
35.9k
      field.m_longList.push_back(long(input->readLong(2)));
1007
17.2k
    return true;
1008
5.46k
  case 0x81452040: {
1009
5.46k
    if (fSz!=8) {
1010
137
      MWAW_DEBUG_MSG(("RagTime5StructManager::readField: unexpected data fSz for id+long\n"));
1011
137
      f << "###clustIdxlong";
1012
137
      break;
1013
137
    }
1014
5.32k
    field.m_type=Field::T_ZoneId;
1015
5.32k
    field.m_name="clustIdxlong";
1016
5.32k
    field.m_entry.setBegin(input->tell());
1017
5.32k
    field.m_entry.setEnd(endDataPos);
1018
5.32k
    std::vector<int> listIds;
1019
5.32k
    if (!readDataIdList(input, 1, listIds)) {
1020
71
      MWAW_DEBUG_MSG(("RagTime5StructManager::readField: can not read the cluster id for id+long\n"));
1021
71
      f << "###clustId,";
1022
71
      break;
1023
71
    }
1024
5.25k
    field.m_longValue[0]=listIds[0];
1025
5.25k
    unsigned long val= input->readULong(4); // always 90000001
1026
5.25k
    if (val!=0x90000001) f << std::hex << val << std::dec << ",";
1027
5.25k
    field.m_extra=f.str();
1028
5.25k
    return true;
1029
5.32k
  }
1030
20.5k
  case 0xa7017: // unicode
1031
20.7k
  case 0xa7027:
1032
41.8k
  case 0xa7037:
1033
63.1k
  case 0xa7047:
1034
84.1k
  case 0xa7057:
1035
104k
  case 0xa7067:
1036
127k
  case 0x146905a: // unicode
1037
1038
146k
  case 0x7a047: // font definition
1039
167k
  case 0x7a057: // ?? definition
1040
187k
  case 0x7a067: // ?? definition
1041
1042
187k
  case 0x146005a: // code
1043
187k
  case 0x146007a:
1044
187k
  case 0x14600aa:
1045
194k
  case 0x147403a:
1046
203k
  case 0x14740ba:
1047
203k
  case 0x147501a:
1048
203k
  case 0x148981a:
1049
1050
215k
  case 0x145e0ba: // bool
1051
223k
  case 0x147406a:
1052
223k
  case 0x147550a:
1053
239k
  case 0x17d486a:
1054
1055
239k
  case 0x147512a: // small int
1056
1057
259k
  case 0xa7077: // with type=3b880
1058
305k
  case 0x145e01a:
1059
327k
  case 0x146904a: // int with type=0x149d880
1060
327k
  case 0x146907a: // withe type = 149d880
1061
349k
  case 0x146908a: // with type=0x3b880
1062
349k
  case 0x1469840: // with type=147b88
1063
366k
  case 0x146e02a:
1064
383k
  case 0x146e03a:
1065
400k
  case 0x146e04a:
1066
417k
  case 0x146e06a:
1067
417k
  case 0x146e08a:
1068
455k
  case 0x145e11a: // with type=0x17d5880
1069
456k
  case 0x145e12a: // with type=017d5880
1070
464k
  case 0x147407a:
1071
472k
  case 0x147408a:
1072
485k
  case 0x1474042:
1073
485k
  case 0x147416a:
1074
493k
  case 0x14741ea:
1075
493k
  case 0x147420a: // with type=3b880
1076
493k
  case 0x14754aa: // with type=328c0
1077
493k
  case 0x147551a: // with type=1479080
1078
493k
  case 0x147e81a: // with type=3b880
1079
542k
  case 0x17d481a: // int
1080
1081
555k
  case 0x7d04a:
1082
555k
  case 0x147405a:
1083
555k
  case 0x14741ca: // 2 long
1084
556k
  case 0x145e02a: // with type=b600000
1085
556k
  case 0x14741ba: // with type=b600000
1086
556k
  case 0x145e0ea:
1087
556k
  case 0x146008a:
1088
556k
  case 0x14752da: // with type=1495000
1089
556k
  case 0x14740ea: // with type=b600000
1090
556k
  case 0x147536a: // with type=1495000
1091
556k
  case 0x147538a: // with type=1495000
1092
579k
  case 0x146902a: // double
1093
601k
  case 0x146903a: // double
1094
601k
  case 0x17d484a: // with type=34800
1095
601k
  case 0x147404a: // with type=149c94
1096
715k
  case 0x7d02a: // rgba color?
1097
728k
  case 0x145e05a:
1098
1099
728k
  case 0x14750ea: // keep with next para
1100
728k
  case 0x147530a: // break behavior
1101
728k
  case 0x14753aa: // min word spacing
1102
728k
  case 0x14753ca: // optimal word spacing
1103
728k
  case 0x14753ea: // max word spacing
1104
728k
  case 0x147546a: // number line in widows
1105
728k
  case 0x147548a: // number line in orphan
1106
728k
  case 0x147552a: // do not use spacing for single word
1107
728k
  case 0x147516a: // align paragraph on grid
1108
728k
  case 0x147418a: // small caps scaling x
1109
728k
  case 0x14741aa: // small caps scaling y
1110
1111
728k
  case 0x14c2042: /* function container*/
1112
728k
  case 0x1559842:
1113
728k
  case 0x1663842:
1114
728k
  case 0x1be5042:
1115
728k
  case 0x1d50842:
1116
728k
  case 0x1e16842:
1117
728k
  case 0x23aa042:
1118
728k
  case 0x23af042:
1119
728k
  case 0x23b4042:
1120
1121
771k
  case 0x7a09a: // with a4000 or a4840
1122
780k
  case 0x7a05a: // unknown
1123
801k
  case 0x7a0aa:
1124
801k
  case 0x14600ca: // with type=80033000
1125
819k
  case 0x146e05a: // with type=33000
1126
827k
  case 0x147402a:
1127
846k
  case 0x14741fa: // unsure find with type=80045080
1128
846k
  case 0x147502a: // with type=149a940
1129
846k
  case 0x147505a: // with type=1493800
1130
846k
  case 0x147506a: // with type=1493800
1131
846k
  case 0x147507a: // with type=1493800
1132
846k
  case 0x14750aa: // with type=149a940
1133
846k
  case 0x14750ba: // with type=149a940
1134
854k
  case 0x14750ca: // with type=1474040
1135
854k
  case 0x147510a: // with type=81474040 or 1474040
1136
861k
  case 0x147513a: // with type=1493800
1137
861k
  case 0x14754ba: // with type=1476840
1138
861k
  case 0x148983a: // with type=0074040
1139
861k
  case 0x148985a: // with type=1495800
1140
1141
861k
  case 0x16c1825: // chart pref with type=0042040 CHECKME
1142
861k
  case 0x16d5840: // chart main pref
1143
1144
  // docinfo zone
1145
861k
  case 0x1f7817:
1146
861k
  case 0x1f7827:
1147
861k
  case 0x1f7837:
1148
861k
  case 0x1f7847:
1149
861k
  case 0x1f7857:
1150
861k
  case 0x1f7887:
1151
1152
  // gobj property
1153
905k
  case 0x6615a:
1154
949k
  case 0x6616a:
1155
993k
  case 0x6617a:
1156
998k
  case 0x6619a:
1157
998k
  case 0xfd827:
1158
998k
  case 0x10581a:
1159
1.00M
  case 0x111817:
1160
1.00M
  case 0x111827:
1161
1.00M
  case 0x1467837:
1162
1.01M
  case 0x146789a:
1163
1.02M
  case 0x14678aa: {
1164
1.02M
    if (fSz<4) {
1165
506
      MWAW_DEBUG_MSG(("RagTime5StructManager::readField: unexpected list field size\n"));
1166
506
      f << "###list,";
1167
506
      break;
1168
506
    }
1169
1170
1.01M
    long pos=input->tell();
1171
1.01M
    Field child;
1172
1.01M
    if (!readField(input, endDataPos, ascFile, child, fSz, depth+1)) {
1173
2.57k
      f << "###pos=" << pos-debPos;
1174
2.57k
      input->seek(pos, librevenge::RVNG_SEEK_SET);
1175
2.57k
      break;
1176
2.57k
    }
1177
1.01M
    field.m_name="container";
1178
1179
1.01M
    field.m_type=Field::T_FieldList;
1180
1.01M
    field.m_fieldList.push_back(child);
1181
1.01M
    if (input->tell() != endDataPos) {
1182
20
      MWAW_DEBUG_MSG(("RagTime5StructManager::readField: can not read some field list data\n"));
1183
20
      f.str("");
1184
20
      f << "###pos=" << pos-debPos;
1185
20
      field.m_extra+=f.str();
1186
20
      input->seek(endDataPos, librevenge::RVNG_SEEK_SET);
1187
20
    }
1188
1.01M
    return true;
1189
1.01M
  }
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
0
  case 0x154a840: {
1223
0
    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
0
    auto val=static_cast<int>(input->readLong(1)); // always 0?
1229
0
    if (val) f << "f1=" << val << ",";
1230
0
    auto N=static_cast<int>(input->readULong(1));
1231
0
    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
0
    for (int i=0; i<3; ++i) { // 0,-1|0|1,0
1237
0
      val=static_cast<int>(input->readLong(1));
1238
0
      if (!val) continue;
1239
0
      f << "f" << i+2 << "=" << val << ",";
1240
0
    }
1241
0
    val=static_cast<int>(input->readULong(1)); //0|40|c0
1242
0
    if (val) f << "f5=" << std::hex << val << std::dec << ",";
1243
    // list of [0|1|20]*
1244
0
    field.m_type=Field::T_LongList;
1245
0
    field.m_name="func[def]";
1246
0
    for (int i=0; i<N; ++i)
1247
0
      field.m_longList.push_back(static_cast<int>(input->readULong(1)));
1248
0
    field.m_extra=f.str();
1249
0
    return true;
1250
0
  }
1251
39.2k
  case 0x42040: {
1252
39.2k
    if (fSz<10) {
1253
247
      MWAW_DEBUG_MSG(("RagTime5StructManager::readField: unexpected field size for day/month list\n"));
1254
247
      f << "###list[day/month],";
1255
247
      break;
1256
247
    }
1257
39.0k
    int val;
1258
117k
    for (int i=0; i<2; ++i) { // always 0?
1259
78.0k
      val=static_cast<int>(input->readULong(2));
1260
78.0k
      if (val) f << "f" << i+1 << "=" << val << ",";
1261
78.0k
    }
1262
39.0k
    auto N=static_cast<int>(input->readULong(2));
1263
39.0k
    val=static_cast<int>(input->readULong(2)); // always 20 ?
1264
39.0k
    if (val!=20) f << "f3=" << val << ",";
1265
39.0k
    val=static_cast<int>(input->readULong(2)); // always 0 ?
1266
39.0k
    if (val) f << "f4=" << val << ",";
1267
39.0k
    field.m_type=Field::T_FieldList;
1268
39.0k
    field.m_name="container[list]"; // can be day/month, ...
1269
39.0k
    bool ok=true;
1270
339k
    for (int i=0; i<N; ++i) {
1271
310k
      Field child;
1272
310k
      long pos=input->tell();
1273
310k
      if (!readField(input, endDataPos, ascFile, child, 0, depth+1)) {
1274
10.6k
        ok=false;
1275
10.6k
        input->seek(pos, librevenge::RVNG_SEEK_SET);
1276
10.6k
        break;
1277
10.6k
      }
1278
300k
      field.m_fieldList.push_back(child);
1279
300k
    }
1280
39.0k
    if (!ok || input->tell() != endDataPos) {
1281
10.9k
      MWAW_DEBUG_MSG(("RagTime5StructManager::readField: can not read some container list data\n"));
1282
10.9k
      f.str("");
1283
10.9k
      f << "###pos=" << input->tell()-debPos;
1284
10.9k
      input->seek(endDataPos, librevenge::RVNG_SEEK_SET);
1285
10.9k
    }
1286
39.0k
    field.m_extra+=f.str();
1287
39.0k
    return true;
1288
39.2k
  }
1289
14.5k
  case 0xd7842: { // list of ? : header fl=0|4000, f2=3
1290
14.5k
    if ((fSz%6)!=0) {
1291
372
      MWAW_DEBUG_MSG(("RagTime5StructManager::readField: unexpected data fSz for 0xd7842\n"));
1292
372
      f << "###";
1293
372
      break;
1294
372
    }
1295
14.1k
    fSz/=2;
1296
14.1k
    field.m_type=Field::T_LongList;
1297
14.1k
    field.m_name="3unknList";
1298
14.1k
    field.m_numLongByData=3;
1299
56.9k
    for (long i=0; i<fSz; ++i)
1300
42.8k
      field.m_longList.push_back(long(input->readLong(2)));
1301
14.1k
    return true;
1302
14.5k
  }
1303
525k
  default: {
1304
525k
    auto const &functIds=m_document.getFormulaParser()->getFunctionsId();
1305
525k
    if (functIds.find(static_cast<unsigned long>(type))!=functIds.end()) {
1306
0
      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
0
      for (int i=0; i<3; ++i) { // f1=0|-1, f2=small number, other 0
1312
0
        auto val=static_cast<int>(input->readLong(2));
1313
0
        if (val) f << "f" << i+1 << "=" << val << ",";
1314
0
      }
1315
0
      field.m_type=Field::T_FieldList;
1316
0
      field.m_name="func[name]";
1317
0
      bool ok=true;
1318
0
      for (int i=0; i<2; ++i) {
1319
0
        Field child;
1320
0
        long pos=input->tell();
1321
0
        if (!readField(input, endDataPos, ascFile, child, 0, depth+1)) {
1322
0
          ok=false;
1323
0
          input->seek(pos, librevenge::RVNG_SEEK_SET);
1324
0
          break;
1325
0
        }
1326
0
        field.m_fieldList.push_back(child);
1327
0
      }
1328
0
      if (!ok || input->tell() != endDataPos) {
1329
0
        MWAW_DEBUG_MSG(("RagTime5StructManager::readField: can not read some 2fields list data\n"));
1330
0
        f.str("");
1331
0
        f << "###pos=" << input->tell()-debPos;
1332
0
        input->seek(endDataPos, librevenge::RVNG_SEEK_SET);
1333
0
      }
1334
0
      field.m_extra+=f.str();
1335
0
      return true;
1336
0
    }
1337
525k
    break;
1338
525k
  }
1339
4.42M
  }
1340
1341
544k
  input->seek(debDataPos, librevenge::RVNG_SEEK_SET);
1342
544k
  if (!complex) {
1343
277k
    static bool first=true;
1344
277k
    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
277k
    field.m_name="#unknType";
1349
277k
    ascFile.addDelimiter(input->tell(),'|');
1350
277k
    input->seek(endDataPos, librevenge::RVNG_SEEK_SET);
1351
277k
    return true;
1352
277k
  }
1353
267k
  switch (type) {
1354
18.8k
  case 0x14b5815: // increasing list: with fl1=3, fl2=80, f1=29
1355
18.8k
  case 0x16be055: // fl1=f, fl2=80, f1=30
1356
18.8k
  case 0x16be065: // fl1=f, fl2=80, f1=30
1357
41.9k
  case 0x146e815: // maybe a list of dim: fl1=28-2a, fl2=80, f1=34
1358
171k
  case 0x1473815: // maybe a list of dim, fl2=80,f1=32
1359
192k
  case 0x14e6825: // maybe a list of coldim
1360
240k
  case 0x14eb015: // maybe a list of rowdim
1361
240k
  case 0x14f1825:
1362
240k
  case 0x15f4815: // maybe related to list
1363
240k
  case 0x160f815:
1364
240k
  case 0x1671845:
1365
240k
  case 0x17db015: // in group cluster
1366
240k
    field.m_name="longList";
1367
240k
    break;
1368
0
  case 0x1451025:
1369
48
  case 0x146c015: // with ce017
1370
48
  case 0x14e6875:
1371
48
  case 0x15f4015: // with ce017
1372
48
  case 0x15f6815:
1373
48
  case 0x15f9015: // sometimes a list of 15f6815
1374
48
    field.m_name="unstructList";
1375
48
    break;
1376
14.0k
  case 0x15e0825:
1377
14.0k
    field.m_name="3unknList";
1378
14.0k
    break;
1379
21
  case 0x14b4815: // with type=ce842
1380
21
    field.m_name="unknLayout";
1381
21
    break;
1382
0
  case 0x1715815: // with type=ce842
1383
0
    field.m_name="unknLstPict";
1384
0
    break;
1385
12.0k
  default:
1386
12.0k
    MWAW_DEBUG_MSG(("RagTime5StructManager::readField: unexpected list type=%lx\n", static_cast<unsigned long>(type)));
1387
12.0k
    field.m_name="#unknList";
1388
12.0k
    break;
1389
267k
  }
1390
267k
  field.m_type=Field::T_FieldList;
1391
520k
  while (input->tell()<endDataPos) {
1392
269k
    long pos=input->tell();
1393
269k
    Field child;
1394
269k
    if (!readField(input, endDataPos, ascFile, child, 0, depth+1)) {
1395
15.9k
      f << "###pos=" << pos-debPos;
1396
15.9k
      input->seek(pos, librevenge::RVNG_SEEK_SET);
1397
15.9k
      break;
1398
15.9k
    }
1399
253k
    field.m_fieldList.push_back(child);
1400
253k
  }
1401
267k
  if (input->tell()+4<endDataPos) {
1402
14.3k
    MWAW_DEBUG_MSG(("RagTime5StructManager::readField: can not read some data\n"));
1403
14.3k
    ascFile.addDelimiter(input->tell(),'|');
1404
14.3k
    input->seek(endDataPos, librevenge::RVNG_SEEK_SET);
1405
14.3k
    return true;
1406
14.3k
  }
1407
252k
  input->seek(endDataPos, librevenge::RVNG_SEEK_SET);
1408
252k
  field.m_extra=f.str();
1409
252k
  return true;
1410
267k
}
1411
1412
////////////////////////////////////////////////////////////
1413
// field function
1414
////////////////////////////////////////////////////////////
1415
std::ostream &operator<<(std::ostream &o, RagTime5StructManager::Field const &field)
1416
51.8k
{
1417
51.8k
  if (!field.m_name.empty())
1418
51.0k
    o << field.m_name << ":" << RagTime5StructManager::printType(field.m_fileType);
1419
710
  else
1420
710
    o << "T:" << RagTime5StructManager::printType(field.m_fileType);
1421
51.8k
  switch (field.m_type) {
1422
1.06k
  case RagTime5StructManager::Field::T_Double:
1423
1.06k
    o << "=" << field.m_doubleValue << ",";
1424
1.06k
    break;
1425
292
  case RagTime5StructManager::Field::T_Bool:
1426
292
    if (field.m_longValue[0]==1)
1427
232
      o << ",";
1428
60
    else if (field.m_longValue[0]==0)
1429
28
      o << "=no,";
1430
32
    else
1431
32
      o << field.m_longValue[0] << ",";
1432
292
    break;
1433
5.66k
  case RagTime5StructManager::Field::T_Long:
1434
5.66k
    if (field.m_longValue[0]>1000)
1435
888
      o << "=0x" << std::hex << field.m_longValue[0] << std::dec << ",";
1436
4.77k
    else
1437
4.77k
      o << "=" << field.m_longValue[0] << ",";
1438
5.66k
    break;
1439
224
  case RagTime5StructManager::Field::T_2Long:
1440
224
    o << "=" << field.m_longValue[0] << ":" <<  field.m_longValue[1] << ",";
1441
224
    break;
1442
0
  case RagTime5StructManager::Field::T_LongDouble:
1443
0
    o << "=" << field.m_doubleValue << ":" <<  field.m_longValue[0] << ",";
1444
0
    break;
1445
328
  case RagTime5StructManager::Field::T_Color:
1446
328
    o << "=" << field.m_color;
1447
328
    if (field.m_longValue[0])
1448
274
      o << "[" << field.m_longValue[0] << "]";
1449
328
    o << ",";
1450
328
    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
972
  case RagTime5StructManager::Field::T_Code:
1456
972
    o << "=" << field.m_string.cstr() << ",";
1457
972
    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
368
  case RagTime5StructManager::Field::T_Unicode:
1463
368
    o << "=\"" << field.m_string.cstr() << "\",";
1464
368
    return o;
1465
0
  case RagTime5StructManager::Field::T_PrintInfo:
1466
124
  case RagTime5StructManager::Field::T_Unstructured:
1467
124
    o << "=" << field.m_extra << ",";
1468
124
    return o;
1469
2.00k
  case RagTime5StructManager::Field::T_FieldList:
1470
2.00k
    if (!field.m_fieldList.empty()) {
1471
588
      o << "=[";
1472
588
      for (auto const &val : field.m_fieldList)
1473
588
        o << "[" << val << "],";
1474
588
      o << "]";
1475
588
    }
1476
2.00k
    o << ",";
1477
2.00k
    break;
1478
126
  case RagTime5StructManager::Field::T_DoubleList:
1479
126
    if (!field.m_doubleList.empty()) {
1480
126
      o << "=[";
1481
126
      for (auto const &val : field.m_doubleList)
1482
252
        o << val << ",";
1483
126
      o << "],";
1484
126
    }
1485
126
    break;
1486
1.01k
  case RagTime5StructManager::Field::T_LongList:
1487
1.01k
    if (!field.m_longList.empty() && field.m_numLongByData>0) {
1488
1.01k
      o << "=[";
1489
1.01k
      size_t pos=0;
1490
9.53k
      while (pos+size_t(field.m_numLongByData-1)<field.m_longList.size()) {
1491
17.0k
        for (int i=0; i<field.m_numLongByData; ++i) {
1492
8.52k
          long val=field.m_longList[pos++];
1493
8.52k
          if (!val)
1494
22
            o << "_";
1495
8.50k
          else if (val>-1000 && val <1000)
1496
6.53k
            o << val;
1497
1.97k
          else if (val==long(0x80000000))
1498
0
            o << "inf";
1499
          // find sometime 0x3e7f0001
1500
1.97k
          else
1501
1.97k
            o << "0x" << std::hex << val << std::dec;
1502
8.52k
          o << ((i+1==field.m_numLongByData) ? "," : ":");
1503
8.52k
        }
1504
8.52k
      }
1505
1.01k
      o << "]";
1506
1.01k
    }
1507
1.01k
    o << ",";
1508
1.01k
    break;
1509
146
  case RagTime5StructManager::Field::T_TabList:
1510
146
    if (!field.m_tabList.empty()) {
1511
146
      o << "=[";
1512
146
      for (auto const &tab : field.m_tabList)
1513
196
        o << tab << ",";
1514
146
      o << "],";
1515
146
    }
1516
146
    break;
1517
39.4k
  case RagTime5StructManager::Field::T_Unknown:
1518
#if !defined(__clang__)
1519
  default:
1520
#endif
1521
39.4k
    o << "[###unkn],";
1522
39.4k
    break;
1523
51.8k
  }
1524
50.0k
  o << field.m_extra;
1525
50.0k
  return o;
1526
51.8k
}
1527
1528
////////////////////////////////////////////////////////////
1529
// parser function
1530
////////////////////////////////////////////////////////////
1531
bool RagTime5StructManager::GObjPropFieldParser::parseField(Field &field, RagTime5Zone &/*zone*/, int /*n*/, libmwaw::DebugStream &f)
1532
163k
{
1533
163k
  if (field.m_type==Field::T_FieldList) {
1534
158k
    switch (field.m_fileType) {
1535
44.0k
    case 0x6615a:
1536
44.0k
      for (auto const &child : field.m_fieldList) {
1537
44.0k
        if (child.m_type==Field::T_2Long && child.m_fileType==0x8c000) {
1538
43.6k
          f << "dim=" << child.m_longValue[0] << "x" << child.m_longValue[1] << ",";
1539
43.6k
          continue;
1540
43.6k
        }
1541
431
        MWAW_DEBUG_MSG(("RagTime5StructManager::GObjPropFieldParser::parseField: find unexpected dim field\n"));
1542
431
        f << "##dim=" << child << ",";
1543
431
      }
1544
44.0k
      break;
1545
43.9k
    case 0x6616a:
1546
43.9k
      for (auto const &child : field.m_fieldList) {
1547
43.9k
        if (child.m_type==Field::T_Unstructured && child.m_fileType==0x79040) {
1548
42.7k
          f << "data1=" << child << ",";
1549
42.7k
          continue;
1550
42.7k
        }
1551
1.23k
        MWAW_DEBUG_MSG(("RagTime5StructManager::GObjPropFieldParser::parseField: find unexpected data1 field\n"));
1552
1.23k
        f << "##data1=" << child << ",";
1553
1.23k
      }
1554
43.9k
      break;
1555
43.6k
    case 0x6617a: // 0[13]0[01]
1556
43.6k
      for (auto const &child : field.m_fieldList) {
1557
43.6k
        if (child.m_type==Field::T_Long && child.m_fileType==0x34080) {
1558
43.1k
          f << "data2=" << std::hex << child.m_longValue[0] << std::dec << ",";
1559
43.1k
          continue;
1560
43.1k
        }
1561
443
        MWAW_DEBUG_MSG(("RagTime5StructManager::GObjPropFieldParser::parseField: find unexpected data2 field\n"));
1562
443
        f << "##data2=" << child << ",";
1563
443
      }
1564
43.6k
      break;
1565
5.48k
    case 0x6619a:
1566
5.48k
      for (auto const &child : field.m_fieldList) {
1567
5.48k
        if (child.m_type==Field::T_ZoneId && static_cast<unsigned long>(child.m_fileType)==0x81452040) {
1568
5.32k
          f << "cluster[id]=data" << child.m_longValue[0] << "A,";
1569
5.32k
          continue;
1570
5.32k
        }
1571
163
        MWAW_DEBUG_MSG(("RagTime5StructManager::GObjPropFieldParser::parseField: find unexpected cluster id field\n"));
1572
163
        f << "##cluster[id]=" << child << ",";
1573
163
      }
1574
5.48k
      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
0
    case 0x10581a: // 1,_ or _,1 or 4000,1
1586
0
      for (auto const &child : field.m_fieldList) {
1587
0
        if (child.m_type==Field::T_LongList && child.m_fileType==0x33000) {
1588
0
          f << "long[list]=[";
1589
0
          for (auto val : child.m_longList) f << std::hex << val << std::dec << ",";
1590
0
          f << "],";
1591
0
          continue;
1592
0
        }
1593
0
        MWAW_DEBUG_MSG(("RagTime5StructManager::GObjPropFieldParser::parseField: find long[list] field\n"));
1594
0
        f << "##long[list]=" << child << ",";
1595
0
      }
1596
0
      break;
1597
5.27k
    case 0x111817: // margin in %
1598
5.27k
      for (auto const &child : field.m_fieldList) {
1599
5.27k
        if (child.m_type==Field::T_DoubleList && child.m_fileType==0x112040 && child.m_doubleList.size()==4) {
1600
5.26k
          f << "margins=" << MWAWBox2f(MWAWVec2f(float(child.m_doubleList[0]),float(child.m_doubleList[1])),
1601
5.26k
                                       MWAWVec2f(float(child.m_doubleList[2]),float(child.m_doubleList[3]))) << ",";
1602
5.26k
          continue;
1603
5.26k
        }
1604
14
        MWAW_DEBUG_MSG(("RagTime5StructManager::GObjPropFieldParser::parseField: find margins field\n"));
1605
14
        f << "##margins[list]=" << child << ",";
1606
14
      }
1607
5.27k
      break;
1608
6
    case 0x111827: // always 0,0
1609
6
      for (auto const &child : field.m_fieldList) {
1610
6
        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
6
        MWAW_DEBUG_MSG(("RagTime5StructManager::GObjPropFieldParser::parseField: find unexpected unknPos field\n"));
1615
6
        f << "##unknPos=" << child << ",";
1616
6
      }
1617
6
      break;
1618
5.27k
    case 0x1467837: // always 0,0
1619
5.27k
      for (auto const &child : field.m_fieldList) {
1620
5.27k
        if (child.m_type==Field::T_DoubleList && child.m_fileType==0x74040) {
1621
5.24k
          f << "float[list]=[";
1622
10.4k
          for (auto const &val : child.m_doubleList) f << val << ",";
1623
5.24k
          f << "],";
1624
5.24k
          continue;
1625
5.24k
        }
1626
33
        MWAW_DEBUG_MSG(("RagTime5StructManager::GObjPropFieldParser::parseField: find unexpected float[list] field\n"));
1627
33
        f << "##float[list]=" << child << ",";
1628
33
      }
1629
5.27k
      break;
1630
5.27k
    case 0x146789a: // 1-2
1631
10.5k
    case 0x14678aa: // 1-2
1632
10.5k
      for (auto const &child : field.m_fieldList) {
1633
10.5k
        if (child.m_type==Field::T_Long && child.m_fileType==0x149e080) {
1634
10.4k
          f << "d" << ((field.m_fileType>>4)&0xf) << "=" << std::hex << child.m_longValue[0] << std::dec << ",";
1635
10.4k
          continue;
1636
10.4k
        }
1637
78
        MWAW_DEBUG_MSG(("RagTime5StructManager::GObjPropFieldParser::parseField: find unexpected data%ld field\n", ((field.m_fileType>>4)&0xf)));
1638
78
        f << "##d" << ((field.m_fileType>>4)&0xf) << "=" << child << ",";
1639
78
      }
1640
10.5k
      break;
1641
20
    default:
1642
20
      MWAW_DEBUG_MSG(("RagTime5StructManager::GObjPropFieldParser::parseField: find unexpected list field\n"));
1643
20
      f << "###field=" << field << ",";
1644
20
      break;
1645
158k
    }
1646
158k
  }
1647
5.32k
  else {
1648
5.32k
    MWAW_DEBUG_MSG(("RagTime5StructManager::GObjPropFieldParser::parseField: find unexpected field type\n"));
1649
5.32k
    f << "###field=" << field << ",";
1650
5.32k
  }
1651
163k
  return true;
1652
163k
}
1653
1654
////////////////////////////////////////////////////////////
1655
// zone function
1656
////////////////////////////////////////////////////////////
1657
RagTime5Zone::~RagTime5Zone()
1658
5.17M
{
1659
5.17M
}
1660
1661
void RagTime5Zone::createAsciiFile()
1662
631k
{
1663
631k
  if (!m_input)
1664
15
    return;
1665
631k
  if (m_asciiName.empty()) {
1666
0
    MWAW_DEBUG_MSG(("RagTime5Zone::createAsciiFile: can not find the ascii name\n"));
1667
0
    return;
1668
0
  }
1669
631k
  if (m_localAsciiFile) {
1670
0
    MWAW_DEBUG_MSG(("RagTime5Zone::createAsciiFile: the ascii file already exist\n"));
1671
0
  }
1672
631k
  m_localAsciiFile.reset(new libmwaw::DebugFile(m_input));
1673
631k
  m_asciiFile = m_localAsciiFile.get();
1674
631k
  m_asciiFile->open(m_asciiName);
1675
631k
}
1676
1677
std::string RagTime5Zone::getZoneName() const
1678
625k
{
1679
625k
  if (m_level==1) {
1680
615k
    if (m_ids[0]==0 && m_idsFlag[0]==1)
1681
1.24k
      return "FileHeader";
1682
614k
    else if (m_ids[0]==1 && m_idsFlag[0]==0)
1683
466k
      return "ZoneInfo";
1684
615k
  }
1685
157k
  std::stringstream s;
1686
157k
  if (m_level==1)
1687
147k
    s << "Data" << m_ids[0] << "A";
1688
10.0k
  else if (m_level<0 || m_level>3)
1689
0
    s << "###unknLevel" << m_level << "-" << m_ids[0];
1690
10.0k
  else if (!m_parentName.empty())
1691
857
    s << m_parentName << "-" << m_ids[0] << char('A'+m_level-1);
1692
9.23k
  else
1693
9.23k
    s << "###unknChild" << m_ids[0] << char('A'+m_level-1) ;
1694
157k
  return s.str();
1695
625k
}
1696
1697
void RagTime5Zone::addErrorInDebugFile(std::string const &zoneName)
1698
10.6k
{
1699
10.6k
  m_isParsed=true;
1700
10.6k
  if (m_entry.valid()) {
1701
6.95k
    libmwaw::DebugStream f;
1702
6.95k
    f << "Entries(" << zoneName << ")[" << *this << "]:###bad";
1703
6.95k
    ascii().addPos(m_entry.begin());
1704
6.95k
    ascii().addNote(f.str().c_str());
1705
6.95k
    ascii().addPos(m_entry.end());
1706
6.95k
    ascii().addNote("_");
1707
6.95k
  }
1708
10.6k
  libmwaw::DebugStream f;
1709
10.6k
  f << zoneName << ":###bad";
1710
10.6k
  m_mainAsciiFile->addPos(m_defPosition);
1711
10.6k
  m_mainAsciiFile->addNote(f.str().c_str());
1712
10.6k
}
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: