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