mirror of
https://github.com/libretro/scummvm.git
synced 2025-01-31 07:53:36 +00:00
Moved FSDirectory implementation from common/archive.cpp to common/fs.cpp
svn-id: r38824
This commit is contained in:
parent
35e3364675
commit
d7b3c04588
@ -65,186 +65,6 @@ int Archive::listMatchingMembers(ArchiveMemberList &list, const String &pattern)
|
||||
return matches;
|
||||
}
|
||||
|
||||
FSDirectory::FSDirectory(const FSNode &node, int depth)
|
||||
: _node(node), _cached(false), _depth(depth) {
|
||||
}
|
||||
|
||||
FSDirectory::FSDirectory(const String &prefix, const FSNode &node, int depth)
|
||||
: _node(node), _cached(false), _depth(depth) {
|
||||
|
||||
setPrefix(prefix);
|
||||
}
|
||||
|
||||
FSDirectory::FSDirectory(const String &name, int depth)
|
||||
: _node(name), _cached(false), _depth(depth) {
|
||||
}
|
||||
|
||||
FSDirectory::FSDirectory(const String &prefix, const String &name, int depth)
|
||||
: _node(name), _cached(false), _depth(depth) {
|
||||
|
||||
setPrefix(prefix);
|
||||
}
|
||||
|
||||
FSDirectory::~FSDirectory() {
|
||||
}
|
||||
|
||||
void FSDirectory::setPrefix(const String &prefix) {
|
||||
_prefix = prefix;
|
||||
|
||||
if (!_prefix.empty() && !_prefix.hasSuffix("/"))
|
||||
_prefix += "/";
|
||||
}
|
||||
|
||||
FSNode FSDirectory::getFSNode() const {
|
||||
return _node;
|
||||
}
|
||||
|
||||
FSNode *FSDirectory::lookupCache(NodeCache &cache, const String &name) const {
|
||||
// make caching as lazy as possible
|
||||
if (!name.empty()) {
|
||||
ensureCached();
|
||||
|
||||
if (cache.contains(name))
|
||||
return &cache[name];
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
bool FSDirectory::hasFile(const String &name) {
|
||||
if (name.empty() || !_node.isDirectory())
|
||||
return false;
|
||||
|
||||
FSNode *node = lookupCache(_fileCache, name);
|
||||
return node && node->exists();
|
||||
}
|
||||
|
||||
ArchiveMemberPtr FSDirectory::getMember(const String &name) {
|
||||
if (name.empty() || !_node.isDirectory())
|
||||
return ArchiveMemberPtr();
|
||||
|
||||
FSNode *node = lookupCache(_fileCache, name);
|
||||
|
||||
if (!node || !node->exists()) {
|
||||
warning("FSDirectory::getMember: FSNode does not exist");
|
||||
return ArchiveMemberPtr();
|
||||
} else if (node->isDirectory()) {
|
||||
warning("FSDirectory::getMember: FSNode is a directory");
|
||||
return ArchiveMemberPtr();
|
||||
}
|
||||
|
||||
return ArchiveMemberPtr(new FSNode(*node));
|
||||
}
|
||||
|
||||
SeekableReadStream *FSDirectory::createReadStreamForMember(const String &name) const {
|
||||
if (name.empty() || !_node.isDirectory())
|
||||
return 0;
|
||||
|
||||
FSNode *node = lookupCache(_fileCache, name);
|
||||
if (!node)
|
||||
return 0;
|
||||
SeekableReadStream *stream = node->createReadStream();
|
||||
if (!stream)
|
||||
warning("FSDirectory::createReadStreamForMember: Can't create stream for file '%s'", name.c_str());
|
||||
|
||||
return stream;
|
||||
}
|
||||
|
||||
FSDirectory *FSDirectory::getSubDirectory(const String &name, int depth) {
|
||||
return getSubDirectory(String::emptyString, name, depth);
|
||||
}
|
||||
|
||||
FSDirectory *FSDirectory::getSubDirectory(const String &prefix, const String &name, int depth) {
|
||||
if (name.empty() || !_node.isDirectory())
|
||||
return 0;
|
||||
|
||||
FSNode *node = lookupCache(_subDirCache, name);
|
||||
if (!node)
|
||||
return 0;
|
||||
|
||||
return new FSDirectory(prefix, *node, depth);
|
||||
}
|
||||
|
||||
void FSDirectory::cacheDirectoryRecursive(FSNode node, int depth, const String& prefix) const {
|
||||
if (depth <= 0)
|
||||
return;
|
||||
|
||||
FSList list;
|
||||
node.getChildren(list, FSNode::kListAll, false);
|
||||
|
||||
FSList::iterator it = list.begin();
|
||||
for ( ; it != list.end(); ++it) {
|
||||
String name = prefix + it->getName();
|
||||
|
||||
// don't touch name as it might be used for warning messages
|
||||
String lowercaseName = name;
|
||||
lowercaseName.toLowercase();
|
||||
|
||||
// since the hashmap is case insensitive, we need to check for clashes when caching
|
||||
if (it->isDirectory()) {
|
||||
if (_subDirCache.contains(lowercaseName)) {
|
||||
warning("FSDirectory::cacheDirectory: name clash when building cache, ignoring sub-directory '%s'", name.c_str());
|
||||
} else {
|
||||
cacheDirectoryRecursive(*it, depth - 1, lowercaseName + "/");
|
||||
_subDirCache[lowercaseName] = *it;
|
||||
}
|
||||
} else {
|
||||
if (_fileCache.contains(lowercaseName)) {
|
||||
warning("FSDirectory::cacheDirectory: name clash when building cache, ignoring file '%s'", name.c_str());
|
||||
} else {
|
||||
_fileCache[lowercaseName] = *it;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
void FSDirectory::ensureCached() const {
|
||||
if (_cached)
|
||||
return;
|
||||
cacheDirectoryRecursive(_node, _depth, _prefix);
|
||||
_cached = true;
|
||||
}
|
||||
|
||||
int FSDirectory::listMatchingMembers(ArchiveMemberList &list, const String &pattern) {
|
||||
if (!_node.isDirectory())
|
||||
return 0;
|
||||
|
||||
// Cache dir data
|
||||
ensureCached();
|
||||
|
||||
String lowercasePattern(pattern);
|
||||
lowercasePattern.toLowercase();
|
||||
|
||||
int matches = 0;
|
||||
NodeCache::iterator it = _fileCache.begin();
|
||||
for ( ; it != _fileCache.end(); ++it) {
|
||||
if (it->_key.matchString(lowercasePattern, true)) {
|
||||
list.push_back(ArchiveMemberPtr(new FSNode(it->_value)));
|
||||
matches++;
|
||||
}
|
||||
}
|
||||
return matches;
|
||||
}
|
||||
|
||||
int FSDirectory::listMembers(ArchiveMemberList &list) {
|
||||
if (!_node.isDirectory())
|
||||
return 0;
|
||||
|
||||
// Cache dir data
|
||||
ensureCached();
|
||||
|
||||
int files = 0;
|
||||
for (NodeCache::iterator it = _fileCache.begin(); it != _fileCache.end(); ++it) {
|
||||
list.push_back(ArchiveMemberPtr(new FSNode(it->_value)));
|
||||
++files;
|
||||
}
|
||||
|
||||
return files;
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
SearchSet::ArchiveNodeList::iterator SearchSet::find(const String &name) const {
|
||||
|
179
common/fs.cpp
179
common/fs.cpp
@ -163,4 +163,183 @@ Common::WriteStream *FSNode::createWriteStream() const {
|
||||
return _realNode->createWriteStream();
|
||||
}
|
||||
|
||||
FSDirectory::FSDirectory(const FSNode &node, int depth)
|
||||
: _node(node), _cached(false), _depth(depth) {
|
||||
}
|
||||
|
||||
FSDirectory::FSDirectory(const String &prefix, const FSNode &node, int depth)
|
||||
: _node(node), _cached(false), _depth(depth) {
|
||||
|
||||
setPrefix(prefix);
|
||||
}
|
||||
|
||||
FSDirectory::FSDirectory(const String &name, int depth)
|
||||
: _node(name), _cached(false), _depth(depth) {
|
||||
}
|
||||
|
||||
FSDirectory::FSDirectory(const String &prefix, const String &name, int depth)
|
||||
: _node(name), _cached(false), _depth(depth) {
|
||||
|
||||
setPrefix(prefix);
|
||||
}
|
||||
|
||||
FSDirectory::~FSDirectory() {
|
||||
}
|
||||
|
||||
void FSDirectory::setPrefix(const String &prefix) {
|
||||
_prefix = prefix;
|
||||
|
||||
if (!_prefix.empty() && !_prefix.hasSuffix("/"))
|
||||
_prefix += "/";
|
||||
}
|
||||
|
||||
FSNode FSDirectory::getFSNode() const {
|
||||
return _node;
|
||||
}
|
||||
|
||||
FSNode *FSDirectory::lookupCache(NodeCache &cache, const String &name) const {
|
||||
// make caching as lazy as possible
|
||||
if (!name.empty()) {
|
||||
ensureCached();
|
||||
|
||||
if (cache.contains(name))
|
||||
return &cache[name];
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
bool FSDirectory::hasFile(const String &name) {
|
||||
if (name.empty() || !_node.isDirectory())
|
||||
return false;
|
||||
|
||||
FSNode *node = lookupCache(_fileCache, name);
|
||||
return node && node->exists();
|
||||
}
|
||||
|
||||
ArchiveMemberPtr FSDirectory::getMember(const String &name) {
|
||||
if (name.empty() || !_node.isDirectory())
|
||||
return ArchiveMemberPtr();
|
||||
|
||||
FSNode *node = lookupCache(_fileCache, name);
|
||||
|
||||
if (!node || !node->exists()) {
|
||||
warning("FSDirectory::getMember: FSNode does not exist");
|
||||
return ArchiveMemberPtr();
|
||||
} else if (node->isDirectory()) {
|
||||
warning("FSDirectory::getMember: FSNode is a directory");
|
||||
return ArchiveMemberPtr();
|
||||
}
|
||||
|
||||
return ArchiveMemberPtr(new FSNode(*node));
|
||||
}
|
||||
|
||||
SeekableReadStream *FSDirectory::createReadStreamForMember(const String &name) const {
|
||||
if (name.empty() || !_node.isDirectory())
|
||||
return 0;
|
||||
|
||||
FSNode *node = lookupCache(_fileCache, name);
|
||||
if (!node)
|
||||
return 0;
|
||||
SeekableReadStream *stream = node->createReadStream();
|
||||
if (!stream)
|
||||
warning("FSDirectory::createReadStreamForMember: Can't create stream for file '%s'", name.c_str());
|
||||
|
||||
return stream;
|
||||
}
|
||||
|
||||
FSDirectory *FSDirectory::getSubDirectory(const String &name, int depth) {
|
||||
return getSubDirectory(String::emptyString, name, depth);
|
||||
}
|
||||
|
||||
FSDirectory *FSDirectory::getSubDirectory(const String &prefix, const String &name, int depth) {
|
||||
if (name.empty() || !_node.isDirectory())
|
||||
return 0;
|
||||
|
||||
FSNode *node = lookupCache(_subDirCache, name);
|
||||
if (!node)
|
||||
return 0;
|
||||
|
||||
return new FSDirectory(prefix, *node, depth);
|
||||
}
|
||||
|
||||
void FSDirectory::cacheDirectoryRecursive(FSNode node, int depth, const String& prefix) const {
|
||||
if (depth <= 0)
|
||||
return;
|
||||
|
||||
FSList list;
|
||||
node.getChildren(list, FSNode::kListAll, false);
|
||||
|
||||
FSList::iterator it = list.begin();
|
||||
for ( ; it != list.end(); ++it) {
|
||||
String name = prefix + it->getName();
|
||||
|
||||
// don't touch name as it might be used for warning messages
|
||||
String lowercaseName = name;
|
||||
lowercaseName.toLowercase();
|
||||
|
||||
// since the hashmap is case insensitive, we need to check for clashes when caching
|
||||
if (it->isDirectory()) {
|
||||
if (_subDirCache.contains(lowercaseName)) {
|
||||
warning("FSDirectory::cacheDirectory: name clash when building cache, ignoring sub-directory '%s'", name.c_str());
|
||||
} else {
|
||||
cacheDirectoryRecursive(*it, depth - 1, lowercaseName + "/");
|
||||
_subDirCache[lowercaseName] = *it;
|
||||
}
|
||||
} else {
|
||||
if (_fileCache.contains(lowercaseName)) {
|
||||
warning("FSDirectory::cacheDirectory: name clash when building cache, ignoring file '%s'", name.c_str());
|
||||
} else {
|
||||
_fileCache[lowercaseName] = *it;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
void FSDirectory::ensureCached() const {
|
||||
if (_cached)
|
||||
return;
|
||||
cacheDirectoryRecursive(_node, _depth, _prefix);
|
||||
_cached = true;
|
||||
}
|
||||
|
||||
int FSDirectory::listMatchingMembers(ArchiveMemberList &list, const String &pattern) {
|
||||
if (!_node.isDirectory())
|
||||
return 0;
|
||||
|
||||
// Cache dir data
|
||||
ensureCached();
|
||||
|
||||
String lowercasePattern(pattern);
|
||||
lowercasePattern.toLowercase();
|
||||
|
||||
int matches = 0;
|
||||
NodeCache::iterator it = _fileCache.begin();
|
||||
for ( ; it != _fileCache.end(); ++it) {
|
||||
if (it->_key.matchString(lowercasePattern, true)) {
|
||||
list.push_back(ArchiveMemberPtr(new FSNode(it->_value)));
|
||||
matches++;
|
||||
}
|
||||
}
|
||||
return matches;
|
||||
}
|
||||
|
||||
int FSDirectory::listMembers(ArchiveMemberList &list) {
|
||||
if (!_node.isDirectory())
|
||||
return 0;
|
||||
|
||||
// Cache dir data
|
||||
ensureCached();
|
||||
|
||||
int files = 0;
|
||||
for (NodeCache::iterator it = _fileCache.begin(); it != _fileCache.end(); ++it) {
|
||||
list.push_back(ArchiveMemberPtr(new FSNode(it->_value)));
|
||||
++files;
|
||||
}
|
||||
|
||||
return files;
|
||||
}
|
||||
|
||||
|
||||
} // End of namespace Common
|
||||
|
Loading…
x
Reference in New Issue
Block a user