1293116Semaste/*
2293116Semaste * Copyright 2003-2013, Axel D��rfler, axeld@pinc-software.de.
3353358Sdim * Copyright 2008, Fran��ois Revol <revol@free.fr>
4353358Sdim * Distributed under the terms of the MIT License.
5353358Sdim */
6293116Semaste
7293116Semaste
8293116Semaste#include "File.h"
9293116Semaste
10293116Semaste#include <sys/stat.h>
11293116Semaste#include <unistd.h>
12293116Semaste
13314564Sdim#include "Directory.h"
14293116Semaste
15360784Sdim
16353358Sdim//#define TRACE(x) dprintf x
17353358Sdim#define TRACE(x) do {} while (0)
18293116Semaste
19293116Semaste
20293116Semastenamespace FATFS {
21314564Sdim
22360784Sdim
23293116SemasteFile::File(Volume &volume, off_t dirEntryOffset, uint32 cluster, off_t size,
24314564Sdim	const char *name)
25293116Semaste	:
26360784Sdim	fVolume(volume),
27360784Sdim	fStream(volume, cluster, size, name),
28360784Sdim	fDirEntryOffset(dirEntryOffset)
29360784Sdim{
30353358Sdim	TRACE(("FATFS::File::()\n"));
31360784Sdim}
32314564Sdim
33314564Sdim
34314564SdimFile::~File()
35293116Semaste{
36314564Sdim	TRACE(("FATFS::File::~()\n"));
37314564Sdim}
38293116Semaste
39314564Sdim
40314564Sdimstatus_t
41314564SdimFile::InitCheck()
42314564Sdim{
43314564Sdim	if (fStream.InitCheck() != B_OK)
44314564Sdim		return fStream.InitCheck();
45314564Sdim
46314564Sdim	return B_OK;
47314564Sdim}
48314564Sdim
49293116Semaste
50293116Semastestatus_t
51293116SemasteFile::Open(void **_cookie, int mode)
52293116Semaste{
53293116Semaste	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