Add std::streambuf wrapper around SDL_RWops for boost
Also add SDL_RWops version of the readFile utility function.
This commit is contained in:
		
							parent
							
								
									5974d05380
								
							
						
					
					
						commit
						35077793a0
					
				
					 3 changed files with 119 additions and 14 deletions
				
			
		| 
						 | 
				
			
			@ -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;
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -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>(); );
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -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
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
		Loading…
	
	Add table
		Add a link
		
	
		Reference in a new issue