diff options
Diffstat (limited to 'src')
-rw-r--r-- | src/CMakeLists.txt | 3 | ||||
-rw-r--r-- | src/common/resources/inputstream.cpp | 12 | ||||
-rw-r--r-- | src/common/resources/inputstreambuffer.cpp | 129 | ||||
-rw-r--r-- | src/common/resources/inputstreambuffer.h | 48 | ||||
-rw-r--r-- | src/common/resources/outputstream.cpp | 16 | ||||
-rw-r--r-- | src/common/resources/outputstream.h | 3 | ||||
-rw-r--r-- | src/common/resources/outputstreambuffer.cpp | 85 | ||||
-rw-r--r-- | src/common/resources/outputstreambuffer.h | 45 | ||||
-rw-r--r-- | src/common/resources/resourcestreambuffer.cpp | 122 | ||||
-rw-r--r-- | src/common/resources/resourcestreambuffer.h | 47 |
10 files changed, 321 insertions, 189 deletions
diff --git a/src/CMakeLists.txt b/src/CMakeLists.txt index 62bad96..e02a30b 100644 --- a/src/CMakeLists.txt +++ b/src/CMakeLists.txt @@ -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 diff --git a/src/common/resources/inputstream.cpp b/src/common/resources/inputstream.cpp index e121971..b5ba63f 100644 --- a/src/common/resources/inputstream.cpp +++ b/src/common/resources/inputstream.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(); } diff --git a/src/common/resources/inputstreambuffer.cpp b/src/common/resources/inputstreambuffer.cpp new file mode 100644 index 0000000..b8710e9 --- /dev/null +++ b/src/common/resources/inputstreambuffer.cpp @@ -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)); +} diff --git a/src/common/resources/inputstreambuffer.h b/src/common/resources/inputstreambuffer.h new file mode 100644 index 0000000..93cb43c --- /dev/null +++ b/src/common/resources/inputstreambuffer.h @@ -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; +}; diff --git a/src/common/resources/outputstream.cpp b/src/common/resources/outputstream.cpp index c4fd973..ba43ba6 100644 --- a/src/common/resources/outputstream.cpp +++ b/src/common/resources/outputstream.cpp @@ -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(); } diff --git a/src/common/resources/outputstream.h b/src/common/resources/outputstream.h index bbd921f..4f4cd72 100644 --- a/src/common/resources/outputstream.h +++ b/src/common/resources/outputstream.h @@ -28,6 +28,5 @@ public: void open(const std::string &filename); void close(); - bool is_open(); - size_t size(); + bool is_open(); }; diff --git a/src/common/resources/outputstreambuffer.cpp b/src/common/resources/outputstreambuffer.cpp new file mode 100644 index 0000000..e611d13 --- /dev/null +++ b/src/common/resources/outputstreambuffer.cpp @@ -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()); +} diff --git a/src/common/resources/outputstreambuffer.h b/src/common/resources/outputstreambuffer.h new file mode 100644 index 0000000..1d98791 --- /dev/null +++ b/src/common/resources/outputstreambuffer.h @@ -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; +}; diff --git a/src/common/resources/resourcestreambuffer.cpp b/src/common/resources/resourcestreambuffer.cpp index ed6e738..e69de29 100644 --- a/src/common/resources/resourcestreambuffer.cpp +++ b/src/common/resources/resourcestreambuffer.cpp @@ -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)); -} diff --git a/src/common/resources/resourcestreambuffer.h b/src/common/resources/resourcestreambuffer.h index a9ec0db..e69de29 100644 --- a/src/common/resources/resourcestreambuffer.h +++ b/src/common/resources/resourcestreambuffer.h @@ -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; -}; |