1/*
2 * Copyright 2003-2013, Axel D��rfler, axeld@pinc-software.de.
3 * Copyright 2008, Fran��ois Revol <revol@free.fr>
4 * Distributed under the terms of the MIT License.
5 */
6
7
8#include "File.h"
9
10#include <sys/stat.h>
11#include <unistd.h>
12
13#include "Directory.h"
14
15
16//#define TRACE(x) dprintf x
17#define TRACE(x) do {} while (0)
18
19
20namespace FATFS {
21
22
23File::File(Volume &volume, off_t dirEntryOffset, uint32 cluster, off_t size,
24	const char *name)
25	:
26	fVolume(volume),
27	fStream(volume, cluster, size, name),
28	fDirEntryOffset(dirEntryOffset)
29{
30	TRACE(("FATFS::File::()\n"));
31}
32
33
34File::~File()
35{
36	TRACE(("FATFS::File::~()\n"));
37}
38
39
40status_t
41File::InitCheck()
42{
43	if (fStream.InitCheck() != B_OK)
44		return fStream.InitCheck();
45
46	return B_OK;
47}
48
49
50status_t
51File::Open(void **_cookie, int mode)
52{
53	TRACE(("FATFS::File::%s(, %d)\n", __FUNCTION__, mode));
54	if (fStream.InitCheck() < B_OK)
55		return fStream.InitCheck();
56
57	return Node::Open(_cookie, mode);
58}
59
60
61status_t
62File::Close(void *cookie)
63{
64	return Node::Close(cookie);
65}
66
67
68ssize_t
69File::ReadAt(void *cookie, off_t pos, void *buffer, size_t bufferSize)
70{
71	TRACE(("FATFS::File::%s(, %lld,, %d)\n", __FUNCTION__, pos, bufferSize));
72	status_t err;
73	err = fStream.ReadAt(pos, buffer, &bufferSize);
74	if (err < B_OK)
75		return err;
76	return bufferSize;
77}
78
79
80ssize_t
81File::WriteAt(void *cookie, off_t pos, const void *buffer, size_t bufferSize)
82{
83	off_t streamSize = fStream.Size();
84	uint32 firstCluster = fStream.FirstCluster();
85
86	// write data
87	size_t written = bufferSize;
88	status_t error = fStream.WriteAt(pos, buffer, &written);
89	if (error != B_OK)
90		return error;
91
92	// If the file size has changed, we need to adjust the directory entry.
93	if (fStream.Size() > streamSize || fStream.FirstCluster() != firstCluster) {
94		error = Directory::UpdateDirEntry(fVolume, fDirEntryOffset,
95			fStream.FirstCluster(), fStream.Size());
96		if (error != B_OK)
97			return error;
98			// TODO: Undo the changes!
99	}
100
101	return written;
102}
103
104
105status_t
106File::GetName(char *nameBuffer, size_t bufferSize) const
107{
108	return fStream.GetName(nameBuffer, bufferSize);
109}
110
111
112status_t
113File::GetFileMap(struct file_map_run *runs, int32 *count)
114{
115	return fStream.GetFileMap(runs, count);
116}
117
118
119int32
120File::Type() const
121{
122	return S_IFREG;
123}
124
125
126off_t
127File::Size() const
128{
129	return fStream.Size();
130}
131
132
133ino_t
134File::Inode() const
135{
136	return fStream.FirstCluster() << 16;
137}
138
139
140}	// namespace FATFS
141