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 11 Attribute::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 24 Attribute::~Attribute() 25 { 26 } 27 28 // InitCheck 29 status_t 30 Attribute::InitCheck() const 31 { 32 return (fName.GetString() ? B_OK : B_NO_INIT); 33 } 34 35 // SetType 36 void 37 Attribute::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 51 status_t 52 Attribute::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 66 status_t 67 Attribute::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 98 void 99 Attribute::SetIndex(AttributeIndex *index, bool inIndex) 100 { 101 fIndex = index; 102 fInIndex = inIndex; 103 } 104 105 // GetKey 106 void 107 Attribute::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 116 void 117 Attribute::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 128 void 129 Attribute::AttachAttributeIterator(AttributeIterator *iterator) 130 { 131 if (iterator && iterator->GetCurrent() == this && !iterator->IsSuspended()) 132 fIterators.Insert(iterator); 133 } 134 135 // DetachAttributeIterator 136 void 137 Attribute::DetachAttributeIterator(AttributeIterator *iterator) 138 { 139 if (iterator && iterator->GetCurrent() == this && iterator->IsSuspended()) 140 fIterators.Remove(iterator); 141 } 142 143 // GetAllocationInfo 144 void 145 Attribute::GetAllocationInfo(AllocationInfo &info) 146 { 147 DataContainer::GetAllocationInfo(info); 148 info.AddAttributeAllocation(GetSize()); 149 info.AddStringAllocation(fName.GetLength()); 150 } 151 152