src/physfs/ifile_streambuf.cpp

Go to the documentation of this file.
00001 //  SuperTux
00002 //  Copyright (C) 2006 Matthias Braun <matze@braunis.de>
00003 //
00004 //  This program is free software: you can redistribute it and/or modify
00005 //  it under the terms of the GNU General Public License as published by
00006 //  the Free Software Foundation, either version 3 of the License, or
00007 //  (at your option) any later version.
00008 //
00009 //  This program is distributed in the hope that it will be useful,
00010 //  but WITHOUT ANY WARRANTY; without even the implied warranty of
00011 //  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
00012 //  GNU General Public License for more details.
00013 //
00014 //  You should have received a copy of the GNU General Public License
00015 //  along with this program.  If not, see <http://www.gnu.org/licenses/>.
00016 
00017 #include "physfs/ifile_streambuf.hpp"
00018 
00019 #include <stdexcept>
00020 #include <sstream>
00021 
00022 #include <assert.h>
00023 
00024 IFileStreambuf::IFileStreambuf(const std::string& filename) :
00025   file()
00026 {
00027   // check this as PHYSFS seems to be buggy and still returns a
00028   // valid pointer in this case
00029   if(filename == "") {
00030     throw std::runtime_error("Couldn't open file: empty filename");
00031   }
00032   file = PHYSFS_openRead(filename.c_str());
00033   if(file == 0) {
00034     std::stringstream msg;
00035     msg << "Couldn't open file '" << filename << "': "
00036         << PHYSFS_getLastError();
00037     throw std::runtime_error(msg.str());
00038   }
00039 }
00040 
00041 IFileStreambuf::~IFileStreambuf()
00042 {
00043   PHYSFS_close(file);
00044 }
00045 
00046 int
00047 IFileStreambuf::underflow()
00048 {
00049   if(PHYSFS_eof(file)) {
00050     return traits_type::eof();
00051   }
00052 
00053   PHYSFS_sint64 bytesread = PHYSFS_read(file, buf, 1, sizeof(buf));
00054   if(bytesread <= 0) {
00055     return traits_type::eof();
00056   }
00057   setg(buf, buf, buf + bytesread);
00058 
00059   return buf[0];
00060 }
00061 
00062 IFileStreambuf::pos_type
00063 IFileStreambuf::seekpos(pos_type pos, std::ios_base::openmode)
00064 {
00065   if(PHYSFS_seek(file, static_cast<PHYSFS_uint64> (pos)) == 0) {
00066     return pos_type(off_type(-1));
00067   }
00068 
00069   // the seek invalidated the buffer
00070   setg(buf, buf, buf);
00071   return pos;
00072 }
00073 
00074 IFileStreambuf::pos_type
00075 IFileStreambuf::seekoff(off_type off, std::ios_base::seekdir dir,
00076                         std::ios_base::openmode mode)
00077 {
00078   off_type pos = off;
00079   PHYSFS_sint64 ptell = PHYSFS_tell(file);
00080 
00081   switch(dir) {
00082     case std::ios_base::beg:
00083       break;
00084     case std::ios_base::cur:
00085       if(off == 0)
00086         return static_cast<pos_type> (ptell) - static_cast<pos_type> (egptr() - gptr());
00087       pos += static_cast<off_type> (ptell) - static_cast<off_type> (egptr() - gptr());
00088       break;
00089     case std::ios_base::end:
00090       pos += static_cast<off_type> (PHYSFS_fileLength(file));
00091       break;
00092     default:
00093       assert(false);
00094       return pos_type(off_type(-1));
00095   }
00096 
00097   return seekpos(static_cast<pos_type> (pos), mode);
00098 }
00099 
00100 /* EOF */

Generated on Mon Jun 9 03:38:20 2014 for SuperTux by  doxygen 1.5.1