summaryrefslogtreecommitdiffstats
path: root/src/common
diff options
context:
space:
mode:
authorKrzysztof Dermont <erihel@gmail.com>2014-06-23 23:19:55 +0200
committerKrzysztof Dermont <erihel@gmail.com>2014-06-23 23:19:55 +0200
commit68d41d3b214856f8d321b4dbdffc0cd4c7333c36 (patch)
tree8a4926268e7b262bb096f51e01cf5d842ff8c1cb /src/common
parent3aca1de731fa7517db7d4dc00913542412150898 (diff)
downloadcolobot-68d41d3b214856f8d321b4dbdffc0cd4c7333c36.tar.gz
colobot-68d41d3b214856f8d321b4dbdffc0cd4c7333c36.tar.bz2
colobot-68d41d3b214856f8d321b4dbdffc0cd4c7333c36.zip
More work on streams
Diffstat (limited to 'src/common')
-rw-r--r--src/common/resources/inputstream.cpp12
-rw-r--r--src/common/resources/inputstreambuffer.cpp129
-rw-r--r--src/common/resources/inputstreambuffer.h48
-rw-r--r--src/common/resources/outputstream.cpp16
-rw-r--r--src/common/resources/outputstream.h3
-rw-r--r--src/common/resources/outputstreambuffer.cpp85
-rw-r--r--src/common/resources/outputstreambuffer.h45
-rw-r--r--src/common/resources/resourcestreambuffer.cpp122
-rw-r--r--src/common/resources/resourcestreambuffer.h47
9 files changed, 319 insertions, 188 deletions
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;
-};