Committed slightly modified patch #2034983 "Case-insensitivy and directory handling for engines".

svn-id: r34734
This commit is contained in:
Johannes Schickel 2008-10-03 16:57:40 +00:00
parent 4b236a787f
commit e417471177
6 changed files with 109 additions and 76 deletions

View File

@ -30,11 +30,23 @@
namespace Common {
GenericArchiveMember::GenericArchiveMember(String name, Archive *parent)
: _parent(parent), _name(name) {
}
int Archive::matchPattern(StringList &list, const String &pattern) {
String GenericArchiveMember::getName() const {
return _name;
}
SeekableReadStream *GenericArchiveMember::open() {
return _parent->openFile(_name);
}
int Archive::listMatchingMembers(ArchiveMemberList &list, const String &pattern) {
// Get all "names" (TODO: "files" ?)
StringList allNames;
getAllNames(allNames);
ArchiveMemberList allNames;
listMembers(allNames);
int matches = 0;
@ -42,9 +54,9 @@ int Archive::matchPattern(StringList &list, const String &pattern) {
String lowercasePattern = pattern;
lowercasePattern.toLowercase();
StringList::iterator it = allNames.begin();
ArchiveMemberList::iterator it = allNames.begin();
for ( ; it != allNames.end(); it++) {
if (it->matchString(lowercasePattern)) {
if ((*it)->getName().matchString(lowercasePattern)) {
list.push_back(*it);
matches++;
}
@ -53,6 +65,34 @@ int Archive::matchPattern(StringList &list, const String &pattern) {
return matches;
}
/**
* FSDirectoryMemeber is the implementation of ArchiveMember used by
* by FSDirectory. It is right now a light wrapper or FSNode.
*/
class FSDirectoryMember : public ArchiveMember {
FSNode _node;
public:
FSDirectoryMember(FSNode &node) : _node(node) {
}
/*
NOTE/FIXME: since I assume that the only use case for getName()
is for error messages, I am returning the full path of the node
here. This seems better than we did before, when matchPattern
and getAllNames used to work with StringList, and we used to
put the relative path of the file to the list instead.
*/
String getName() const {
return _node.getPath();
}
SeekableReadStream *open() {
return _node.openForReading();
}
};
typedef SharedPtr<FSDirectoryMember> FSDirectoryMemberPtr;
FSDirectory::FSDirectory(const FSNode &node, int depth)
: _node(node), _cached(false), _depth(depth) {
@ -160,7 +200,7 @@ void FSDirectory::cacheDirectoryRecursive(FSNode node, int depth, const String&
}
int FSDirectory::matchPattern(StringList &list, const String &pattern) {
int FSDirectory::listMatchingMembers(ArchiveMemberList &list, const String &pattern) {
if (!_node.isDirectory())
return 0;
@ -170,43 +210,28 @@ int FSDirectory::matchPattern(StringList &list, const String &pattern) {
_cached = true;
}
// Small optimization: Ensure the StringList has to grow at most once
list.reserve(list.size() + _fileCache.size());
// Add all filenames from our cache
String lowercasePattern(pattern);
lowercasePattern.toLowercase();
int matches = 0;
NodeCache::iterator it = _fileCache.begin();
for ( ; it != _fileCache.end(); it++) {
if (it->_key.matchString(pattern))
list.push_back(it->_key);
if ((*it)._key.matchString(lowercasePattern)) {
list.push_back(FSDirectoryMemberPtr(new FSDirectoryMember((*it)._value)));
matches++;
}
}
return _fileCache.size();
return matches;
}
int FSDirectory::getAllNames(StringList &list) {
if (!_node.isDirectory())
return 0;
// Cache dir data
if (!_cached) {
cacheDirectoryRecursive(_node, _depth, "");
_cached = true;
}
// Small optimization: Ensure the StringList has to grow at most once
list.reserve(list.size() + _fileCache.size());
// Add all filenames from our cache
NodeCache::iterator it = _fileCache.begin();
for ( ; it != _fileCache.end(); it++) {
list.push_back((*it)._key);
}
return _fileCache.size();
int FSDirectory::listMembers(ArchiveMemberList &list) {
return listMatchingMembers(list, "*");
}
SearchSet::ArchiveList::iterator SearchSet::find(const String &name) const {
ArchiveList::iterator it = _list.begin();
for ( ; it != _list.end(); it++) {
@ -289,23 +314,23 @@ bool SearchSet::hasFile(const String &name) {
return false;
}
int SearchSet::matchPattern(StringList &list, const String &pattern) {
int SearchSet::listMatchingMembers(ArchiveMemberList &list, const String &pattern) {
int matches = 0;
ArchiveList::iterator it = _list.begin();
for ( ; it != _list.end(); it++) {
matches += (*it)._arc->matchPattern(list, pattern);
matches += (*it)._arc->listMatchingMembers(list, pattern);
}
return matches;
}
int SearchSet::getAllNames(StringList &list) {
int SearchSet::listMembers(ArchiveMemberList &list) {
int matches = 0;
ArchiveList::iterator it = _list.begin();
for ( ; it != _list.end(); it++) {
matches += (*it)._arc->getAllNames(list);
matches += (*it)._arc->listMembers(list);
}
return matches;

View File

@ -36,6 +36,35 @@
namespace Common {
class ArchiveMember {
public:
virtual ~ArchiveMember() { }
virtual String getName() const = 0;
virtual SeekableReadStream *open() = 0;
};
typedef List<SharedPtr<ArchiveMember> > ArchiveMemberList;
class Archive;
/**
* Simple ArchiveMemeber implementation which allows
* creation of ArchiveMember compatible objects via
* a simple Archive and name pair.
*
* Note that GenericArchiveMember objects will not
* be working anymore after the 'parent' object
* is destroyed.
*/
class GenericArchiveMember : public ArchiveMember {
Archive *_parent;
String _name;
public:
GenericArchiveMember(String name, Archive *parent);
String getName() const;
SeekableReadStream *open();
};
/**
* FilePtr is a convenient way to keep track of a SeekableReadStream without
* having to worry about releasing its memory.
@ -63,7 +92,7 @@ public:
*
* @return the number of names added to list
*/
virtual int matchPattern(StringList &list, const String &pattern);
virtual int listMatchingMembers(ArchiveMemberList &list, const String &pattern);
/**
* Add all the names present in the Archive to list. Returned
@ -72,7 +101,7 @@ public:
*
* @return the number of names added to list
*/
virtual int getAllNames(StringList &list) = 0;
virtual int listMembers(ArchiveMemberList &list) = 0;
/**
* Create a stream bound to a file in the archive.
@ -138,8 +167,8 @@ public:
FSDirectory *getSubDirectory(const String &name);
virtual bool hasFile(const String &name);
virtual int matchPattern(StringList &list, const String &pattern);
virtual int getAllNames(StringList &list);
virtual int listMatchingMembers(ArchiveMemberList &list, const String &pattern);
virtual int listMembers(ArchiveMemberList &list);
virtual SeekableReadStream *openFile(const String &name);
};
@ -195,8 +224,8 @@ public:
void setPriority(const String& name, int priority);
virtual bool hasFile(const String &name);
virtual int matchPattern(StringList &list, const String &pattern);
virtual int getAllNames(StringList &list);
virtual int listMatchingMembers(ArchiveMemberList &list, const String &pattern);
virtual int listMembers(ArchiveMemberList &list);
/**
* Implements openFile from Archive base class. The current policy is

View File

@ -1392,26 +1392,6 @@ bool ZipArchive::hasFile(const Common::String &name) {
return (_zipFile && unzLocateFile(_zipFile, name.c_str(), 2) == UNZ_OK);
}
int ZipArchive::getAllNames(Common::StringList &list) {
if (!_zipFile)
return 0;
if (unzGoToFirstFile(_zipFile) != UNZ_OK)
return 0;
char fileNameBuffer[UNZ_MAXFILENAMEINZIP + 1];
int fileCount = 0;
do {
unzGetCurrentFileInfo(_zipFile, 0, fileNameBuffer, UNZ_MAXFILENAMEINZIP + 1, 0, 0, 0, 0);
list.push_back(Common::String(fileNameBuffer));
fileCount++;
} while (unzGoToNextFile(_zipFile) == UNZ_OK);
return fileCount;
}
/*
int ZipArchive::listMembers(Common::ArchiveMemberList &list) {
if (!_zipFile)
return 0;
@ -1424,14 +1404,13 @@ int ZipArchive::listMembers(Common::ArchiveMemberList &list) {
unzGetCurrentFileInfo(_zipFile, NULL,
szCurrentFileName, sizeof(szCurrentFileName)-1,
NULL, 0, NULL, 0);
szCurrentFileName
list.push_back(ArchiveMemberList::value_type(new GenericArchiveMember(szCurrentFileName, this)));
matches++;
err = unzGoToNextFile(file);
err = unzGoToNextFile(_zipFile);
}
return 0;
return matches;
}
*/
Common::SeekableReadStream *ZipArchive::openFile(const Common::String &name) {
if (!_zipFile)

View File

@ -44,7 +44,7 @@ public:
bool isOpen() const;
virtual bool hasFile(const String &name);
virtual int getAllNames(StringList &list);
virtual int listMembers(Common::ArchiveMemberList &list);
virtual Common::SeekableReadStream *openFile(const Common::String &name);
};

View File

@ -51,11 +51,11 @@ bool PlainArchive::hasFile(const Common::String &name) {
return (_files.find(name) != _files.end());
}
int PlainArchive::getAllNames(Common::StringList &list) {
int PlainArchive::listMembers(Common::ArchiveMemberList &list) {
int count = 0;
for (FileMap::const_iterator i = _files.begin(); i != _files.end(); ++i) {
list.push_back(i->_key);
list.push_back(Common::ArchiveMemberList::value_type(new Common::GenericArchiveMember(i->_key, this)));
++count;
}
@ -98,11 +98,11 @@ bool CachedArchive::hasFile(const Common::String &name) {
return (_files.find(name) != _files.end());
}
int CachedArchive::getAllNames(Common::StringList &list) {
int CachedArchive::listMembers(Common::ArchiveMemberList &list) {
int count = 0;
for (FileMap::const_iterator i = _files.begin(); i != _files.end(); ++i) {
list.push_back(i->_key);
list.push_back(Common::ArchiveMemberList::value_type(new Common::GenericArchiveMember(i->_key, this)));
++count;
}

View File

@ -50,7 +50,7 @@ public:
PlainArchive(Resource *owner, const Common::String &filename, const FileInputList &files);
bool hasFile(const Common::String &name);
int getAllNames(Common::StringList &list);
int listMembers(Common::ArchiveMemberList &list);
Common::SeekableReadStream *openFile(const Common::String &name);
private:
struct Entry {
@ -80,7 +80,7 @@ public:
~CachedArchive();
bool hasFile(const Common::String &name);
int getAllNames(Common::StringList &list);
int listMembers(Common::ArchiveMemberList &list);
Common::SeekableReadStream *openFile(const Common::String &name);
private:
struct Entry {