27 #include <boost/scope_exit.hpp> 54 #define CHECK_HASH_COLLISION 1 66 name(n), type(t), resource(&r), opened(0) {
88 assert(known->resource);
90 assert(known->resource->archive);
92 parent = known->resource->archive;
93 parent->children.push_back(
this);
99 source(
kSourceNone), archive(0), archiveIndex(0xFFFFFFFF) {
228 throw Common::Exception(
"ResourceManager::setHashAlgo(): We already have resources!");
279 for (KnownArchives::iterator a = archives.begin(); a != archives.end(); ++a) {
280 if (a->name.toLower().endsWith(file))
320 switch (knownArchive->
type) {
322 indexKEY(archiveStream, priority, change);
362 std::vector<byte> password;
368 std::vector<KnownArchive *> &archives,
369 std::vector<KEYDataFile *> &keyData) {
371 bool success =
false;
372 BOOST_SCOPE_EXIT( (&success) (&archives) (&keyData) ) {
374 for (std::vector<KEYDataFile *>::iterator b = keyData.begin(); b != keyData.end(); ++b)
380 } BOOST_SCOPE_EXIT_END
386 archives.resize(keyBIFs.size(), 0);
387 keyData.resize(keyBIFs.size(), 0);
389 for (
uint32 i = 0; i < keyBIFs.size(); i++) {
399 keyData[i]->mergeKEY(key, i);
403 return archives.size();
407 std::vector<KnownArchive *> archives;
408 std::vector<KEYDataFile *> keyData;
412 for (
uint32 i = 0; i < count; i++)
413 indexArchive(*archives[i], keyData[i], priority, change);
421 throw Common::Exception(
"ResourceManager::indexArchive(): Archive uses a different name hashing " 422 "algorithm than we do (%d vs. %d)", (
int) hashAlgo, (
int)
_hashAlgo);
424 bool couldSet =
false;
432 } BOOST_SCOPE_EXIT_END
442 for (Archive::ResourceList::const_iterator resource = resources.begin(); resource != resources.end(); ++resource) {
449 res.
name = resource->name;
450 res.
type = resource->type;
504 if (directory.
empty())
535 for (OpenedArchiveChanges::iterator oaChange = change->
_change->openedArchives.begin();
536 oaChange != change->
_change->openedArchives.end(); ++oaChange) {
538 if (!(*oaChange)->children.empty())
539 throw Common::Exception(
"Attempted to deindex an archive that has opened children archives");
541 assert((*oaChange)->known);
544 (*oaChange)->known->opened = 0;
547 if ((*oaChange)->parent) {
548 std::list<OpenedArchive *> &pChildren = (*oaChange)->parent->children;
551 for (std::list<OpenedArchive *>::iterator c = pChildren.begin(); c != pChildren.end(); ++c) {
552 if (*c == &**oaChange) {
563 delete (*oaChange)->archive;
568 for (KnownArchiveChanges::iterator kaChange = change->
_change->knownArchives.begin();
569 kaChange != change->
_change->knownArchives.end(); ++kaChange) {
571 if (kaChange->second->opened)
575 assert(kaChange->second->resource);
576 kaChange->second->resource->selfArchive.first = 0;
578 kaChange->first->erase(kaChange->second);
582 for (ResourceChanges::iterator resChange = change->
_change->resources.begin();
583 resChange != change->
_change->resources.end(); ++resChange) {
587 if (resChange->resIt->selfArchive.first) {
588 if (resChange->resIt->selfArchive.second->opened)
589 throw Common::Exception(
"Attempted to deindex an archive resource that's still opened");
591 resChange->resIt->selfArchive.first->erase(resChange->resIt->selfArchive.second);
595 resChange->hashIt->second.erase(resChange->resIt);
597 if (resChange->hashIt->second.empty())
617 for (ResourceList::iterator res = resList->second.begin(); res != resList->second.end(); ++res)
622 bool isSmall =
false;
637 for (ResourceList::iterator r = resList->second.begin(); r != resList->second.end(); ++r) {
640 r->isSmall = isSmall;
651 std::vector<FileType> types;
653 types.push_back(type);
669 return getRes(name, types) != 0;
677 std::vector<FileType> types;
679 types.push_back(type);
695 const std::vector<FileType> &types)
const {
725 std::vector<FileType> types;
727 types.push_back(type);
737 const std::vector<FileType> &types,
FileType *foundType)
const {
745 *foundType = res->
type;
801 std::list<ResourceID> &list)
const {
804 if (!r->second.empty() && (r->second.front().type == type)) {
807 list.back().name = r->second.front().name;
808 list.back().type = r->second.front().type;
809 list.back().hash = r->first;
815 std::list<ResourceID> &list)
const {
818 for (std::vector<FileType>::const_iterator t = types.begin(); t != types.end(); ++t) {
819 if (!r->second.empty() && (r->second.front().type == *t)) {
822 list.back().name = r->second.front().name;
823 list.back().type = r->second.front().type;
824 list.back().hash = r->first;
832 std::list<ResourceID> &list)
const {
850 switch (resource.
source) {
852 return resource.
path;
868 std::map<FileType, FileType>::const_iterator alias =
_typeAliases.find(resource.
type);
870 resource.
type = alias->second;
904 if (resource.
name.
empty() || resList->second.empty())
909 for (ResourceList::const_iterator r = resList->second.begin(); r != resList->second.end(); ++r) {
914 if (oldName != newName) {
915 warning(
"ResourceManager: Found hash collision: %s (\"%s\" and \"%s\")",
945 resource.
selfArchive = std::make_pair(&archives, --archives.end());
954 ResourceMap::iterator resList =
_resources.find(hash);
958 std::pair<ResourceMap::iterator, bool> result;
962 resList = result.first;
965 #ifdef CHECK_HASH_COLLISION 970 resList->second.push_back(resource);
971 Resource *res = &resList->second.back();
978 change->
_change->resources.back().hashIt = resList;
979 change->
_change->resources.back().resIt = --resList->second.end();
983 resList->second.sort();
1017 ResourceMap::const_iterator r =
_resources.find(hash);
1018 if ((r ==
_resources.end()) || r->second.empty() || (r->second.back().priority == 0))
1021 return &r->second.back();
1025 const std::vector<FileType> &types)
const {
1028 for (std::vector<FileType>::const_iterator type = types.begin(); type != types.end(); ++type) {
1030 if (res && (!result || *result < *res))
1034 for (std::vector<FileType>::const_iterator type = types.begin(); type != types.end(); ++type) {
1038 if (res && (!result || *result < *res))
1047 std::vector<FileType> types(1, type);
1049 return getRes(name, types);
1055 if (!file.
open(fileName))
1059 file.
writeString(
"-------------------------------------|--------------------|-------------\n");
1062 if (r->second.empty())
1065 const Resource &res = r->second.back();
1069 const uint64 hash = r->first;
uint32 getResourceSize(const Resource &res) const
ChangeSetList::iterator _change
Compressed file, Nintendo LZSS.
FileTypeList _resourceTypeTypes[kResourceMAX]
All valid resource type file types.
bool hasResourceDir(const Common::UString &dir)
Does a specific directory, relative to the base directory, exist?
void addResources(const Common::FileList &files, Change *change, uint32 priority)
Source source
Where can the resource be found?
#define TypeMan
Shortcut for accessing the file type manager.
Class to hold resource data information of a BIF file.
std::vector< Common::UString > BIFList
A class holding an UTF-8 string.
static void decompress(Common::ReadStream &small, Common::WriteStream &out)
64bit Fowler-Noll-Vo hash by Glenn Fowler, Landon Curt Noll and Phong Vo.
void writeString(const UString &str)
Write the given string to the stream, encoded as UTF-8.
void reset(PointerType o=0)
Resets the pointer with the new value.
static UString getExtension(const UString &p)
Return a file name's extension.
void setHasSmall(bool hasSmall)
Do we have "small" files (compressed with Nintendo DS's LZSS algorithm)?
PointerType release()
Returns the plain pointer value and releases ScopedPtr.
FileType type
The resource's type.
Handling BioWare's RIMs (resource archives).
Common::SeekableReadStream * openArchiveStream(const KnownArchive &archive) const
uint32 archiveIndex
Index into the archive.
const Resource * getRes(uint64 hash) const
static bool isDirectory(const UString &p)
Does specified path exist and is it a directory?
void indexResourceDir(const Common::UString &dir, const char *glob, int depth, uint32 priority, Common::ChangeID *changeID=0)
Add a directory's contents to the resource manager.
bool equalsIgnoreCase(const UString &str) const
A simple streaming file reading class.
Treat Nintendo NSBTX files, which contain multiple textures as an archive of intermediate textures...
A set of changes produced by a manager operation.
Utility functions to handle files used in BioWare's Aurora engine.
Class to hold resource data of an HERF archive file.
std::list< UString >::const_iterator const_iterator
virtual const ResourceList & getResources() const =0
Return the list of resources.
Geometry, model mesh data.
std::vector< Common::UString > _cursorRemap
Cursor ID -> cursor name.
A change produced by indexing archive resources.
KnownArchives _knownArchives[kArchiveMAX]
List of all known archives.
ChangeContent * getContent() const
void clear()
Clear all resource information.
void dumpResourcesList(const Common::UString &fileName) const
Dump a list of all resources into a file.
Class to hold resource index information of a KEY file.
std::list< Resource > ResourceList
List of resources, sorted by priority.
ChangeSetList _changes
Changes produced by indexing the currently known resources.
Face bone definitions, FaceFX Actor.
Exception that provides a stack of explanations.
Archive * archive
The actual archive.
Class to hold resource data information of a BZF file.
A simple scoped smart pointer template.
Image, Portable Network Graphics.
static UString formatHash(uint64 hash)
void set(KnownArchive &kA, Archive &a)
bool isSmall
Is this a "small" (compressed Nintendo DS) file?
void setCursorRemap(const std::vector< Common::UString > &remap)
Set the array used to map cursor ID to cursor names.
void indexKEY(Common::SeekableReadStream *stream, uint32 priority, Change *change)
Handling BioWare's KEYs (resource index files).
Basic exceptions to throw.
Font, character bitmap data.
bool normalizeType(Resource &resource)
const char * c_str() const
Return the (utf8 encoded) string data.
Geometry, model mesh data.
bool open(const UString &fileName)
Try to open the file with the given fileName.
virtual uint32 getResourceSize(uint32 index) const
Return the size of a resource.
Handling BioWare's BIFs (resource data files).
static UString format(const char *s,...) GCC_PRINTF(1
Print formatted data into an UString object, similar to sprintf().
static bool isRegularFile(const UString &p)
Does specified path exist and is it a regular file?
Common::HashAlgo _hashAlgo
With which hash algorithm are/should the names be hashed?
void addResource(Resource &resource, uint64 hash, Change *change)
Utility templates and functions.
Handling BioWare's BZFs (resource data files), used in the iOS version of Knights of the Old Republic...
void registerDataBase(const Common::UString &path)
Register a path to be the data base.
#define DECLARE_SINGLETON(T)
Note that you need to use this macro from the global namespace.
FileTypeSet _archiveTypeTypes[kArchiveMAX]
All valid archive types file types.
std::list< Resource > ResourceList
void blacklist(const Common::UString &name, FileType type)
Blacklist a specific resource.
Common::UString findResourceFile(const Common::UString &name, FileType type) const
Find and return the absolute filesystem file behind a resource.
bool _hasSmall
Do we have "small" files?
std::map< FileType, FileType > _typeAliases
The current type aliases, changing one type to another.
bool hasResource(uint64 hash) const
Does a specific resource exist?
BioWare's HERF (hashed ERF) file parsing.
Handling BioWare's ERFs (encapsulated resource file).
Game resource data, LZMA-compressed BIF.
static UString canonicalize(const UString &p, bool resolveSymLinks=true)
Return the canonical, absolutized and normalized path.
virtual Common::HashAlgo getNameHashAlgo() const
Return with which algorithm the name is hashed.
bool empty() const
Is the string empty?
ArchiveType getArchiveType(FileType type) const
HashAlgo
The algorithm used for hashing.
void indexArchive(const Common::UString &file, uint32 priority, Common::ChangeID *changeID=0)
Add all the resources of an archive to the resource manager.
Archive, Nintendo DS ROM file.
Common::UString getArchiveName(const Resource &resource) const
void setContent(ChangeContent *content)
static uint64 hashString(const UString &string, HashAlgo algo)
Hash the string with the given algorithm, as a series of UTF-8 characters.
A scoped plain pointer, allowing pointer-y access and normal deletion.
Common::UString name
The resource's name.
void warning(const char *s,...)
uint64 getHash(const Common::UString &name, FileType type) const
Basic reading stream interfaces.
ResourceMap _resources
All currently known resources.
std::list< KnownArchive > KnownArchives
List of all known archive files.
bool hasArchive(const Common::UString &file)
Does a specific archive exist?
void flush()
Commit any buffered data to the underlying channel or storage medium; unbuffered streams can use the ...
Implementing the stream reading interfaces for files.
const BIFList & getBIFs() const
Return a list of all managed bifs.
Video, RAD Game Tools Bink.
KnownArchive * findArchive(const Common::UString &file)
void close()
Close the file, if open.
Common::UString path
The file's path.
void indexResourceFile(const Common::UString &file, uint32 priority, Common::ChangeID *changeID=0)
Add a single file to the resource manager.
static UString getStem(const UString &p)
Return a file name's stem.
UString toLower() const
Return a lowercased copy of the string.
Neverwinter Nights original campaign module, ERF.
An abstract KEY data file (BIF or BZF).
Common::SeekableReadStream * getResource(uint64 hash, FileType *type=0) const
Return a resource.
Decompressing "small" files, Nintendo DS LZSS (types 0x00 and 0x10), found in Sonic.
uint32 openKEYBIFs(Common::SeekableReadStream *keyStream, std::vector< KnownArchive *> &archives, std::vector< KEYDataFile *> &keyData)
A class representing an undoable change.
static bool isAbsolute(const UString &p)
Is the given string an absolute path?
Class to hold resource data of an ERF archive file.
A portable executable archive.
static size_t getFileSize(const UString &p)
Return a file's size.
static UString normalize(const UString &p, bool resolveSymLinks=true)
Normalize a path.
bool operator<(const Resource &right) const
virtual Common::SeekableReadStream * getResource(uint32 index, bool tryNoCopy=false) const =0
Return a stream of the resource's contents.
FileType
Various file types used by the Aurora engine and found in archives.
Image, Truevision TARGA image.
Implementing the stream writing interfaces for files.
uint32 priority
The resource's priority over others with the same name and type.
Common::UString _baseArchive
The data base archive (if any), the archive the current game is in.
const_iterator begin() const
Return a const_iterator pointing to the beginning of the list.
bool addDirectory(const UString &directory, int recurseDepth=0)
Add a directory to the list.
Class to hold resource data of a RIM archive file.
Resource * resource
The resource this archive is.
A class encapsulating Nintendo DS ROM access.
An abstract file archive.
const Common::UString & getDataBase() const
Return the path of the currently registered base data directory or archive.
A resource manager holding information about and handling all request for all resources usable by the...
const Exception kOpenError("Can't open file")
Exception when a file couldn't be opened.
std::pair< KnownArchives *, KnownArchives::iterator > selfArchive
The archive this resource itself is.
void undo(Common::ChangeID &changeID)
Undo the changes done in the specified change ID.
void setRIMsAreERFs(bool rimsAreERFs)
Are .rim/.rimp files actually ERF files?
A simple streaming file writing class.
void addTypeAlias(FileType alias, FileType realType)
Add an alias for one file type to another.
Common::UString _baseDir
The data base directory (if any), the directory the current game is in.
Common::SeekableReadStream * getArchiveResource(const Resource &res, bool tryNoCopy=false) const
void clear()
Clear the string's contents.
bool getSubListGlob(const UString &glob, bool caseInsensitive, FileList &subList) const
Add files matching the given regex into another FileList.
OpenedArchives _openedArchives
List of currently used archives.
ArchiveType type
The archive's type.
Interface for a seekable & readable data stream.
void getAvailableResources(FileType type, std::list< ResourceID > &list) const
Return a list of all available resources of the specified type.
void declareResource(const Common::UString &name, FileType type)
Declare the name of a specific resource.
void setHashAlgo(Common::HashAlgo algo)
With which hash algorithm are/should the names be hashed?
Texture, DirectDraw Surface.
bool checkResourceIsArchive(Resource &resource, Change *change)
The global resource manager for Aurora resources.
Utility class for manipulating file paths.
Change * newChangeSet(Common::ChangeID &changeID)
static UString changeExtension(const UString &p, const UString &ext="")
Change a file name's extension.
A class encapsulating PE exe's for resource archive access.
const_iterator end() const
Return a const_iterator pointing past the end of the list.
void checkHashCollision(const Resource &resource, ResourceMap::const_iterator resList)
static UString findSubDirectory(const UString &directory, const UString &subDirectory, bool caseInsensitive=false)
Find a directory's subdirectory.
OpenedArchive * archive
Pointer to the opened archive.
A class encapsulating ZIP files for resource archive access.
Audio, MP3 with extra header.