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 14 Attribute::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 27 Attribute::~Attribute() 28 { 29 } 30 31 // InitCheck 32 status_t 33 Attribute::InitCheck() const 34 { 35 return (fName.GetString() ? B_OK : B_NO_INIT); 36 } 37 38 // SetType 39 void 40 Attribute::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 54 status_t 55 Attribute::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 69 status_t 70 Attribute::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; 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 < kMaxIndexKeyLength && size > 0 && fIndex) 84 fIndex->Changed(this, oldKey, oldLength); 85 86 // update live queries 87 uint8 newKey[kMaxIndexKeyLength]; 88 size_t newLength; 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 101 void 102 Attribute::SetIndex(AttributeIndex *index, bool inIndex) 103 { 104 fIndex = index; 105 fInIndex = inIndex; 106 } 107 108 // GetKey 109 void 110 Attribute::GetKey(uint8 *key, size_t *length) 111 { 112 *length = min(*length, kMaxIndexKeyLength); 113 ReadAt(0, key, *length, length); 114 } 115 116 // AttachAttributeIterator 117 void 118 Attribute::AttachAttributeIterator(AttributeIterator *iterator) 119 { 120 if (iterator && iterator->GetCurrent() == this && !iterator->IsSuspended()) 121 fIterators.Insert(iterator); 122 } 123 124 // DetachAttributeIterator 125 void 126 Attribute::DetachAttributeIterator(AttributeIterator *iterator) 127 { 128 if (iterator && iterator->GetCurrent() == this && iterator->IsSuspended()) 129 fIterators.Remove(iterator); 130 } 131 132 // GetAllocationInfo 133 void 134 Attribute::GetAllocationInfo(AllocationInfo &info) 135 { 136 DataContainer::GetAllocationInfo(info); 137 info.AddAttributeAllocation(GetSize()); 138 info.AddStringAllocation(fName.GetLength()); 139 } 140 141