More work on streams
parent
3aca1de731
commit
68d41d3b21
|
@ -75,7 +75,8 @@ common/profile.cpp
|
|||
common/restext.cpp
|
||||
common/stringutils.cpp
|
||||
common/resources/resourcemanager.cpp
|
||||
common/resources/resourcestreambuffer.cpp
|
||||
common/resources/inputstreambuffer.cpp
|
||||
common/resources/outputstreambuffer.cpp
|
||||
common/resources/inputstream.cpp
|
||||
common/resources/outputstream.cpp
|
||||
common/resources/sndfile.cpp
|
||||
|
|
|
@ -15,10 +15,10 @@
|
|||
// * along with this program. If not, see http://www.gnu.org/licenses/.
|
||||
|
||||
#include "common/resources/inputstream.h"
|
||||
#include "common/resources/resourcestreambuffer.h"
|
||||
#include "common/resources/inputstreambuffer.h"
|
||||
|
||||
|
||||
CInputStream::CInputStream() : std::istream(new CResourceStreamBuffer())
|
||||
CInputStream::CInputStream() : std::istream(new CInputStreamBuffer())
|
||||
{
|
||||
}
|
||||
|
||||
|
@ -31,23 +31,23 @@ CInputStream::~CInputStream()
|
|||
|
||||
void CInputStream::open(const std::string& filename)
|
||||
{
|
||||
static_cast<CResourceStreamBuffer *>(rdbuf())->open(filename);
|
||||
static_cast<CInputStreamBuffer *>(rdbuf())->open(filename);
|
||||
}
|
||||
|
||||
|
||||
void CInputStream::close()
|
||||
{
|
||||
static_cast<CResourceStreamBuffer *>(rdbuf())->close();
|
||||
static_cast<CInputStreamBuffer *>(rdbuf())->close();
|
||||
}
|
||||
|
||||
|
||||
bool CInputStream::is_open()
|
||||
{
|
||||
return static_cast<CResourceStreamBuffer *>(rdbuf())->is_open();
|
||||
return static_cast<CInputStreamBuffer *>(rdbuf())->is_open();
|
||||
}
|
||||
|
||||
|
||||
size_t CInputStream::size()
|
||||
{
|
||||
return static_cast<CResourceStreamBuffer *>(rdbuf())->size();
|
||||
return static_cast<CInputStreamBuffer *>(rdbuf())->size();
|
||||
}
|
||||
|
|
|
@ -0,0 +1,129 @@
|
|||
// * This file is part of the COLOBOT source code
|
||||
// * Copyright (C) 2014 Polish Portal of Colobot (PPC)
|
||||
// *
|
||||
// * This program is free software: you can redistribute it and/or modify
|
||||
// * it under the terms of the GNU General Public License as published by
|
||||
// * the Free Software Foundation, either version 3 of the License, or
|
||||
// * (at your option) any later version.
|
||||
// *
|
||||
// * This program 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
|
||||
// * along with this program. If not, see http://www.gnu.org/licenses/.
|
||||
|
||||
#include "common/resources/inputstreambuffer.h"
|
||||
|
||||
#include <stdexcept>
|
||||
#include <sstream>
|
||||
|
||||
CInputStreamBuffer::CInputStreamBuffer(size_t buffer_size) : m_buffer_size(buffer_size)
|
||||
{
|
||||
if (buffer_size <= 0)
|
||||
{
|
||||
throw std::runtime_error("File buffer must be larger then 0 bytes");
|
||||
}
|
||||
|
||||
m_buffer = new char[buffer_size];
|
||||
m_file = nullptr;
|
||||
}
|
||||
|
||||
|
||||
CInputStreamBuffer::~CInputStreamBuffer()
|
||||
{
|
||||
close();
|
||||
delete m_buffer;
|
||||
}
|
||||
|
||||
|
||||
void CInputStreamBuffer::open(const std::string &filename)
|
||||
{
|
||||
if (PHYSFS_isInit())
|
||||
m_file = PHYSFS_openRead(filename.c_str());
|
||||
}
|
||||
|
||||
|
||||
void CInputStreamBuffer::close()
|
||||
{
|
||||
if (is_open())
|
||||
PHYSFS_close(m_file);
|
||||
}
|
||||
|
||||
|
||||
bool CInputStreamBuffer::is_open()
|
||||
{
|
||||
return m_file;
|
||||
}
|
||||
|
||||
|
||||
size_t CInputStreamBuffer::size()
|
||||
{
|
||||
return PHYSFS_fileLength(m_file);
|
||||
}
|
||||
|
||||
|
||||
std::streambuf::int_type CInputStreamBuffer::underflow()
|
||||
{
|
||||
if (gptr() < egptr())
|
||||
return traits_type::to_int_type(*gptr());
|
||||
|
||||
if (PHYSFS_eof(m_file))
|
||||
return traits_type::eof();
|
||||
|
||||
PHYSFS_sint64 read_count = PHYSFS_read(m_file, m_buffer, sizeof(char), m_buffer_size);
|
||||
if (read_count <= 0)
|
||||
return traits_type::eof();
|
||||
|
||||
setg(m_buffer, m_buffer, m_buffer + read_count);
|
||||
|
||||
return traits_type::to_int_type(*gptr());
|
||||
}
|
||||
|
||||
|
||||
std::streampos CInputStreamBuffer::seekpos(std::streampos sp, std::ios_base::openmode which)
|
||||
{
|
||||
return seekoff(off_type(sp), std::ios_base::beg, which);
|
||||
}
|
||||
|
||||
|
||||
std::streampos CInputStreamBuffer::seekoff(std::streamoff off, std::ios_base::seekdir way, std::ios_base::openmode which)
|
||||
{
|
||||
/* A bit of explanation:
|
||||
We are reading file by m_buffer_size parts so our 3 internal pointers will be
|
||||
* eback (not used here) - start of block
|
||||
* gptr - position of read cursor in block
|
||||
* egtpr - end of block
|
||||
off argument is relative to way */
|
||||
|
||||
std::streamoff new_position;
|
||||
|
||||
switch (way)
|
||||
{
|
||||
case std::ios_base::beg:
|
||||
new_position = off;
|
||||
break;
|
||||
|
||||
case std::ios_base::cur:
|
||||
// tell will give cursor at begining of block so we have to add where in block we currently are
|
||||
new_position = off + static_cast<off_type>(PHYSFS_tell(m_file)) - static_cast<off_type> (egptr() - gptr());
|
||||
break;
|
||||
|
||||
case std::ios_base::end:
|
||||
new_position = off + static_cast<off_type>(PHYSFS_fileLength(m_file));
|
||||
break;
|
||||
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
||||
if (PHYSFS_seek(m_file, new_position))
|
||||
{
|
||||
setg(m_buffer, m_buffer, m_buffer); // reset buffer
|
||||
|
||||
return pos_type(new_position);
|
||||
}
|
||||
|
||||
return pos_type(off_type(-1));
|
||||
}
|
|
@ -0,0 +1,48 @@
|
|||
// * This file is part of the COLOBOT source code
|
||||
// * Copyright (C) 2014 Polish Portal of Colobot (PPC)
|
||||
// *
|
||||
// * This program is free software: you can redistribute it and/or modify
|
||||
// * it under the terms of the GNU General Public License as published by
|
||||
// * the Free Software Foundation, either version 3 of the License, or
|
||||
// * (at your option) any later version.
|
||||
// *
|
||||
// * This program 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
|
||||
// * along with this program. If not, see http://www.gnu.org/licenses/.
|
||||
|
||||
#pragma once
|
||||
|
||||
#include <streambuf>
|
||||
#include <string>
|
||||
#include <physfs.h>
|
||||
|
||||
class CInputStreamBuffer : public std::streambuf
|
||||
{
|
||||
public:
|
||||
CInputStreamBuffer(size_t buffer_size = 512);
|
||||
virtual ~CInputStreamBuffer();
|
||||
|
||||
void open(const std::string &filename);
|
||||
void close();
|
||||
bool is_open();
|
||||
size_t size();
|
||||
|
||||
private:
|
||||
int_type underflow();
|
||||
|
||||
std::streampos seekpos(std::streampos sp, std::ios_base::openmode which);
|
||||
std::streampos seekoff(std::streamoff off, std::ios_base::seekdir way, std::ios_base::openmode which);
|
||||
|
||||
// copy ctor and assignment not implemented;
|
||||
// copying not allowed
|
||||
CInputStreamBuffer(const CInputStreamBuffer &);
|
||||
CInputStreamBuffer &operator= (const CInputStreamBuffer &);
|
||||
|
||||
PHYSFS_File *m_file;
|
||||
char *m_buffer;
|
||||
size_t m_buffer_size;
|
||||
};
|
|
@ -15,10 +15,10 @@
|
|||
// * along with this program. If not, see http://www.gnu.org/licenses/.
|
||||
|
||||
#include "common/resources/outputstream.h"
|
||||
#include "common/resources/resourcestreambuffer.h"
|
||||
#include "common/resources/outputstreambuffer.h"
|
||||
|
||||
|
||||
COutputStream::COutputStream() : std::ostream(new CResourceStreamBuffer())
|
||||
COutputStream::COutputStream() : std::ostream(new COutputStreamBuffer())
|
||||
{
|
||||
}
|
||||
|
||||
|
@ -31,23 +31,17 @@ COutputStream::~COutputStream()
|
|||
|
||||
void COutputStream::open(const std::string& filename)
|
||||
{
|
||||
static_cast<CResourceStreamBuffer *>(rdbuf())->open(filename);
|
||||
static_cast<COutputStreamBuffer *>(rdbuf())->open(filename);
|
||||
}
|
||||
|
||||
|
||||
void COutputStream::close()
|
||||
{
|
||||
static_cast<CResourceStreamBuffer *>(rdbuf())->close();
|
||||
static_cast<COutputStreamBuffer *>(rdbuf())->close();
|
||||
}
|
||||
|
||||
|
||||
bool COutputStream::is_open()
|
||||
{
|
||||
return static_cast<CResourceStreamBuffer *>(rdbuf())->is_open();
|
||||
}
|
||||
|
||||
|
||||
size_t COutputStream::size()
|
||||
{
|
||||
return static_cast<CResourceStreamBuffer *>(rdbuf())->size();
|
||||
return static_cast<COutputStreamBuffer *>(rdbuf())->is_open();
|
||||
}
|
||||
|
|
|
@ -28,6 +28,5 @@ public:
|
|||
|
||||
void open(const std::string &filename);
|
||||
void close();
|
||||
bool is_open();
|
||||
size_t size();
|
||||
bool is_open();
|
||||
};
|
||||
|
|
|
@ -0,0 +1,85 @@
|
|||
// * This file is part of the COLOBOT source code
|
||||
// * Copyright (C) 2014 Polish Portal of Colobot (PPC)
|
||||
// *
|
||||
// * This program is free software: you can redistribute it and/or modify
|
||||
// * it under the terms of the GNU General Public License as published by
|
||||
// * the Free Software Foundation, either version 3 of the License, or
|
||||
// * (at your option) any later version.
|
||||
// *
|
||||
// * This program 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
|
||||
// * along with this program. If not, see http://www.gnu.org/licenses/.
|
||||
|
||||
#include "common/resources/outputstreambuffer.h"
|
||||
|
||||
#include <stdexcept>
|
||||
#include <sstream>
|
||||
|
||||
COutputStreamBuffer::COutputStreamBuffer(size_t buffer_size) : m_buffer_size(buffer_size)
|
||||
{
|
||||
m_file = nullptr;
|
||||
m_buffer = new char[buffer_size];
|
||||
setp(m_buffer, m_buffer + buffer_size);
|
||||
}
|
||||
|
||||
|
||||
COutputStreamBuffer::~COutputStreamBuffer()
|
||||
{
|
||||
close();
|
||||
delete m_buffer;
|
||||
}
|
||||
|
||||
|
||||
void COutputStreamBuffer::open(const std::string &filename)
|
||||
{
|
||||
if (PHYSFS_isInit())
|
||||
m_file = PHYSFS_openWrite(filename.c_str());
|
||||
}
|
||||
|
||||
|
||||
void COutputStreamBuffer::close()
|
||||
{
|
||||
if (is_open())
|
||||
PHYSFS_close(m_file);
|
||||
}
|
||||
|
||||
|
||||
bool COutputStreamBuffer::is_open()
|
||||
{
|
||||
return m_file;
|
||||
}
|
||||
|
||||
|
||||
std::streambuf::int_type COutputStreamBuffer::overflow(std::streambuf::int_type ch)
|
||||
{
|
||||
/* This function should be called when pptr() == epptr(). We use it also in sync()
|
||||
so we also have to write data if buffer is not full. */
|
||||
|
||||
if (pbase() == pptr()) // no data to write, sync() called with empty buffer
|
||||
return 0;
|
||||
|
||||
// save buffer
|
||||
PHYSFS_sint64 bytes_written = PHYSFS_write(m_file, pbase(), 1, pptr() - pbase());
|
||||
if (bytes_written <= 0)
|
||||
return traits_type::eof();
|
||||
|
||||
pbump(-bytes_written);
|
||||
// write final char
|
||||
if (ch != traits_type::eof()) {
|
||||
bytes_written = PHYSFS_write(m_file, &ch, 1, 1);
|
||||
if (bytes_written <= 0)
|
||||
return traits_type::eof();
|
||||
}
|
||||
|
||||
return ch;
|
||||
}
|
||||
|
||||
|
||||
int COutputStreamBuffer::sync()
|
||||
{
|
||||
return overflow(traits_type::eof());
|
||||
}
|
|
@ -0,0 +1,45 @@
|
|||
// * This file is part of the COLOBOT source code
|
||||
// * Copyright (C) 2014 Polish Portal of Colobot (PPC)
|
||||
// *
|
||||
// * This program is free software: you can redistribute it and/or modify
|
||||
// * it under the terms of the GNU General Public License as published by
|
||||
// * the Free Software Foundation, either version 3 of the License, or
|
||||
// * (at your option) any later version.
|
||||
// *
|
||||
// * This program 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
|
||||
// * along with this program. If not, see http://www.gnu.org/licenses/.
|
||||
|
||||
#pragma once
|
||||
|
||||
#include <streambuf>
|
||||
#include <string>
|
||||
#include <physfs.h>
|
||||
|
||||
class COutputStreamBuffer : public std::streambuf
|
||||
{
|
||||
public:
|
||||
COutputStreamBuffer(size_t buffer_size = 512);
|
||||
virtual ~COutputStreamBuffer();
|
||||
|
||||
void open(const std::string &filename);
|
||||
void close();
|
||||
bool is_open();
|
||||
|
||||
private:
|
||||
int_type overflow(int_type ch);
|
||||
int sync();
|
||||
|
||||
// copy ctor and assignment not implemented;
|
||||
// copying not allowed
|
||||
COutputStreamBuffer(const COutputStreamBuffer &);
|
||||
COutputStreamBuffer &operator= (const COutputStreamBuffer &);
|
||||
|
||||
PHYSFS_File *m_file;
|
||||
char *m_buffer;
|
||||
size_t m_buffer_size;
|
||||
};
|
|
@ -1,122 +0,0 @@
|
|||
// * This file is part of the COLOBOT source code
|
||||
// * Copyright (C) 2014 Polish Portal of Colobot (PPC)
|
||||
// *
|
||||
// * This program is free software: you can redistribute it and/or modify
|
||||
// * it under the terms of the GNU General Public License as published by
|
||||
// * the Free Software Foundation, either version 3 of the License, or
|
||||
// * (at your option) any later version.
|
||||
// *
|
||||
// * This program 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
|
||||
// * along with this program. If not, see http://www.gnu.org/licenses/.
|
||||
|
||||
#include "common/resources/resourcestreambuffer.h"
|
||||
|
||||
#include <stdexcept>
|
||||
#include <sstream>
|
||||
|
||||
CResourceStreamBuffer::CResourceStreamBuffer(size_t buffer_size) : m_buffer_size(buffer_size)
|
||||
{
|
||||
if (buffer_size <= 0)
|
||||
{
|
||||
throw std::runtime_error("File buffer must be larger then 0 bytes");
|
||||
}
|
||||
|
||||
m_buffer = new char[buffer_size];
|
||||
m_file = nullptr;
|
||||
}
|
||||
|
||||
|
||||
CResourceStreamBuffer::~CResourceStreamBuffer()
|
||||
{
|
||||
close();
|
||||
delete m_buffer;
|
||||
}
|
||||
|
||||
|
||||
void CResourceStreamBuffer::open(const std::string &filename)
|
||||
{
|
||||
if (PHYSFS_isInit())
|
||||
{
|
||||
m_file = PHYSFS_openRead(filename.c_str());
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void CResourceStreamBuffer::close()
|
||||
{
|
||||
if (is_open())
|
||||
{
|
||||
PHYSFS_close(m_file);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
bool CResourceStreamBuffer::is_open()
|
||||
{
|
||||
return m_file;
|
||||
}
|
||||
|
||||
|
||||
size_t CResourceStreamBuffer::size()
|
||||
{
|
||||
return PHYSFS_fileLength(m_file);
|
||||
}
|
||||
|
||||
|
||||
std::streambuf::int_type CResourceStreamBuffer::underflow()
|
||||
{
|
||||
if (PHYSFS_eof(m_file))
|
||||
{
|
||||
return traits_type::eof();
|
||||
}
|
||||
|
||||
PHYSFS_sint64 read_count = PHYSFS_read(m_file, m_buffer, sizeof(char), m_buffer_size);
|
||||
if (read_count <= 0)
|
||||
{
|
||||
return traits_type::eof();
|
||||
}
|
||||
|
||||
setg(m_buffer, m_buffer, m_buffer + read_count);
|
||||
|
||||
return traits_type::to_int_type(*gptr());
|
||||
}
|
||||
|
||||
|
||||
std::streampos CResourceStreamBuffer::seekpos(std::streampos sp, std::ios_base::openmode which)
|
||||
{
|
||||
return seekoff(off_type(sp), std::ios_base::beg, which);
|
||||
}
|
||||
|
||||
|
||||
std::streampos CResourceStreamBuffer::seekoff(std::streamoff off, std::ios_base::seekdir way, std::ios_base::openmode which)
|
||||
{
|
||||
/* A bit of explanation:
|
||||
We are reading file by m_buffer_size parts so our 3 internal pointers will be
|
||||
* eback (not used here) - start of block
|
||||
* gptr - position of read cursor in block
|
||||
* egtpr - end of block
|
||||
off argument is relative to way */
|
||||
|
||||
switch (way)
|
||||
{
|
||||
case std::ios_base::beg:
|
||||
return pos_type(off_type(off));
|
||||
|
||||
case std::ios_base::cur:
|
||||
// tell will give cursor at begining of block so we have to add where in block we currently are
|
||||
return off + static_cast<off_type>(PHYSFS_tell(m_file)) - static_cast<off_type> (egptr() - gptr());
|
||||
|
||||
case std::ios_base::end:
|
||||
return off + static_cast<off_type>(PHYSFS_fileLength(m_file));
|
||||
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
||||
return pos_type(off_type(-1));
|
||||
}
|
|
@ -1,47 +0,0 @@
|
|||
// * This file is part of the COLOBOT source code
|
||||
// * Copyright (C) 2014 Polish Portal of Colobot (PPC)
|
||||
// *
|
||||
// * This program is free software: you can redistribute it and/or modify
|
||||
// * it under the terms of the GNU General Public License as published by
|
||||
// * the Free Software Foundation, either version 3 of the License, or
|
||||
// * (at your option) any later version.
|
||||
// *
|
||||
// * This program 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
|
||||
// * along with this program. If not, see http://www.gnu.org/licenses/.
|
||||
|
||||
#pragma once
|
||||
|
||||
#include <streambuf>
|
||||
#include <string>
|
||||
#include <physfs.h>
|
||||
|
||||
class CResourceStreamBuffer : public std::streambuf
|
||||
{
|
||||
public:
|
||||
CResourceStreamBuffer(size_t buffer_size = 512);
|
||||
virtual ~CResourceStreamBuffer();
|
||||
|
||||
void open(const std::string &filename);
|
||||
void close();
|
||||
bool is_open();
|
||||
size_t size();
|
||||
|
||||
private:
|
||||
int_type underflow();
|
||||
std::streampos seekpos(std::streampos sp, std::ios_base::openmode which);
|
||||
std::streampos seekoff(std::streamoff off, std::ios_base::seekdir way, std::ios_base::openmode which);
|
||||
|
||||
// copy ctor and assignment not implemented;
|
||||
// copying not allowed
|
||||
CResourceStreamBuffer(const CResourceStreamBuffer &);
|
||||
CResourceStreamBuffer &operator= (const CResourceStreamBuffer &);
|
||||
|
||||
PHYSFS_File *m_file;
|
||||
char *m_buffer;
|
||||
size_t m_buffer_size;
|
||||
};
|
Loading…
Reference in New Issue