History: OgreAndroidOgreADPArchive_cpp
Source of version: 2 (current)
Copy to clipboard
{CODE(wrap="1", colors="c++")}#include "OgreADPArchive.h"
#include <OgreStringConverter.h>
#include <OgreLogManager.h>
#include <android/log.h>
#define LOG_TAG "ADPArchive"
#define LOGI(...) __android_log_print(ANDROID_LOG_INFO,LOG_TAG,__VA_ARGS__)
#define LOGE(...) __android_log_print(ANDROID_LOG_ERROR,LOG_TAG,__VA_ARGS__)
namespace Ogre{
ADPArchive::ADPArchive(const String& name, const String& archType, ADPSource *source)
:Archive(name, archType), mBuffer(0), mBufferSize(0), mSource(source)
{
}
ADPArchive::~ADPArchive()
{
unload();
}
bool ADPArchive::isCaseSensitive() const
{
return true;
}
void ADPArchive::load()
{
Ogre::DataStreamPtr in;
std::ifstream *stream = 0;
if(mSource)
{
in = mSource->getPackage(mName);
if(in.isNull())
{
OGRE_EXCEPT(Exception::ERR_FILE_NOT_FOUND,
"Cannot open file: " + mName,
"ADPArchive::load");
}
}
else
{
stream = new std::ifstream(mName.c_str(), std::ios_base::in | std::ios_base::binary);
if(!stream->is_open())
{
delete stream;
OGRE_EXCEPT(Exception::ERR_FILE_NOT_FOUND,
"Cannot open file: " + mName,
"ADPArchive::load");
}
in = Ogre::DataStreamPtr(new FileStreamDataStream(stream));
}
// First are magic characters for the file type
char c1 = 0, c2 = 0, c3 = 0;
in->read(&c1, 1);
in->read(&c2, 1);
in->read(&c3, 1);
if(c1 == 'a' && c2 == 'd' && c3 == 'p')
{
int version = 0;
in->read(&version, sizeof(int));
int numFiles = 0;
in->read(&numFiles, sizeof(int));
Ogre::LogManager::getSingleton().logMessage("Num files: " + Ogre::StringConverter::toString(numFiles));
char *name = 0;
int nameBufSize = 0;
size_t totalSize = 0;
for(int i = 0; i < numFiles; ++i)
{
ADPEntry entry;
// Read in each entry
int nameLen = 0;
in->read(&nameLen, sizeof(int));
// Reallocate buffer for larger names
if(nameLen > nameBufSize)
{
if(name)
OGRE_FREE(name, Ogre::MEMCATEGORY_GENERAL);
name = (char*)OGRE_MALLOC(nameLen, Ogre::MEMCATEGORY_GENERAL);
nameBufSize = nameLen;
}
in->read(name, nameLen);
unsigned int offset = 0;
in->read(&offset, sizeof(unsigned int));
unsigned int size = 0;
in->read(&size, sizeof(unsigned int));
entry.name = String(name, nameLen);
entry.offset = offset;
entry.length = size;
mEntries.push_back(entry);
totalSize += size;
}
if(name)
OGRE_FREE(name, Ogre::MEMCATEGORY_GENERAL);
// Read in the rest of the buffer
mBuffer = (Ogre::uint8*)OGRE_MALLOC(totalSize, Ogre::MEMCATEGORY_GENERAL);
in->read(mBuffer, totalSize);
mBufferSize = totalSize;
}
else
{
OGRE_EXCEPT(Exception::ERR_FILE_NOT_FOUND,
"Unsupported ADP archive format: " + mName,
"ADPArchive::load");
}
if(stream)
delete stream;
}
void ADPArchive::unload()
{
mEntries.clear();
if(mBuffer)
OGRE_FREE(mBuffer, Ogre::MEMCATEGORY_GENERAL);
mBuffer = 0;
mBufferSize = 0;
}
DataStreamPtr ADPArchive::open(const Ogre::String &filename, bool readOnly) const
{
DataStreamPtr stream;
for(Ogre::list<ADPEntry>::type::const_iterator i = mEntries.begin(); i != mEntries.end(); ++i)
{
if(i->name == filename)
{
Ogre::uint8 *buffer = mBuffer + i->offset;
stream = DataStreamPtr(new Ogre::MemoryDataStream(buffer, i->length, false, readOnly));
}
}
return stream;
}
DataStreamPtr ADPArchive::create(const Ogre::String &filename) const
{
return DataStreamPtr();
}
void ADPArchive::remove(const String &filename) const
{
}
StringVectorPtr ADPArchive::list(bool recursive, bool dirs)
{
StringVectorPtr files(new StringVector);
for(Ogre::list<ADPEntry>::type::iterator i = mEntries.begin(); i != mEntries.end(); ++i)
{
files->push_back(i->name);
}
return files;
}
FileInfoListPtr ADPArchive::listFileInfo(bool recursive, bool dirs)
{
FileInfoListPtr files(new FileInfoList);
for(Ogre::list<ADPEntry>::type::iterator i = mEntries.begin(); i != mEntries.end(); ++i)
{
FileInfo info;
info.archive = this;
info.basename = info.filename = info.path = i->name;
info.compressedSize = info.uncompressedSize = i->length;
files->push_back(info);
}
return files;
}
StringVectorPtr ADPArchive::find(const String& pattern, bool recursive, bool dirs)
{
StringVectorPtr files(new StringVector);
for(Ogre::list<ADPEntry>::type::iterator i = mEntries.begin(); i != mEntries.end(); ++i)
{
if(StringUtil::match(i->name, pattern))
files->push_back(i->name);
}
return files;
}
FileInfoListPtr ADPArchive::findFileInfo(const String& pattern, bool recursive, bool dirs)
{
FileInfoListPtr files(new FileInfoList);
for(Ogre::list<ADPEntry>::type::iterator i = mEntries.begin(); i != mEntries.end(); ++i)
{
if(StringUtil::match(i->name, pattern))
{
FileInfo info;
info.archive = this;
info.basename = info.filename = info.path = i->name;
info.compressedSize = info.uncompressedSize = i->length;
files->push_back(info);
}
}
return files;
}
bool ADPArchive::exists(const String& filename)
{
for(Ogre::list<ADPEntry>::type::iterator i = mEntries.begin(); i != mEntries.end(); ++i)
{
if(i->name == filename)
return true;
}
return false;
}
time_t ADPArchive::getModifiedTime(const Ogre::String &filename)
{
return 0;
}
//////////////////////////////////////////////////////////////////////////////
const String &ADPArchiveFactory::getType() const
{
static String type = "ADP";
return type;
}
}{CODE}