1// Attribute.cpp 2 3#include "AllocationInfo.h" 4#include "Attribute.h" 5#include "Misc.h" 6#include "Node.h" 7#include "ramfs.h" 8#include "Volume.h" 9 10// constructor 11Attribute::Attribute(Volume *volume, Node *node, const char *name, 12 uint32 type) 13 : DataContainer(volume), 14 fNode(node), 15 fName(name), 16 fType(type), 17 fIndex(NULL), 18 fInIndex(false), 19 fIterators() 20{ 21} 22 23// destructor 24Attribute::~Attribute() 25{ 26} 27 28// InitCheck 29status_t 30Attribute::InitCheck() const 31{ 32 return (fName.GetString() ? B_OK : B_NO_INIT); 33} 34 35// SetType 36void 37Attribute::SetType(uint32 type) 38{ 39 if (type != fType) { 40 if (fIndex) 41 fIndex->Removed(this); 42 fType = type; 43 if (AttributeIndex *index = GetVolume()->FindAttributeIndex(GetName(), 44 fType)) { 45 index->Added(this); 46 } 47 } 48} 49 50// SetSize 51status_t 52Attribute::SetSize(off_t newSize) 53{ 54 status_t error = B_OK; 55 off_t oldSize = DataContainer::GetSize(); 56 if (newSize != oldSize) { 57 if (fNode) 58 fNode->MarkModified(B_STAT_MODIFICATION_TIME); 59 60 error = DataContainer::Resize(newSize); 61 } 62 return error; 63} 64 65// WriteAt 66status_t 67Attribute::WriteAt(off_t offset, const void *buffer, size_t size, 68 size_t *bytesWritten) 69{ 70 // get the current key for the attribute 71 uint8 oldKey[kMaxIndexKeyLength]; 72 size_t oldLength; 73 GetKey(oldKey, &oldLength); 74 75 // write the new value 76 status_t error = DataContainer::WriteAt(offset, buffer, size, bytesWritten); 77 78 // If there is an index and a change has been made within the key, notify 79 // the index. 80 if (offset < kMaxIndexKeyLength && size > 0 && fIndex) 81 fIndex->Changed(this, oldKey, oldLength); 82 83 // update live queries 84 const uint8* newKey; 85 size_t newLength; 86 GetKey(&newKey, &newLength); 87 GetVolume()->UpdateLiveQueries(NULL, fNode, GetName(), fType, oldKey, 88 oldLength, newKey, newLength); 89 90 // node has been changed 91 if (fNode && size > 0) 92 fNode->MarkModified(B_STAT_MODIFICATION_TIME); 93 94 return error; 95} 96 97// SetIndex 98void 99Attribute::SetIndex(AttributeIndex *index, bool inIndex) 100{ 101 fIndex = index; 102 fInIndex = inIndex; 103} 104 105// GetKey 106void 107Attribute::GetKey(const uint8 **key, size_t *length) 108{ 109 if (key && length) { 110 GetFirstDataBlock(key, length); 111 *length = min(*length, kMaxIndexKeyLength); 112 } 113} 114 115// GetKey 116void 117Attribute::GetKey(uint8 *key, size_t *length) 118{ 119 if (key && length) { 120 const uint8 *originalKey = NULL; 121 GetKey(&originalKey, length); 122 if (length > 0) 123 memcpy(key, originalKey, *length); 124 } 125} 126 127// AttachAttributeIterator 128void 129Attribute::AttachAttributeIterator(AttributeIterator *iterator) 130{ 131 if (iterator && iterator->GetCurrent() == this && !iterator->IsSuspended()) 132 fIterators.Insert(iterator); 133} 134 135// DetachAttributeIterator 136void 137Attribute::DetachAttributeIterator(AttributeIterator *iterator) 138{ 139 if (iterator && iterator->GetCurrent() == this && iterator->IsSuspended()) 140 fIterators.Remove(iterator); 141} 142 143// GetAllocationInfo 144void 145Attribute::GetAllocationInfo(AllocationInfo &info) 146{ 147 DataContainer::GetAllocationInfo(info); 148 info.AddAttributeAllocation(GetSize()); 149 info.AddStringAllocation(fName.GetLength()); 150} 151 152