1/*
2 * Copyright 2009-2010, Ingo Weinhold, ingo_weinhold@gmx.de.
3 * Distributed under the terms of the MIT License.
4 */
5
6
7#include <FileIO.h>
8
9#include <errno.h>
10#include <stdio.h>
11
12
13BFileIO::BFileIO(FILE* file, bool takeOverOwnership)
14	:
15	fFile(file),
16	fOwnsFile(takeOverOwnership)
17{
18}
19
20
21BFileIO::~BFileIO()
22{
23	if (fOwnsFile && fFile != NULL)
24		fclose(fFile);
25}
26
27
28ssize_t
29BFileIO::Read(void* buffer, size_t size)
30{
31	errno = B_OK;
32	ssize_t bytesRead = fread(buffer, 1, size, fFile);
33	return bytesRead >= 0 ? bytesRead : errno;
34}
35
36
37ssize_t
38BFileIO::Write(const void* buffer, size_t size)
39{
40	errno = B_OK;
41	ssize_t bytesRead = fwrite(buffer, 1, size, fFile);
42	return bytesRead >= 0 ? bytesRead : errno;
43}
44
45
46ssize_t
47BFileIO::ReadAt(off_t position, void* buffer, size_t size)
48{
49	// save the old position and seek to the requested one
50	off_t oldPosition = _Seek(position, SEEK_SET);
51	if (oldPosition < 0)
52		return oldPosition;
53
54	// read
55	ssize_t result = BFileIO::Read(buffer, size);
56
57	// seek back
58	fseeko(fFile, oldPosition, SEEK_SET);
59
60	return result;
61}
62
63
64ssize_t
65BFileIO::WriteAt(off_t position, const void* buffer, size_t size)
66{
67	// save the old position and seek to the requested one
68	off_t oldPosition = _Seek(position, SEEK_SET);
69	if (oldPosition < 0)
70		return oldPosition;
71
72	// write
73	ssize_t result = BFileIO::Write(buffer, size);
74
75	// seek back
76	fseeko(fFile, oldPosition, SEEK_SET);
77
78	return result;
79}
80
81
82off_t
83BFileIO::Seek(off_t position, uint32 seekMode)
84{
85	if (fseeko(fFile, position, seekMode) < 0)
86		return errno;
87
88	return BFileIO::Position();
89}
90
91
92off_t
93BFileIO::Position() const
94{
95	off_t result = ftello(fFile);
96	return result >= 0 ? result : errno;
97}
98
99
100status_t
101BFileIO::SetSize(off_t size)
102{
103	return B_UNSUPPORTED;
104}
105
106
107status_t
108BFileIO::GetSize(off_t* _size) const
109{
110	// save the current position and seek to the end
111	off_t position = _Seek(0, SEEK_END);
112	if (position < 0)
113		return position;
114
115	// get the size (position at end) and seek back
116	off_t size = _Seek(position, SEEK_SET);
117	if (size < 0)
118		return size;
119
120	*_size = size;
121	return B_OK;
122}
123
124
125off_t
126BFileIO::_Seek(off_t position, uint32 seekMode) const
127{
128	// save the current position
129	off_t oldPosition = ftello(fFile);
130	if (oldPosition < 0)
131		return errno;
132
133	// seek to the requested position
134	if (fseeko(fFile, position, seekMode) < 0)
135		return errno;
136
137	return oldPosition;
138}
139