void ghb_dict_copy(GhbValue *dst, const GhbValue *src) { GhbDictIter iter; const char *key; GhbValue *val, *dst_val; iter = ghb_dict_iter_init(src); while (ghb_dict_iter_next(src, &iter, &key, &val)) { dst_val = ghb_dict_get(dst, key); if (ghb_value_type(val) == GHB_DICT) { if (dst_val == NULL || ghb_value_type(dst_val) != GHB_DICT) { dst_val = ghb_value_dup(val); ghb_dict_set(dst, key, dst_val); } else if (ghb_value_type(dst_val) == GHB_DICT) { ghb_dict_copy(dst_val, val); } } else { ghb_dict_set(dst, key, ghb_value_dup(val)); } } }
void debug_show_value(GhbValue *gval) { GhbType tp; tp = ghb_value_type(gval); if (tp == GHB_STRING) { g_message("Type %s value %s", "string", json_string_value(gval)); } else if (tp == GHB_INT) { g_message("Type %s value %"JSON_INTEGER_FORMAT, "int", json_integer_value(gval)); } else if (tp == GHB_DOUBLE) { g_message("Type %s value %f", "double", json_real_value(gval)); } else if (tp == GHB_BOOL) { g_message("Type %s value %d", "boolean", json_is_true(gval)); } else if (tp == GHB_ARRAY) { g_message("Type %s", "array"); } else if (tp == GHB_DICT) { g_message("Type %s", "dict"); } }
static void x264_opt_update(signal_user_data_t *ud, GtkWidget *widget) { gint jj; const gchar *name = ghb_get_setting_key(widget); gchar **opt_syns = NULL; const gchar *def_val = NULL; gint type; trans_table_t *trans; for (jj = 0; jj < X264_OPT_MAP_SIZE; jj++) { if (strcmp(name, x264_opt_map[jj].name) == 0) { // found the options that needs updating opt_syns = x264_opt_map[jj].opt_syns; def_val = x264_opt_map[jj].def_val; type = x264_opt_map[jj].type; trans = x264_opt_map[jj].translation; break; } } if (opt_syns != NULL) { GString *x264opts = g_string_new(""); const gchar *options; gchar **split = NULL; gint ii; gboolean foundit = FALSE; options = ghb_dict_get_string(ud->settings, "x264Option"); if (options) { split = g_strsplit(options, ":", -1); } for (ii = 0; split && split[ii] != NULL; ii++) { gint syn; gchar *val = NULL; gchar *pos = strchr(split[ii], '='); if (pos != NULL) { val = pos + 1; *pos = 0; } syn = find_syn_match(split[ii], opt_syns); if (syn >= 0) { // Updating this option gchar *val; foundit = TRUE; if (type == X264_OPT_DEBLOCK) val = get_deblock_val(ud); else if (type == X264_OPT_PSY) val = get_psy_val(ud); else { GhbValue *gval; gval = ghb_widget_value(widget); if (ghb_value_type(gval) == GHB_BOOL) { if (ghb_value_get_bool(gval)) val = g_strdup("1"); else val = g_strdup("0"); } else { val = ghb_widget_string(widget); } ghb_value_free(&gval); } if (type == X264_OPT_TRANS) { gchar *tmp; tmp = g_strdup(trans_ui_val(trans, val)); if (tmp) { g_free(val); val = tmp; } } if (strcmp(def_val, val) != 0) { g_string_append_printf(x264opts, "%s=%s:", opt_syns[syn], val); } g_free(val); } else if (val != NULL) g_string_append_printf(x264opts, "%s=%s:", split[ii], val); else g_string_append_printf(x264opts, "%s:", split[ii]); } if (split) g_strfreev(split); if (!foundit) { gchar *val; if (type == X264_OPT_DEBLOCK) val = get_deblock_val(ud); else if (type == X264_OPT_PSY) val = get_psy_val(ud); else { GhbValue *gval; gval = ghb_widget_value(widget); if (ghb_value_type(gval) == GHB_BOOL) { if (ghb_value_get_bool(gval)) val = g_strdup("1"); else val = g_strdup("0"); } else { val = ghb_widget_string(widget); } ghb_value_free(&gval); } if (type == X264_OPT_TRANS) { gchar *tmp; tmp = g_strdup(trans_ui_val(trans, val)); if (tmp) { g_free(val); val = tmp; } } if (strcmp(def_val, val) != 0) { g_string_append_printf(x264opts, "%s=%s:", opt_syns[0], val); } g_free(val); } // Update the options value // strip the trailing ":" gchar *result; gint len; result = g_string_free(x264opts, FALSE); len = strlen(result); if (len > 0) result[len - 1] = 0; gchar *sopts; sopts = sanitize_x264opts(ud, result); ghb_update_x264Option(ud, sopts); ghb_x264_parse_options(ud, sopts); g_free(sopts); g_free(result); } }
static void start_element( GMarkupParseContext *ctx, const gchar *name, const gchar **attr_names, const gchar **attr_values, gpointer ud, GError **error) { parse_data_t *pd = (parse_data_t*)ud; union { gint id; gpointer pid; } id; gint ii; // Check to see if the first element found has been closed // If so, ignore any junk following it. if (pd->closed_top) return; for (ii = 0; ii < TAG_MAP_SZ; ii++) { if (strcmp(name, tag_map[ii].tag) == 0) { id.id = tag_map[ii].id; break; } } if (ii == TAG_MAP_SZ) { g_warning("Unrecognized start tag (%s)", name); return; } g_queue_push_head(pd->tag_stack, id.pid); GhbType gtype = 0; GhbValue *gval = NULL; GhbValue *current = g_queue_peek_head(pd->stack); switch (id.id) { case P_PLIST: { // Ignore } break; case P_KEY: { if (pd->key) g_free(pd->key); pd->key = NULL; } break; case P_DICT: { gval = ghb_dict_new(); g_queue_push_head(pd->stack, gval); } break; case P_ARRAY: { gval = ghb_array_new(); g_queue_push_head(pd->stack, gval); } break; case P_INTEGER: { } break; case P_REAL: { } break; case P_STRING: { } break; case P_DATE: { } break; case P_TRUE: { } break; case P_FALSE: { } break; case P_DATA: { } break; } // Add the element to the current container if (gval) { // There's an element to add if (current == NULL) { pd->plist = gval; return; } gtype = ghb_value_type(current); if (gtype == GHB_ARRAY) { ghb_array_append(current, gval); } else if (gtype == GHB_DICT) { if (pd->key == NULL) { g_warning("No key for dictionary item"); ghb_value_free(&gval); } else { ghb_dict_set(current, pd->key, gval); } } else { g_error("Invalid container type. This shouldn't happen"); } } }
static void gval_write(FILE *file, GhbValue *gval) { static gint indent = 0; gint ii; GhbType gtype; if (gval == NULL) return; gtype = ghb_value_type(gval); if (gtype == GHB_ARRAY) { GhbValue *val; gint count; indent_fprintf(file, indent, "<array>\n"); indent++; count = ghb_array_len(gval); for (ii = 0; ii < count; ii++) { val = ghb_array_get(gval, ii); gval_write(file, val); } indent--; indent_fprintf(file, indent, "</array>\n"); } else if (gtype == GHB_DICT) { const char *key; GhbValue *val; GhbDictIter iter; indent_fprintf(file, indent, "<dict>\n"); indent++; iter = ghb_dict_iter_init(gval); while (ghb_dict_iter_next(gval, &iter, &key, &val)) { indent_fprintf(file, indent, "<key>%s</key>\n", key); gval_write(file, val); } indent--; indent_fprintf(file, indent, "</dict>\n"); } else if (gtype == GHB_BOOL) { gchar *tag; if (ghb_value_get_bool(gval)) { tag = "true"; } else { tag = "false"; } indent_fprintf(file, indent, "<%s />\n", tag); } else if (gtype == GHB_DOUBLE) { gdouble val = ghb_value_get_double(gval); indent_fprintf(file, indent, "<real>%.17g</real>\n", val); } else if (gtype == GHB_INT) { gint64 val = ghb_value_get_int(gval); indent_fprintf(file, indent, "<integer>%"PRId64"</integer>\n", val); } else if (gtype == GHB_STRING) { const gchar *str = ghb_value_get_string(gval); gchar *esc = g_markup_escape_text(str, -1); indent_fprintf(file, indent, "<string>%s</string>\n", esc); g_free(esc); } else { // Try to make anything thats unrecognized into a string g_warning("Unhandled data type %d", gtype); } }
static void end_element( GMarkupParseContext *ctx, const gchar *name, gpointer ud, GError **error) { parse_data_t *pd = (parse_data_t*)ud; gint id; union { gint id; gpointer pid; } start_id; gint ii; // Check to see if the first element found has been closed // If so, ignore any junk following it. if (pd->closed_top) return; for (ii = 0; ii < TAG_MAP_SZ; ii++) { if (strcmp(name, tag_map[ii].tag) == 0) { id = tag_map[ii].id; break; } } if (ii == TAG_MAP_SZ) { g_warning("Unrecognized start tag (%s)", name); return; } start_id.pid = g_queue_pop_head(pd->tag_stack); if (start_id.id != id) g_warning("start tag != end tag: (%s %d) %d", name, id, id); GhbValue *gval = NULL; GhbValue *current = g_queue_peek_head(pd->stack); GhbType gtype = 0; switch (id) { case P_PLIST: { // Ignore } break; case P_KEY: { if (pd->key) g_free(pd->key); pd->key = g_strdup(pd->value); return; } break; case P_DICT: { g_queue_pop_head(pd->stack); } break; case P_ARRAY: { g_queue_pop_head(pd->stack); } break; case P_INTEGER: { gint64 val = g_strtod(pd->value, NULL); gval = ghb_int_value_new(val); } break; case P_REAL: { gdouble val = g_strtod(pd->value, NULL); gval = ghb_double_value_new(val); } break; case P_STRING: { gval = ghb_string_value_new(pd->value); } break; case P_TRUE: { gval = ghb_bool_value_new(TRUE); } break; case P_FALSE: { gval = ghb_bool_value_new(FALSE); } break; default: { g_message("Unhandled plist type %d", id); } break; } if (gval) { // Get the top of the data structure stack and if it's an array // or dict, add the current element if (current == NULL) { pd->plist = gval; pd->closed_top = TRUE; return; } gtype = ghb_value_type(current); if (gtype == GHB_ARRAY) { ghb_array_append(current, gval); } else if (gtype == GHB_DICT) { if (pd->key == NULL) { g_warning("No key for dictionary item"); ghb_value_free(&gval); } else { ghb_dict_set(current, pd->key, gval); } } else { g_error("Invalid container type. This shouldn't happen"); } } if (g_queue_is_empty(pd->stack)) pd->closed_top = TRUE; }