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