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