Skip to content

Commit

Permalink
Evaluate a std stream with a specialized lua reader
Browse files Browse the repository at this point in the history
  • Loading branch information
Arnaud Bellec committed Apr 24, 2013
1 parent 288375c commit 90d077c
Show file tree
Hide file tree
Showing 2 changed files with 39 additions and 0 deletions.
28 changes: 28 additions & 0 deletions lundi.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,8 @@
#include <boost/fusion/view/reverse_view.hpp>
#include <boost/fusion/algorithm/iteration/for_each.hpp>
#include <boost/fusion/functional/invocation/invoke.hpp>
#include <boost/type_traits/is_base_of.hpp>
#include <istream>
#include <lua.hpp>

#include "lundi/variant.hpp"
Expand Down Expand Up @@ -82,8 +84,26 @@ int dispatch_to_wrapper(lua_State *state) {
return (*wrapper)(state);
}

template<typename StreamT>
static const char *read_stream(StreamT &stream, std::vector<char> &buffer, size_t &size) {
stream.read(&buffer[0], buffer.size());
size = stream.gcount();
return &buffer[0];
}

template<typename StreamT>
static const char *stream_reader(lua_State *L, void *data, size_t *size) {
auto &info = *reinterpret_cast<std::pair<std::reference_wrapper<StreamT>, std::vector<char>>*>(data);

This comment has been minimized.

Copy link
@bananu7

bananu7 Apr 29, 2013

Member

The code is ok, we just have to do something with that.

return read_stream<StreamT>(info.first, info.second, *size);
}

} // detail

template<typename StreamT>
char const *stream_name(StreamT &stream) {
return "<stream>";
}

class state {
lua_State *state_;
std::function<void(std::string const&)> error_func_;
Expand Down Expand Up @@ -174,6 +194,14 @@ class state {
return proxy<variant, state>(std::move(name), *this);
}

template<typename StreamT>
typename boost::enable_if<boost::is_base_of<std::istream, StreamT>, void>::type eval(StreamT &stream) {
using namespace detail;
auto reader_info = std::make_pair(std::ref(stream), std::vector<char>(4096));
protect(lua_load(state_, &stream_reader<StreamT>, &reader_info, stream_name(stream)));
protect(lua_pcall(state_, 0, LUA_MULTRET, 0));
}

void eval(std::string const &program) {
protect(luaL_dostring(state_, program.c_str()));
}
Expand Down
11 changes: 11 additions & 0 deletions test.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -97,6 +97,17 @@ TEST_CASE( "simple/call", "Lua function is called with a few parameters from C++
REQUIRE_NOTHROW( lua.call("foo") );
}

TEST_CASE( "simple/evalStream", "The VM evaluates a stream's contents using a reader" ) {
lua::state lua(&exceptionErrorReporter);

std::stringstream script;
int g = 9;
script << "g = " << g << ";";

REQUIRE_NOTHROW( lua.eval(script) );
REQUIRE( equals(lua.get_global("g"), 9.0) );
}

TEST_CASE( "simple/callWithParameters", "Lua function is called with a few parameters from C++" ) {
lua::state lua(&exceptionErrorReporter);

Expand Down

0 comments on commit 90d077c

Please sign in to comment.