Add std::streambuf wrapper around SDL_RWops for boost

Also add SDL_RWops version of the readFile utility function.
This commit is contained in:
Jonas Kulla 2014-12-24 05:30:43 +01:00
parent 5974d05380
commit 35077793a0
3 changed files with 119 additions and 14 deletions

View File

@ -25,6 +25,7 @@
#include "eventthread.h"
#include "filesystem.h"
#include "util.h"
#include "sdl-util.h"
#include "debugwriter.h"
#include "graphics.h"
#include "audio.h"
@ -339,7 +340,7 @@ static void runCustomScript(const std::string &filename)
{
std::string scriptData;
if (!readFile(filename.c_str(), scriptData))
if (!readFileSDL(filename.c_str(), scriptData))
{
showMsg(std::string("Unable to open '") + filename + "'");
return;

View File

@ -32,6 +32,7 @@
#include "debugwriter.h"
#include "util.h"
#include "sdl-util.h"
#ifdef INI_ENCODING
extern "C" {
@ -223,22 +224,19 @@ void Config::read(int argc, char *argv[])
}
/* Parse configuration file */
std::ifstream confFile;
confFile.open(CONF_FILE);
SDLRWStream confFile(CONF_FILE, "r");
if (confFile)
{
try
{
po::store(po::parse_config_file(confFile, podesc, true), vm);
po::store(po::parse_config_file(confFile.stream(), podesc, true), vm);
po::notify(vm);
}
catch (po::error &error)
{
Debug() << CONF_FILE":" << error.what();
}
confFile.close();
}
#undef PO_DESC
@ -306,16 +304,25 @@ void Config::readGameINI()
("Game.Scripts", po::value<std::string>())
;
std::string iniPath = gameFolder + "/Game.ini";
std::ifstream iniFile;
iniFile.open((iniPath).c_str());
po::variables_map vm;
po::store(po::parse_config_file(iniFile, podesc, true), vm);
po::notify(vm);
SDLRWStream iniFile("Game.ini", "r");
iniFile.close();
if (iniFile)
{
try
{
po::store(po::parse_config_file(iniFile.stream(), podesc, true), vm);
po::notify(vm);
}
catch (po::error &error)
{
Debug() << "Game.ini:" << error.what();
}
}
else
{
Debug() << "FAILED to open Game.ini";
}
GUARD_ALL( game.title = vm["Game.Title"].as<std::string>(); );
GUARD_ALL( game.scripts = vm["Game.Scripts"].as<std::string>(); );

View File

@ -3,8 +3,10 @@
#include <SDL_atomic.h>
#include <SDL_thread.h>
#include <SDL_rwops.h>
#include <string>
#include <iostream>
struct AtomicFlag
{
@ -45,4 +47,99 @@ SDL_Thread *createSDLThread(C *obj, const std::string &name = std::string())
return SDL_CreateThread(__sdlThreadFun<C, func>, name.c_str(), obj);
}
inline bool readFileSDL(const char *path,
std::string &out)
{
SDL_RWops *f = SDL_RWFromFile(path, "rb");
if (!f)
return false;
long size = SDL_RWsize(f);
size_t back = out.size();
out.resize(back+size);
size_t read = SDL_RWread(f, &out[back], 1, size);
SDL_RWclose(f);
if (read != (size_t) size)
out.resize(back+read);
return true;
}
template<size_t bufSize = 248, size_t pbSize = 8>
class SDLRWBuf : public std::streambuf
{
public:
SDLRWBuf(SDL_RWops *ops)
: ops(ops)
{
char *end = buf + bufSize + pbSize;
setg(end, end, end);
}
private:
int_type underflow()
{
if (!ops)
return traits_type::eof();
if (gptr() < egptr())
return traits_type::to_int_type(*gptr());
char *base = buf;
char *start = base;
if (eback() == base)
{
memmove(base, egptr() - pbSize, pbSize);
start += pbSize;
}
size_t n = SDL_RWread(ops, start, 1, bufSize - (start - base));
if (n == 0)
return traits_type::eof();
setg(base, start, start + n);
return underflow();
}
SDL_RWops *ops;
char buf[bufSize+pbSize];
};
class SDLRWStream
{
public:
SDLRWStream(const char *filename,
const char *mode)
: ops(SDL_RWFromFile(filename, mode)),
buf(ops),
s(&buf)
{}
~SDLRWStream()
{
if (ops)
SDL_RWclose(ops);
}
operator bool() const
{
return ops != 0;
}
std::istream &stream()
{
return s;
}
private:
SDL_RWops *ops;
SDLRWBuf<> buf;
std::istream s;
};
#endif // SDLUTIL_H