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