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