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