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