1//---------------------------------------------------------------------- 2// This software is part of the OpenBeOS distribution and is covered 3// by the OpenBeOS license. 4// 5// Copyright (c) 2003 Tyler Dauwalder, tyler@dauwalder.net 6//---------------------------------------------------------------------- 7 8/*! \file PositionIOStream.cpp 9*/ 10 11#include "PositionIOStream.h" 12 13#include <stdlib.h> 14#include <string.h> 15 16PositionIOStream::PositionIOStream(BPositionIO &stream) 17 : fStream(stream) 18{ 19} 20 21ssize_t 22PositionIOStream::Read(void *buffer, size_t size) 23{ 24 return fStream.Read(buffer, size); 25} 26 27ssize_t 28PositionIOStream::ReadAt(off_t pos, void *buffer, size_t size) 29{ 30 return fStream.ReadAt(pos, buffer, size); 31} 32 33ssize_t 34PositionIOStream::Write(const void *buffer, size_t size) 35{ 36 return fStream.Write(buffer, size); 37} 38 39ssize_t 40PositionIOStream::WriteAt(off_t pos, const void *buffer, size_t size) 41{ 42 return fStream.WriteAt(pos, buffer, size); 43} 44 45/*! \brief Writes \a size bytes worth of data from \a data at the current 46 position in the file, incrementing the file's position marker as it goes. 47*/ 48ssize_t 49PositionIOStream::Write(BDataIO &data, size_t size) 50{ 51 status_t error = kBufferSize > 0 ? B_OK : B_BAD_VALUE; 52 size_t bytes = 0; 53 if (!error) { 54 void *buffer = malloc(kBufferSize); 55 error = buffer ? B_OK : B_NO_MEMORY; 56 if (!error) { 57 // Fudge the buffer size from here out if the requested 58 // number of bytes to write is smaller than the buffer 59 size_t bufferSize = (size < kBufferSize ? size : kBufferSize); 60 // Zero 61 memset(buffer, 0, bufferSize); 62 // Write 63 while (bytes < size) { 64 ssize_t bytesRead = data.Read(buffer, bufferSize); 65 if (bytesRead >= 0) { 66 ssize_t bytesWritten = fStream.Write(buffer, bytesRead); 67 if (bytesWritten >= 0) { 68 bytes += bytesWritten; 69 } else { 70 error = status_t(bytesWritten); 71 break; 72 } 73 } else { 74 error = status_t(bytesRead); 75 break; 76 } 77 } 78 } 79 free(buffer); 80 } 81 return error ? ssize_t(error) : ssize_t(bytes); 82} 83 84/*! \brief Writes \a size bytes worth of data from \a data at position 85 \a pos in the file without incrementing the file's position marker. 86*/ 87ssize_t 88PositionIOStream::WriteAt(off_t pos, BDataIO &data, size_t size) 89{ 90 status_t error = kBufferSize > 0 ? B_OK : B_BAD_VALUE; 91 size_t bytes = 0; 92 if (!error) { 93 void *buffer = malloc(kBufferSize); 94 error = buffer ? B_OK : B_NO_MEMORY; 95 if (!error) { 96 // Fudge the buffer size from here out if the requested 97 // number of bytes to write is smaller than the buffer 98 size_t bufferSize = (size < kBufferSize ? size : kBufferSize); 99 // Zero 100 memset(buffer, 0, bufferSize); 101 // Write 102 while (bytes < size) { 103 ssize_t bytesRead = data.Read(buffer, bufferSize); 104 if (bytesRead >= 0) { 105 ssize_t bytesWritten = fStream.WriteAt(pos, buffer, bytesRead); 106 if (bytesWritten >= 0) { 107 bytes += bytesWritten; 108 pos += bytesWritten; 109 } else { 110 error = status_t(bytesWritten); 111 break; 112 } 113 } else { 114 error = status_t(bytesRead); 115 break; 116 } 117 } 118 } 119 free(buffer); 120 } 121 return error ? ssize_t(error) : ssize_t(bytes); 122} 123 124/*! \brief Writes \a size bytes worth of zeros at the current position 125 in the file, incrementing the file's position marker as it goes. 126*/ 127ssize_t 128PositionIOStream::Zero(size_t size) 129{ 130 status_t error = kBufferSize > 0 ? B_OK : B_BAD_VALUE; 131 size_t bytes = 0; 132 if (!error) { 133 void *buffer = malloc(kBufferSize); 134 error = buffer ? B_OK : B_NO_MEMORY; 135 if (!error) { 136 // Fudge the buffer size from here out if the requested 137 // number of bytes to write is smaller than the buffer 138 size_t bufferSize = (size < kBufferSize ? size : kBufferSize); 139 // Zero 140 memset(buffer, 0, bufferSize); 141 // Write 142 while (bytes < size) { 143 ssize_t bytesWritten = fStream.Write(buffer, bufferSize); 144 if (bytesWritten >= 0) { 145 bytes += bytesWritten; 146 } else { 147 error = status_t(bytesWritten); 148 break; 149 } 150 } 151 } 152 free(buffer); 153 } 154 return error ? ssize_t(error) : ssize_t(bytes); 155} 156 157/*! \brief Writes \a size bytes worth of zeros at position \a pos 158 in the file without incrementing the file's position marker. 159*/ 160ssize_t 161PositionIOStream::ZeroAt(off_t pos, size_t size) 162{ 163 status_t error = kBufferSize > 0 ? B_OK : B_BAD_VALUE; 164 size_t bytes = 0; 165 if (!error) { 166 void *buffer = malloc(kBufferSize); 167 error = buffer ? B_OK : B_NO_MEMORY; 168 if (!error) { 169 // Fudge the buffer size from here out if the requested 170 // number of bytes to write is smaller than the buffer 171 size_t bufferSize = (size < kBufferSize ? size : kBufferSize); 172 // Zero 173 memset(buffer, 0, bufferSize); 174 // Write 175 while (bytes < size) { 176 ssize_t bytesWritten = fStream.WriteAt(pos, buffer, bufferSize); 177 if (bytesWritten >= 0) { 178 bytes += bytesWritten; 179 pos += bytesWritten; 180 } else { 181 error = status_t(bytesWritten); 182 break; 183 } 184 } 185 } 186 free(buffer); 187 } 188 return error ? ssize_t(error) : ssize_t(bytes); 189} 190 191off_t 192PositionIOStream::Seek(off_t position, uint32 seek_mode) 193{ 194 return fStream.Seek(position, seek_mode); 195} 196 197off_t 198PositionIOStream::Position() const 199{ 200 return fStream.Position(); 201} 202 203status_t 204PositionIOStream::SetSize(off_t size) 205{ 206 return fStream.SetSize(size); 207} 208