xref: /haiku/src/add-ons/kernel/file_systems/ramfs/EntryIterator.cpp (revision 21258e2674226d6aa732321b6f8494841895af5f)
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