lua/fs/lib.cxx

197 lines
5.3 KiB
C++

#include "lib.h"
#include <string>
#ifdef USE_BOOST_FILESYSTEM
#include <boost/filesystem.hpp>
namespace fs = boost::filesystem;
#else
#include <filesystem>
namespace fs = std::filesystem;
#endif
/*
return 语句的值代表着你从 C++ 函数返回的 Lua 堆栈上的元素个数。
*/
static const luaL_Reg lua_fs[] = {{"exists", exists},
{"is_regular_file", is_regular_file},
{"copy_file", copy_file},
{"delete_file", delete_file},
{"get_dir_files", get_dir_files},
{"get_current_directory", get_current_directory},
{"get_parent", get_parent},
{"append_path", append_path},
{"mkdir", mkdir},
{"normalize", normalize},
{NULL, NULL}};
int luaopen_lua_fs(lua_State* L)
{
luaL_newlib(L, lua_fs);
return 1;
}
static std::string replace(const std::string& str, const std::string& from, const std::string& to)
{
if (from.empty()) {
return str;
}
std::string result = str;
size_t startPos = 0;
while ((startPos = result.find(from, startPos)) != std::string::npos) {
result.replace(startPos, from.length(), to);
startPos += to.length();
}
return result;
}
/// @brief 创建文件夹
/// @param path string 路径或者文件夹名称
/// @return boolean
int mkdir(lua_State* L)
{
const char* path = luaL_checkstring(L, 1);
try {
fs::path p(path);
if (p.is_relative()) {
p = fs::current_path().append(path);
}
fs::create_directories(p);
lua_pushboolean(L, true);
return 1;
} catch (const std::exception& e) {
lua_pushnil(L);
lua_pushstring(L, e.what());
return 2;
}
}
/// @brief 获取父目录
/// @param path string 路径
/// @return string
int get_parent(lua_State* L)
{
const char* path = luaL_checkstring(L, 1);
auto r = fs::path(path).parent_path().string();
lua_pushstring(L, r.c_str());
return 1;
}
/// @brief 规范化路径
/// @param path string 路径
/// @return string
int normalize(lua_State* L)
{
const char* path = luaL_checkstring(L, 1);
#ifdef _WIN32
std::string normalized = replace(path, "/", "\\");
if (!normalized.empty() && normalized.back() == '\\') {
normalized.pop_back();
}
#else
std::string normalized = replace(path, "\\", "/");
if (!normalized.empty() && normalized.back() == '/') {
normalized.pop_back();
}
#endif
lua_pushstring(L, normalized.c_str());
return 1;
}
/// @brief 拼接路径
/// @param path string 基本路径
/// @param append string 添加路径
/// @return string
int append_path(lua_State* L)
{
const char* path = luaL_checkstring(L, 1);
const char* append = luaL_checkstring(L, 2);
auto r = fs::path(path).append(append).string();
lua_pushstring(L, r.c_str());
return 1;
}
/// @brief 文件是否存在
/// @param path string 文件路径
/// @return boolean
int exists(lua_State* L)
{
const char* path = luaL_checkstring(L, 1);
bool result = fs::exists(path);
lua_pushboolean(L, result);
return 1;
}
/// @brief 文件是否是一个常规文件
/// @param path string 文件路径
/// @return boolean
int is_regular_file(lua_State* L)
{
const char* path = luaL_checkstring(L, 1);
bool result = fs::is_regular_file(path);
lua_pushboolean(L, result);
return 1;
}
/// @brief 复制文件
/// @param source string 源文件
/// @param destination string 目标文件
/// @return boolean
int copy_file(lua_State* L)
{
const char* source = luaL_checkstring(L, 1);
const char* destination = luaL_checkstring(L, 2);
bool result = fs::copy_file(source, destination);
lua_pushboolean(L, result);
return 1;
}
/// @brief 删除文件
/// @param path string 文件路径
/// @return boolean
int delete_file(lua_State* L)
{
const char* path = luaL_checkstring(L, 1);
bool result = fs::remove(path);
lua_pushboolean(L, result);
return 1;
}
/// @brief 获取当前工作目录
/// @return string
int get_current_directory(lua_State* L)
{
std::string current_dir = fs::current_path().string();
lua_pushstring(L, current_dir.c_str());
return 1;
}
/// @brief 获取一个目录下所有文件(不递归)
/// @param dir_path string 目录
/// @return table
int get_dir_files(lua_State* L)
{
// 获取第一个参数:目录路径
const char* dir_path = luaL_checkstring(L, 1);
// 检查目录是否存在
if (!fs::exists(dir_path) || !fs::is_directory(dir_path)) {
lua_pushnil(L);
lua_pushstring(L, "Invalid directory path");
return 2; // 返回 nil 和错误信息
}
// 创建一个新的 Lua 表用于存放文件列表
lua_newtable(L);
int table_index = lua_gettop(L); // 获取当前 Lua 表的位置
int index = 1;
for (const auto& entry : fs::directory_iterator(dir_path)) {
if (fs::is_regular_file(entry.status())) {
lua_pushstring(L, entry.path().filename().string().c_str());
lua_rawseti(L, table_index, index);
index++;
}
}
return 1;
}