You cannot select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
xBAK/cresourceindex.cpp

160 lines
3.5 KiB
C++

#include "cexception.h"
#include "cresourcearchive.h"
#include "cresourceindex.h"
cResourceIndex::cResourceIndex()
: m_resourceFilename("")
, m_numResources(0)
, m_resIdxMap()
, m_resIdxIterator(m_resIdxMap.begin())
{
}
cResourceIndex::~cResourceIndex()
{
m_resIdxMap.clear();
}
void cResourceIndex::load(const QString& filename)
{
try
{
cResourceFile rmf;
rmf.open(filename, false);
cFileBuffer rmfBuffer(rmf.size());
rmf.seek(0);
rmf.load(rmfBuffer);
rmf.close();
if((rmfBuffer.getUint32LE() != 1) || (rmfBuffer.getUint16LE() != 4))
throw cDataCorruption(__FILE__, __LINE__);
m_resourceFilename = QString::fromStdString(rmfBuffer.getString(RES_FILENAME_LEN));
m_numResources = rmfBuffer.getUint16LE();
cResourceFile res;
res.open(m_resourceFilename, false);
cFileBuffer resBuffer(RES_FILENAME_LEN + 4);
for(unsigned int i = 0; i < m_numResources; i++)
{
unsigned int hashkey = rmfBuffer.getUint32LE();
std::streamoff offset = rmfBuffer.getUint32LE();
res.seek(offset);
res.load(resBuffer);
std::string resIdxName = resBuffer.getString(RES_FILENAME_LEN);
cResourceIndexData resIdxData;
resIdxData.m_hashkey = hashkey;
resIdxData.m_offset = offset + RES_FILENAME_LEN + 4;
resIdxData.m_size = resBuffer.getUint32LE();
m_resIdxMap.insert(std::pair<const QString, cResourceIndexData>(QString::fromStdString(resIdxName), resIdxData));
}
res.close();
}
catch (cException &e)
{
e.print("ResourceIndex::Load");
throw;
}
}
void cResourceIndex::save(const QString& filename)
{
try
{
cFileBuffer rmfBuffer(4 + 2 + RES_FILENAME_LEN + 2 + m_numResources * (4 + 4));
rmfBuffer.putUint32LE(1);
rmfBuffer.putUint16LE(4);
rmfBuffer.putString(m_resourceFilename.toStdString(), RES_FILENAME_LEN);
rmfBuffer.putUint16LE(m_numResources);
cResourceFile res;
res.open(m_resourceFilename, false);
cFileBuffer resBuffer(RES_FILENAME_LEN + 4);
unsigned int offset = 0;
for(unsigned int i = 0; i < m_numResources; i++)
{
res.seek(offset);
res.load(resBuffer);
std::string resIdxName = resBuffer.getString(RES_FILENAME_LEN);
cResourceIndexData resIdxData;
find(QString::fromStdString(resIdxName), resIdxData);
rmfBuffer.putUint32LE(resIdxData.m_hashkey);
rmfBuffer.putUint32LE(offset);
offset += RES_FILENAME_LEN + 4 + resIdxData.m_size;
}
res.close();
cResourceFile rmf;
rmf.open(filename, true);
rmf.save(rmfBuffer);
rmf.close();
}
catch (cException &e)
{
e.print("ResourceIndex::Save");
throw;
}
}
QString cResourceIndex::getResourceFilename() const
{
return(m_resourceFilename);
}
unsigned int cResourceIndex::getNumResources() const
{
return(m_numResources);
}
bool cResourceIndex::find(const QString& name, cResourceIndexData &data)
{
std::map<const QString, cResourceIndexData>::iterator it = m_resIdxMap.find(name);
if(it != m_resIdxMap.end())
{
data = it->second;
return(true);
}
return(false);
}
bool cResourceIndex::getFirst(QString& name, cResourceIndexData &data)
{
m_resIdxIterator = m_resIdxMap.begin();
if(m_resIdxIterator != m_resIdxMap.end())
{
name = m_resIdxIterator->first;
data = m_resIdxIterator->second;
return(true);
}
return(false);
}
bool cResourceIndex::getNext(QString& name, cResourceIndexData &data)
{
if(m_resIdxIterator == m_resIdxMap.end())
return(false);
m_resIdxIterator++;
if(m_resIdxIterator != m_resIdxMap.end())
{
name = m_resIdxIterator->first;
data = m_resIdxIterator->second;
return(true);
}
return(false);
}