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