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