xref: /haiku/src/add-ons/kernel/file_systems/ext2/DirectoryIterator.cpp (revision e0ef64750f3169cd634bb2f7a001e22488b05231)
1 /*
2  * Copyright 2008, Axel Dörfler, axeld@pinc-software.de.
3  * This file may be used under the terms of the MIT License.
4  */
5 
6 
7 #include "DirectoryIterator.h"
8 
9 #include <string.h>
10 
11 #include "HTree.h"
12 #include "Inode.h"
13 
14 
15 //#define TRACE_EXT2
16 #ifdef TRACE_EXT2
17 #	define TRACE(x...) dprintf("\33[34mext2:\33[0m " x)
18 #else
19 #	define TRACE(x...) ;
20 #endif
21 
22 
23 DirectoryIterator::DirectoryIterator(Inode* inode)
24 	:
25 	fInode(inode),
26 	fOffset(0)
27 {
28 }
29 
30 
31 DirectoryIterator::~DirectoryIterator()
32 {
33 }
34 
35 
36 status_t
37 DirectoryIterator::GetNext(char* name, size_t* _nameLength, ino_t* _id)
38 {
39 	if (fOffset + sizeof(ext2_dir_entry) >= fInode->Size()) {
40 		TRACE("DirectoryIterator::GetNext() out of entries\n");
41 		return B_ENTRY_NOT_FOUND;
42 	}
43 
44 	ext2_dir_entry entry;
45 
46 	while (true) {
47 		size_t length = ext2_dir_entry::MinimumSize();
48 		status_t status = fInode->ReadAt(fOffset, (uint8*)&entry, &length);
49 		if (status != B_OK)
50 			return status;
51 		if (length < ext2_dir_entry::MinimumSize() || entry.Length() == 0)
52 			return B_ENTRY_NOT_FOUND;
53 		if (!entry.IsValid())
54 			return B_BAD_DATA;
55 
56 		if (entry.NameLength() != 0)
57 			break;
58 
59 		fOffset += entry.Length();
60 		TRACE("DirectoryIterator::GetNext() skipping entry\n");
61 	}
62 
63 	TRACE("offset %Ld: entry ino %lu, length %u, name length %u, type %u\n",
64 		fOffset, entry.InodeID(), entry.Length(), entry.NameLength(),
65 		entry.FileType());
66 
67 	// read name
68 
69 	size_t length = entry.NameLength();
70 	status_t status = fInode->ReadAt(fOffset + ext2_dir_entry::MinimumSize(),
71 		(uint8*)entry.name, &length);
72 	if (status == B_OK) {
73 		if (*_nameLength < length)
74 			length = *_nameLength - 1;
75 		memcpy(name, entry.name, length);
76 		name[length] = '\0';
77 
78 		*_id = entry.InodeID();
79 		*_nameLength = length;
80 
81 		fOffset += entry.Length();
82 	}
83 
84 	return status;
85 }
86 
87 
88 status_t
89 DirectoryIterator::Rewind()
90 {
91 	fOffset = 0;
92 	return B_OK;
93 }
94