X-Git-Url: https://git.verplant.org/?a=blobdiff_plain;f=src%2Fphysfs%2Fphysfs_stream.cpp;h=28d92c567a632085a65a5bb7ee3beb8c9b879111;hb=43db9a6c44b6ee544e7694d1bb234ba559b0849c;hp=0a41a545cf8dd2fb3bb27f5066bb9ad8fdd2a40a;hpb=36266bca23c8ef1a4b036572b7c5fa07df7a1afd;p=supertux.git diff --git a/src/physfs/physfs_stream.cpp b/src/physfs/physfs_stream.cpp index 0a41a545c..28d92c567 100644 --- a/src/physfs/physfs_stream.cpp +++ b/src/physfs/physfs_stream.cpp @@ -1,30 +1,38 @@ -/* -Copyright (C) 2005 Matthias Braun - -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 2 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, write to the Free Software -Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA -*/ +// $Id$ +// +// SuperTux +// Copyright (C) 2006 Matthias Braun +// +// 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 2 +// 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, write to the Free Software +// Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. + #include -#include "physfs_stream.h" +#include "physfs_stream.hpp" +#include #include #include #include IFileStreambuf::IFileStreambuf(const std::string& filename) { + // check this as PHYSFS seems to be buggy and still returns a + // valid pointer in this case + if(filename == "") { + throw std::runtime_error("Couldn't open file: empty filename"); + } file = PHYSFS_openRead(filename.c_str()); if(file == 0) { std::stringstream msg; @@ -42,17 +50,60 @@ IFileStreambuf::~IFileStreambuf() int IFileStreambuf::underflow() { - if(PHYSFS_eof(file)) + if(PHYSFS_eof(file)) { return traits_type::eof(); - - size_t bytesread = (size_t) PHYSFS_read(file, buf, 1, sizeof(buf)); - if(bytesread == 0) + } + + PHYSFS_sint64 bytesread = PHYSFS_read(file, buf, 1, sizeof(buf)); + if(bytesread <= 0) { return traits_type::eof(); + } setg(buf, buf, buf + bytesread); return buf[0]; } +IFileStreambuf::pos_type +IFileStreambuf::seekpos(pos_type pos, std::ios_base::openmode) +{ + if(PHYSFS_seek(file, static_cast (pos)) == 0) { + return pos_type(off_type(-1)); + } + + // the seek invalidated the buffer + setg(buf, buf, buf); + return pos; +} + +IFileStreambuf::pos_type +IFileStreambuf::seekoff(off_type off, std::ios_base::seekdir dir, + std::ios_base::openmode mode) +{ + off_type pos = off; + PHYSFS_sint64 ptell = PHYSFS_tell(file); + + switch(dir) { + case std::ios_base::beg: + break; + case std::ios_base::cur: + if(off == 0) + return static_cast (ptell) - static_cast (egptr() - gptr()); + pos += static_cast (ptell) - static_cast (egptr() - gptr()); + break; + case std::ios_base::end: + pos += static_cast (PHYSFS_fileLength(file)); + break; + default: +#ifdef DEBUG + assert(false); +#else + return pos_type(off_type(-1)); +#endif + } + + return seekpos(static_cast (pos), mode); +} + //--------------------------------------------------------------------------- OFileStreambuf::OFileStreambuf(const std::string& filename) @@ -64,7 +115,7 @@ OFileStreambuf::OFileStreambuf(const std::string& filename) << PHYSFS_getLastError(); throw std::runtime_error(msg.str()); } - + setp(buf, buf+sizeof(buf)); } @@ -77,6 +128,8 @@ OFileStreambuf::~OFileStreambuf() int OFileStreambuf::overflow(int c) { + char c2 = (char)c; + if(pbase() == pptr()) return 0; @@ -84,9 +137,9 @@ OFileStreambuf::overflow(int c) PHYSFS_sint64 res = PHYSFS_write(file, pbase(), 1, size); if(res <= 0) return traits_type::eof(); - + if(c != traits_type::eof()) { - PHYSFS_sint64 res = PHYSFS_write(file, &c, 1, 1); + PHYSFS_sint64 res = PHYSFS_write(file, &c2, 1, 1); if(res <= 0) return traits_type::eof(); } @@ -124,4 +177,3 @@ OFileStream::~OFileStream() { delete rdbuf(); } -