00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
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
00028
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
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