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