]> granicus.if.org Git - handbrake/commitdiff
LinGui: add methods for reading and writing json config files
authorjstebbins <jstebbins.hb@gmail.com>
Fri, 6 Mar 2015 22:17:34 +0000 (22:17 +0000)
committerjstebbins <jstebbins.hb@gmail.com>
Fri, 6 Mar 2015 22:17:34 +0000 (22:17 +0000)
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

gtk/src/audiohandler.c
gtk/src/create_resources.c
gtk/src/plist.c
gtk/src/presets.c
gtk/src/presets.h
gtk/src/queuehandler.c
gtk/src/quotestring.py
gtk/src/resources.c
gtk/src/subtitlehandler.c
gtk/src/values.c
gtk/src/values.h

index 8f59f6d7c13d929aa46443623ba523b6ac148d27..50ec98eeb703be1e8b089fb5964acdb6619de938 100644 (file)
@@ -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--;
         }
     }
index d9a5e76684839565ce5f4d2ab2c972e31c2cf40c..c21fb5626688f22cf38c41d3d9f6cccf3966779c 100644 (file)
@@ -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;
 }
index a2429864f828eda782f8e3547e7c0d21f8b3a03d..51430cc5b599b3e35f2aa0b439f449d3061ba5fd 100644 (file)
@@ -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);
 }
 
 
index 82199c0eca1831212c6603a66033bdd68a852d93..acaf31dbb896b9ffab6a96b58fae337c8c2ecd82 100644 (file)
@@ -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");
index f3bbaf0cb88e0f797dd0cdc9acf6e8e61fbd86cb..d9fe4e92fe1d3b858594f468ee3f75164aff39e9 100644 (file)
@@ -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_
index c3457989efe8a1e6c2790e8d17d6f9702f1918c4..20d97337271b8f95b05c1c5ac3f7fd9c41b8ba0f 100644 (file)
@@ -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
index 1c0c5b2d1c39028be8da65fdce5058ec4c6a88bf..1038719e700aa740133e8e63972220f4622b6883 100644 (file)
@@ -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)
index 7010202f1ed5bbfd537372ab56ac1d384e524fae..420795dc77038fb9e0ec95f62e5c165de075e7a6 100644 (file)
@@ -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*
index 0b80cfe89ead1435f1bc65a45435386a9b59eb2c..9b07203d624ed3be2337f2cfbfc32b3ebde404b5 100644 (file)
@@ -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);
index c0bb1305b70263d952be175fdd3b290aad55c14c..749ce0bca41b72624c8b2a7bbbe31edc032d962f 100644 (file)
@@ -13,6 +13,7 @@
  */
 
 #include <glib.h>
+#include <glib/gstdio.h>
 #include <glib-object.h>
 #include <stdio.h>
 #include <string.h>
@@ -61,6 +62,20 @@ ghb_value_new(GhbType type)
     return val;
 }
 
+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)
 {
@@ -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);
+}
+
index ceb70687c725c53f82a0d1bc2f3986b25bcc8fca..dd3a1dc0443f2dc218d886e0b32798fadf805308 100644 (file)
@@ -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_