/src/libmwaw/src/lib/ZWrtParser.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 <iomanip> |
35 | | #include <iostream> |
36 | | #include <limits> |
37 | | #include <set> |
38 | | #include <sstream> |
39 | | |
40 | | #include <librevenge/librevenge.h> |
41 | | |
42 | | #include "MWAWTextListener.hxx" |
43 | | #include "MWAWFontConverter.hxx" |
44 | | #include "MWAWHeader.hxx" |
45 | | #include "MWAWPosition.hxx" |
46 | | #include "MWAWPrinter.hxx" |
47 | | #include "MWAWRSRCParser.hxx" |
48 | | #include "MWAWSubDocument.hxx" |
49 | | |
50 | | #include "ZWrtText.hxx" |
51 | | |
52 | | #include "ZWrtParser.hxx" |
53 | | |
54 | | /** Internal: the structures of a ZWrtParser */ |
55 | | namespace ZWrtParserInternal |
56 | | { |
57 | | //////////////////////////////////////// |
58 | | //! Internal: the state of a ZWrtParser |
59 | | struct State { |
60 | | //! constructor |
61 | | State() |
62 | 10.7k | : m_actPage(0) |
63 | 10.7k | , m_numPages(0) |
64 | 10.7k | , m_headerUsed(true) |
65 | 10.7k | , m_footerUsed(true) |
66 | 10.7k | , m_headerHeight(0) |
67 | 10.7k | , m_footerHeight(0) |
68 | 10.7k | { |
69 | 10.7k | } |
70 | | |
71 | | int m_actPage /** the actual page */, m_numPages /** the number of page of the final document */; |
72 | | |
73 | | //! true if the header is used |
74 | | bool m_headerUsed; |
75 | | //! true if the footer is used |
76 | | bool m_footerUsed; |
77 | | int m_headerHeight /** the header height if known */, |
78 | | m_footerHeight /** the footer height if known */; |
79 | | }; |
80 | | |
81 | | //////////////////////////////////////// |
82 | | //! Internal: the subdocument of a ZWrtParser |
83 | | class SubDocument final : public MWAWSubDocument |
84 | | { |
85 | | public: |
86 | | SubDocument(ZWrtParser &pars, MWAWInputStreamPtr const &input, bool header) |
87 | 1.81k | : MWAWSubDocument(&pars, input, MWAWEntry()) |
88 | 1.81k | , m_isHeader(header) |
89 | 1.81k | { |
90 | 1.81k | } |
91 | | |
92 | | //! destructor |
93 | 0 | ~SubDocument() final {} |
94 | | |
95 | | //! operator!= |
96 | | bool operator!=(MWAWSubDocument const &doc) const final |
97 | 0 | { |
98 | 0 | if (MWAWSubDocument::operator!=(doc)) return true; |
99 | 0 | auto const *sDoc = dynamic_cast<SubDocument const *>(&doc); |
100 | 0 | if (!sDoc) return true; |
101 | 0 | if (m_isHeader != sDoc->m_isHeader) return true; |
102 | 0 | return false; |
103 | 0 | } |
104 | | |
105 | | //! the parser function |
106 | | void parse(MWAWListenerPtr &listener, libmwaw::SubDocumentType type) final; |
107 | | |
108 | | protected: |
109 | | //! true if we need to send the parser |
110 | | int m_isHeader; |
111 | | }; |
112 | | |
113 | | void SubDocument::parse(MWAWListenerPtr &listener, libmwaw::SubDocumentType /*type*/) |
114 | 1.81k | { |
115 | 1.81k | if (!listener.get()) { |
116 | 0 | MWAW_DEBUG_MSG(("ZWrtParserInternal::SubDocument::parse: no listener\n")); |
117 | 0 | return; |
118 | 0 | } |
119 | 1.81k | auto *parser=dynamic_cast<ZWrtParser *>(m_parser); |
120 | 1.81k | if (!parser) { |
121 | 0 | MWAW_DEBUG_MSG(("ZWrtParserInternal::SubDocument::parse: no parser\n")); |
122 | 0 | return; |
123 | 0 | } |
124 | | |
125 | 1.81k | parser->sendHeaderFooter(m_isHeader); |
126 | 1.81k | } |
127 | | } |
128 | | |
129 | | |
130 | | //////////////////////////////////////////////////////////// |
131 | | // constructor/destructor, ... |
132 | | //////////////////////////////////////////////////////////// |
133 | | ZWrtParser::ZWrtParser(MWAWInputStreamPtr const &input, MWAWRSRCParserPtr const &rsrcParser, MWAWHeader *header) |
134 | 4.36k | : MWAWTextParser(input, rsrcParser, header) |
135 | 4.36k | , m_state() |
136 | 4.36k | , m_textParser() |
137 | 4.36k | { |
138 | 4.36k | init(); |
139 | 4.36k | } |
140 | | |
141 | | ZWrtParser::~ZWrtParser() |
142 | 4.36k | { |
143 | 4.36k | } |
144 | | |
145 | | void ZWrtParser::init() |
146 | 4.36k | { |
147 | 4.36k | resetTextListener(); |
148 | 4.36k | setAsciiName("main-1"); |
149 | | |
150 | 4.36k | m_state.reset(new ZWrtParserInternal::State); |
151 | | |
152 | | // reduce the margin (in case, the page is not defined) |
153 | 4.36k | getPageSpan().setMargins(0.1); |
154 | | |
155 | 4.36k | m_textParser.reset(new ZWrtText(*this)); |
156 | 4.36k | } |
157 | | |
158 | | MWAWInputStreamPtr ZWrtParser::rsrcInput() |
159 | 43.1k | { |
160 | 43.1k | return getRSRCParser()->getInput(); |
161 | 43.1k | } |
162 | | |
163 | | libmwaw::DebugFile &ZWrtParser::rsrcAscii() |
164 | 22.6k | { |
165 | 22.6k | return getRSRCParser()->ascii(); |
166 | 22.6k | } |
167 | | |
168 | | //////////////////////////////////////////////////////////// |
169 | | // position and height |
170 | | //////////////////////////////////////////////////////////// |
171 | | MWAWVec2f ZWrtParser::getPageLeftTop() const |
172 | 0 | { |
173 | 0 | return MWAWVec2f(float(getPageSpan().getMarginLeft()), |
174 | 0 | float(getPageSpan().getMarginTop()+m_state->m_headerHeight/72.0)); |
175 | 0 | } |
176 | | |
177 | | //////////////////////////////////////////////////////////// |
178 | | // interface with the text parser |
179 | | //////////////////////////////////////////////////////////// |
180 | | bool ZWrtParser::sendHeaderFooter(bool header) |
181 | 1.81k | { |
182 | 1.81k | MWAWInputStreamPtr rsrc = rsrcInput(); |
183 | 1.81k | long rsrcPos = rsrc->tell(); |
184 | 1.81k | m_textParser->sendHeaderFooter(header); |
185 | 1.81k | rsrc->seek(rsrcPos, librevenge::RVNG_SEEK_SET); |
186 | 1.81k | return true; |
187 | 1.81k | } |
188 | | |
189 | | //////////////////////////////////////////////////////////// |
190 | | // new page |
191 | | //////////////////////////////////////////////////////////// |
192 | | void ZWrtParser::newPage(int number) |
193 | 3.70k | { |
194 | 3.70k | if (number <= m_state->m_actPage || number > m_state->m_numPages) |
195 | 0 | return; |
196 | | |
197 | 7.41k | while (m_state->m_actPage < number) { |
198 | 3.70k | m_state->m_actPage++; |
199 | 3.70k | if (!getTextListener() || m_state->m_actPage == 1) |
200 | 1.88k | continue; |
201 | 1.81k | getTextListener()->insertBreak(MWAWTextListener::PageBreak); |
202 | 1.81k | } |
203 | 3.70k | } |
204 | | |
205 | | //////////////////////////////////////////////////////////// |
206 | | // the parser |
207 | | //////////////////////////////////////////////////////////// |
208 | | void ZWrtParser::parse(librevenge::RVNGTextInterface *docInterface) |
209 | 2.00k | { |
210 | 2.00k | if (!getInput().get() || !getRSRCParser() || !checkHeader(nullptr)) throw(libmwaw::ParseException()); |
211 | 2.00k | bool ok = false; |
212 | 2.00k | try { |
213 | 2.00k | checkHeader(nullptr); |
214 | 2.00k | ok = createZones(); |
215 | 2.00k | if (ok) { |
216 | 2.00k | createDocument(docInterface); |
217 | 2.00k | m_textParser->sendMainText(); |
218 | | #ifdef DEBUG |
219 | | m_textParser->flushExtra(); |
220 | | #endif |
221 | 2.00k | } |
222 | 2.00k | } |
223 | 2.00k | catch (...) { |
224 | 0 | MWAW_DEBUG_MSG(("ZWrtParser::parse: exception catched when parsing\n")); |
225 | 0 | ok = false; |
226 | 0 | } |
227 | | |
228 | 2.00k | resetTextListener(); |
229 | 2.00k | if (!ok) throw(libmwaw::ParseException()); |
230 | 2.00k | } |
231 | | |
232 | | //////////////////////////////////////////////////////////// |
233 | | // create the document |
234 | | //////////////////////////////////////////////////////////// |
235 | | void ZWrtParser::createDocument(librevenge::RVNGTextInterface *documentInterface) |
236 | 2.00k | { |
237 | 2.00k | if (!documentInterface) return; |
238 | 2.00k | if (getTextListener()) { |
239 | 0 | MWAW_DEBUG_MSG(("ZWrtParser::createDocument: listener already exist\n")); |
240 | 0 | return; |
241 | 0 | } |
242 | | |
243 | | // update the page |
244 | 2.00k | m_state->m_actPage = 0; |
245 | | |
246 | | // create the page list |
247 | 2.00k | int numPages = 1; |
248 | 2.00k | if (m_textParser->numPages() > numPages) |
249 | 1.70k | numPages = m_textParser->numPages(); |
250 | 2.00k | m_state->m_numPages = numPages; |
251 | | |
252 | 2.00k | MWAWPageSpan ps(getPageSpan()); |
253 | 2.00k | if (m_state->m_headerUsed && m_textParser->hasHeaderFooter(true)) { |
254 | 1.34k | MWAWHeaderFooter header(MWAWHeaderFooter::HEADER, MWAWHeaderFooter::ALL); |
255 | 1.34k | header.m_subDocument.reset(new ZWrtParserInternal::SubDocument(*this, getInput(), true)); |
256 | 1.34k | ps.setHeaderFooter(header); |
257 | 1.34k | } |
258 | 2.00k | if (m_state->m_footerUsed && m_textParser->hasHeaderFooter(false)) { |
259 | 472 | MWAWHeaderFooter footer(MWAWHeaderFooter::FOOTER, MWAWHeaderFooter::ALL); |
260 | 472 | footer.m_subDocument.reset(new ZWrtParserInternal::SubDocument(*this, getInput(), false)); |
261 | 472 | ps.setHeaderFooter(footer); |
262 | 472 | } |
263 | 2.00k | ps.setPageSpan(m_state->m_numPages+1); |
264 | 2.00k | std::vector<MWAWPageSpan> pageList(1,ps); |
265 | 2.00k | MWAWTextListenerPtr listen(new MWAWTextListener(*getParserState(), pageList, documentInterface)); |
266 | 2.00k | setTextListener(listen); |
267 | 2.00k | listen->startDocument(); |
268 | 2.00k | } |
269 | | |
270 | | |
271 | | //////////////////////////////////////////////////////////// |
272 | | // |
273 | | // Intermediate level |
274 | | // |
275 | | //////////////////////////////////////////////////////////// |
276 | | bool ZWrtParser::createZones() |
277 | 2.00k | { |
278 | 2.00k | MWAWRSRCParserPtr rsrcParser = getRSRCParser(); |
279 | 2.00k | if (!rsrcParser) { |
280 | 0 | MWAW_DEBUG_MSG(("ZWrtParser::createZones: can not find the entry map\n")); |
281 | 0 | return false; |
282 | 0 | } |
283 | 2.00k | auto const &entryMap = rsrcParser->getEntriesMap(); |
284 | | |
285 | | // the 128 zones |
286 | 2.00k | char const *zNames[] = {"BBAR", "HTML", "PRIN", "RANG", "WPOS", "PGPT"}; |
287 | 14.0k | for (int z = 0; z < 6; z++) { |
288 | 12.0k | auto it = entryMap.lower_bound(zNames[z]); |
289 | 22.4k | while (it != entryMap.end()) { |
290 | 22.2k | if (it->first != zNames[z]) |
291 | 11.7k | break; |
292 | 10.4k | MWAWEntry const &entry = it++->second; |
293 | 10.4k | bool done=true; |
294 | 10.4k | switch (z) { |
295 | 1.86k | case 0: |
296 | 1.86k | done=readBarState(entry); |
297 | 1.86k | break; |
298 | 1.54k | case 1: |
299 | 1.54k | done=readHTMLPref(entry); |
300 | 1.54k | break; |
301 | 1.58k | case 2: |
302 | 1.58k | done=readPrintInfo(entry); |
303 | 1.58k | break; |
304 | 2.00k | case 3: |
305 | 2.00k | done=readSectionRange(entry); |
306 | 2.00k | break; |
307 | 1.87k | case 4: |
308 | 1.87k | done=readWindowPos(entry); |
309 | 1.87k | break; |
310 | 1.54k | case 5: |
311 | 1.54k | done=readCPRT(entry); |
312 | 1.54k | break; |
313 | 0 | default: |
314 | 0 | done=false; |
315 | 0 | break; |
316 | 10.4k | } |
317 | 10.4k | if (done || !entry.valid()) continue; |
318 | 32 | readUnknownZone(entry); |
319 | 32 | } |
320 | 12.0k | } |
321 | | |
322 | | // 1001 and following |
323 | 2.00k | char const *sNames[] = {"CPOS", "SLEN"}; |
324 | 6.01k | for (int z = 0; z < 2; z++) { |
325 | 4.01k | auto it = entryMap.lower_bound(sNames[z]); |
326 | 7.69k | while (it != entryMap.end()) { |
327 | 7.59k | if (it->first != sNames[z]) |
328 | 3.91k | break; |
329 | 3.68k | MWAWEntry const &entry = it++->second; |
330 | 3.68k | bool done=true; |
331 | 3.68k | switch (z) { |
332 | 1.82k | case 0: |
333 | 1.82k | done=readCPos(entry); |
334 | 1.82k | break; |
335 | 1.85k | case 1: |
336 | 1.85k | done=readSLen(entry); |
337 | 1.85k | break; |
338 | 0 | default: |
339 | 0 | done = false; |
340 | 3.68k | } |
341 | 3.68k | if (done || !entry.valid()) continue; |
342 | 0 | readUnknownZone(entry); |
343 | 0 | } |
344 | 4.01k | } |
345 | 2.00k | if (!m_textParser->createZones()) |
346 | 0 | return false; |
347 | 2.00k | return true; |
348 | 2.00k | } |
349 | | |
350 | | //////////////////////////////////////////////////////////// |
351 | | // read the print info |
352 | | //////////////////////////////////////////////////////////// |
353 | | bool ZWrtParser::readPrintInfo(MWAWEntry const &entry) |
354 | 1.58k | { |
355 | 1.58k | if (!entry.valid()) { |
356 | 193 | MWAW_DEBUG_MSG(("ZWrtParser::readPrintInfo: the entry is bad\n")); |
357 | 193 | return false; |
358 | 193 | } |
359 | | |
360 | 1.39k | if (entry.id()!=128) { |
361 | 75 | MWAW_DEBUG_MSG(("ZWrtParser::readPrintInfo: the entry id is odd\n")); |
362 | 75 | } |
363 | 1.39k | long pos = entry.begin(); |
364 | 1.39k | MWAWInputStreamPtr input = rsrcInput(); |
365 | 1.39k | libmwaw::DebugFile &ascFile = rsrcAscii(); |
366 | 1.39k | libmwaw::DebugStream f; |
367 | 1.39k | f << "Entries(" << entry.type() << ")[" << entry << "]:"; |
368 | 1.39k | entry.setParsed(true); |
369 | | |
370 | 1.39k | std::vector<ZWField> fields; |
371 | 1.39k | if (!getFieldList(entry, fields)) { |
372 | 0 | MWAW_DEBUG_MSG(("ZWrtParser::readPrintInfo: can not get fields list\n")); |
373 | 0 | f << "###"; |
374 | 0 | ascFile.addPos(pos-4); |
375 | 0 | ascFile.addNote(f.str().c_str()); |
376 | 0 | return false; |
377 | 0 | } |
378 | | |
379 | 1.39k | size_t numFields = fields.size(); |
380 | 1.39k | if (numFields < 6) { |
381 | 117 | MWAW_DEBUG_MSG(("ZWrtParser::readPrintInfo: the fields list seems very short\n")); |
382 | 117 | } |
383 | 1.39k | bool boolVal; |
384 | 1.39k | float floatVal; |
385 | 1.39k | int intVal; |
386 | 1.39k | std::string strVal; |
387 | 1.39k | int margins[4]= {0,0,0,0}; |
388 | 1.39k | bool marginsOk=true; |
389 | 91.6k | for (size_t ff = 0; ff < numFields; ff++) { |
390 | 90.2k | ZWField const &field = fields[ff]; |
391 | 90.2k | bool done = false; |
392 | 90.2k | switch (ff) { |
393 | 1.39k | case 0: // T |
394 | 2.70k | case 1: // B |
395 | 4.00k | case 2: // L |
396 | 5.30k | case 3: // R |
397 | 5.30k | done = field.getInt(input, intVal); |
398 | 5.30k | if (!done) { |
399 | 452 | marginsOk = false; |
400 | 452 | break; |
401 | 452 | } |
402 | 4.85k | margins[ff]=intVal; |
403 | 4.85k | break; |
404 | 1.29k | case 4: // 2,-2,-4 |
405 | 1.29k | done = field.getInt(input, intVal); |
406 | 1.29k | if (!done||!intVal) |
407 | 1.20k | break; |
408 | 82 | f << "autoResize=" << intVal << ","; |
409 | 82 | break; |
410 | 1.27k | case 5: //1.2 |
411 | 1.27k | done = field.getFloat(input, floatVal); |
412 | 1.27k | if (!done) |
413 | 124 | break; |
414 | 1.15k | f << "lineSpacing=" << floatVal << ","; |
415 | 1.15k | break; |
416 | 1.23k | case 6: |
417 | 2.47k | case 7: // always set |
418 | 3.67k | case 8: // always set |
419 | 3.67k | done = field.getBool(input, boolVal); |
420 | 3.67k | if (!done) |
421 | 448 | break; |
422 | 3.22k | if (!boolVal) |
423 | 157 | continue; |
424 | 3.06k | switch (ff) { // checkme: does not seems to works in all case... |
425 | 1.12k | case 6: |
426 | 1.12k | f << "sectionAddNewPage,"; |
427 | 1.12k | break; |
428 | 1.11k | case 7: |
429 | 1.11k | f << "useHeader,"; |
430 | 1.11k | break; |
431 | 830 | case 8: |
432 | 830 | f << "useFooter,"; |
433 | 830 | break; |
434 | 0 | default: |
435 | 0 | f << "#f" << ff << "Set,"; |
436 | 0 | break; |
437 | 3.06k | } |
438 | 3.06k | break; |
439 | 78.7k | default: |
440 | 78.7k | break; |
441 | 90.2k | } |
442 | 90.0k | if (done) |
443 | 10.2k | continue; |
444 | 79.8k | if (fields[ff].getDebugString(input, strVal)) |
445 | 79.8k | f << "#f" << ff << "=\"" << strVal << "\","; |
446 | 0 | else |
447 | 0 | f << "#f" << ff << ","; |
448 | 79.8k | } |
449 | 1.39k | if (marginsOk) { |
450 | 1.16k | getPageSpan().setMarginTop(double(margins[0])/72.0); |
451 | 1.16k | getPageSpan().setMarginBottom(double(margins[1])/72.0); |
452 | 1.16k | getPageSpan().setMarginLeft(double(margins[2])/72.0); |
453 | 1.16k | getPageSpan().setMarginRight(double(margins[3])/72.0); |
454 | 1.16k | } |
455 | 1.39k | f << "margins=(" << margins[2] << "x" << margins[0] << "<->" << margins[3] << "x" << margins[1] << "),"; |
456 | 1.39k | ascFile.addPos(pos-4); |
457 | 1.39k | ascFile.addNote(f.str().c_str()); |
458 | 1.39k | return true; |
459 | 1.39k | } |
460 | | |
461 | | // read the print info xml data |
462 | | bool ZWrtParser::readCPRT(MWAWEntry const &entry) |
463 | 1.54k | { |
464 | 1.54k | if (entry.length() < 0x10) { |
465 | 377 | MWAW_DEBUG_MSG(("ZWrtParser::readCPRT: data seems to short\n")); |
466 | 377 | return false; |
467 | 377 | } |
468 | | |
469 | 1.17k | MWAWInputStreamPtr input = rsrcInput(); |
470 | 1.17k | long pos = entry.begin(); |
471 | 1.17k | input->seek(pos, librevenge::RVNG_SEEK_SET); |
472 | | #ifdef DEBUG_WITH_FILES |
473 | | libmwaw::DebugFile &ascFile = rsrcAscii(); |
474 | | librevenge::RVNGBinaryData file; |
475 | | input->readDataBlock(entry.length(), file); |
476 | | |
477 | | static int volatile cprtName = 0; |
478 | | libmwaw::DebugStream f; |
479 | | f << "CPRT" << ++cprtName << ".plist"; |
480 | | libmwaw::Debug::dumpFile(file, f.str().c_str()); |
481 | | |
482 | | ascFile.addPos(pos-4); |
483 | | ascFile.addNote(f.str().c_str()); |
484 | | ascFile.skipZone(entry.begin(),entry.end()-1); |
485 | | #endif |
486 | 1.17k | return true; |
487 | 1.54k | } |
488 | | |
489 | | //////////////////////////////////////////////////////////// |
490 | | // read the bar state/windows pos, ... |
491 | | //////////////////////////////////////////////////////////// |
492 | | bool ZWrtParser::readBarState(MWAWEntry const &entry) |
493 | 1.86k | { |
494 | 1.86k | if (!entry.valid()) { |
495 | 83 | MWAW_DEBUG_MSG(("ZWrtParser::readBarState: the entry is bad\n")); |
496 | 83 | return false; |
497 | 83 | } |
498 | | |
499 | 1.77k | if (entry.id()!=128) { |
500 | 133 | MWAW_DEBUG_MSG(("ZWrtParser::readBarState: the entry id is odd\n")); |
501 | 133 | } |
502 | 1.77k | long pos = entry.begin(); |
503 | 1.77k | MWAWInputStreamPtr input = rsrcInput(); |
504 | 1.77k | libmwaw::DebugFile &ascFile = rsrcAscii(); |
505 | 1.77k | libmwaw::DebugStream f; |
506 | 1.77k | f << "Entries(" << entry.type() << ")[" << entry << "]:"; |
507 | 1.77k | entry.setParsed(true); |
508 | | |
509 | 1.77k | std::vector<ZWField> fields; |
510 | 1.77k | if (!getFieldList(entry, fields) || !fields.size()) { |
511 | 0 | MWAW_DEBUG_MSG(("ZWrtParser::readBarState: can not get fields list\n")); |
512 | 0 | f << "###"; |
513 | 0 | ascFile.addPos(pos-4); |
514 | 0 | ascFile.addNote(f.str().c_str()); |
515 | 0 | return false; |
516 | 0 | } |
517 | 1.77k | std::string res(""); |
518 | 1.77k | if (fields[0].getString(input, res)) |
519 | 1.77k | f << "set=" << res << ","; |
520 | 0 | else |
521 | 0 | f << "#set,"; |
522 | 1.77k | size_t numFields = fields.size(); |
523 | 1.77k | if (numFields > 1) { |
524 | 608 | MWAW_DEBUG_MSG(("ZWrtParser::readBarState: find extra fields\n")); |
525 | 608 | } |
526 | 15.1k | for (size_t ff = 1; ff < numFields; ff++) { |
527 | 13.3k | if (fields[ff].getDebugString(input, res)) |
528 | 13.3k | f << "#f" << ff << "=\"" << res << "\","; |
529 | 0 | else |
530 | 0 | f << "#f" << ff << ","; |
531 | 13.3k | } |
532 | | |
533 | 1.77k | ascFile.addPos(pos-4); |
534 | 1.77k | ascFile.addNote(f.str().c_str()); |
535 | 1.77k | return true; |
536 | 1.77k | } |
537 | | |
538 | | bool ZWrtParser::readHTMLPref(MWAWEntry const &entry) |
539 | 1.54k | { |
540 | 1.54k | if (!entry.valid()) { |
541 | 218 | MWAW_DEBUG_MSG(("ZWrtParser::readHTMLPref: the entry is bad\n")); |
542 | 218 | return false; |
543 | 218 | } |
544 | | |
545 | 1.32k | if (entry.id()!=128) { |
546 | 208 | MWAW_DEBUG_MSG(("ZWrtParser::readHTMLPref: the entry id is odd\n")); |
547 | 208 | } |
548 | 1.32k | long pos = entry.begin(); |
549 | 1.32k | MWAWInputStreamPtr input = rsrcInput(); |
550 | 1.32k | libmwaw::DebugFile &ascFile = rsrcAscii(); |
551 | 1.32k | libmwaw::DebugStream f; |
552 | 1.32k | f << "Entries(" << entry.type() << ")[" << entry << "]:"; |
553 | 1.32k | entry.setParsed(true); |
554 | | |
555 | 1.32k | std::vector<ZWField> fields; |
556 | 1.32k | if (!getFieldList(entry, fields)) { |
557 | 0 | MWAW_DEBUG_MSG(("ZWrtParser::readHTMLPref: can not get fields list\n")); |
558 | 0 | f << "###"; |
559 | 0 | ascFile.addPos(pos-4); |
560 | 0 | ascFile.addNote(f.str().c_str()); |
561 | 0 | return false; |
562 | 0 | } |
563 | | |
564 | 1.32k | size_t numFields = fields.size(); |
565 | 1.32k | if (numFields < 4) { |
566 | 321 | MWAW_DEBUG_MSG(("ZWrtParser::readHTMLPref: the fields list seems very short\n")); |
567 | 321 | } |
568 | 1.32k | std::string strVal; |
569 | 1.32k | bool boolVal; |
570 | 44.8k | for (size_t ff = 0; ff < numFields; ff++) { |
571 | 43.5k | ZWField const &field = fields[ff]; |
572 | 43.5k | bool done = false; |
573 | 43.5k | switch (ff) { |
574 | 1.32k | case 0: |
575 | 2.51k | case 1: |
576 | 3.53k | case 2: // always true? |
577 | 4.53k | case 3: // true if name? |
578 | 4.53k | done = field.getBool(input, boolVal); |
579 | 4.53k | if (!done || !boolVal) |
580 | 2.77k | break; |
581 | 1.76k | f << "f" << ff << "Set,"; |
582 | 1.76k | break; |
583 | 985 | case 4: // find one time sidebar |
584 | 985 | done = field.getString(input, strVal); |
585 | 985 | if (!done||!strVal.length()) |
586 | 667 | break; |
587 | 318 | f << "name=" << strVal << ","; |
588 | 318 | break; |
589 | 38.0k | default: |
590 | 38.0k | break; |
591 | 43.5k | } |
592 | 43.5k | if (done) |
593 | 4.88k | continue; |
594 | 38.6k | if (fields[ff].getDebugString(input, strVal)) |
595 | 38.6k | f << "#f" << ff << "=\"" << strVal << "\","; |
596 | 0 | else |
597 | 0 | f << "#f" << ff << ","; |
598 | 38.6k | } |
599 | 1.32k | ascFile.addPos(pos-4); |
600 | 1.32k | ascFile.addNote(f.str().c_str()); |
601 | 1.32k | return true; |
602 | 1.32k | } |
603 | | |
604 | | bool ZWrtParser::readSectionRange(MWAWEntry const &entry) |
605 | 2.00k | { |
606 | 2.00k | long pos = entry.begin(); |
607 | 2.00k | if (pos <= 0) { |
608 | 0 | MWAW_DEBUG_MSG(("ZWrtParser::readSectionRange: the entry is bad\n")); |
609 | 0 | return false; |
610 | 0 | } |
611 | | |
612 | 2.00k | MWAWInputStreamPtr input = rsrcInput(); |
613 | 2.00k | libmwaw::DebugFile &ascFile = rsrcAscii(); |
614 | 2.00k | libmwaw::DebugStream f; |
615 | 2.00k | f << "Entries(" << entry.type() << ")[" << entry << "]:"; |
616 | 2.00k | entry.setParsed(true); |
617 | | |
618 | 2.00k | if (entry.length() <= 0) { |
619 | 1.45k | ascFile.addPos(pos-4); |
620 | 1.45k | ascFile.addNote(f.str().c_str()); |
621 | 1.45k | return true; |
622 | 1.45k | } |
623 | 548 | input->seek(pos, librevenge::RVNG_SEEK_SET); |
624 | 548 | pos -= 4; |
625 | 548 | std::string name(""); |
626 | 548 | int num=0; |
627 | 58.3k | while (!input->isEnd()) { |
628 | 58.3k | bool done=input->tell()>=entry.end(); |
629 | 58.3k | char c = done ? char(0xa) : char(input->readULong(1)); |
630 | 58.3k | if (c==0) { |
631 | 424 | MWAW_DEBUG_MSG(("ZWrtParser::readSectionRange: find a 0 char\n")); |
632 | 424 | name +="##[0]"; |
633 | 424 | continue; |
634 | 424 | } |
635 | 57.9k | if (c!=0xa) { |
636 | 55.8k | name += c; |
637 | 55.8k | continue; |
638 | 55.8k | } |
639 | | |
640 | 2.11k | f << name; |
641 | 2.11k | ascFile.addPos(pos); |
642 | 2.11k | ascFile.addNote(f.str().c_str()); |
643 | 2.11k | pos = input->tell(); |
644 | 2.11k | name = ""; |
645 | 2.11k | f.str(""); |
646 | 2.11k | f << entry.type() << "-" << ++num << ":"; |
647 | 2.11k | if (done) |
648 | 548 | break; |
649 | 2.11k | } |
650 | 548 | if (name.length()) { |
651 | 0 | f << name; |
652 | 0 | ascFile.addPos(pos); |
653 | 0 | ascFile.addNote(f.str().c_str()); |
654 | 0 | } |
655 | 548 | return true; |
656 | 2.00k | } |
657 | | |
658 | | bool ZWrtParser::readWindowPos(MWAWEntry const &entry) |
659 | 1.87k | { |
660 | 1.87k | if (!entry.valid()) { |
661 | 511 | MWAW_DEBUG_MSG(("ZWrtParser::readWindowPos: the entry is bad\n")); |
662 | 511 | return false; |
663 | 511 | } |
664 | | |
665 | 1.36k | if (entry.id()!=128) { |
666 | 157 | MWAW_DEBUG_MSG(("ZWrtParser::readWindowPos: the entry id is odd\n")); |
667 | 157 | } |
668 | 1.36k | long pos = entry.begin(); |
669 | 1.36k | MWAWInputStreamPtr input = rsrcInput(); |
670 | 1.36k | libmwaw::DebugFile &ascFile = rsrcAscii(); |
671 | 1.36k | libmwaw::DebugStream f; |
672 | 1.36k | f << "Entries(" << entry.type() << ")[" << entry << "]:"; |
673 | 1.36k | entry.setParsed(true); |
674 | | |
675 | 1.36k | std::vector<ZWField> fields; |
676 | 1.36k | if (!getFieldList(entry, fields)) { |
677 | 0 | MWAW_DEBUG_MSG(("ZWrtParser::readWindowPos: can not get fields list\n")); |
678 | 0 | f << "###"; |
679 | 0 | ascFile.addPos(pos-4); |
680 | 0 | ascFile.addNote(f.str().c_str()); |
681 | 0 | return false; |
682 | 0 | } |
683 | | |
684 | 1.36k | size_t numFields = fields.size(); |
685 | 1.36k | if (numFields < 6) { |
686 | 340 | MWAW_DEBUG_MSG(("ZWrtParser::readWindowPos: the fields list seems very short\n")); |
687 | 340 | } |
688 | 1.36k | std::string strVal; |
689 | 1.36k | int intVal; |
690 | 1.36k | int dim[4]= {0,0,0,0}; |
691 | 68.1k | for (size_t ff = 0; ff < numFields; ff++) { |
692 | 66.7k | ZWField const &field = fields[ff]; |
693 | 66.7k | bool done = false; |
694 | 66.7k | switch (ff) { |
695 | 1.36k | case 0: |
696 | 2.59k | case 1: |
697 | 3.81k | case 2: |
698 | 5.02k | case 3: |
699 | 5.02k | done = field.getInt(input, intVal); |
700 | 5.02k | if (!done) |
701 | 224 | break; |
702 | 4.80k | dim[ff]=intVal; |
703 | 4.80k | break; |
704 | 1.18k | case 4: // 137|139|144 |
705 | 2.21k | case 5: // 0|3|9|12 ( actual section ?) |
706 | 2.21k | done = field.getInt(input, intVal); |
707 | 2.21k | if (!done||!intVal) |
708 | 1.17k | break; |
709 | 1.04k | f << "f" << ff << "=" << intVal << ","; |
710 | 1.04k | break; |
711 | 59.5k | default: |
712 | 59.5k | break; |
713 | 66.7k | } |
714 | 66.7k | if (done) |
715 | 6.71k | continue; |
716 | 60.0k | if (fields[ff].getDebugString(input, strVal)) |
717 | 60.0k | f << "#f" << ff << "=\"" << strVal << "\","; |
718 | 0 | else |
719 | 0 | f << "#f" << ff << ","; |
720 | 60.0k | } |
721 | 1.36k | f << "pos=(" << dim[0] << "x" << dim[1] << "<->" << dim[2] << "x" << dim[3] << "),"; |
722 | 1.36k | ascFile.addPos(pos-4); |
723 | 1.36k | ascFile.addNote(f.str().c_str()); |
724 | 1.36k | return true; |
725 | 1.36k | } |
726 | | |
727 | | //////////////////////////////////////////////////////////// |
728 | | // read a section zone ... |
729 | | //////////////////////////////////////////////////////////// |
730 | | |
731 | | // read a cursor position in a section ? |
732 | | bool ZWrtParser::readCPos(MWAWEntry const &entry) |
733 | 1.82k | { |
734 | 1.82k | if (!entry.valid()) { |
735 | 149 | MWAW_DEBUG_MSG(("ZWrtParser::readCPos: the entry is bad\n")); |
736 | 149 | return false; |
737 | 149 | } |
738 | | |
739 | 1.67k | long pos = entry.begin(); |
740 | 1.67k | MWAWInputStreamPtr input = rsrcInput(); |
741 | 1.67k | libmwaw::DebugFile &ascFile = rsrcAscii(); |
742 | 1.67k | libmwaw::DebugStream f; |
743 | 1.67k | f << "Entries(" << entry.type() << ")[" << entry << "]:"; |
744 | 1.67k | entry.setParsed(true); |
745 | | |
746 | 1.67k | std::vector<ZWField> fields; |
747 | 1.67k | if (!getFieldList(entry, fields) || !fields.size()) { |
748 | 0 | MWAW_DEBUG_MSG(("ZWrtParser::readCPos: can not get fields list\n")); |
749 | 0 | f << "###"; |
750 | 0 | ascFile.addPos(pos-4); |
751 | 0 | ascFile.addNote(f.str().c_str()); |
752 | 0 | return false; |
753 | 0 | } |
754 | 1.67k | int intVal; |
755 | 1.67k | size_t ff=0; |
756 | 1.67k | if (fields[ff++].getInt(input, intVal)) { |
757 | 1.00k | if (intVal) |
758 | 993 | f << "cPos=" << intVal << ","; |
759 | 1.00k | } |
760 | 676 | else { |
761 | 676 | MWAW_DEBUG_MSG(("ZWrtParser::readCPos: can not read cursor pos\n")); |
762 | 676 | ff = 0; |
763 | 676 | } |
764 | 1.67k | size_t numFields = fields.size(); |
765 | 1.67k | if (numFields > 1) { |
766 | 264 | MWAW_DEBUG_MSG(("ZWrtParser::readCPos: find extra fields\n")); |
767 | 264 | } |
768 | 1.67k | std::string res; |
769 | 19.4k | for (; ff < numFields; ff++) { |
770 | 17.7k | if (fields[ff].getDebugString(input, res)) |
771 | 17.7k | f << "#f" << ff << "=\"" << res << "\","; |
772 | 0 | else |
773 | 0 | f << "#f" << ff << ","; |
774 | 17.7k | } |
775 | | |
776 | 1.67k | ascFile.addPos(pos-4); |
777 | 1.67k | ascFile.addNote(f.str().c_str()); |
778 | 1.67k | return true; |
779 | 1.67k | } |
780 | | |
781 | | // read a cursor position in a section ? |
782 | | bool ZWrtParser::readSLen(MWAWEntry const &entry) |
783 | 1.85k | { |
784 | 1.85k | if (!entry.valid()) { |
785 | 57 | MWAW_DEBUG_MSG(("ZWrtParser::readSLen: the entry is bad\n")); |
786 | 57 | return false; |
787 | 57 | } |
788 | | |
789 | 1.80k | long pos = entry.begin(); |
790 | 1.80k | MWAWInputStreamPtr input = rsrcInput(); |
791 | 1.80k | libmwaw::DebugFile &ascFile = rsrcAscii(); |
792 | 1.80k | libmwaw::DebugStream f; |
793 | 1.80k | f << "Entries(" << entry.type() << ")[" << entry << "]:"; |
794 | 1.80k | entry.setParsed(true); |
795 | | |
796 | 1.80k | std::vector<ZWField> fields; |
797 | 1.80k | if (!getFieldList(entry, fields) || !fields.size()) { |
798 | 0 | MWAW_DEBUG_MSG(("ZWrtParser::readSLen: can not get fields list\n")); |
799 | 0 | f << "###"; |
800 | 0 | ascFile.addPos(pos-4); |
801 | 0 | ascFile.addNote(f.str().c_str()); |
802 | 0 | return false; |
803 | 0 | } |
804 | 1.80k | int intVal; |
805 | 1.80k | size_t ff=0; |
806 | 1.80k | if (fields[ff++].getInt(input, intVal)) { |
807 | 1.17k | if (intVal) |
808 | 104 | f << "len?=" << intVal << ","; |
809 | 1.17k | } |
810 | 622 | else { |
811 | 622 | MWAW_DEBUG_MSG(("ZWrtParser::readSLen: can not read cursor pos\n")); |
812 | 622 | ff = 0; |
813 | 622 | } |
814 | 1.80k | size_t numFields = fields.size(); |
815 | 1.80k | if (numFields > 1) { |
816 | 617 | MWAW_DEBUG_MSG(("ZWrtParser::readSLen: find extra fields\n")); |
817 | 617 | } |
818 | 1.80k | std::string res; |
819 | 76.2k | for (; ff < numFields; ff++) { |
820 | 74.4k | if (fields[ff].getDebugString(input, res)) |
821 | 74.4k | f << "#f" << ff << "=\"" << res << "\","; |
822 | 0 | else |
823 | 0 | f << "#f" << ff << ","; |
824 | 74.4k | } |
825 | | |
826 | 1.80k | ascFile.addPos(pos-4); |
827 | 1.80k | ascFile.addNote(f.str().c_str()); |
828 | 1.80k | return true; |
829 | 1.80k | } |
830 | | |
831 | | //////////////////////////////////////////////////////////// |
832 | | // read a generic zone ... |
833 | | //////////////////////////////////////////////////////////// |
834 | | bool ZWrtParser::readUnknownZone(MWAWEntry const &entry) |
835 | 32 | { |
836 | 32 | if (entry.begin() <= 0) { |
837 | 0 | MWAW_DEBUG_MSG(("ZWrtParser::readUnknownZone: the entry is bad\n")); |
838 | 0 | return false; |
839 | 0 | } |
840 | | |
841 | 32 | MWAWInputStreamPtr input = rsrcInput(); |
842 | 32 | libmwaw::DebugFile &ascFile = rsrcAscii(); |
843 | 32 | long pos = entry.begin(); |
844 | | |
845 | 32 | libmwaw::DebugStream f; |
846 | 32 | f << "Entries(" << entry.type() << ")[" << entry << "]:"; |
847 | 32 | entry.setParsed(true); |
848 | | |
849 | 32 | std::vector<ZWField> fields; |
850 | 32 | if (!getFieldList(entry, fields)) { |
851 | 0 | MWAW_DEBUG_MSG(("ZWrtParser::readUnknownZone: can not get fields list\n")); |
852 | 0 | f << "###"; |
853 | 0 | ascFile.addPos(pos-4); |
854 | 0 | ascFile.addNote(f.str().c_str()); |
855 | 0 | return false; |
856 | 0 | } |
857 | 32 | std::string res(""); |
858 | 32 | size_t numFields = fields.size(); |
859 | 189 | for (size_t ff = 0; ff < numFields; ff++) { |
860 | 157 | if (fields[ff].getDebugString(input, res)) |
861 | 157 | f << "f" << ff << "=\"" << res << "\","; |
862 | 0 | else |
863 | 0 | f << "#f" << ff << ","; |
864 | 157 | } |
865 | | |
866 | 32 | ascFile.addPos(pos-4); |
867 | 32 | ascFile.addNote(f.str().c_str()); |
868 | 32 | return true; |
869 | 32 | } |
870 | | |
871 | | //////////////////////////////////////////////////////////// |
872 | | // |
873 | | // Low level |
874 | | // |
875 | | //////////////////////////////////////////////////////////// |
876 | | |
877 | | //////////////////////////////////////////////////////////// |
878 | | // read the header |
879 | | //////////////////////////////////////////////////////////// |
880 | | bool ZWrtParser::checkHeader(MWAWHeader *header, bool strict) |
881 | 6.37k | { |
882 | 6.37k | *m_state = ZWrtParserInternal::State(); |
883 | 6.37k | if (!getRSRCParser()) |
884 | 68 | return false; |
885 | | // check if the RANG section exists |
886 | 6.30k | MWAWEntry entry = getRSRCParser()->getEntry("RANG", 128); |
887 | 6.30k | if (entry.begin()<=0) { // length can be 0, so ... |
888 | 164 | MWAW_DEBUG_MSG(("ZWrtParser::checkHeader: can not find the RANG[128] resource\n")); |
889 | 164 | return false; |
890 | 164 | } |
891 | 6.13k | if (getInput()->hasDataFork() && getInput()->size()>0) { |
892 | 0 | MWAW_DEBUG_MSG(("ZWrtParser::checkHeader: find some data fork\n")); |
893 | 0 | if (strict) |
894 | 0 | return false; |
895 | 0 | } |
896 | 6.13k | if (header) |
897 | 2.12k | header->reset(MWAWDocument::MWAW_T_ZWRITE, 1); |
898 | | |
899 | 6.13k | return true; |
900 | 6.13k | } |
901 | | |
902 | | //////////////////////////////////////////////////////////// |
903 | | // read a list of field |
904 | | //////////////////////////////////////////////////////////// |
905 | | bool ZWrtParser::getFieldList(MWAWEntry const &entry, std::vector<ZWField> &list) |
906 | 13.7k | { |
907 | 13.7k | list.resize(0); |
908 | 13.7k | MWAWInputStreamPtr input = rsrcInput(); |
909 | 13.7k | long pos=entry.begin(); |
910 | 13.7k | input->seek(entry.begin(), librevenge::RVNG_SEEK_SET); |
911 | 6.18M | while (!input->isEnd()) { |
912 | 6.18M | long actPos=input->tell(); |
913 | 6.18M | long done = actPos>=entry.end(); |
914 | 6.18M | char c= done ? '\t' : char(input->readULong(1)); |
915 | 6.18M | if (c=='\t') { |
916 | 586k | ZWField field; |
917 | 586k | field.m_pos.setBegin(pos); |
918 | 586k | field.m_pos.setEnd(actPos); |
919 | 586k | pos = actPos+1; |
920 | 586k | list.push_back(field); |
921 | 586k | if (done) |
922 | 13.7k | return true; |
923 | 572k | continue; |
924 | 586k | } |
925 | 6.18M | } |
926 | 0 | return true; |
927 | 13.7k | } |
928 | | |
929 | | //////////////////////////////////////////////////////////// |
930 | | // field function |
931 | | //////////////////////////////////////////////////////////// |
932 | | bool ZWField::getString(MWAWInputStreamPtr &input, std::string &str) const |
933 | 60.2k | { |
934 | 60.2k | str=""; |
935 | 60.2k | if (!m_pos.valid()) |
936 | 1.81k | return true; |
937 | 58.4k | input->seek(m_pos.begin(), librevenge::RVNG_SEEK_SET); |
938 | 1.22M | while (!input->isEnd() && input->tell()!=m_pos.end()) { |
939 | 1.17M | auto c=char(input->readULong(1)); |
940 | 1.17M | if (c==0) { |
941 | 389k | MWAW_DEBUG_MSG(("ZWField::getString::readFieldString: find a zero entry\n")); |
942 | 389k | str += "##[0]"; |
943 | 389k | continue; |
944 | 389k | } |
945 | 781k | str += c; |
946 | 781k | } |
947 | 58.4k | return true; |
948 | 60.2k | } |
949 | | |
950 | | bool ZWField::getDebugString(MWAWInputStreamPtr &input, std::string &str) const |
951 | 534k | { |
952 | 534k | str=""; |
953 | 534k | if (!m_pos.valid()) |
954 | 313k | return true; |
955 | 220k | input->seek(m_pos.begin(), librevenge::RVNG_SEEK_SET); |
956 | 220k | std::stringstream ss; |
957 | 5.35M | while (!input->isEnd() && input->tell()!=m_pos.end()) { |
958 | 5.13M | auto c=char(input->readULong(1)); |
959 | 5.13M | if (static_cast<unsigned char>(c)<=0x1f && c!= 0x9) |
960 | 570k | ss << "##[" << std::hex << int(c) << std::dec << "]"; |
961 | 4.56M | else |
962 | 4.56M | ss << c; |
963 | 5.13M | } |
964 | 220k | str = ss.str(); |
965 | 220k | return true; |
966 | 534k | } |
967 | | |
968 | | bool ZWField::getBool(MWAWInputStreamPtr &input, bool &val) const |
969 | 22.4k | { |
970 | 22.4k | val = false; |
971 | 22.4k | if (m_pos.length()==0 && m_pos.begin()>0) |
972 | 573 | return true; |
973 | 21.8k | std::string str; |
974 | 21.8k | if (!getString(input,str) || str.length() != 1) { |
975 | 3.09k | MWAW_DEBUG_MSG(("ZWField::getBool: can not read field\n")); |
976 | 3.09k | return false; |
977 | 3.09k | } |
978 | 18.7k | if (str[0]=='T') |
979 | 6.31k | val = true; |
980 | 12.4k | else if (str[0]=='F') |
981 | 11.5k | val = false; |
982 | 920 | else { |
983 | 920 | MWAW_DEBUG_MSG(("ZWField::getBool: find unexpected char %x\n", static_cast<unsigned int>(str[0]))); |
984 | 920 | return false; |
985 | 920 | } |
986 | 17.8k | return true; |
987 | 18.7k | } |
988 | | |
989 | | bool ZWField::getInt(MWAWInputStreamPtr &input, int &val) const |
990 | 27.4k | { |
991 | 27.4k | val = 0; |
992 | 27.4k | std::string str; |
993 | 27.4k | if (!getString(input,str) || str.length() == 0) { |
994 | 180 | MWAW_DEBUG_MSG(("ZWField::getInt: can not read field\n")); |
995 | 180 | return false; |
996 | 180 | } |
997 | 27.2k | int sign = 1; |
998 | 27.2k | size_t numChar = str.length(); |
999 | 27.2k | size_t p = 0; |
1000 | 27.2k | if (str[0]=='-') { |
1001 | 535 | sign = -1; |
1002 | 535 | p++; |
1003 | 535 | } |
1004 | 74.0k | while (p < numChar) { |
1005 | 51.2k | char c = str[p++]; |
1006 | 51.2k | if (c>='0' && c <= '9') { |
1007 | 46.8k | val = 10*val+(c-'0'); |
1008 | 46.8k | continue; |
1009 | 46.8k | } |
1010 | 4.47k | MWAW_DEBUG_MSG(("ZWField::getInt: find unexpected char %x\n", static_cast<unsigned int>(c))); |
1011 | 4.47k | val *= sign; |
1012 | 4.47k | return false; |
1013 | 51.2k | } |
1014 | 22.7k | val *= sign; |
1015 | 22.7k | return true; |
1016 | 27.2k | } |
1017 | | |
1018 | | bool ZWField::getFloat(MWAWInputStreamPtr &input, float &val) const |
1019 | 1.27k | { |
1020 | 1.27k | val = 0; |
1021 | 1.27k | std::string str; |
1022 | 1.27k | if (!getString(input,str) || str.length() == 0) { |
1023 | 12 | MWAW_DEBUG_MSG(("ZWField::getFloat: can not read field\n")); |
1024 | 12 | return false; |
1025 | 12 | } |
1026 | 1.26k | std::stringstream ss; |
1027 | 1.26k | ss << str; |
1028 | 1.26k | ss >> val; |
1029 | 1.26k | return !(!ss); |
1030 | 1.27k | } |
1031 | | |
1032 | | bool ZWField::getIntList(MWAWInputStreamPtr &input, std::vector<int> &list) const |
1033 | 2.84k | { |
1034 | 2.84k | list.resize(0); |
1035 | 2.84k | std::string str; |
1036 | 2.84k | if (!getString(input,str) || str.length() == 0) { |
1037 | 1 | MWAW_DEBUG_MSG(("ZWField::getIntList: can not read field\n")); |
1038 | 1 | return false; |
1039 | 1 | } |
1040 | 2.84k | int sign = 1, val=0; |
1041 | 2.84k | size_t numChar = str.length(); |
1042 | 2.84k | size_t p = 0; |
1043 | 20.9k | while (p <= numChar) { |
1044 | 20.9k | if (p==numChar) { |
1045 | 2.35k | list.push_back(sign *val); |
1046 | 2.35k | break; |
1047 | 2.35k | } |
1048 | 18.5k | char c = str[p++]; |
1049 | 18.5k | if (c==',') { |
1050 | 4.80k | list.push_back(sign *val); |
1051 | 4.80k | val = 0; |
1052 | 4.80k | sign = 1; |
1053 | 4.80k | continue; |
1054 | 4.80k | } |
1055 | 13.7k | if (c=='-') { |
1056 | 100 | if (val != 0 || sign != 1) { |
1057 | 59 | MWAW_DEBUG_MSG(("ZWField::getIntList: find a int inside a word\n")); |
1058 | 59 | return list.size(); |
1059 | 59 | } |
1060 | 41 | sign = -1; |
1061 | 41 | } |
1062 | 13.7k | if (c>='0' && c <= '9') { |
1063 | 13.2k | val = 10*val+(c-'0'); |
1064 | 13.2k | continue; |
1065 | 13.2k | } |
1066 | 431 | MWAW_DEBUG_MSG(("ZWField::getIntList: find unexpected char %x\n", static_cast<unsigned int>(c))); |
1067 | 431 | return list.size(); |
1068 | 13.7k | } |
1069 | 2.35k | return true; |
1070 | 2.84k | } |
1071 | | |
1072 | | // vim: set filetype=cpp tabstop=2 shiftwidth=2 cindent autoindent smartindent noexpandtab: |