summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorjstebbins <[email protected]>2015-03-06 22:17:34 +0000
committerjstebbins <[email protected]>2015-03-06 22:17:34 +0000
commit01eabb2d314372bb301c3468d53840994105c652 (patch)
treef82169e882e5b83b7be85d0301b3451e3d93b139
parent0d4c60c548ffc487c66ca055efb18c7f09faa0c6 (diff)
LinGui: add methods for reading and writing json config files
queue, preferences and app resources are now stored in json. presets are not yet stored as json, pending sync with other platforms git-svn-id: svn://svn.handbrake.fr/HandBrake/trunk@6970 b64f7644-9d1e-0410-96f1-a4d463321fa5
-rw-r--r--gtk/src/audiohandler.c8
-rw-r--r--gtk/src/create_resources.c51
-rw-r--r--gtk/src/plist.c7
-rw-r--r--gtk/src/presets.c115
-rw-r--r--gtk/src/presets.h2
-rw-r--r--gtk/src/queuehandler.c55
-rw-r--r--gtk/src/quotestring.py7
-rw-r--r--gtk/src/resources.c3
-rw-r--r--gtk/src/subtitlehandler.c8
-rw-r--r--gtk/src/values.c46
-rw-r--r--gtk/src/values.h7
11 files changed, 192 insertions, 117 deletions
diff --git a/gtk/src/audiohandler.c b/gtk/src/audiohandler.c
index 8f59f6d7c..50ec98eeb 100644
--- a/gtk/src/audiohandler.c
+++ b/gtk/src/audiohandler.c
@@ -1598,8 +1598,6 @@ audio_remove_clicked_cb(GtkWidget *widget, gchar *path, signal_user_data_t *ud)
// treeview. Removing from the treeview sometimes provokes an
// immediate selection change, so the list needs to be up to date
// when this happens.
- GhbValue *old = ghb_array_get_nth(audio_list, row);
- ghb_value_free(old);
ghb_array_remove(audio_list, row);
// Remove the selected item
@@ -2110,9 +2108,7 @@ audio_remove_lang_clicked_cb(GtkWidget *widget, signal_user_data_t *ud)
// Remove from preset language list
alang_list = ghb_settings_get_value(ud->settings, "AudioLanguageList");
- GhbValue *glang = ghb_array_get_nth(alang_list, index);
ghb_array_remove(alang_list, index);
- ghb_value_free(glang);
ghb_clear_presets_selection(ud);
}
}
@@ -2337,9 +2333,7 @@ audio_def_setting_remove_cb(GtkWidget *widget, signal_user_data_t *ud)
return;
}
gtk_widget_destroy(GTK_WIDGET(row));
- GhbValue *asettings = ghb_array_get_nth(alist, index);
ghb_array_remove(alist, index);
- ghb_value_free(asettings);
ghb_clear_presets_selection(ud);
}
@@ -2443,9 +2437,7 @@ audio_def_lang_list_init(signal_user_data_t *ud)
{
// Error in list. Probably duplicate languages. Remove
// this item from the list.
- GhbValue *glang = ghb_array_get_nth(lang_list, ii);
ghb_array_remove(lang_list, ii);
- ghb_value_free(glang);
count--;
}
}
diff --git a/gtk/src/create_resources.c b/gtk/src/create_resources.c
index d9a5e7668..c21fb5626 100644
--- a/gtk/src/create_resources.c
+++ b/gtk/src/create_resources.c
@@ -17,6 +17,7 @@ enum
R_SECTION,
R_ICON,
R_PLIST,
+ R_JSON,
R_STRING,
};
@@ -32,6 +33,7 @@ static tag_map_t tag_map[] =
{"section", R_SECTION},
{"icon", R_ICON},
{"plist", R_PLIST},
+ {"json", R_JSON},
{"string", R_STRING},
};
#define TAG_MAP_SZ (sizeof(tag_map)/sizeof(tag_map_t))
@@ -40,7 +42,7 @@ typedef struct
{
gchar *key;
gchar *value;
- GhbValue *plist;
+ GhbValue *dict;
GQueue *stack;
GQueue *tag_stack;
gboolean closed_top;
@@ -297,6 +299,35 @@ start_element(
pd->key = g_strdup(key);
g_free(fname);
} break;
+ case R_JSON:
+ {
+ gchar *fname;
+ const gchar *name, *key;
+
+ name = lookup_attr_value("file", attr_names, attr_values);
+ if (name == NULL)
+ {
+ g_warning("json: missing a requried *file* attribute");
+ exit(EXIT_FAILURE);
+ }
+ fname = find_file(inc_list, name);
+ if (fname == NULL)
+ {
+ g_warning("json: no such file %s", name);
+ exit(EXIT_FAILURE);
+ }
+ key = lookup_attr_value("name", attr_names, attr_values);
+ if (key == NULL)
+ {
+ g_warning("json: missing a requried *name* attribute");
+ g_free(fname);
+ exit(EXIT_FAILURE);
+ }
+ gval = ghb_json_parse_file(fname);
+ if (pd->key) g_free(pd->key);
+ pd->key = g_strdup(key);
+ g_free(fname);
+ } break;
case R_STRING:
{
gchar *fname;
@@ -357,7 +388,7 @@ start_element(
{ // There's an element to add
if (current == NULL)
{
- pd->plist = gval;
+ pd->dict = gval;
return;
}
insert_value(current, pd->key, gval);
@@ -417,7 +448,7 @@ end_element(
// or dict, add the current element
if (current == NULL)
{
- pd->plist = gval;
+ pd->dict = gval;
pd->closed_top = TRUE;
return;
}
@@ -478,8 +509,8 @@ ghb_resource_parse(const gchar *buf, gssize len)
pd.tag_stack = g_queue_new();
pd.key = NULL;
pd.value = NULL;
- pd.plist = ghb_dict_value_new();
- g_queue_push_head(pd.stack, pd.plist);
+ pd.dict = ghb_dict_value_new();
+ g_queue_push_head(pd.stack, pd.dict);
pd.closed_top = FALSE;
parser.start_element = start_element;
@@ -494,7 +525,7 @@ ghb_resource_parse(const gchar *buf, gssize len)
g_markup_parse_context_free(ctx);
g_queue_free(pd.stack);
g_queue_free(pd.tag_stack);
- return pd.plist;
+ return pd.dict;
}
GhbValue*
@@ -521,13 +552,13 @@ static void
usage(char *cmd)
{
fprintf(stderr,
-"Usage: %s [-I <inc path>] <in resource list> <out resource plist>\n"
+"Usage: %s [-I <inc path>] <in resource list> <out resource dict>\n"
"Summary:\n"
-" Creates a resource plist from a resource list\n"
+" Creates a resource dict from a resource list\n"
"Options:\n"
" I - Include path to search for files\n"
" <in resource list> Input resources file\n"
-" <out resource plist> Output resources plist file\n"
+" <out resource dict> Output resources dict file\n"
, cmd);
exit(EXIT_FAILURE);
@@ -576,7 +607,7 @@ main(gint argc, gchar *argv[])
}
gval = ghb_resource_parse_file(file);
- ghb_plist_write_file(dst, gval);
+ ghb_json_write_file(dst, gval);
fclose(file);
return 0;
}
diff --git a/gtk/src/plist.c b/gtk/src/plist.c
index a2429864f..51430cc5b 100644
--- a/gtk/src/plist.c
+++ b/gtk/src/plist.c
@@ -506,13 +506,12 @@ ghb_plist_write_file(const gchar *filename, GhbValue *gval)
{
FILE *file;
- file = fopen(filename, "w");
+ file = g_fopen(filename, "w");
if (file == NULL)
return;
- fprintf(file, "%s", preamble);
- gval_write(file, gval);
- fprintf(file, "%s", postfix);
+ ghb_plist_write(file, gval);
+ fclose(file);
}
diff --git a/gtk/src/presets.c b/gtk/src/presets.c
index 82199c0ec..acaf31dbb 100644
--- a/gtk/src/presets.c
+++ b/gtk/src/presets.c
@@ -48,7 +48,6 @@ static GhbValue *prefsPlist = NULL;
static gboolean prefs_modified = FALSE;
static const GhbValue* preset_dict_get_value(GhbValue *dict, const gchar *key);
-static void store_plist(GhbValue *plist, const gchar *name);
static void store_presets(void);
static void store_prefs(void);
@@ -322,15 +321,12 @@ ghb_preset_type(GhbValue *dict)
static void
presets_remove_nth(GhbValue *presets, gint pos)
{
- GhbValue *dict;
gint count;
if (presets == NULL || pos < 0) return;
count = ghb_array_len(presets);
if (pos >= count) return;
- dict = ghb_array_get_nth(presets, pos);
ghb_array_remove(presets, pos);
- ghb_value_free(dict);
}
gboolean
@@ -1170,35 +1166,66 @@ ghb_get_user_config_dir(gchar *subdir)
}
static void
-store_plist(GhbValue *plist, const gchar *name)
+write_config_file(const gchar *name, GhbValue *dict)
{
gchar *config, *path;
- FILE *file;
config = ghb_get_user_config_dir(NULL);
path = g_strdup_printf ("%s/%s", config, name);
- file = g_fopen(path, "w");
g_free(config);
+ ghb_json_write_file(path, dict);
+ g_free(path);
+}
+
+void
+ghb_write_settings_file(const gchar *path, GhbValue *dict)
+{
+ ghb_json_write_file(path, dict);
+}
+
+static void
+store_plist(const gchar *name, GhbValue *plist)
+{
+ gchar *config, *path;
+
+ config = ghb_get_user_config_dir(NULL);
+ path = g_strdup_printf ("%s/%s", config, name);
+ g_free(config);
+ ghb_plist_write_file(path, plist);
g_free(path);
- ghb_plist_write(file, plist);
- fclose(file);
}
static GhbValue*
-load_plist(const gchar *name)
+read_config_file(const gchar *name)
{
gchar *config, *path;
- GhbValue *plist = NULL;
+ GhbValue *gval = NULL;
config = ghb_get_user_config_dir(NULL);
path = g_strdup_printf ("%s/%s", config, name);
+ g_free(config);
if (g_file_test(path, G_FILE_TEST_IS_REGULAR))
{
- plist = ghb_plist_parse_file(path);
+ gval = ghb_json_parse_file(path);
+ if (gval == NULL)
+ gval = ghb_plist_parse_file(path);
}
- g_free(config);
g_free(path);
- return plist;
+ return gval;
+}
+
+GhbValue*
+ghb_read_settings_file(const gchar *path)
+{
+ GhbValue *gval = NULL;
+
+ if (g_file_test(path, G_FILE_TEST_IS_REGULAR))
+ {
+ gval = ghb_json_parse_file(path);
+ if (gval == NULL)
+ gval = ghb_plist_parse_file(path);
+ }
+ return gval;
}
gboolean
@@ -1331,7 +1358,7 @@ ghb_find_pid_file()
}
static void
-remove_plist(const gchar *name)
+remove_config_file(const gchar *name)
{
gchar *config, *path;
@@ -1495,7 +1522,7 @@ ghb_prefs_load(signal_user_data_t *ud)
g_debug("ghb_prefs_load");
GhbValue *internalPlist = ghb_resource_get("internal-defaults");
- prefsPlist = load_plist("preferences");
+ prefsPlist = read_config_file("preferences");
if (prefsPlist == NULL)
prefsPlist = ghb_dict_value_new();
dict = plist_get_dict(prefsPlist, "Preferences");
@@ -1859,12 +1886,12 @@ void
ghb_save_queue(GhbValue *queue)
{
pid_t pid;
- char *path;
+ char *name;
pid = getpid();
- path = g_strdup_printf ("queue.%d", pid);
- store_plist(queue, path);
- g_free(path);
+ name = g_strdup_printf ("queue.%d", pid);
+ write_config_file(name, queue);
+ g_free(name);
}
GhbValue*
@@ -1872,12 +1899,12 @@ ghb_load_queue()
{
GhbValue *queue;
pid_t pid;
- char *path;
+ char *name;
pid = getpid();
- path = g_strdup_printf ("queue.%d", pid);
- queue = load_plist(path);
- g_free(path);
+ name = g_strdup_printf ("queue.%d", pid);
+ queue = read_config_file(name);
+ g_free(name);
return queue;
}
@@ -1885,34 +1912,34 @@ GhbValue*
ghb_load_old_queue(int pid)
{
GhbValue *queue;
- char *path;
+ char *name;
- path = g_strdup_printf ("queue.%d", pid);
- queue = load_plist(path);
- g_free(path);
+ name = g_strdup_printf ("queue.%d", pid);
+ queue = read_config_file(name);
+ g_free(name);
return queue;
}
void
ghb_remove_old_queue_file(int pid)
{
- char *path;
+ char *name;
- path = g_strdup_printf ("queue.%d", pid);
- remove_plist(path);
- g_free(path);
+ name = g_strdup_printf ("queue.%d", pid);
+ remove_config_file(name);
+ g_free(name);
}
void
ghb_remove_queue_file()
{
pid_t pid;
- char *path;
+ char *name;
pid = getpid();
- path = g_strdup_printf ("queue.%d", pid);
- remove_plist(path);
- g_free(path);
+ name = g_strdup_printf ("queue.%d", pid);
+ remove_config_file(name);
+ g_free(name);
}
typedef struct
@@ -2933,7 +2960,7 @@ static guint prefs_timeout_id = 0;
static gboolean
delayed_store_prefs(gpointer data)
{
- store_plist(prefsPlist, "preferences");
+ write_config_file("preferences", prefsPlist);
prefs_timeout_id = 0;
return FALSE;
}
@@ -2945,7 +2972,7 @@ store_presets()
export = ghb_value_dup(presetsPlist);
export_xlat_presets(export);
- store_plist(export, "presets");
+ store_plist("presets", export);
ghb_value_free(export);
}
@@ -3125,7 +3152,7 @@ void
ghb_presets_load(signal_user_data_t *ud)
{
gboolean store = FALSE;
- presetsPlistFile = load_plist("presets");
+ presetsPlistFile = read_config_file("presets");
if ((presetsPlistFile == NULL) ||
(ghb_value_type(presetsPlistFile) == GHB_DICT) ||
(check_old_presets(presetsPlistFile)))
@@ -3439,7 +3466,7 @@ preset_import_clicked_cb(GtkWidget *xwidget, signal_user_data_t *ud)
g_free(filename);
return;
}
- array = ghb_plist_parse_file(filename);
+ array = ghb_read_settings_file(filename);
import_xlat_presets(array);
presets_clear_default(array);
@@ -3576,7 +3603,6 @@ preset_export_clicked_cb(GtkWidget *xwidget, signal_user_data_t *ud)
if (response == GTK_RESPONSE_ACCEPT)
{
GhbValue *export, *dict, *array;
- FILE *file;
gchar *dir;
filename = gtk_file_chooser_get_filename(GTK_FILE_CHOOSER(dialog));
@@ -3591,12 +3617,7 @@ preset_export_clicked_cb(GtkWidget *xwidget, signal_user_data_t *ud)
presets_customize(array);
export_xlat_presets(array);
- file = g_fopen(filename, "w");
- if (file != NULL)
- {
- ghb_plist_write(file, array);
- fclose(file);
- }
+ store_plist(filename, array);
ghb_value_free(array);
exportDir = ghb_settings_get_const_string(ud->prefs, "ExportDirectory");
diff --git a/gtk/src/presets.h b/gtk/src/presets.h
index f3bbaf0cb..d9fe4e92f 100644
--- a/gtk/src/presets.h
+++ b/gtk/src/presets.h
@@ -53,5 +53,7 @@ GhbValue* ghb_get_current_preset_path(signal_user_data_t *ud);
void ghb_preset_to_settings(GhbValue *settings, GhbValue *preset);
void ghb_prefs_to_settings(GhbValue *settings);
void dump_preset_path(const gchar *msg, const GhbValue *path);
+GhbValue* ghb_read_settings_file(const gchar *path);
+void ghb_write_settings_file(const gchar *path, GhbValue *dict);
#endif // _GHB_PRESETS_H_
diff --git a/gtk/src/queuehandler.c b/gtk/src/queuehandler.c
index c3457989e..20d973372 100644
--- a/gtk/src/queuehandler.c
+++ b/gtk/src/queuehandler.c
@@ -772,12 +772,7 @@ save_queue_file(signal_user_data_t *ud)
char *filename = gtk_file_chooser_get_filename(GTK_FILE_CHOOSER (dialog));
gtk_widget_destroy(dialog);
- FILE *file = g_fopen(filename, "w");
- if (file != NULL)
- {
- ghb_plist_write(file, queue);
- fclose(file);
- }
+ ghb_write_settings_file(filename, queue);
g_free (filename);
ghb_value_free(queue);
}
@@ -821,29 +816,27 @@ open_queue_file(signal_user_data_t *ud)
char *filename = gtk_file_chooser_get_filename(GTK_FILE_CHOOSER (dialog));
gtk_widget_destroy(dialog);
- if (g_file_test(filename, G_FILE_TEST_IS_REGULAR))
+ queue = ghb_read_settings_file(filename);
+ if (queue != NULL)
{
- queue = ghb_plist_parse_file(filename);
- if (queue != NULL)
+ int ii, count;
+ count = ghb_array_len(queue);
+ for (ii = 0; ii < count; ii++)
{
- int ii, count;
- count = ghb_array_len(queue);
- for (ii = 0; ii < count; ii++)
- {
- GhbValue *settings = ghb_array_get_nth(queue, ii);
- ghb_array_remove(queue, ii);
- ghb_settings_set_int(settings, "job_status", GHB_QUEUE_PENDING);
- ghb_settings_set_int(settings, "job_unique_id", 0);
-
- if (ud->queue == NULL)
- ud->queue = ghb_array_value_new(32);
- ghb_array_append(ud->queue, settings);
- add_to_queue_list(ud, settings, NULL);
- }
- ghb_queue_buttons_grey(ud);
- ghb_save_queue(ud->queue);
- ghb_value_free(queue);
+ GhbValue *settings = ghb_array_get_nth(queue, ii);
+ ghb_value_incref(settings);
+ ghb_array_remove(queue, ii);
+ ghb_settings_set_int(settings, "job_status", GHB_QUEUE_PENDING);
+ ghb_settings_set_int(settings, "job_unique_id", 0);
+
+ if (ud->queue == NULL)
+ ud->queue = ghb_array_value_new(32);
+ ghb_array_append(ud->queue, settings);
+ add_to_queue_list(ud, settings, NULL);
}
+ ghb_queue_buttons_grey(ud);
+ ghb_save_queue(ud->queue);
+ ghb_value_free(queue);
}
g_free (filename);
}
@@ -1684,9 +1677,7 @@ queue_remove_clicked_cb(GtkWidget *widget, gchar *path, signal_user_data_t *ud)
// Remove the selected item
gtk_tree_store_remove(GTK_TREE_STORE(store), &iter);
// Remove the corresponding item from the queue list
- GhbValue *old = ghb_array_get_nth(ud->queue, row);
ghb_array_remove(ud->queue, row);
- ghb_value_free(old);
ghb_save_queue(ud->queue);
}
else
@@ -1893,6 +1884,7 @@ queue_drag_cb(
indices = gtk_tree_path_get_indices(dstpath);
row = indices[0];
gtk_tree_path_free(dstpath);
+ ghb_value_incref(js);
ghb_array_insert(ud->queue, row, js);
srcpath = gtk_tree_model_get_path (srcmodel, &srciter);
@@ -2128,8 +2120,6 @@ find_pid:
status = ghb_settings_get_int(settings, "job_status");
if (status == GHB_QUEUE_DONE || status == GHB_QUEUE_CANCELED)
{
- GhbValue *old = ghb_array_get_nth(queue, ii);
- ghb_value_free(old);
ghb_array_remove(queue, ii);
}
}
@@ -2174,8 +2164,6 @@ ghb_queue_remove_row(signal_user_data_t *ud, int row)
}
g_free(path);
- GhbValue *old = ghb_array_get_nth(ud->queue, row);
- ghb_value_free(old);
ghb_array_remove(ud->queue, row);
ghb_save_queue(ud->queue);
}
@@ -2232,8 +2220,6 @@ queue_key_press_cb(
// Remove the selected item
gtk_tree_store_remove(GTK_TREE_STORE(store), &iter);
// Remove the corresponding item from the queue list
- GhbValue *old = ghb_array_get_nth(ud->queue, row);
- ghb_value_free(old);
ghb_array_remove(ud->queue, row);
ghb_save_queue(ud->queue);
return TRUE;
@@ -2280,6 +2266,7 @@ queue_edit_clicked_cb(GtkWidget *xwidget, signal_user_data_t *ud)
// Remove the selected item
gtk_tree_store_remove(GTK_TREE_STORE(store), &iter);
// Remove the corresponding item from the queue list
+ ghb_value_incref(ghb_queue_edit_settings);
ghb_array_remove(ud->queue, row);
}
else
diff --git a/gtk/src/quotestring.py b/gtk/src/quotestring.py
index 1c0c5b2d1..1038719e7 100644
--- a/gtk/src/quotestring.py
+++ b/gtk/src/quotestring.py
@@ -50,11 +50,10 @@ def main():
outfile = sys.stdout
ss = infile.read()
- ss = re.sub("\"", "\\\"", ss)
+ ss = re.sub(r'\\', r'\\\\', ss)
+ ss = re.sub(r'"', r'\\"', ss)
pattern = re.compile("$", re.M)
- # the replacement string below seems a bit strange, but it seems to be
- # the only way to get the litteral chars '\' 'n' inserted into the string
- ss = re.sub(pattern, "\\\\n\"", ss)
+ ss = re.sub(pattern, r'\\n"', ss)
pattern = re.compile("^", re.M)
ss = re.sub(pattern, "\"", ss)
outfile.write(ss)
diff --git a/gtk/src/resources.c b/gtk/src/resources.c
index 7010202f1..420795dc7 100644
--- a/gtk/src/resources.c
+++ b/gtk/src/resources.c
@@ -17,7 +17,6 @@
#include <string.h>
#include "ghbcompat.h"
#include "settings.h"
-#include "plist.h"
#include "resources.h"
#include "values.h"
@@ -30,7 +29,7 @@ static GhbValue *resources;
void
ghb_resource_init()
{
- resources = ghb_plist_parse(resource_str, sizeof(resource_str)-1);
+ resources = ghb_json_parse(resource_str, sizeof(resource_str)-1);
}
GhbValue*
diff --git a/gtk/src/subtitlehandler.c b/gtk/src/subtitlehandler.c
index 0b80cfe89..9b07203d6 100644
--- a/gtk/src/subtitlehandler.c
+++ b/gtk/src/subtitlehandler.c
@@ -1299,9 +1299,7 @@ ghb_subtitle_prune(signal_user_data_t *ud)
burned = burned || !hb_subtitle_can_pass(source, mux->format);
if (burned && one_burned)
{
- GhbValue *gsub = ghb_array_get_nth(subtitle_list, ii);
ghb_array_remove(subtitle_list, ii);
- ghb_value_free(gsub);
continue;
}
one_burned = one_burned || burned;
@@ -1479,9 +1477,7 @@ subtitle_remove_lang_clicked_cb(GtkWidget *widget, signal_user_data_t *ud)
// Remove from preset language list
lang_list = ghb_settings_get_value(ud->settings, "SubtitleLanguageList");
- GhbValue *glang = ghb_array_get_nth(lang_list, index);
ghb_array_remove(lang_list, index);
- ghb_value_free(glang);
ghb_clear_presets_selection(ud);
@@ -1564,9 +1560,7 @@ static void subtitle_def_lang_list_init(signal_user_data_t *ud)
{
// Error in list. Probably duplicate languages. Remove
// this item from the list.
- GhbValue *glang = ghb_array_get_nth(lang_list, ii);
ghb_array_remove(lang_list, ii);
- ghb_value_free(glang);
count--;
}
}
@@ -1683,9 +1677,7 @@ subtitle_remove_clicked_cb(GtkWidget *widget, gchar *path, signal_user_data_t *u
// treeview. Removing from the treeview sometimes provokes an
// immediate selection change, so the list needs to be up to date
// when this happens.
- GhbValue *old = ghb_array_get_nth(subtitle_list, row);
ghb_array_remove(subtitle_list, row);
- ghb_value_free(old);
// Remove the selected item
gtk_tree_store_remove(GTK_TREE_STORE(tm), &ti);
diff --git a/gtk/src/values.c b/gtk/src/values.c
index c0bb1305b..749ce0bca 100644
--- a/gtk/src/values.c
+++ b/gtk/src/values.c
@@ -13,6 +13,7 @@
*/
#include <glib.h>
+#include <glib/gstdio.h>
#include <glib-object.h>
#include <stdio.h>
#include <string.h>
@@ -62,6 +63,20 @@ ghb_value_new(GhbType type)
}
void
+ghb_value_incref(GhbValue *gval)
+{
+ if (gval == NULL) return;
+ json_incref(gval);
+}
+
+void
+ghb_value_decref(GhbValue *gval)
+{
+ if (gval == NULL) return;
+ json_decref(gval);
+}
+
+void
ghb_value_free(GhbValue *gval)
{
if (gval == NULL) return;
@@ -535,3 +550,34 @@ ghb_array_len(const GhbValue *array)
{
return json_array_size(array);
}
+
+void
+ghb_json_write(FILE *file, GhbValue *gval)
+{
+ char * json = json_dumps(gval, JSON_INDENT(4)|JSON_PRESERVE_ORDER);
+ fprintf(file, "%s", json);
+ free(json);
+}
+
+void
+ghb_json_write_file(const char *path, GhbValue *gval)
+{
+ FILE *file = g_fopen(path, "w");
+ if (file == NULL)
+ return;
+ ghb_json_write(file, gval);
+ fclose(file);
+}
+
+GhbValue*
+ghb_json_parse(const char *json, size_t size)
+{
+ return json_loadb(json, size, JSON_REJECT_DUPLICATES, NULL);
+}
+
+GhbValue*
+ghb_json_parse_file(const char *path)
+{
+ return json_load_file(path, JSON_REJECT_DUPLICATES, NULL);
+}
+
diff --git a/gtk/src/values.h b/gtk/src/values.h
index ceb70687c..dd3a1dc04 100644
--- a/gtk/src/values.h
+++ b/gtk/src/values.h
@@ -32,6 +32,8 @@ typedef json_t GhbValue;
typedef int GhbType;
typedef void* GhbDictIter;
+void ghb_value_incref(GhbValue *gval);
+void ghb_value_decref(GhbValue *gval);
GhbType ghb_value_type(const GhbValue *val);
GhbType ghb_array_get_type(void);
GhbType ghb_dict_get_type(void);
@@ -81,4 +83,9 @@ gboolean ghb_dict_remove(GhbValue *gval, const gchar *key);
void debug_show_value(GhbValue *gval);
void debug_show_type(GhbType tp);
+void ghb_json_write(FILE *file, GhbValue *gval);
+void ghb_json_write_file(const char *path, GhbValue *gval);
+GhbValue* ghb_json_parse(const char *json, size_t size);
+GhbValue* ghb_json_parse_file(const char *path);
+
#endif // _GHB_VALUES_H_