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