xref: /haiku/src/system/boot/loader/file_systems/fat/File.cpp (revision f11b30463296494633476a81bdb9a64e8cb2e85d)
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 
20 namespace FATFS {
21 
22 
23 File::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 
34 File::~File()
35 {
36 	TRACE(("FATFS::File::~()\n"));
37 }
38 
39 
40 status_t
41 File::InitCheck()
42 {
43 	if (fStream.InitCheck() != B_OK)
44 		return fStream.InitCheck();
45 
46 	return B_OK;
47 }
48 
49 
50 status_t
51 File::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 
61 status_t
62 File::Close(void *cookie)
63 {
64 	return Node::Close(cookie);
65 }
66 
67 
68 ssize_t
69 File::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 
80 ssize_t
81 File::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 
105 status_t
106 File::GetName(char *nameBuffer, size_t bufferSize) const
107 {
108 	return fStream.GetName(nameBuffer, bufferSize);
109 }
110 
111 
112 status_t
113 File::GetFileMap(struct file_map_run *runs, int32 *count)
114 {
115 	return fStream.GetFileMap(runs, count);
116 }
117 
118 
119 int32
120 File::Type() const
121 {
122 	return S_IFREG;
123 }
124 
125 
126 off_t
127 File::Size() const
128 {
129 	return fStream.Size();
130 }
131 
132 
133 ino_t
134 File::Inode() const
135 {
136 	return fStream.FirstCluster() << 16;
137 }
138 
139 
140 }	// namespace FATFS
141