/* -*- 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 <iomanip>
#include <iostream>
#include "RagTimeStruct.hxx"
namespace RagTimeStruct
{
bool ResourceList::read(MWAWInputStreamPtr input, MWAWEntry &entry)
{
long pos=entry.begin();
if (pos<=0 || !input->checkPosition(pos+2))
return false;
entry.setParsed(true);
input->seek(pos, librevenge::RVNG_SEEK_SET);
auto dSz=static_cast<int>(input->readULong(2));
m_headerPos=pos+2;
if (dSz==0)
return true;
m_endPos=pos+2+dSz;
m_headerSize=static_cast<int>(input->readULong(2));
m_dataSize=static_cast<int>(input->readULong(2));
m_dataNumber=static_cast<int>(input->readULong(2));
if (m_headerSize<0x20 || dSz<m_headerSize+long(m_dataNumber+1)*m_dataSize || !input->checkPosition(m_endPos))
return false;
libmwaw::DebugStream f;
int unkn[3];
for (auto &u : unkn) u=static_cast<int>(input->readLong(2));
bool printUnknown=true;
/* try to use the first value to retrieve the type of the zone */
switch (unkn[0]) {
case 0:
if (m_dataSize==6 && unkn[1]==2 && unkn[2]==4) {
m_type=gray;
printUnknown=false;
}
else if (entry.type()=="rsrcgray")
m_type=gray;
break;
case 6:
if (m_dataSize==10 && unkn[1]==4 && unkn[2]==0) {
m_type=SpTe;
printUnknown=false;
}
else if (entry.type()=="rsrcSpTe")
m_type=SpTe;
break;
case 8:
if (m_dataSize==12 && unkn[1]==4 && unkn[2]==0) {
m_type=SpVa;
printUnknown=false;
}
else if (entry.type()=="rsrcSpVa")
m_type=SpVa;
break;
case 16:
if (m_dataSize==20 && unkn[1]==4 && unkn[2]==0) {
m_type=SpBo;
printUnknown=false;
}
else if (entry.type()=="rsrcSpBo")
m_type=SpBo;
break;
case 22:
if (m_dataSize==26 && unkn[1]==4 && unkn[2]==0) {
m_type=BuGr;
printUnknown=false;
}
else if (entry.type()=="rsrcBuGr")
m_type=BuGr;
break;
case 4:
if (m_dataSize==8 && unkn[1]==4 && unkn[2]==0) {
m_type=SpCe;
printUnknown=false;
break;
}
if (m_dataSize==10 && unkn[1]==4 && unkn[2]==0) { // find also with unkn[1]==0
m_type=SpDE;
printUnknown=false;
break;
}
// (m_dataSize==6 && unkn[1]==4 && unkn[2]==2) can be BuSl, colr, res_
if (entry.type()=="rsrcSpCe")
m_type=SpCe;
else if (entry.type()=="rsrcSpDE")
m_type=SpDE;
else if (entry.type()=="rsrcBuSl")
m_type=BuSl;
else if (entry.type()=="rsrccolr")
m_type=colr;
else if (entry.type()=="rsrcres_")
m_type=res_;
break;
default:
break;
}
if (printUnknown) {
f << "unkn=[";
for (auto u : unkn) f << u << ",";
f << "],";
}
for (int i=0; i<9; ++i) { // g3=3|5|7,g4=-1|-2|9
auto val=static_cast<int>(input->readLong(2));
if (val) f << "g" << i << "=" << val << ",";
}
auto subN=static_cast<int>(input->readLong(2));
if (m_headerSize!=0x20+subN*6) {
MWAW_DEBUG_MSG(("RagTimeStruct::ResourceList::read: the number of sub data seems bad\n"));
f << "##subN=" << subN << ",";
subN=0;
}
for (int i=0; i<subN; ++i) {
f << "unkn" << i << "=[";
// first always 0, second d|17|21|35|49|67|71|85|a3, last increasing index
for (int j=0; j<3; ++j) {
auto val=static_cast<int>(input->readLong(2));
if (val) f << val << ",";
else f << "_,";
}
f << "],";
}
m_extra=f.str();
m_dataPos=pos+2+m_headerSize;
return true;
}
std::ostream &operator<<(std::ostream &o, ResourceList &zone)
{
o << "type=" << ResourceList::getName(zone.m_type) << ",";
if (zone.m_headerSize)
o << "sz[header]=" << zone.m_headerSize << ",";
if (zone.m_dataNumber)
o << "N[data]=" << zone.m_dataNumber << ",sz[data]=" << zone.m_dataSize << ",";
o << zone.m_extra;
return o;
}
}
// vim: set filetype=cpp tabstop=2 shiftwidth=2 cindent autoindent smartindent noexpandtab: