Coverage Report

Created: 2026-09-14 06:37

next uncovered line (L), next uncovered region (R), next uncovered branch (B)
/src/libmwaw/src/lib/NisusWrtStruct.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 "MWAWDebug.hxx"
35
#include "MWAWInputStream.hxx"
36
37
#include "NisusWrtParser.hxx"
38
39
#include "NisusWrtStruct.hxx"
40
41
namespace NisusWrtStruct
42
{
43
std::ostream &operator<< (std::ostream &o, Position const &pos)
44
0
{
45
0
  o << pos.m_paragraph << "x";
46
0
  if (pos.m_word) o << pos.m_word << "x";
47
0
  else o << "_x";
48
0
  if (pos.m_char) o << pos.m_char;
49
0
  else o << "_";
50
51
0
  return o;
52
0
}
53
54
std::ostream &operator<< (std::ostream &o, FootnoteInfo const &fnote)
55
0
{
56
0
  if (fnote.m_flags&0x4) o << "sepPos=right,";
57
0
  if (fnote.m_flags&0x8) o << "endNotes,"; // footnote|endnote
58
0
  if (fnote.m_flags&0x10) o << "renumber[Pages],";
59
0
  if (fnote.m_flags&0x20) o << "maySep,"; // can put note on diff page than ref
60
0
  if (fnote.m_flags&0x40) o << "dontBrk,"; // dont brk a footnote
61
0
  if (fnote.m_flags&0x80) o << "notePos=bottom,";
62
0
  if (fnote.m_flags&0xFF03)
63
0
    o << "fl=" << std::hex << (fnote.m_flags&0xFF03) << std::dec << ",";
64
0
  if (fnote.m_distToDocument != 5)
65
0
    o << "dist=" << fnote.m_distToDocument << "[bef],";
66
0
  if (fnote.m_distSeparator != 36)
67
0
    o << "dist=" << fnote.m_distSeparator << "[between],";
68
0
  if (fnote.m_separatorLength != 108)
69
0
    o << "w[sep]=" << fnote.m_separatorLength << "pt";
70
0
  if (fnote.m_unknown) o << "unkn=" << fnote.m_unknown << ",";
71
0
  return o;
72
0
}
73
74
////////////////////////////////////////////////////////////
75
// read a recursive zone
76
////////////////////////////////////////////////////////////
77
bool RecursifData::read(NisusWrtParser &parser, MWAWEntry const &entry)
78
68.7k
{
79
68.7k
  if (!m_info || m_info->m_zoneType >= 3) {
80
0
    MWAW_DEBUG_MSG(("NisusWrtStruct::RecursifData::Read: find unexpected zoneType\n"));
81
0
    return false;
82
0
  }
83
68.7k
  if (m_level < 0 || m_level >= 3) {
84
0
    MWAW_DEBUG_MSG(("NisusWrtStruct::RecursifData::Read: find unexpected level: %d\n", m_level));
85
0
    return false;
86
0
  }
87
68.7k
  if (entry.length() < 12) {
88
7.82k
    MWAW_DEBUG_MSG(("NisusWrtStruct::RecursifData::Read: the entry is bad\n"));
89
7.82k
    return false;
90
7.82k
  }
91
92
60.9k
  auto zoneId = int(m_info->m_zoneType);
93
60.9k
  entry.setParsed(true);
94
60.9k
  MWAWInputStreamPtr input = parser.rsrcInput();
95
60.9k
  libmwaw::DebugFile &asciiFile = parser.rsrcAscii();
96
60.9k
  long pos = entry.begin();
97
60.9k
  input->seek(pos, librevenge::RVNG_SEEK_SET);
98
99
60.9k
  libmwaw::DebugStream f;
100
60.9k
  if (m_level == 0) {
101
15.5k
    f << "Entries(" << entry.name() << "):";
102
15.5k
    asciiFile.addPos(pos);
103
15.5k
    asciiFile.addNote(f.str().c_str());
104
15.5k
  }
105
60.9k
  int num = 0;
106
358k
  while (input->tell() != entry.end()) {
107
309k
    pos = input->tell();
108
309k
    bool ok = true;
109
309k
    if (pos+12 > entry.end()) {
110
92
      MWAW_DEBUG_MSG(("NisusWrtStruct::RecursifData::Read: can not read entry %d\n", num-1));
111
92
      ok = false;
112
92
    }
113
309k
    auto level = static_cast<int>(input->readLong(2));
114
309k
    if (level != m_level && level != m_level+1) {
115
6.80k
      MWAW_DEBUG_MSG(("NisusWrtStruct::RecursifData::Read: find unexpected level for entry %d\n", num-1));
116
6.80k
      ok = false;
117
6.80k
    }
118
309k
    f.str("");
119
309k
    f << entry.name() << level << "-" << num++;
120
309k
    if (zoneId) f << "[" << zoneId << "]";
121
309k
    f << ":";
122
309k
    if (!ok) {
123
6.84k
      f << "###";
124
6.84k
      asciiFile.addPos(pos);
125
6.84k
      asciiFile.addNote(f.str().c_str());
126
6.84k
      return false;
127
6.84k
    }
128
302k
    auto val = static_cast<int>(input->readLong(2));
129
302k
    f << "unkn=" << val << ","; // always x10 for level<=2 and c for level==3 ?
130
302k
    long sz = input->readLong(4);
131
302k
    long totalSz = sz;
132
302k
    long minSize = 16;
133
302k
    if (level == 3) {
134
252k
      totalSz += 13;
135
252k
      if (totalSz%2) totalSz++;
136
252k
      minSize = 14;
137
252k
    }
138
302k
    long endPos = pos+totalSz;
139
302k
    if (totalSz < minSize || endPos > entry.end()) {
140
4.75k
      MWAW_DEBUG_MSG(("NisusWrtStruct::RecursifData::Read: can not read entry %d\n", num-1));
141
4.75k
      f << "###";
142
4.75k
      asciiFile.addPos(pos);
143
4.75k
      asciiFile.addNote(f.str().c_str());
144
4.75k
      return false;
145
4.75k
    }
146
147
297k
    auto type = static_cast<int>(input->readLong(4));
148
297k
    if ((level == 1 && type == 0x7FFFFEDF) ||
149
289k
        (level == 2 && type == 0x7FFFFFFF))
150
13.9k
      ;
151
284k
    else if ((type>>16)==0x7FFF)
152
4.50k
      f << "type=" << type-0x7FFFFFFF-1 << ",";
153
279k
    else
154
279k
      f << "type=" << type << ",";
155
156
297k
    if (level != 3) {
157
46.9k
      val = static_cast<int>(input->readULong(4));
158
46.9k
      if ((level==1 && val==0x10) || (level==2 && val == 1))
159
42.4k
        ;
160
4.45k
      else
161
4.45k
        f << "wh=" << val << ",";
162
46.9k
    }
163
297k
    asciiFile.addPos(pos);
164
297k
    asciiFile.addNote(f.str().c_str());
165
166
297k
    Node child;
167
297k
    child.m_type = type;
168
297k
    child.m_entry = entry;
169
297k
    child.m_entry.setBegin(input->tell());
170
297k
    child.m_entry.setEnd(endPos);
171
172
297k
    if (level == 3) {
173
251k
      child.m_entry.setLength(sz);
174
251k
      m_childList.push_back(child);
175
251k
      input->seek(endPos, librevenge::RVNG_SEEK_SET);
176
251k
      continue;
177
251k
    }
178
179
46.9k
    if (child.m_entry.length()==0) {
180
9
      if (level != 1) {
181
9
        MWAW_DEBUG_MSG(("NisusWrtStruct::RecursifData::Read: Oops find 0 length child\n"));
182
9
        asciiFile.addPos(pos);
183
9
        asciiFile.addNote("###");
184
9
      }
185
9
      continue;
186
9
    }
187
188
46.9k
    std::shared_ptr<RecursifData> childData(new RecursifData(*this));
189
46.9k
    childData->m_level = level;
190
46.9k
    child.m_data = childData;
191
192
46.9k
    if (!childData->read(parser, child.m_entry)) {
193
6.28k
      MWAW_DEBUG_MSG(("NisusWrtStruct::RecursifData::Read: can not read child entry\n"));
194
6.28k
      asciiFile.addPos(pos);
195
6.28k
      asciiFile.addNote("###");
196
6.28k
    }
197
40.6k
    else
198
40.6k
      m_childList.push_back(child);
199
200
46.9k
    input->seek(endPos, librevenge::RVNG_SEEK_SET);
201
46.9k
  }
202
49.3k
  return true;
203
60.9k
}
204
205
}
206
// vim: set filetype=cpp tabstop=2 shiftwidth=2 cindent autoindent smartindent noexpandtab: