150d9710fSAxel Dörfler/*
24b723e3fSAxel Dörfler * Copyright 2003-2013, Axel D��rfler, axeld@pinc-software.de.
34b723e3fSAxel Dörfler * Distributed under the terms of the MIT License.
44b723e3fSAxel Dörfler */
550d9710fSAxel Dörfler
650d9710fSAxel Dörfler
750d9710fSAxel Dörfler#include "Directory.h"
850d9710fSAxel Dörfler#include "Volume.h"
950d9710fSAxel Dörfler#include "File.h"
1050d9710fSAxel Dörfler
1150d9710fSAxel Dörfler#include <StorageDefs.h>
1250d9710fSAxel Dörfler
1350d9710fSAxel Dörfler#include <string.h>
1450d9710fSAxel Dörfler#include <unistd.h>
1550d9710fSAxel Dörfler#include <stdio.h>
1650d9710fSAxel Dörfler
1750d9710fSAxel Dörfler
1895d4ed67SJonathan Schleiferusing std::nothrow;
1995d4ed67SJonathan Schleifer
2095d4ed67SJonathan Schleifer
2150d9710fSAxel Dörflernamespace FFS {
2250d9710fSAxel Dörfler
234b723e3fSAxel Dörfler
240dc4d1e5SIngo WeinholdDirectory::Directory(Volume &volume, int32 block)
2550d9710fSAxel Dörfler	:
2650d9710fSAxel Dörfler	fVolume(volume)
2750d9710fSAxel Dörfler{
2850d9710fSAxel Dörfler	void *data = malloc(volume.BlockSize());
2950d9710fSAxel Dörfler	if (data == NULL)
3050d9710fSAxel Dörfler		return;
3150d9710fSAxel Dörfler
3250d9710fSAxel Dörfler	if (read_pos(volume.Device(), block * volume.BlockSize(), data, volume.BlockSize()) == volume.BlockSize())
3350d9710fSAxel Dörfler		fNode.SetTo(data, volume.BlockSize());
3450d9710fSAxel Dörfler}
3550d9710fSAxel Dörfler
3650d9710fSAxel Dörfler
370dc4d1e5SIngo WeinholdDirectory::Directory(Volume &volume, RootBlock &root)
3850d9710fSAxel Dörfler	:
3950d9710fSAxel Dörfler	fVolume(volume)
4050d9710fSAxel Dörfler{
4150d9710fSAxel Dörfler	fNode.SetTo(root.BlockData(), root.BlockSize());
4250d9710fSAxel Dörfler}
4350d9710fSAxel Dörfler
4450d9710fSAxel Dörfler
4550d9710fSAxel DörflerDirectory::~Directory()
4650d9710fSAxel Dörfler{
4750d9710fSAxel Dörfler	free(fNode.BlockData());
4850d9710fSAxel Dörfler}
4950d9710fSAxel Dörfler
5050d9710fSAxel Dörfler
51cbc85916SIngo Weinholdstatus_t
5250d9710fSAxel DörflerDirectory::InitCheck()
5350d9710fSAxel Dörfler{
5450d9710fSAxel Dörfler	return fNode.ValidateCheckSum();
5550d9710fSAxel Dörfler}
5650d9710fSAxel Dörfler
5750d9710fSAxel Dörfler
58cbc85916SIngo Weinholdstatus_t
5950d9710fSAxel DörflerDirectory::Open(void **_cookie, int mode)
6050d9710fSAxel Dörfler{
61553e5a0fSAxel Dörfler	_inherited::Open(_cookie, mode);
62553e5a0fSAxel Dörfler
6382029bdaSMarcus Overhagen	HashIterator *iterator = new(nothrow) HashIterator(fVolume.Device(), fNode);
64434eb843SAxel Dörfler	if (iterator == NULL)
6550d9710fSAxel Dörfler		return B_NO_MEMORY;
6650d9710fSAxel Dörfler
67434eb843SAxel Dörfler	if (iterator->InitCheck() != B_OK) {
68434eb843SAxel Dörfler		delete iterator;
69434eb843SAxel Dörfler		return B_NO_MEMORY;
70434eb843SAxel Dörfler	}
71434eb843SAxel Dörfler
72434eb843SAxel Dörfler	*_cookie = (void *)iterator;
7350d9710fSAxel Dörfler	return B_OK;
7450d9710fSAxel Dörfler}
7550d9710fSAxel Dörfler
7650d9710fSAxel Dörfler
77cbc85916SIngo Weinholdstatus_t
7850d9710fSAxel DörflerDirectory::Close(void *cookie)
7950d9710fSAxel Dörfler{
80553e5a0fSAxel Dörfler	_inherited::Close(cookie);
81553e5a0fSAxel Dörfler
8250d9710fSAxel Dörfler	delete (HashIterator *)cookie;
8350d9710fSAxel Dörfler	return B_OK;
8450d9710fSAxel Dörfler}
8550d9710fSAxel Dörfler
8650d9710fSAxel Dörfler
87cbc85916SIngo WeinholdNode*
88cbc85916SIngo WeinholdDirectory::LookupDontTraverse(const char* name)
8950d9710fSAxel Dörfler{
90434eb843SAxel Dörfler	if (!strcmp(name, ".")) {
91434eb843SAxel Dörfler		Acquire();
92434eb843SAxel Dörfler		return this;
93434eb843SAxel Dörfler	}
94434eb843SAxel Dörfler
95d178a0d7SAxel Dörfler	HashIterator iterator(fVolume.Device(), fNode);
96d178a0d7SAxel Dörfler	if (iterator.InitCheck() != B_OK)
97d178a0d7SAxel Dörfler		return NULL;
98d178a0d7SAxel Dörfler
99434eb843SAxel Dörfler	iterator.Goto(fNode.HashIndexFor(fVolume.Type(), name));
100434eb843SAxel Dörfler
101434eb843SAxel Dörfler	NodeBlock *node;
102434eb843SAxel Dörfler	int32 block;
103434eb843SAxel Dörfler	while ((node = iterator.GetNext(block)) != NULL) {
104434eb843SAxel Dörfler		char fileName[FFS_NAME_LENGTH];
105434eb843SAxel Dörfler		if (node->GetName(fileName, sizeof(fileName)) == B_OK
106434eb843SAxel Dörfler			&& !strcmp(name, fileName)) {
107434eb843SAxel Dörfler			if (node->IsFile())
10882029bdaSMarcus Overhagen				return new(nothrow) File(fVolume, block);
109434eb843SAxel Dörfler			if (node->IsDirectory())
1100dc4d1e5SIngo Weinhold				return new(nothrow) Directory(fVolume, block);
111434eb843SAxel Dörfler
112434eb843SAxel Dörfler			return NULL;
113434eb843SAxel Dörfler		}
114434eb843SAxel Dörfler	}
11550d9710fSAxel Dörfler	return NULL;
11650d9710fSAxel Dörfler}
11750d9710fSAxel Dörfler
11850d9710fSAxel Dörfler
119cbc85916SIngo Weinholdstatus_t
12050d9710fSAxel DörflerDirectory::GetNextEntry(void *cookie, char *name, size_t size)
12150d9710fSAxel Dörfler{
12250d9710fSAxel Dörfler	HashIterator *iterator = (HashIterator *)cookie;
12350d9710fSAxel Dörfler	int32 block;
12450d9710fSAxel Dörfler
12550d9710fSAxel Dörfler	NodeBlock *node = iterator->GetNext(block);
12650d9710fSAxel Dörfler	if (node == NULL)
12750d9710fSAxel Dörfler		return B_ENTRY_NOT_FOUND;
12850d9710fSAxel Dörfler
12950d9710fSAxel Dörfler	return node->GetName(name, size);
13050d9710fSAxel Dörfler}
13150d9710fSAxel Dörfler
13250d9710fSAxel Dörfler
133cbc85916SIngo Weinholdstatus_t
13450d9710fSAxel DörflerDirectory::GetNextNode(void *cookie, Node **_node)
13550d9710fSAxel Dörfler{
13650d9710fSAxel Dörfler	return B_ERROR;
13750d9710fSAxel Dörfler}
13850d9710fSAxel Dörfler
13950d9710fSAxel Dörfler
1400e3f14eeSAxel Dörflerstatus_t
14150d9710fSAxel DörflerDirectory::Rewind(void *cookie)
14250d9710fSAxel Dörfler{
14350d9710fSAxel Dörfler	HashIterator *iterator = (HashIterator *)cookie;
14450d9710fSAxel Dörfler	iterator->Rewind();
14550d9710fSAxel Dörfler
14650d9710fSAxel Dörfler	return B_OK;
14750d9710fSAxel Dörfler}
14850d9710fSAxel Dörfler
14950d9710fSAxel Dörfler
1500e3f14eeSAxel Dörflerbool
151d178a0d7SAxel DörflerDirectory::IsEmpty()
152d178a0d7SAxel Dörfler{
153d178a0d7SAxel Dörfler	int32 index;
154d178a0d7SAxel Dörfler	return fNode.FirstHashValue(index) == -1;
155d178a0d7SAxel Dörfler}
156d178a0d7SAxel Dörfler
157d178a0d7SAxel Dörfler
1580e3f14eeSAxel Dörflerstatus_t
15950d9710fSAxel DörflerDirectory::GetName(char *name, size_t size) const
16050d9710fSAxel Dörfler{
16150d9710fSAxel Dörfler	return fNode.GetName(name, size);
16250d9710fSAxel Dörfler}
16350d9710fSAxel Dörfler
1640e3f14eeSAxel Dörfler
1650e3f14eeSAxel Dörflerino_t
1660e3f14eeSAxel DörflerDirectory::Inode() const
1670e3f14eeSAxel Dörfler{
1680e3f14eeSAxel Dörfler	return fNode.HeaderKey();
1690e3f14eeSAxel Dörfler}
1700e3f14eeSAxel Dörfler
1714b723e3fSAxel Dörfler
17250d9710fSAxel Dörfler}	// namespace FFS
173