xref: /haiku/src/kits/storage/OffsetFile.cpp (revision 4c8e85b316c35a9161f5a1c50ad70bc91c83a76f)
1 //----------------------------------------------------------------------
2 //  This software is part of the Haiku distribution and is covered
3 //  by the MIT License.
4 //---------------------------------------------------------------------
5 /*!
6 	\file OffsetFile.cpp
7 	OffsetFile implementation.
8 */
9 
10 #include <stdio.h>
11 
12 #include "OffsetFile.h"
13 
14 namespace BPrivate {
15 namespace Storage {
16 
17 // constructor
18 OffsetFile::OffsetFile()
19 	: fFile(NULL),
20 	  fOffset(0),
21 	  fCurrentPosition(0)
22 {
23 }
24 
25 // constructor
26 OffsetFile::OffsetFile(BFile *file, off_t offset)
27 	: fFile(NULL),
28 	  fOffset(0),
29 	  fCurrentPosition(0)
30 {
31 	SetTo(file, offset);
32 }
33 
34 // destructor
35 OffsetFile::~OffsetFile()
36 {
37 }
38 
39 // SetTo
40 status_t
41 OffsetFile::SetTo(BFile *file, off_t offset)
42 {
43 	Unset();
44 	fFile = file;
45 	fOffset = offset;
46 	return fFile->InitCheck();
47 }
48 
49 // Unset
50 void
51 OffsetFile::Unset()
52 {
53 	fFile = NULL;
54 	fOffset = 0;
55 	fCurrentPosition = 0;
56 }
57 
58 // InitCheck
59 status_t
60 OffsetFile::InitCheck() const
61 {
62 	return (fFile ? fFile->InitCheck() : B_NO_INIT);
63 }
64 
65 // File
66 BFile *
67 OffsetFile::File() const
68 {
69 	return fFile;
70 }
71 
72 // ReadAt
73 ssize_t
74 OffsetFile::ReadAt(off_t pos, void *buffer, size_t size)
75 {
76 	status_t error = InitCheck();
77 	ssize_t result = 0;
78 	if (error == B_OK)
79 		result = fFile->ReadAt(pos + fOffset, buffer, size);
80 	return (error == B_OK ? result : error);
81 }
82 
83 // WriteAt
84 ssize_t
85 OffsetFile::WriteAt(off_t pos, const void *buffer, size_t size)
86 {
87 	status_t error = InitCheck();
88 	ssize_t result = 0;
89 	if (error == B_OK)
90 		result = fFile->WriteAt(pos + fOffset, buffer, size);
91 	return (error == B_OK ? result : error);
92 }
93 
94 // Seek
95 off_t
96 OffsetFile::Seek(off_t position, uint32 seekMode)
97 {
98 	off_t result = B_BAD_VALUE;
99 	status_t error = InitCheck();
100 	if (error == B_OK) {
101 		switch (seekMode) {
102 			case SEEK_SET:
103 				if (position >= 0)
104 					result = fCurrentPosition = position;
105 				break;
106 			case SEEK_END:
107 			{
108 				off_t size;
109 				error = GetSize(&size);
110 				if (error == B_OK) {
111 					if (size + position >= 0)
112 						result = fCurrentPosition = size + position;
113 				}
114 				break;
115 			}
116 			case SEEK_CUR:
117 				if (fCurrentPosition + position >= 0)
118 					result = fCurrentPosition += position;
119 				break;
120 			default:
121 				break;
122 		}
123 	}
124 	return (error == B_OK ? result : error);
125 }
126 
127 // Position
128 off_t
129 OffsetFile::Position() const
130 {
131 	return fCurrentPosition;
132 }
133 
134 // SetSize
135 status_t
136 OffsetFile::SetSize(off_t size)
137 {
138 	status_t error = (size >= 0 ? B_OK : B_BAD_VALUE );
139 	if (error == B_OK)
140 		error = InitCheck();
141 	if (error == B_OK)
142 		error = fFile->SetSize(size + fOffset);
143 	return error;
144 }
145 
146 // GetSize
147 status_t
148 OffsetFile::GetSize(off_t *size) const
149 {
150 	status_t error = (size ? B_OK : B_BAD_VALUE );
151 	if (error == B_OK)
152 		error = InitCheck();
153 	if (error == B_OK)
154 		error = fFile->GetSize(size);
155 	if (error == B_OK) {
156 		*size -= fOffset;
157 		if (*size < 0)
158 			*size = 0;
159 	}
160 	return error;
161 }
162 
163 // Offset
164 off_t
165 OffsetFile::Offset() const
166 {
167 	return fOffset;
168 }
169 
170 };	// namespace Storage
171 };	// namespace BPrivate
172