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
OffsetFile()18 OffsetFile::OffsetFile()
19 : fFile(NULL),
20 fOffset(0),
21 fCurrentPosition(0)
22 {
23 }
24
25 // constructor
OffsetFile(BFile * file,off_t offset)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
~OffsetFile()35 OffsetFile::~OffsetFile()
36 {
37 }
38
39 // SetTo
40 status_t
SetTo(BFile * file,off_t offset)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
Unset()51 OffsetFile::Unset()
52 {
53 fFile = NULL;
54 fOffset = 0;
55 fCurrentPosition = 0;
56 }
57
58 // InitCheck
59 status_t
InitCheck() const60 OffsetFile::InitCheck() const
61 {
62 return (fFile ? fFile->InitCheck() : B_NO_INIT);
63 }
64
65 // File
66 BFile *
File() const67 OffsetFile::File() const
68 {
69 return fFile;
70 }
71
72 // ReadAt
73 ssize_t
ReadAt(off_t pos,void * buffer,size_t size)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
WriteAt(off_t pos,const void * buffer,size_t size)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
Seek(off_t position,uint32 seekMode)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
Position() const129 OffsetFile::Position() const
130 {
131 return fCurrentPosition;
132 }
133
134 // SetSize
135 status_t
SetSize(off_t size)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
GetSize(off_t * size) const148 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
Offset() const165 OffsetFile::Offset() const
166 {
167 return fOffset;
168 }
169
170 }; // namespace Storage
171 }; // namespace BPrivate
172