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