xref: /haiku/src/add-ons/kernel/file_systems/xfs/ShortAttribute.cpp (revision 4a55cc230cf7566cadcbb23b1928eefff8aea9a2)
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 
100 	size_t namelength = strlen(fName);
101 
102 	status_t status = Lookup(fName, &namelength);
103 
104 	uint32 lengthToRead = 0;
105 
106 	if (pos + *length > fEntry->valuelen)
107 		lengthToRead = fEntry->valuelen - pos;
108 	else
109 		lengthToRead = *length;
110 
111 	char* ptrToOffset = (char*) fHeader + sizeof(AShortFormHeader)
112 		+ 3 * sizeof(uint8) + fEntry->namelen;
113 
114 	memcpy(buffer, ptrToOffset, lengthToRead);
115 
116 	*length = lengthToRead;
117 
118 	return B_OK;
119 }
120 
121 
122 status_t
123 ShortAttribute::GetNext(char* name, size_t* nameLength)
124 {
125 	TRACE("Short Attribute : GetNext\n");
126 
127 	AShortFormEntry* entry = _FirstEntry();
128 	uint16 curOffset = 1;
129 	for (int i = 0; i < fHeader->count; i++) {
130 		if (curOffset > fLastEntryOffset) {
131 
132 			fLastEntryOffset = curOffset;
133 
134 			char* PtrToOffset = (char*)entry + 3 * sizeof(uint8);
135 
136 			memcpy(name, PtrToOffset, entry->namelen);
137 			name[entry->namelen] = '\0';
138 			*nameLength = entry->namelen + 1;
139 			TRACE("Entry found name : %s, namelength : %ld", name, *nameLength);
140 			return B_OK;
141 		}
142 		entry = (AShortFormEntry*)((char*)entry + 3 * sizeof(uint8) + _DataLength(entry));
143 		curOffset += 3 * sizeof(uint8) + _DataLength(entry);
144 	}
145 
146 	return B_ENTRY_NOT_FOUND;
147 }
148 
149 
150 status_t
151 ShortAttribute::Lookup(const char* name, size_t* nameLength)
152 {
153 	TRACE("Short Attribute : Lookup\n");
154 
155 	AShortFormEntry* entry = _FirstEntry();
156 
157 	int status;
158 
159 	for (int i = 0; i < fHeader->count; i++) {
160 		char* PtrToOffset = (char*)entry + 3 * sizeof(uint8);
161 		status = strncmp(name, PtrToOffset, *nameLength);
162 		if (status == 0) {
163 			fEntry = entry;
164 			return B_OK;
165 		}
166 		entry = (AShortFormEntry*)((char*)entry + 3 * sizeof(uint8) + _DataLength(entry));
167 	}
168 
169 	return B_ENTRY_NOT_FOUND;
170 }
171