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