xref: /haiku/src/add-ons/kernel/file_systems/packagefs/nodes/AutoPackageAttributeDirectoryCookie.cpp (revision 4c61288e73ab85766ae2709a38809384cd7ed489)
1*4c61288eSIngo Weinhold /*
2*4c61288eSIngo Weinhold  * Copyright 2011-2013, Ingo Weinhold, ingo_weinhold@gmx.de.
3*4c61288eSIngo Weinhold  * Distributed under the terms of the MIT License.
4*4c61288eSIngo Weinhold  */
5*4c61288eSIngo Weinhold 
6*4c61288eSIngo Weinhold 
7*4c61288eSIngo Weinhold #include "AutoPackageAttributeDirectoryCookie.h"
8*4c61288eSIngo Weinhold 
9*4c61288eSIngo Weinhold #include "DebugSupport.h"
10*4c61288eSIngo Weinhold #include "Utils.h"
11*4c61288eSIngo Weinhold 
12*4c61288eSIngo Weinhold 
AutoPackageAttributeDirectoryCookie()13*4c61288eSIngo Weinhold AutoPackageAttributeDirectoryCookie::AutoPackageAttributeDirectoryCookie()
14*4c61288eSIngo Weinhold 	:
15*4c61288eSIngo Weinhold 	fState(AUTO_PACKAGE_ATTRIBUTE_ENUM_FIRST)
16*4c61288eSIngo Weinhold {
17*4c61288eSIngo Weinhold }
18*4c61288eSIngo Weinhold 
19*4c61288eSIngo Weinhold 
~AutoPackageAttributeDirectoryCookie()20*4c61288eSIngo Weinhold AutoPackageAttributeDirectoryCookie::~AutoPackageAttributeDirectoryCookie()
21*4c61288eSIngo Weinhold {
22*4c61288eSIngo Weinhold }
23*4c61288eSIngo Weinhold 
24*4c61288eSIngo Weinhold 
25*4c61288eSIngo Weinhold status_t
Read(dev_t volumeID,ino_t nodeID,struct dirent * buffer,size_t bufferSize,uint32 * _count)26*4c61288eSIngo Weinhold AutoPackageAttributeDirectoryCookie::Read(dev_t volumeID, ino_t nodeID,
27*4c61288eSIngo Weinhold 	struct dirent* buffer, size_t bufferSize, uint32* _count)
28*4c61288eSIngo Weinhold {
29*4c61288eSIngo Weinhold 	uint32 maxCount = *_count;
30*4c61288eSIngo Weinhold 	uint32 count = 0;
31*4c61288eSIngo Weinhold 
32*4c61288eSIngo Weinhold 	dirent* previousEntry = NULL;
33*4c61288eSIngo Weinhold 
34*4c61288eSIngo Weinhold 	String customAttributeName = CurrentCustomAttributeName();
35*4c61288eSIngo Weinhold 
36*4c61288eSIngo Weinhold 	while (fState < AUTO_PACKAGE_ATTRIBUTE_ENUM_COUNT
37*4c61288eSIngo Weinhold 		|| !customAttributeName.IsEmpty()) {
38*4c61288eSIngo Weinhold 		// don't read more entries than requested
39*4c61288eSIngo Weinhold 		if (count >= maxCount)
40*4c61288eSIngo Weinhold 			break;
41*4c61288eSIngo Weinhold 
42*4c61288eSIngo Weinhold 		// align the buffer for subsequent entries
43*4c61288eSIngo Weinhold 		if (count > 0) {
44*4c61288eSIngo Weinhold 			addr_t offset = (addr_t)buffer % 8;
45*4c61288eSIngo Weinhold 			if (offset > 0) {
46*4c61288eSIngo Weinhold 				offset = 8 - offset;
47*4c61288eSIngo Weinhold 				if (bufferSize <= offset)
48*4c61288eSIngo Weinhold 					break;
49*4c61288eSIngo Weinhold 
50*4c61288eSIngo Weinhold 				previousEntry->d_reclen += offset;
51*4c61288eSIngo Weinhold 				buffer = (dirent*)((addr_t)buffer + offset);
52*4c61288eSIngo Weinhold 				bufferSize -= offset;
53*4c61288eSIngo Weinhold 			}
54*4c61288eSIngo Weinhold 		}
55*4c61288eSIngo Weinhold 
56*4c61288eSIngo Weinhold 		// get the attribute name
57*4c61288eSIngo Weinhold 		const String& name = fState < AUTO_PACKAGE_ATTRIBUTE_ENUM_COUNT
58*4c61288eSIngo Weinhold 			? AutoPackageAttributes::NameForAttribute(
59*4c61288eSIngo Weinhold 				(AutoPackageAttribute)fState)
60*4c61288eSIngo Weinhold 			: customAttributeName;
61*4c61288eSIngo Weinhold 
62*4c61288eSIngo Weinhold 		// fill in the entry name -- checks whether the entry fits into the
63*4c61288eSIngo Weinhold 		// buffer
64*4c61288eSIngo Weinhold 		if (!set_dirent_name(buffer, bufferSize, name, strlen(name))) {
65*4c61288eSIngo Weinhold 			if (count == 0)
66*4c61288eSIngo Weinhold 				RETURN_ERROR(B_BUFFER_OVERFLOW);
67*4c61288eSIngo Weinhold 			break;
68*4c61288eSIngo Weinhold 		}
69*4c61288eSIngo Weinhold 
70*4c61288eSIngo Weinhold 		// fill in the other data
71*4c61288eSIngo Weinhold 		buffer->d_dev = volumeID;
72*4c61288eSIngo Weinhold 		buffer->d_ino = nodeID;
73*4c61288eSIngo Weinhold 
74*4c61288eSIngo Weinhold 		count++;
75*4c61288eSIngo Weinhold 		previousEntry = buffer;
76*4c61288eSIngo Weinhold 		bufferSize -= buffer->d_reclen;
77*4c61288eSIngo Weinhold 		buffer = (dirent*)((addr_t)buffer + buffer->d_reclen);
78*4c61288eSIngo Weinhold 
79*4c61288eSIngo Weinhold 		if (fState < AUTO_PACKAGE_ATTRIBUTE_ENUM_COUNT)
80*4c61288eSIngo Weinhold 			fState++;
81*4c61288eSIngo Weinhold 		else
82*4c61288eSIngo Weinhold 			customAttributeName = NextCustomAttributeName();
83*4c61288eSIngo Weinhold 	}
84*4c61288eSIngo Weinhold 
85*4c61288eSIngo Weinhold 	*_count = count;
86*4c61288eSIngo Weinhold 	return B_OK;
87*4c61288eSIngo Weinhold }
88*4c61288eSIngo Weinhold 
89*4c61288eSIngo Weinhold 
90*4c61288eSIngo Weinhold status_t
Rewind()91*4c61288eSIngo Weinhold AutoPackageAttributeDirectoryCookie::Rewind()
92*4c61288eSIngo Weinhold {
93*4c61288eSIngo Weinhold 	fState = AUTO_PACKAGE_ATTRIBUTE_ENUM_FIRST;
94*4c61288eSIngo Weinhold 
95*4c61288eSIngo Weinhold 	return B_OK;
96*4c61288eSIngo Weinhold }
97*4c61288eSIngo Weinhold 
98*4c61288eSIngo Weinhold 
99*4c61288eSIngo Weinhold String
CurrentCustomAttributeName()100*4c61288eSIngo Weinhold AutoPackageAttributeDirectoryCookie::CurrentCustomAttributeName()
101*4c61288eSIngo Weinhold {
102*4c61288eSIngo Weinhold 	return String();
103*4c61288eSIngo Weinhold }
104*4c61288eSIngo Weinhold 
105*4c61288eSIngo Weinhold 
106*4c61288eSIngo Weinhold String
NextCustomAttributeName()107*4c61288eSIngo Weinhold AutoPackageAttributeDirectoryCookie::NextCustomAttributeName()
108*4c61288eSIngo Weinhold {
109*4c61288eSIngo Weinhold 	return String();
110*4c61288eSIngo Weinhold }
111