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
10AttributeIterator::AttributeIterator(Node *node)
11	: fNode(node),
12	  fAttribute(NULL),
13	  fSuspended(false),
14	  fIsNext(false),
15	  fDone(false)
16{
17}
18
19// destructor
20AttributeIterator::~AttributeIterator()
21{
22	Unset();
23}
24
25// SetTo
26status_t
27AttributeIterator::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
42void
43AttributeIterator::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
55status_t
56AttributeIterator::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
75status_t
76AttributeIterator::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
94status_t
95AttributeIterator::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
112status_t
113AttributeIterator::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
131void
132AttributeIterator::SetCurrent(Attribute *attribute, bool isNext)
133{
134	fIsNext = isNext;
135	fAttribute = attribute;
136	fDone = !fAttribute;
137}
138
139