mirror of
https://github.com/scp-fs2open/fs2open.github.com.git
synced 2026-11-09 04:49:39 -10:00
158 lines
4.5 KiB
C++
158 lines
4.5 KiB
C++
//
|
|
//
|
|
|
|
#include "cfile.h"
|
|
#include "scripting/api/objs/file.h"
|
|
|
|
#include "cfile/cfile.h"
|
|
#include "cfile/cfilesystem.h"
|
|
|
|
namespace {
|
|
|
|
int l_cf_get_path_id(const char* n_path)
|
|
{
|
|
size_t i;
|
|
size_t path_len = strlen(n_path);
|
|
|
|
char *buf = (char*) vm_malloc((path_len+1) * sizeof(char));
|
|
|
|
if (!buf)
|
|
return CF_TYPE_INVALID;
|
|
|
|
strcpy(buf, n_path);
|
|
|
|
//Remove trailing slashes; avoid buffer overflow on 1-char strings
|
|
i = path_len - 1;
|
|
while(i < std::numeric_limits<size_t>::max() && (buf[i] == '\\' || buf[i] == '/'))
|
|
buf[i--] = '\0';
|
|
|
|
//Remove leading slashes
|
|
i = 0;
|
|
while(i < path_len && (buf[i] == '\\' || buf[i] == '/'))
|
|
buf[i++] = '\0';
|
|
|
|
//Use official DIR_SEPARATOR_CHAR
|
|
for(i = 0; i < path_len; i++)
|
|
{
|
|
if(buf[i] == '\\' || buf[i] == '/')
|
|
buf[i] = DIR_SEPARATOR_CHAR;
|
|
}
|
|
for(i = 0; i < CF_MAX_PATH_TYPES; i++)
|
|
{
|
|
if(Pathtypes[i].path != NULL && !stricmp(buf, Pathtypes[i].path)) {
|
|
vm_free(buf);
|
|
buf = NULL;
|
|
return Pathtypes[i].index;
|
|
}
|
|
}
|
|
|
|
vm_free(buf);
|
|
buf = NULL;
|
|
return CF_TYPE_INVALID;
|
|
}
|
|
|
|
}
|
|
|
|
namespace scripting {
|
|
namespace api {
|
|
|
|
//**********LIBRARY: CFILE
|
|
//WMC - It's on my to-do list! (Well, if I had one anyway)
|
|
//WMC - Did it. I had to invent a to-do list first, though.
|
|
//Ironically, I never actually put this on it.
|
|
ADE_LIB(l_CFile, "CFile", "cf", "CFile FS2 filesystem access");
|
|
|
|
ADE_FUNC(deleteFile, l_CFile, "string Filename, string Path", "Deletes given file. Path must be specified. Use a slash for the root directory.", "boolean", "True if deleted, false")
|
|
{
|
|
char *n_filename = NULL;
|
|
const char *n_path = "";
|
|
if(!ade_get_args(L, "ss", &n_filename, &n_path))
|
|
return ade_set_error(L, "b", false);
|
|
|
|
int path = CF_TYPE_INVALID;
|
|
if(n_path != NULL && strlen(n_path))
|
|
path = l_cf_get_path_id(n_path);
|
|
|
|
if(path == CF_TYPE_INVALID)
|
|
return ade_set_error(L, "b", false);
|
|
|
|
return ade_set_args(L, "b", cf_delete(n_filename, path) != 0);
|
|
}
|
|
|
|
ADE_FUNC(fileExists, l_CFile, "string Filename, [string Path = \"\", boolean CheckVPs = false]", "Checks if a file exists. Use a blank string for path for any directory, or a slash for the root directory.", "boolean", "True if file exists, false or nil otherwise")
|
|
{
|
|
char *n_filename = NULL;
|
|
const char *n_path = "";
|
|
bool check_vps = false;
|
|
if(!ade_get_args(L, "s|sb", &n_filename, &n_path, &check_vps))
|
|
return ADE_RETURN_NIL;
|
|
|
|
int path = CF_TYPE_ANY;
|
|
if(n_path != NULL && strlen(n_path))
|
|
path = l_cf_get_path_id(n_path);
|
|
|
|
if(path == CF_TYPE_INVALID)
|
|
return ade_set_error(L, "b", false);
|
|
|
|
if(!check_vps)
|
|
return ade_set_args(L, "b", cf_exists(n_filename, path) != 0);
|
|
else
|
|
return ade_set_args(L, "b", cf_exists_full(n_filename, path ) != 0);
|
|
}
|
|
|
|
ADE_FUNC(openFile, l_CFile, "string Filename, [string Mode=\"r\", string Path = \"\"]",
|
|
"Opens a file. 'Mode' uses standard C fopen arguments. Use a blank string for path for any directory, or a slash for the root directory."
|
|
"Be EXTREMELY CAREFUL when using this function, as you may PERMANENTLY delete any file by accident",
|
|
"file",
|
|
"File handle, or invalid file handle if the specified file couldn't be opened")
|
|
{
|
|
char *n_filename = NULL;
|
|
const char *n_mode = "r";
|
|
const char *n_path = "";
|
|
if(!ade_get_args(L, "s|ss", &n_filename, &n_mode, &n_path))
|
|
return ade_set_error(L, "o", l_File.Set(NULL));
|
|
|
|
int type = CFILE_NORMAL;
|
|
|
|
int path = CF_TYPE_ANY;
|
|
if(n_path != NULL && strlen(n_path))
|
|
path = l_cf_get_path_id(n_path);
|
|
|
|
if(path == CF_TYPE_INVALID)
|
|
return ade_set_error(L, "o", l_File.Set(NULL));
|
|
|
|
CFILE *cfp = cfopen(n_filename, n_mode, type, path);
|
|
|
|
if(!cf_is_valid(cfp))
|
|
return ade_set_error(L, "o", l_File.Set(NULL));
|
|
|
|
return ade_set_args(L, "o", l_File.Set(cfp));
|
|
}
|
|
|
|
ADE_FUNC(openTempFile, l_CFile, NULL, "Opens a temp file that is automatically deleted when closed", "file", "File handle, or invalid file handle if tempfile couldn't be created")
|
|
{
|
|
return ade_set_args(L, "o", l_File.Set(ctmpfile()));
|
|
}
|
|
|
|
ADE_FUNC(renameFile, l_CFile, "string CurrentFilename, string NewFilename, string Path", "Renames given file. Path must be specified. Use a slash for the root directory.", "boolean", "True if file was renamed, otherwise false")
|
|
{
|
|
char *n_filename = NULL;
|
|
char *n_new_filename = NULL;
|
|
const char *n_path = "";
|
|
if(!ade_get_args(L, "ss|s", &n_filename, &n_new_filename, &n_path))
|
|
return ade_set_error(L, "b", false);
|
|
|
|
int path = CF_TYPE_INVALID;
|
|
if(n_path != NULL && strlen(n_path))
|
|
path = l_cf_get_path_id(n_path);
|
|
|
|
if(path == CF_TYPE_INVALID)
|
|
return ade_set_error(L, "b", false);
|
|
|
|
return ade_set_args(L, "b", cf_rename(n_filename, n_new_filename, path) != 0);
|
|
}
|
|
|
|
}
|
|
}
|
|
|