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
13AutoPackageAttributeDirectoryCookie::AutoPackageAttributeDirectoryCookie()
14	:
15	fState(AUTO_PACKAGE_ATTRIBUTE_ENUM_FIRST)
16{
17}
18
19
20AutoPackageAttributeDirectoryCookie::~AutoPackageAttributeDirectoryCookie()
21{
22}
23
24
25status_t
26AutoPackageAttributeDirectoryCookie::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
90status_t
91AutoPackageAttributeDirectoryCookie::Rewind()
92{
93	fState = AUTO_PACKAGE_ATTRIBUTE_ENUM_FIRST;
94
95	return B_OK;
96}
97
98
99String
100AutoPackageAttributeDirectoryCookie::CurrentCustomAttributeName()
101{
102	return String();
103}
104
105
106String
107AutoPackageAttributeDirectoryCookie::NextCustomAttributeName()
108{
109	return String();
110}
111