Split control/joystickkeyboardcontroller.?pp
[supertux.git] / src / physfs / ifile_streambuf.cpp
1 //  SuperTux
2 //  Copyright (C) 2006 Matthias Braun <matze@braunis.de>
3 //
4 //  This program is free software: you can redistribute it and/or modify
5 //  it under the terms of the GNU General Public License as published by
6 //  the Free Software Foundation, either version 3 of the License, or
7 //  (at your option) any later version.
8 //
9 //  This program is distributed in the hope that it will be useful,
10 //  but WITHOUT ANY WARRANTY; without even the implied warranty of
11 //  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
12 //  GNU General Public License for more details.
13 //
14 //  You should have received a copy of the GNU General Public License
15 //  along with this program.  If not, see <http://www.gnu.org/licenses/>.
16
17 #include "physfs/ifile_streambuf.hpp"
18
19 #include <stdexcept>
20 #include <sstream>
21
22 IFileStreambuf::IFileStreambuf(const std::string& filename) :
23   file()
24 {
25   // check this as PHYSFS seems to be buggy and still returns a
26   // valid pointer in this case
27   if(filename == "") {
28     throw std::runtime_error("Couldn't open file: empty filename");
29   }
30   file = PHYSFS_openRead(filename.c_str());
31   if(file == 0) {
32     std::stringstream msg;
33     msg << "Couldn't open file '" << filename << "': "
34         << PHYSFS_getLastError();
35     throw std::runtime_error(msg.str());
36   }
37 }
38
39 IFileStreambuf::~IFileStreambuf()
40 {
41   PHYSFS_close(file);
42 }
43
44 int
45 IFileStreambuf::underflow()
46 {
47   if(PHYSFS_eof(file)) {
48     return traits_type::eof();
49   }
50
51   PHYSFS_sint64 bytesread = PHYSFS_read(file, buf, 1, sizeof(buf));
52   if(bytesread <= 0) {
53     return traits_type::eof();
54   }
55   setg(buf, buf, buf + bytesread);
56
57   return buf[0];
58 }
59
60 IFileStreambuf::pos_type
61 IFileStreambuf::seekpos(pos_type pos, std::ios_base::openmode)
62 {
63   if(PHYSFS_seek(file, static_cast<PHYSFS_uint64> (pos)) == 0) {
64     return pos_type(off_type(-1));
65   }
66
67   // the seek invalidated the buffer
68   setg(buf, buf, buf);
69   return pos;
70 }
71
72 IFileStreambuf::pos_type
73 IFileStreambuf::seekoff(off_type off, std::ios_base::seekdir dir,
74                         std::ios_base::openmode mode)
75 {
76   off_type pos = off;
77   PHYSFS_sint64 ptell = PHYSFS_tell(file);
78
79   switch(dir) {
80     case std::ios_base::beg:
81       break;
82     case std::ios_base::cur:
83       if(off == 0)
84         return static_cast<pos_type> (ptell) - static_cast<pos_type> (egptr() - gptr());
85       pos += static_cast<off_type> (ptell) - static_cast<off_type> (egptr() - gptr());
86       break;
87     case std::ios_base::end:
88       pos += static_cast<off_type> (PHYSFS_fileLength(file));
89       break;
90     default:
91 #ifdef DEBUG
92       assert(false);
93 #else
94       return pos_type(off_type(-1));
95 #endif
96   }
97
98   return seekpos(static_cast<pos_type> (pos), mode);
99 }
100
101 /* EOF */