1 /* 2 * Copyright 2007, Ingo Weinhold, ingo_weinhold@gmx.de. 3 * All rights reserved. Distributed under the terms of the MIT license. 4 */ 5 6 #include "Directory.h" 7 #include "Entry.h" 8 #include "EntryIterator.h" 9 #include "Volume.h" 10 11 // constructor 12 EntryIterator::EntryIterator(Directory *directory) 13 : fDirectory(directory), 14 fEntry(NULL), 15 fSuspended(false), 16 fIsNext(false), 17 fDone(false) 18 { 19 } 20 21 // destructor 22 EntryIterator::~EntryIterator() 23 { 24 Unset(); 25 } 26 27 // SetTo 28 status_t 29 EntryIterator::SetTo(Directory *directory) 30 { 31 Unset(); 32 status_t error = (directory ? B_OK : B_BAD_VALUE); 33 if (error == B_OK) { 34 fDirectory = directory; 35 fEntry = NULL; 36 fSuspended = false; 37 fIsNext = false; 38 fDone = false; 39 } 40 return error; 41 } 42 43 // Unset 44 void 45 EntryIterator::Unset() 46 { 47 if (fDirectory && fSuspended) 48 Resume(); 49 fDirectory = NULL; 50 fEntry = NULL; 51 fSuspended = false; 52 fIsNext = false; 53 fDone = false; 54 } 55 56 // Suspend 57 status_t 58 EntryIterator::Suspend() 59 { 60 status_t error = (fDirectory ? B_OK : B_ERROR); 61 if (error == B_OK) { 62 if (fDirectory->GetVolume()->IteratorLock()) { 63 if (!fSuspended) { 64 if (fEntry) 65 fEntry->AttachEntryIterator(this); 66 fDirectory->GetVolume()->IteratorUnlock(); 67 fSuspended = true; 68 } else 69 error = B_ERROR; 70 } else 71 error = B_ERROR; 72 } 73 return error; 74 } 75 76 // Resume 77 status_t 78 EntryIterator::Resume() 79 { 80 status_t error = (fDirectory ? B_OK : B_ERROR); 81 if (error == B_OK) { 82 if (fDirectory->GetVolume()->IteratorLock()) { 83 if (fSuspended) { 84 if (fEntry) 85 fEntry->DetachEntryIterator(this); 86 fSuspended = false; 87 } 88 fDirectory->GetVolume()->IteratorUnlock(); 89 } else 90 error = B_ERROR; 91 } 92 return error; 93 } 94 95 // GetNext 96 status_t 97 EntryIterator::GetNext(Entry **entry) 98 { 99 status_t error = B_ENTRY_NOT_FOUND; 100 if (!fDone && fDirectory && entry) { 101 if (fIsNext) { 102 fIsNext = false; 103 if (fEntry) 104 error = B_OK; 105 } else 106 error = fDirectory->GetNextEntry(&fEntry); 107 *entry = fEntry; 108 } 109 fDone = (error != B_OK); 110 return error; 111 } 112 113 // Rewind 114 status_t 115 EntryIterator::Rewind() 116 { 117 status_t error = (fDirectory ? B_OK : B_ERROR); 118 if (error == B_OK) { 119 if (fDirectory->GetVolume()->IteratorLock()) { 120 if (fSuspended && fEntry) 121 fEntry->DetachEntryIterator(this); 122 fEntry = NULL; 123 fIsNext = false; 124 fDone = false; 125 fDirectory->GetVolume()->IteratorUnlock(); 126 } else 127 error = B_ERROR; 128 } 129 return error; 130 } 131 132 // SetCurrent 133 void 134 EntryIterator::SetCurrent(Entry *entry, bool isNext) 135 { 136 fIsNext = isNext; 137 fEntry = entry; 138 fDone = !fEntry; 139 } 140 141