Modified FSDirectory::lookupCache to return a FSNode *pointer*, so that we can distinguish between lookup failures and invalid cache entries. Also changed SearchSet::createReadStreamForMember to not use hasFile anymore, based on the assumption that any Archive::createReadStreamForMember implementation has to verify whether the member name is valid anyway (clarified the doxygen docs accordingly)

svn-id: r38787
This commit is contained in:
Max Horn 2009-02-22 16:48:02 +00:00
parent c397b37bfb
commit 9b45dd2849
3 changed files with 24 additions and 17 deletions

View file

@ -99,49 +99,51 @@ FSNode FSDirectory::getFSNode() const {
return _node; return _node;
} }
FSNode FSDirectory::lookupCache(NodeCache &cache, const String &name) const { FSNode *FSDirectory::lookupCache(NodeCache &cache, const String &name) const {
// make caching as lazy as possible // make caching as lazy as possible
if (!name.empty()) { if (!name.empty()) {
ensureCached(); ensureCached();
if (cache.contains(name)) if (cache.contains(name))
return cache[name]; return &cache[name];
} }
return FSNode(); return 0;
} }
bool FSDirectory::hasFile(const String &name) { bool FSDirectory::hasFile(const String &name) {
if (name.empty() || !_node.isDirectory()) if (name.empty() || !_node.isDirectory())
return false; return false;
FSNode node = lookupCache(_fileCache, name); FSNode *node = lookupCache(_fileCache, name);
return node.exists(); return node && node->exists();
} }
ArchiveMemberPtr FSDirectory::getMember(const String &name) { ArchiveMemberPtr FSDirectory::getMember(const String &name) {
if (name.empty() || !_node.isDirectory()) if (name.empty() || !_node.isDirectory())
return ArchiveMemberPtr(); return ArchiveMemberPtr();
FSNode node = lookupCache(_fileCache, name); FSNode *node = lookupCache(_fileCache, name);
if (!node.exists()) { if (!node || !node->exists()) {
warning("FSDirectory::getMember: FSNode does not exist"); warning("FSDirectory::getMember: FSNode does not exist");
return ArchiveMemberPtr(); return ArchiveMemberPtr();
} else if (node.isDirectory()) { } else if (node->isDirectory()) {
warning("FSDirectory::getMember: FSNode is a directory"); warning("FSDirectory::getMember: FSNode is a directory");
return ArchiveMemberPtr(); return ArchiveMemberPtr();
} }
return ArchiveMemberPtr(new FSNode(node)); return ArchiveMemberPtr(new FSNode(*node));
} }
SeekableReadStream *FSDirectory::createReadStreamForMember(const String &name) const { SeekableReadStream *FSDirectory::createReadStreamForMember(const String &name) const {
if (name.empty() || !_node.isDirectory()) if (name.empty() || !_node.isDirectory())
return 0; return 0;
FSNode node = lookupCache(_fileCache, name); FSNode *node = lookupCache(_fileCache, name);
SeekableReadStream *stream = node.createReadStream(); if (!node)
return 0;
SeekableReadStream *stream = node->createReadStream();
if (!stream) if (!stream)
warning("FSDirectory::createReadStreamForMember: Can't create stream for file '%s'", name.c_str()); warning("FSDirectory::createReadStreamForMember: Can't create stream for file '%s'", name.c_str());
@ -156,8 +158,11 @@ FSDirectory *FSDirectory::getSubDirectory(const String &prefix, const String &na
if (name.empty() || !_node.isDirectory()) if (name.empty() || !_node.isDirectory())
return 0; return 0;
FSNode node = lookupCache(_subDirCache, name); FSNode *node = lookupCache(_subDirCache, name);
return new FSDirectory(prefix, node, depth); if (!node)
return 0;
return new FSDirectory(prefix, *node, depth);
} }
void FSDirectory::cacheDirectoryRecursive(FSNode node, int depth, const String& prefix) const { void FSDirectory::cacheDirectoryRecursive(FSNode node, int depth, const String& prefix) const {
@ -380,8 +385,9 @@ SeekableReadStream *SearchSet::createReadStreamForMember(const String &name) con
ArchiveNodeList::iterator it = _list.begin(); ArchiveNodeList::iterator it = _list.begin();
for ( ; it != _list.end(); ++it) { for ( ; it != _list.end(); ++it) {
if (it->_arc->hasFile(name)) SeekableReadStream *stream = it->_arc->createReadStreamForMember(name);
return it->_arc->createReadStreamForMember(name); if (stream)
return stream;
} }
return 0; return 0;

View file

@ -116,7 +116,8 @@ public:
virtual ArchiveMemberPtr getMember(const String &name) = 0; virtual ArchiveMemberPtr getMember(const String &name) = 0;
/** /**
* Create a stream bound to a file in the archive. * Create a stream bound to a member in the archive. If no member with the
* specified name exists, then 0 is returned.
* @return the newly created input stream * @return the newly created input stream
*/ */
virtual SeekableReadStream *createReadStreamForMember(const String &name) const = 0; virtual SeekableReadStream *createReadStreamForMember(const String &name) const = 0;

View file

@ -268,7 +268,7 @@ class FSDirectory : public Archive {
mutable int _depth; mutable int _depth;
// look for a match // look for a match
FSNode lookupCache(NodeCache &cache, const String &name) const; FSNode *lookupCache(NodeCache &cache, const String &name) const;
// cache management // cache management
void cacheDirectoryRecursive(FSNode node, int depth, const String& prefix) const; void cacheDirectoryRecursive(FSNode node, int depth, const String& prefix) const;