/** * Stats the given file. If <tt>throttleRate</tt> seconds have passed since * the last time stat() was called on this file, then the file will be * re-stat()ted, otherwise the cached stat information will be returned. * * @param filename The file to stat. * @param stat A pointer to a stat struct; the retrieved stat information * will be stored here. * @param throttleRate Tells this CachedFileStat that the file may only * be statted at most every <tt>throttleRate</tt> seconds. * @return 0 if the stat() call succeeded or if the cached stat information was used; * -1 if something went wrong while statting the file. In the latter * case, <tt>errno</tt> will be populated with an appropriate error code. * @throws SystemException Something went wrong while retrieving the * system time. stat() errors will <em>not</em> result in * SystemException being thrown. * @throws boost::thread_interrupted */ int stat(const string &filename, struct stat *buf, unsigned int throttleRate = 0) { boost::unique_lock<boost::mutex> l(lock); EntryMap::iterator it(cache.find(filename)); EntryPtr entry; int ret; if (it == cache.end()) { // Filename not in cache. // If cache is full, remove the least recently used // cache entry. if (maxSize != 0 && cache.size() == maxSize) { EntryList::iterator listEnd(entries.end()); listEnd--; string filename((*listEnd)->filename); entries.pop_back(); cache.erase(filename); } // Add to cache as most recently used. entry = EntryPtr(new Entry(filename)); entries.push_front(entry); cache[filename] = entries.begin(); } else { // Cache hit. entry = *it->second; // Mark this cache item as most recently used. entries.erase(it->second); entries.push_front(entry); cache[filename] = entries.begin(); } ret = entry->refresh(throttleRate); *buf = entry->info; return ret; }
/////////////////////////////////////////////////////////////////////////////// // Read // size_t DirectoryIterator::Read(const char16_t* pDirectory, EntryList& entryList, const char16_t* pFilterPattern, int nDirectoryEntryFlags, size_t maxResultCount) { EntryFindData entryFindData, *pEntryFindData; size_t resultCount = 0; #if EASTL_NAME_ENABLED // If the EntryList doesn't have a unique name, we give it one here. if(entryList.get_allocator().get_name() && !strcmp(EASTL_LIST_DEFAULT_NAME, entryList.get_allocator().get_name())) entryList.get_allocator().set_name(ENTRYLIST_NAME); #endif // Iterate entries. for(pEntryFindData = EntryFindFirst(pDirectory, pFilterPattern, &entryFindData); pEntryFindData && (resultCount < maxResultCount); ) { if(!StrEq16(pEntryFindData->mName, EA_DIRECTORY_CURRENT_16) && // If it is neither "./" nor "../" !StrEq16(pEntryFindData->mName, EA_DIRECTORY_PARENT_16)) { if(pEntryFindData->mbIsDirectory) { if(nDirectoryEntryFlags & kDirectoryEntryDirectory) { resultCount++; entryList.push_back(); entryList.back().mType = kDirectoryEntryDirectory; entryList.back().msName = pEntryFindData->mName; } } else { if(nDirectoryEntryFlags & kDirectoryEntryFile) { resultCount++; entryList.push_back(); entryList.back().mType = kDirectoryEntryFile; entryList.back().msName = pEntryFindData->mName; } } } if(!EntryFindNext(pEntryFindData)) { EntryFindFinish(pEntryFindData); break; } } if(pEntryFindData) { if((nDirectoryEntryFlags & kDirectoryEntryCurrent) && (resultCount < maxResultCount)) { resultCount++; entryList.push_front(); entryList.front().mType = kDirectoryEntryDirectory; entryList.front().msName = EA_DIRECTORY_CURRENT_16; } if((nDirectoryEntryFlags & kDirectoryEntryParent) && (resultCount < maxResultCount)) { // To do: We don't want to do this if the directory is a root directory. resultCount++; entryList.push_front(); entryList.front().mType = kDirectoryEntryDirectory; entryList.front().msName = EA_DIRECTORY_PARENT_16; } } return resultCount; }