xref: /haiku/src/add-ons/kernel/file_systems/ramfs/EntryIterator.cpp (revision 820dca4df6c7bf955c46e8f6521b9408f50b2900)
1 // EntryIterator.cpp
2 
3 #include "Directory.h"
4 #include "Entry.h"
5 #include "EntryIterator.h"
6 #include "Volume.h"
7 
8 // constructor
9 EntryIterator::EntryIterator(Directory *directory)
10 	: fDirectory(directory),
11 	  fEntry(NULL),
12 	  fSuspended(false),
13 	  fIsNext(false),
14 	  fDone(false)
15 {
16 }
17 
18 // destructor
19 EntryIterator::~EntryIterator()
20 {
21 	Unset();
22 }
23 
24 // SetTo
25 status_t
26 EntryIterator::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
41 void
42 EntryIterator::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
54 status_t
55 EntryIterator::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
74 status_t
75 EntryIterator::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
93 status_t
94 EntryIterator::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
111 status_t
112 EntryIterator::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
130 void
131 EntryIterator::SetCurrent(Entry *entry, bool isNext)
132 {
133 	fIsNext = isNext;
134 	fEntry = entry;
135 	fDone = !fEntry;
136 }
137 
138