/* * Copyright 2013, Haiku, Inc. * Distributed under the terms of the MIT License. * * Authors: * Ingo Weinhold, ingo_weinhold@gmx.de */ #include "VirtualDirectoryEntryList.h" #include #include #include "Model.h" #include "VirtualDirectoryManager.h" namespace BPrivate { // #pragma mark - VirtualDirectoryEntryList VirtualDirectoryEntryList::VirtualDirectoryEntryList(Model* model) : EntryListBase(), fDefinitionFileRef(), fMergedDirectory(BMergedDirectory::B_ALWAYS_FIRST) { VirtualDirectoryManager* manager = VirtualDirectoryManager::Instance(); if (manager == NULL) { fStatus = B_NO_MEMORY; return; } AutoLocker managerLocker(manager); BStringList directoryPaths; fStatus = manager->ResolveDirectoryPaths(*model->NodeRef(), *model->EntryRef(), directoryPaths, &fDefinitionFileRef); if (fStatus != B_OK) return; fStatus = _InitMergedDirectory(directoryPaths); } VirtualDirectoryEntryList::VirtualDirectoryEntryList( const node_ref& definitionFileRef, const BStringList& directoryPaths) : EntryListBase(), fDefinitionFileRef(definitionFileRef), fMergedDirectory(BMergedDirectory::B_ALWAYS_FIRST) { fStatus = _InitMergedDirectory(directoryPaths); } VirtualDirectoryEntryList::~VirtualDirectoryEntryList() { } status_t VirtualDirectoryEntryList::InitCheck() const { return EntryListBase::InitCheck(); } status_t VirtualDirectoryEntryList::GetNextEntry(BEntry* entry, bool traverse) { entry_ref ref; status_t error = GetNextRef(&ref); if (error != B_OK) return error; return entry->SetTo(&ref, traverse); } status_t VirtualDirectoryEntryList::GetNextRef(entry_ref* ref) { BPrivate::Storage::LongDirEntry longEntry; struct dirent* entry = longEntry.dirent(); int32 result = GetNextDirents(entry, sizeof(longEntry), 1); if (result < 0) return result; if (result == 0) return B_ENTRY_NOT_FOUND; ref->device = entry->d_pdev; ref->directory = entry->d_pino; return ref->set_name(entry->d_name); } int32 VirtualDirectoryEntryList::GetNextDirents(struct dirent* buffer, size_t length, int32 count) { if (count > 1) count = 1; int32 countRead = fMergedDirectory.GetNextDirents(buffer, length, count); if (countRead != 1) return countRead; // deal with directories entry_ref ref; ref.device = buffer->d_pdev; ref.directory = buffer->d_pino; if (ref.set_name(buffer->d_name) == B_OK && BEntry(&ref).IsDirectory()) { if (VirtualDirectoryManager* manager = VirtualDirectoryManager::Instance()) { AutoLocker managerLocker(manager); manager->TranslateDirectoryEntry(fDefinitionFileRef, buffer); } } return countRead; } status_t VirtualDirectoryEntryList::Rewind() { return fMergedDirectory.Rewind(); } int32 VirtualDirectoryEntryList::CountEntries() { return 0; } status_t VirtualDirectoryEntryList::_InitMergedDirectory( const BStringList& directoryPaths) { status_t error = fMergedDirectory.Init(); if (error != B_OK) return error; int32 count = directoryPaths.CountStrings(); for (int32 i = 0; i < count; i++) fMergedDirectory.AddDirectory(directoryPaths.StringAt(i)); return B_OK; } } // namespace BPrivate