#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; } }