/* -*- Mode: C++; c-default-style: "k&r"; indent-tabs-mode: nil; tab-width: 2; c-basic-offset: 2 -*- */
/* libmwaw
* Version: MPL 2.0 / LGPLv2+
*
* The contents of this file are subject to the Mozilla Public License Version
* 2.0 (the "License"); you may not use this file except in compliance with
* the License or as specified alternatively below. You may obtain a copy of
* the License at http://www.mozilla.org/MPL/
*
* Software distributed under the License is distributed on an "AS IS" basis,
* WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
* for the specific language governing rights and limitations under the
* License.
*
* Major Contributor(s):
* Copyright (C) 2002 William Lachance (wrlach@gmail.com)
* Copyright (C) 2002,2004 Marc Maurer (uwog@uwog.net)
* Copyright (C) 2004-2006 Fridrich Strba (fridrich.strba@bluewin.ch)
* Copyright (C) 2006, 2007 Andrew Ziem
* Copyright (C) 2011, 2012 Alonso Laurent (alonso@loria.fr)
*
*
* All Rights Reserved.
*
* For minor contributions see the git repository.
*
* Alternatively, the contents of this file may be used under the terms of
* the GNU Lesser General Public License Version 2 or later (the "LGPLv2+"),
* in which case the provisions of the LGPLv2+ are applicable
* instead of those above.
*/
#include "MWAWDebug.hxx"
#include "MWAWInputStream.hxx"
#include "NisusWrtParser.hxx"
#include "NisusWrtStruct.hxx"
namespace NisusWrtStruct
{
std::ostream &operator<< (std::ostream &o, Position const &pos)
{
o << pos.m_paragraph << "x";
if (pos.m_word) o << pos.m_word << "x";
else o << "_x";
if (pos.m_char) o << pos.m_char;
else o << "_";
return o;
}
std::ostream &operator<< (std::ostream &o, FootnoteInfo const &fnote)
{
if (fnote.m_flags&0x4) o << "sepPos=right,";
if (fnote.m_flags&0x8) o << "endNotes,"; // footnote|endnote
if (fnote.m_flags&0x10) o << "renumber[Pages],";
if (fnote.m_flags&0x20) o << "maySep,"; // can put note on diff page than ref
if (fnote.m_flags&0x40) o << "dontBrk,"; // dont brk a footnote
if (fnote.m_flags&0x80) o << "notePos=bottom,";
if (fnote.m_flags&0xFF03)
o << "fl=" << std::hex << (fnote.m_flags&0xFF03) << std::dec << ",";
if (fnote.m_distToDocument != 5)
o << "dist=" << fnote.m_distToDocument << "[bef],";
if (fnote.m_distSeparator != 36)
o << "dist=" << fnote.m_distSeparator << "[between],";
if (fnote.m_separatorLength != 108)
o << "w[sep]=" << fnote.m_separatorLength << "pt";
if (fnote.m_unknown) o << "unkn=" << fnote.m_unknown << ",";
return o;
}
////////////////////////////////////////////////////////////
// read a recursive zone
////////////////////////////////////////////////////////////
bool RecursifData::read(NisusWrtParser &parser, MWAWEntry const &entry)
{
if (!m_info || m_info->m_zoneType >= 3) {
MWAW_DEBUG_MSG(("NisusWrtStruct::RecursifData::Read: find unexpected zoneType\n"));
return false;
}
if (m_level < 0 || m_level >= 3) {
MWAW_DEBUG_MSG(("NisusWrtStruct::RecursifData::Read: find unexpected level: %d\n", m_level));
return false;
}
if (entry.length() < 12) {
MWAW_DEBUG_MSG(("NisusWrtStruct::RecursifData::Read: the entry is bad\n"));
return false;
}
auto zoneId = int(m_info->m_zoneType);
entry.setParsed(true);
MWAWInputStreamPtr input = parser.rsrcInput();
libmwaw::DebugFile &asciiFile = parser.rsrcAscii();
long pos = entry.begin();
input->seek(pos, librevenge::RVNG_SEEK_SET);
libmwaw::DebugStream f;
if (m_level == 0) {
f << "Entries(" << entry.name() << "):";
asciiFile.addPos(pos);
asciiFile.addNote(f.str().c_str());
}
int num = 0;
while (input->tell() != entry.end()) {
pos = input->tell();
bool ok = true;
if (pos+12 > entry.end()) {
MWAW_DEBUG_MSG(("NisusWrtStruct::RecursifData::Read: can not read entry %d\n", num-1));
ok = false;
}
auto level = static_cast<int>(input->readLong(2));
if (level != m_level && level != m_level+1) {
MWAW_DEBUG_MSG(("NisusWrtStruct::RecursifData::Read: find unexpected level for entry %d\n", num-1));
ok = false;
}
f.str("");
f << entry.name() << level << "-" << num++;
if (zoneId) f << "[" << zoneId << "]";
f << ":";
if (!ok) {
f << "###";
asciiFile.addPos(pos);
asciiFile.addNote(f.str().c_str());
return false;
}
auto val = static_cast<int>(input->readLong(2));
f << "unkn=" << val << ","; // always x10 for level<=2 and c for level==3 ?
long sz = input->readLong(4);
long totalSz = sz;
long minSize = 16;
if (level == 3) {
totalSz += 13;
if (totalSz%2) totalSz++;
minSize = 14;
}
long endPos = pos+totalSz;
if (totalSz < minSize || endPos > entry.end()) {
MWAW_DEBUG_MSG(("NisusWrtStruct::RecursifData::Read: can not read entry %d\n", num-1));
f << "###";
asciiFile.addPos(pos);
asciiFile.addNote(f.str().c_str());
return false;
}
auto type = static_cast<int>(input->readLong(4));
if ((level == 1 && type == 0x7FFFFEDF) ||
(level == 2 && type == 0x7FFFFFFF))
;
else if ((type>>16)==0x7FFF)
f << "type=" << type-0x7FFFFFFF-1 << ",";
else
f << "type=" << type << ",";
if (level != 3) {
val = static_cast<int>(input->readULong(4));
if ((level==1 && val==0x10) || (level==2 && val == 1))
;
else
f << "wh=" << val << ",";
}
asciiFile.addPos(pos);
asciiFile.addNote(f.str().c_str());
Node child;
child.m_type = type;
child.m_entry = entry;
child.m_entry.setBegin(input->tell());
child.m_entry.setEnd(endPos);
if (level == 3) {
child.m_entry.setLength(sz);
m_childList.push_back(child);
input->seek(endPos, librevenge::RVNG_SEEK_SET);
continue;
}
if (child.m_entry.length()==0) {
if (level != 1) {
MWAW_DEBUG_MSG(("NisusWrtStruct::RecursifData::Read: Oops find 0 length child\n"));
asciiFile.addPos(pos);
asciiFile.addNote("###");
}
continue;
}
std::shared_ptr<RecursifData> childData(new RecursifData(*this));
childData->m_level = level;
child.m_data = childData;
if (!childData->read(parser, child.m_entry)) {
MWAW_DEBUG_MSG(("NisusWrtStruct::RecursifData::Read: can not read child entry\n"));
asciiFile.addPos(pos);
asciiFile.addNote("###");
}
else
m_childList.push_back(child);
input->seek(endPos, librevenge::RVNG_SEEK_SET);
}
return true;
}
}
// vim: set filetype=cpp tabstop=2 shiftwidth=2 cindent autoindent smartindent noexpandtab: