提交 e479d4d0 编写于 作者: J jp9000

libobs: Add obs_data funcs for safe file handling

obs_data_create_from_json_file_safe: Attempts to create an obs_data
object from a file, and if that fails and a backup file exists, deletes
the old file and tries to open it again.

obs_data_save_json_safe: Saves json data to a temporary file first,
optionally backs up the target file if the file exists and backup_ext is
valid (otherwise deletes it), and then renames the temporary file to the
target file.  This helps reduce the chance of json corruption on save.
上级 40988f7e
......@@ -17,6 +17,7 @@
#include "util/bmem.h"
#include "util/threading.h"
#include "util/dstr.h"
#include "util/darray.h"
#include "util/platform.h"
#include "graphics/vec2.h"
......@@ -655,6 +656,37 @@ obs_data_t *obs_data_create_from_json_file(const char *json_file)
return data;
}
obs_data_t *obs_data_create_from_json_file_safe(const char *json_file,
const char *backup_ext)
{
obs_data_t *file_data = obs_data_create_from_json_file(json_file);
if (!file_data && backup_ext && *backup_ext) {
struct dstr backup_file = {0};
dstr_copy(&backup_file, json_file);
if (*backup_ext != '.')
dstr_cat(&backup_file, ".");
dstr_cat(&backup_file, backup_ext);
if (os_file_exists(backup_file.array)) {
blog(LOG_WARNING, "obs-data.c: "
"[obs_data_create_from_json_file_safe] "
"attempting backup file");
/* delete current file if corrupt to prevent it from
* being backed up again */
os_unlink(json_file);
os_rename(backup_file.array, json_file);
file_data = obs_data_create_from_json_file(json_file);
}
dstr_free(&backup_file);
}
return file_data;
}
void obs_data_addref(obs_data_t *data)
{
if (data)
......@@ -711,6 +743,19 @@ bool obs_data_save_json(obs_data_t *data, const char *file)
return false;
}
bool obs_data_save_json_safe(obs_data_t *data, const char *file,
const char *temp_ext, const char *backup_ext)
{
const char *json = obs_data_get_json(data);
if (json && *json) {
return os_quick_write_utf8_file_safe(file, json, strlen(json),
false, temp_ext, backup_ext);
}
return false;
}
static struct obs_data_item *get_item(struct obs_data *data, const char *name)
{
if (!data) return NULL;
......
......@@ -63,11 +63,15 @@ enum obs_data_number_type {
EXPORT obs_data_t *obs_data_create();
EXPORT obs_data_t *obs_data_create_from_json(const char *json_string);
EXPORT obs_data_t *obs_data_create_from_json_file(const char *json_file);
EXPORT obs_data_t *obs_data_create_from_json_file_safe(const char *json_file,
const char *backup_ext);
EXPORT void obs_data_addref(obs_data_t *data);
EXPORT void obs_data_release(obs_data_t *data);
EXPORT const char *obs_data_get_json(obs_data_t *data);
EXPORT bool obs_data_save_json(obs_data_t *data, const char *file);
EXPORT bool obs_data_save_json_safe(obs_data_t *data, const char *file,
const char *temp_ext, const char *backup_ext);
EXPORT void obs_data_apply(obs_data_t *target, obs_data_t *apply_data);
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册