[colobot] 06/390: More work on streams

Didier Raboud odyx at moszumanska.debian.org
Fri Jun 12 14:21:21 UTC 2015


This is an automated email from the git hooks/post-receive script.

odyx pushed a commit to branch upstream/latest
in repository colobot.

commit 68d41d3b214856f8d321b4dbdffc0cd4c7333c36
Author: Krzysztof Dermont <erihel at gmail.com>
Date:   Mon Jun 23 23:19:55 2014 +0200

    More work on streams
---
 src/CMakeLists.txt                                 |   3 +-
 src/common/resources/inputstream.cpp               |  12 +-
 ...ourcestreambuffer.cpp => inputstreambuffer.cpp} |  51 +++++----
 ...{resourcestreambuffer.h => inputstreambuffer.h} |  11 +-
 src/common/resources/outputstream.cpp              |  16 +--
 src/common/resources/outputstream.h                |   3 +-
 src/common/resources/outputstreambuffer.cpp        |  85 ++++++++++++++
 ...resourcestreambuffer.h => outputstreambuffer.h} |  16 ++-
 src/common/resources/resourcestreambuffer.cpp      | 122 ---------------------
 src/common/resources/resourcestreambuffer.h        |  47 --------
 10 files changed, 141 insertions(+), 225 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/resourcestreambuffer.cpp b/src/common/resources/inputstreambuffer.cpp
similarity index 66%
copy from src/common/resources/resourcestreambuffer.cpp
copy to src/common/resources/inputstreambuffer.cpp
index ed6e738..b8710e9 100644
--- a/src/common/resources/resourcestreambuffer.cpp
+++ b/src/common/resources/inputstreambuffer.cpp
@@ -14,12 +14,12 @@
 // * 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 "common/resources/inputstreambuffer.h"
 
 #include <stdexcept>
 #include <sstream>
 
-CResourceStreamBuffer::CResourceStreamBuffer(size_t buffer_size) : m_buffer_size(buffer_size)
+CInputStreamBuffer::CInputStreamBuffer(size_t buffer_size) : m_buffer_size(buffer_size)
 {
     if (buffer_size <= 0)
     {
@@ -31,55 +31,50 @@ CResourceStreamBuffer::CResourceStreamBuffer(size_t buffer_size) : m_buffer_size
 }
 
 
-CResourceStreamBuffer::~CResourceStreamBuffer()
+CInputStreamBuffer::~CInputStreamBuffer()
 {
     close();
     delete m_buffer;
 }
 
 
-void CResourceStreamBuffer::open(const std::string &filename)
+void CInputStreamBuffer::open(const std::string &filename)
 {
     if (PHYSFS_isInit())
-    {
         m_file = PHYSFS_openRead(filename.c_str());
-    }
 }
 
 
-void CResourceStreamBuffer::close()
+void CInputStreamBuffer::close()
 {
     if (is_open())
-    {
         PHYSFS_close(m_file);
-    }
 }
 
 
-bool CResourceStreamBuffer::is_open()
+bool CInputStreamBuffer::is_open()
 {
     return m_file;
 }
 
 
-size_t CResourceStreamBuffer::size()
+size_t CInputStreamBuffer::size()
 {
     return PHYSFS_fileLength(m_file);
 }
 
 
-std::streambuf::int_type CResourceStreamBuffer::underflow()
+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);
 
@@ -87,13 +82,13 @@ std::streambuf::int_type CResourceStreamBuffer::underflow()
 }
 
 
-std::streampos CResourceStreamBuffer::seekpos(std::streampos sp, std::ios_base::openmode which)
+std::streampos CInputStreamBuffer::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)
+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
@@ -101,22 +96,34 @@ std::streampos CResourceStreamBuffer::seekoff(std::streamoff off, std::ios_base:
        * 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:
-            return pos_type(off_type(off));
+            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
-            return off + static_cast<off_type>(PHYSFS_tell(m_file)) - static_cast<off_type> (egptr() - gptr());
+            new_position = off + static_cast<off_type>(PHYSFS_tell(m_file)) - static_cast<off_type> (egptr() - gptr());
+            break;
 
         case std::ios_base::end:
-            return off + static_cast<off_type>(PHYSFS_fileLength(m_file));
-            
+            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/resourcestreambuffer.h b/src/common/resources/inputstreambuffer.h
similarity index 83%
copy from src/common/resources/resourcestreambuffer.h
copy to src/common/resources/inputstreambuffer.h
index a9ec0db..93cb43c 100644
--- a/src/common/resources/resourcestreambuffer.h
+++ b/src/common/resources/inputstreambuffer.h
@@ -20,11 +20,11 @@
 #include <string>
 #include <physfs.h>
 
-class CResourceStreamBuffer : public std::streambuf
+class CInputStreamBuffer : public std::streambuf
 {
 public:
-    CResourceStreamBuffer(size_t buffer_size = 512);
-    virtual ~CResourceStreamBuffer();
+    CInputStreamBuffer(size_t buffer_size = 512);
+    virtual ~CInputStreamBuffer();
     
     void open(const std::string &filename);
     void close();
@@ -33,13 +33,14 @@ public:
 
 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 &);
+    CInputStreamBuffer(const CInputStreamBuffer &);
+    CInputStreamBuffer &operator= (const CInputStreamBuffer &);
     
     PHYSFS_File *m_file;
     char *m_buffer;
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/resourcestreambuffer.h b/src/common/resources/outputstreambuffer.h
similarity index 68%
copy from src/common/resources/resourcestreambuffer.h
copy to src/common/resources/outputstreambuffer.h
index a9ec0db..1d98791 100644
--- a/src/common/resources/resourcestreambuffer.h
+++ b/src/common/resources/outputstreambuffer.h
@@ -20,26 +20,24 @@
 #include <string>
 #include <physfs.h>
 
-class CResourceStreamBuffer : public std::streambuf
+class COutputStreamBuffer : public std::streambuf
 {
 public:
-    CResourceStreamBuffer(size_t buffer_size = 512);
-    virtual ~CResourceStreamBuffer();
+    COutputStreamBuffer(size_t buffer_size = 512);
+    virtual ~COutputStreamBuffer();
     
     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);
+    int_type overflow(int_type ch);
+    int sync();
 
     // copy ctor and assignment not implemented;
     // copying not allowed
-    CResourceStreamBuffer(const CResourceStreamBuffer &);
-    CResourceStreamBuffer &operator= (const CResourceStreamBuffer &);
+    COutputStreamBuffer(const COutputStreamBuffer &);
+    COutputStreamBuffer &operator= (const COutputStreamBuffer &);
     
     PHYSFS_File *m_file;
     char *m_buffer;
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;
-};

-- 
Alioth's /usr/local/bin/git-commit-notice on /srv/git.debian.org/git/pkg-games/colobot.git



More information about the Pkg-games-commits mailing list