Slightly optimize returning strings to lua from ffi functions

This commit is contained in:
Thomas Goyne 2014-12-27 20:03:39 -08:00
parent 010f6c4f79
commit 5201773a3b
5 changed files with 16 additions and 6 deletions

View file

@ -16,6 +16,7 @@
#include <libaegisub/type_name.h> #include <libaegisub/type_name.h>
#include <cstdlib>
#include <lua.hpp> #include <lua.hpp>
namespace agi { namespace lua { namespace agi { namespace lua {
@ -59,4 +60,12 @@ void register_lib_table(lua_State *L, std::initializer_list<const char *> types,
// Leaves lib table on the stack // Leaves lib table on the stack
} }
template<typename T>
char *strndup(T const& str) {
char *ret = static_cast<char*>(malloc(str.size() + 1));
memcpy(ret, str.data(), str.size());
ret[str.size()] = 0;
return ret;
}
} } } }

View file

@ -21,6 +21,7 @@
#include <boost/filesystem/path.hpp> #include <boost/filesystem/path.hpp>
using namespace agi::fs; using namespace agi::fs;
using namespace agi::lua;
namespace bfs = boost::filesystem; namespace bfs = boost::filesystem;
namespace agi { namespace agi {
@ -38,7 +39,7 @@ auto wrap(char **err, Func f) -> decltype(f()) {
return 0; return 0;
} }
catch (agi::Exception const& e) { catch (agi::Exception const& e) {
*err = strdup(e.GetMessage().c_str()); *err = strndup(e.GetMessage());
return 0; return 0;
} }
} }
@ -57,7 +58,7 @@ bool lfs_chdir(const char *dir, char **err) {
char *currentdir(char **err) { char *currentdir(char **err) {
return wrap(err, []{ return wrap(err, []{
return strdup(bfs::current_path().string().c_str()); return strndup(bfs::current_path().string());
}); });
} }
@ -76,7 +77,7 @@ bool touch(const char *path, char **err) {
char *dir_next(DirectoryIterator &it, char **err) { char *dir_next(DirectoryIterator &it, char **err) {
if (it == end(it)) return nullptr; if (it == end(it)) return nullptr;
return wrap(err, [&]{ return wrap(err, [&]{
auto str = strdup((*it).c_str()); auto str = strndup(*it);
++it; ++it;
return str; return str;
}); });

View file

@ -92,7 +92,7 @@ char *regex_replace(u32regex& re, const char *replacement, const char *str, size
} }
ret += suffix; ret += suffix;
return strdup(ret.c_str()); return agi::lua::strndup(ret);
} }
u32regex *regex_compile(const char *pattern, int flags, char **err) { u32regex *regex_compile(const char *pattern, int flags, char **err) {

View file

@ -22,7 +22,7 @@ namespace {
template<std::string (*func)(const char *, std::locale const&)> template<std::string (*func)(const char *, std::locale const&)>
char *wrap(const char *str, char **err) { char *wrap(const char *str, char **err) {
try { try {
return strdup(func(str, std::locale()).c_str()); return agi::lua::strndup(func(str, std::locale()));
} catch (std::exception const& e) { } catch (std::exception const& e) {
*err = strdup(e.what()); *err = strdup(e.what());
return nullptr; return nullptr;

View file

@ -124,7 +124,7 @@ namespace {
std::string data = GetClipboard(); std::string data = GetClipboard();
if (data.empty()) if (data.empty())
return nullptr; return nullptr;
return strdup(data.c_str()); return strndup(data);
} }
bool clipboard_set(const char *str) bool clipboard_set(const char *str)