xref: /haiku/src/add-ons/kernel/file_systems/ramfs/Attribute.cpp (revision 2f470aec1c92ce6917b8a903e343795dc77af41f)
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