src/iohandler/mem_io_handler.cc
Rama master · réplica de lectura del repositorio original.
/*MT*
MediaTomb - http://www.mediatomb.cc/
mem_io_handler.cc - this file is part of MediaTomb.
Copyright (C) 2005 Gena Batyan <bgeradz@mediatomb.cc>,
Sergey 'Jin' Bostandzhyan <jin@mediatomb.cc>
Copyright (C) 2006-2010 Gena Batyan <bgeradz@mediatomb.cc>,
Sergey 'Jin' Bostandzhyan <jin@mediatomb.cc>,
Leonhard Wimmer <leo@mediatomb.cc>
Copyright (C) 2016-2026 Gerbera Contributors
MediaTomb is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License version 2
as published by the Free Software Foundation.
MediaTomb is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
version 2 along with MediaTomb; if not, write to the Free Software
Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA.
$Id$
*/
/// @file iohandler/mem_io_handler.cc
#define GRB_LOG_FAC GrbLogFacility::iohandler
#include "mem_io_handler.h" // API
#include "exceptions.h"
#include <cstring>
MemIOHandler::MemIOHandler(const void* buffer, int length)
: buffer(new char[length])
, length(length)
{
std::memcpy(this->buffer, buffer, length);
}
MemIOHandler::MemIOHandler(const std::string& str)
: buffer(new char[str.length()])
, length(str.length())
{
std::memcpy(this->buffer, str.c_str(), length);
}
MemIOHandler::~MemIOHandler()
{
delete[] buffer;
}
void MemIOHandler::open(enum UpnpOpenFileMode mode)
{
pos = 0;
}
grb_read_t MemIOHandler::read(std::byte* buf, std::size_t length)
{
std::size_t ret;
// we indicate EOF by setting pos to -1
if (pos == -1) {
return 0;
}
off_t rest = this->length - pos;
if (length > static_cast<std::size_t>(rest))
length = rest;
std::memcpy(buf, buffer + pos, length);
pos = pos + length;
ret = length;
if (pos >= this->length) {
pos = -1;
}
return ret;
}
void MemIOHandler::seek(off_t offset, int whence)
{
if (whence == SEEK_SET) {
// offset must be positive when SEEK_SET is used
if (offset < 0) {
throw_std_runtime_error("seek failed: SEEK_SET used with negative offset");
}
if (offset > length) {
throw_std_runtime_error("seek failed: trying to seek past the end of file");
}
pos = offset;
} else if (whence == SEEK_CUR) {
off_t temp = (pos == -1) ? length : pos;
// (((temp + offset) > length) || ((temp + offset) < 0))
if (offset > 0 && (length < offset || temp > length - offset)) {
throw_std_runtime_error("seek failed: trying to seek past end of file");
}
if (offset < 0 && temp < -offset) {
throw_std_runtime_error("seek failed: trying to seek before the beginning of file");
}
pos = temp + offset;
} else if (whence == SEEK_END) {
off_t temp = length;
// (((temp + offset) > length) || ((temp + offset) < 0))
if (offset > 0 && (length < offset || temp > length - offset)) {
throw_std_runtime_error("seek failed: trying to seek past end of file");
}
if (offset < 0 && temp < -offset) {
throw_std_runtime_error("seek failed: trying to seek before the beginning of file");
}
pos = temp + offset;
} else {
throw_std_runtime_error("seek failed: unrecognized whence");
}
}
off_t MemIOHandler::tell()
{
return pos;
}
void MemIOHandler::close()
{
pos = -1;
}