xref: /haiku/src/add-ons/kernel/file_systems/xfs/ShortAttribute.cpp (revision b4b3f69fcadd506df2d09fa07b639b64ab195a06)
1*b4b3f69fSMashijams /*
2*b4b3f69fSMashijams  * Copyright 2022, Raghav Sharma, raghavself28@gmail.com
3*b4b3f69fSMashijams  * Distributed under the terms of the MIT License.
4*b4b3f69fSMashijams  */
5*b4b3f69fSMashijams 
6*b4b3f69fSMashijams 
7*b4b3f69fSMashijams #include "ShortAttribute.h"
8*b4b3f69fSMashijams 
9*b4b3f69fSMashijams 
10*b4b3f69fSMashijams ShortAttribute::ShortAttribute(Inode* inode)
11*b4b3f69fSMashijams 	:
12*b4b3f69fSMashijams 	fInode(inode),
13*b4b3f69fSMashijams 	fName(NULL)
14*b4b3f69fSMashijams {
15*b4b3f69fSMashijams 	fHeader = (AShortFormHeader*)(DIR_AFORK_PTR(fInode->Buffer(),
16*b4b3f69fSMashijams 		fInode->CoreInodeSize(), fInode->ForkOffset()));
17*b4b3f69fSMashijams 
18*b4b3f69fSMashijams 	fLastEntryOffset = 0;
19*b4b3f69fSMashijams }
20*b4b3f69fSMashijams 
21*b4b3f69fSMashijams 
22*b4b3f69fSMashijams ShortAttribute::~ShortAttribute()
23*b4b3f69fSMashijams {
24*b4b3f69fSMashijams }
25*b4b3f69fSMashijams 
26*b4b3f69fSMashijams 
27*b4b3f69fSMashijams uint32
28*b4b3f69fSMashijams ShortAttribute::_DataLength(AShortFormEntry* entry)
29*b4b3f69fSMashijams {
30*b4b3f69fSMashijams 	return entry->namelen + entry->valuelen;
31*b4b3f69fSMashijams }
32*b4b3f69fSMashijams 
33*b4b3f69fSMashijams 
34*b4b3f69fSMashijams AShortFormEntry*
35*b4b3f69fSMashijams ShortAttribute::_FirstEntry()
36*b4b3f69fSMashijams {
37*b4b3f69fSMashijams 	return (AShortFormEntry*) ((char*) fHeader + sizeof(AShortFormHeader));
38*b4b3f69fSMashijams }
39*b4b3f69fSMashijams 
40*b4b3f69fSMashijams 
41*b4b3f69fSMashijams status_t
42*b4b3f69fSMashijams ShortAttribute::Open(const char* name, int openMode, attr_cookie** _cookie)
43*b4b3f69fSMashijams {
44*b4b3f69fSMashijams 	TRACE("ShortAttribute::Open\n");
45*b4b3f69fSMashijams 	status_t status;
46*b4b3f69fSMashijams 
47*b4b3f69fSMashijams 	size_t length = strlen(name);
48*b4b3f69fSMashijams 	status = Lookup(name, &length);
49*b4b3f69fSMashijams 	if (status < B_OK)
50*b4b3f69fSMashijams 		return status;
51*b4b3f69fSMashijams 
52*b4b3f69fSMashijams 	attr_cookie* cookie = new(std::nothrow) attr_cookie;
53*b4b3f69fSMashijams 	if (cookie == NULL)
54*b4b3f69fSMashijams 		return B_NO_MEMORY;
55*b4b3f69fSMashijams 
56*b4b3f69fSMashijams 	fName = name;
57*b4b3f69fSMashijams 
58*b4b3f69fSMashijams 	// initialize the cookie
59*b4b3f69fSMashijams 	strlcpy(cookie->name, fName, B_ATTR_NAME_LENGTH);
60*b4b3f69fSMashijams 	cookie->open_mode = openMode;
61*b4b3f69fSMashijams 	cookie->create = false;
62*b4b3f69fSMashijams 
63*b4b3f69fSMashijams 	*_cookie = cookie;
64*b4b3f69fSMashijams 	return B_OK;
65*b4b3f69fSMashijams }
66*b4b3f69fSMashijams 
67*b4b3f69fSMashijams 
68*b4b3f69fSMashijams status_t
69*b4b3f69fSMashijams ShortAttribute::Stat(attr_cookie* cookie, struct stat& stat)
70*b4b3f69fSMashijams {
71*b4b3f69fSMashijams 	TRACE("Short Attribute : Stat\n");
72*b4b3f69fSMashijams 
73*b4b3f69fSMashijams 	fName = cookie->name;
74*b4b3f69fSMashijams 
75*b4b3f69fSMashijams 	size_t namelength = strlen(fName);
76*b4b3f69fSMashijams 
77*b4b3f69fSMashijams 	// check if this attribute exists
78*b4b3f69fSMashijams 	status_t status = Lookup(fName, &namelength);
79*b4b3f69fSMashijams 	if (status != B_OK)
80*b4b3f69fSMashijams 		return status;
81*b4b3f69fSMashijams 
82*b4b3f69fSMashijams 	// We have valid attribute entry to stat
83*b4b3f69fSMashijams 	stat.st_type = B_XATTR_TYPE;
84*b4b3f69fSMashijams 	stat.st_size = _DataLength(fEntry);
85*b4b3f69fSMashijams 
86*b4b3f69fSMashijams 	return B_OK;
87*b4b3f69fSMashijams }
88*b4b3f69fSMashijams 
89*b4b3f69fSMashijams 
90*b4b3f69fSMashijams status_t
91*b4b3f69fSMashijams ShortAttribute::Read(attr_cookie* cookie, off_t pos, uint8* buffer, size_t* length)
92*b4b3f69fSMashijams {
93*b4b3f69fSMashijams 	TRACE("Short Attribute : Read\n");
94*b4b3f69fSMashijams 
95*b4b3f69fSMashijams 	if (pos < 0)
96*b4b3f69fSMashijams 		return B_BAD_VALUE;
97*b4b3f69fSMashijams 
98*b4b3f69fSMashijams 	fName = cookie->name;
99*b4b3f69fSMashijams 
100*b4b3f69fSMashijams 	size_t namelength = strlen(fName);
101*b4b3f69fSMashijams 
102*b4b3f69fSMashijams 	status_t status = Lookup(fName, &namelength);
103*b4b3f69fSMashijams 
104*b4b3f69fSMashijams 	uint32 lengthToRead = 0;
105*b4b3f69fSMashijams 
106*b4b3f69fSMashijams 	if (pos + *length > fEntry->valuelen)
107*b4b3f69fSMashijams 		lengthToRead = fEntry->valuelen - pos;
108*b4b3f69fSMashijams 	else
109*b4b3f69fSMashijams 		lengthToRead = *length;
110*b4b3f69fSMashijams 
111*b4b3f69fSMashijams 	char* ptrToOffset = (char*) fHeader + sizeof(AShortFormHeader)
112*b4b3f69fSMashijams 		+ 3 * sizeof(uint8) + fEntry->namelen;
113*b4b3f69fSMashijams 
114*b4b3f69fSMashijams 	memcpy(buffer, ptrToOffset, lengthToRead);
115*b4b3f69fSMashijams 
116*b4b3f69fSMashijams 	*length = lengthToRead;
117*b4b3f69fSMashijams 
118*b4b3f69fSMashijams 	return B_OK;
119*b4b3f69fSMashijams }
120*b4b3f69fSMashijams 
121*b4b3f69fSMashijams 
122*b4b3f69fSMashijams status_t
123*b4b3f69fSMashijams ShortAttribute::GetNext(char* name, size_t* nameLength)
124*b4b3f69fSMashijams {
125*b4b3f69fSMashijams 	TRACE("Short Attribute : GetNext\n");
126*b4b3f69fSMashijams 
127*b4b3f69fSMashijams 	AShortFormEntry* entry = _FirstEntry();
128*b4b3f69fSMashijams 	uint16 curOffset = 1;
129*b4b3f69fSMashijams 	for (int i = 0; i < fHeader->count; i++) {
130*b4b3f69fSMashijams 		if (curOffset > fLastEntryOffset) {
131*b4b3f69fSMashijams 
132*b4b3f69fSMashijams 			fLastEntryOffset = curOffset;
133*b4b3f69fSMashijams 
134*b4b3f69fSMashijams 			char* PtrToOffset = (char*)entry + 3 * sizeof(uint8);
135*b4b3f69fSMashijams 
136*b4b3f69fSMashijams 			memcpy(name, PtrToOffset, entry->namelen);
137*b4b3f69fSMashijams 			name[entry->namelen] = '\0';
138*b4b3f69fSMashijams 			*nameLength = entry->namelen + 1;
139*b4b3f69fSMashijams 			TRACE("Entry found name : %s, namelength : %ld", name, *nameLength);
140*b4b3f69fSMashijams 			return B_OK;
141*b4b3f69fSMashijams 		}
142*b4b3f69fSMashijams 		entry = (AShortFormEntry*)((char*)entry + 3 * sizeof(uint8) + _DataLength(entry));
143*b4b3f69fSMashijams 		curOffset += 3 * sizeof(uint8) + _DataLength(entry);
144*b4b3f69fSMashijams 	}
145*b4b3f69fSMashijams 
146*b4b3f69fSMashijams 	return B_ENTRY_NOT_FOUND;
147*b4b3f69fSMashijams }
148*b4b3f69fSMashijams 
149*b4b3f69fSMashijams 
150*b4b3f69fSMashijams status_t
151*b4b3f69fSMashijams ShortAttribute::Lookup(const char* name, size_t* nameLength)
152*b4b3f69fSMashijams {
153*b4b3f69fSMashijams 	TRACE("Short Attribute : Lookup\n");
154*b4b3f69fSMashijams 
155*b4b3f69fSMashijams 	AShortFormEntry* entry = _FirstEntry();
156*b4b3f69fSMashijams 
157*b4b3f69fSMashijams 	int status;
158*b4b3f69fSMashijams 
159*b4b3f69fSMashijams 	for (int i = 0; i < fHeader->count; i++) {
160*b4b3f69fSMashijams 		char* PtrToOffset = (char*)entry + 3 * sizeof(uint8);
161*b4b3f69fSMashijams 		status = strncmp(name, PtrToOffset, *nameLength);
162*b4b3f69fSMashijams 		if (status == 0) {
163*b4b3f69fSMashijams 			fEntry = entry;
164*b4b3f69fSMashijams 			return B_OK;
165*b4b3f69fSMashijams 		}
166*b4b3f69fSMashijams 		entry = (AShortFormEntry*)((char*)entry + 3 * sizeof(uint8) + _DataLength(entry));
167*b4b3f69fSMashijams 	}
168*b4b3f69fSMashijams 
169*b4b3f69fSMashijams 	return B_ENTRY_NOT_FOUND;
170*b4b3f69fSMashijams }
171