summaryrefslogtreecommitdiff
path: root/src/luacxx.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'src/luacxx.cpp')
-rw-r--r--src/luacxx.cpp142
1 files changed, 142 insertions, 0 deletions
diff --git a/src/luacxx.cpp b/src/luacxx.cpp
new file mode 100644
index 0000000..926e30f
--- /dev/null
+++ b/src/luacxx.cpp
@@ -0,0 +1,142 @@
+#include "luacxx.hpp"
+
+extern "C" {
+#include <lauxlib.h>
+#include <lualib.h>
+}
+
+namespace getsuyomi {
+
+using fud::FudStatus;
+
+LuaContext::LuaContext()
+{
+ m_state = luaL_newstate();
+ if (m_state != nullptr) {
+ luaL_openlibs(m_state);
+ }
+}
+
+LuaContext::~LuaContext()
+{
+ if (m_state != nullptr) {
+ lua_close(m_state);
+ m_state = nullptr;
+ }
+}
+
+LuaContext::LuaContext(LuaContext&& rhs) : m_state{rhs.m_state}
+{
+ rhs.m_state = nullptr;
+}
+
+LuaContext& LuaContext::operator=(LuaContext&& rhs)
+{
+ m_state = rhs.m_state;
+ rhs.m_state = nullptr;
+ return *this;
+}
+
+FudStatus LuaContext::loadFile(const char* filename)
+{
+ if (!valid())
+ {
+ return FudStatus::ObjectInvalid;
+ }
+ if (luaL_loadfile(m_state, filename) || lua_pcall(m_state, 0, 0, 0)) {
+ return FudStatus::Failure;
+ }
+ return FudStatus::Success;
+}
+
+LuaResult<int64_t> LuaContext::getGlobalInteger(const char* name)
+{
+ if (m_state == nullptr) {
+ return LuaResult<int64_t>::error(FudStatus::ObjectInvalid);
+ }
+
+ int isNumber{};
+ int64_t result{};
+
+ auto luaType = lua_getglobal(m_state, name);
+ // discard luaType since isNumber will check if variable is integral
+ static_cast<void>(luaType);
+
+ result = lua_tointegerx(m_state, -1, &isNumber);
+
+ lua_pop(m_state, 1);
+
+ if (!static_cast<bool>(isNumber)) {
+ return LuaResult<int64_t>::error(FudStatus::Failure);
+ }
+ return LuaResult<int64_t>::okay(result);
+}
+
+LuaResult<const char*> LuaContext::getGlobalString(const char* name)
+{
+ if (m_state == nullptr) {
+ return LuaResult<const char*>::error(FudStatus::ObjectInvalid);
+ }
+
+ size_t length;
+ const char* result{nullptr};
+
+ auto luaType = lua_getglobal(m_state, name);
+ static_cast<void>(luaType);
+
+ result = lua_tolstring(m_state, -1, &length);
+
+ lua_pop(m_state, 1);
+
+ if (result == nullptr) {
+ return LuaResult<const char*>::error(FudStatus::Failure);
+ }
+ return LuaResult<const char*>::okay(result);
+}
+
+LuaResult<std::vector<std::string>> LuaContext::getGlobalStringArray(const char* name)
+{
+ using RetType = LuaResult<std::vector<std::string>>;
+ if (m_state == nullptr) {
+ return RetType::error(FudStatus::ObjectInvalid);
+ }
+
+ auto luaType = lua_getglobal(m_state, name);
+ static_cast<void>(luaType);
+
+ if (!lua_istable(m_state, -1)) {
+ lua_pop(m_state, 1);
+ return RetType::error(FudStatus::Failure);
+ }
+
+ int64_t length;
+ int isNumber{};
+ lua_len(m_state, -1);
+ length = lua_tointegerx(m_state, -1, &isNumber);
+ lua_pop(m_state, 1);
+
+ if (!static_cast<bool>(isNumber) || length < 0) {
+ lua_pop(m_state, 1);
+ return RetType::error(FudStatus::Failure);
+ }
+
+ std::vector<std::string> output{};
+ output.reserve(static_cast<size_t>(length));
+ for (int64_t index = 1; index <= length; ++index) {
+ const char* result{nullptr};
+ lua_pushinteger(m_state, index);
+ static_cast<void>(lua_gettable(m_state, -2));
+ result = lua_tolstring(m_state, -1, nullptr);
+
+ if (result == nullptr) {
+ lua_pop(m_state, 1);
+ return RetType::error(FudStatus::Failure);
+ }
+ output.emplace_back(result);
+ }
+
+ lua_pop(m_state, 1);
+ return RetType::okay(output);
+}
+
+} // namespace getsuyomi