/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: |