#include <glib.h>
#include <glib-object.h>
#include <string.h>
+#include <inttypes.h>
#include "values.h"
static void dict_delete_key(gpointer data);
return copy;
}
+void
+debug_show_type(GType tp)
+{
+ const gchar *str = "unknown";
+ if (tp == G_TYPE_STRING)
+ {
+ str ="string";
+ }
+ else if (tp == G_TYPE_INT)
+ {
+ str ="int";
+ }
+ else if (tp == G_TYPE_INT64)
+ {
+ str ="int64";
+ }
+ else if (tp == G_TYPE_DOUBLE)
+ {
+ str ="double";
+ }
+ else if (tp == G_TYPE_BOOLEAN)
+ {
+ str ="bool";
+ }
+ else if (tp == ghb_array_get_type())
+ {
+ str ="array";
+ }
+ else if (tp == ghb_dict_get_type())
+ {
+ str ="dict";
+ }
+ g_debug("Type %s", str);
+}
+
+void
+debug_show_value(GValue *gval)
+{
+ GType tp;
+
+ tp = G_VALUE_TYPE(gval);
+ if (tp == G_TYPE_STRING)
+ {
+ g_message("Type %s value %s", "string", g_value_get_string(gval));
+ }
+ else if (tp == G_TYPE_INT)
+ {
+ g_message("Type %s value %d", "int", g_value_get_int(gval));
+ }
+ else if (tp == G_TYPE_INT64)
+ {
+ g_message("Type %s value %" PRId64, "int64", g_value_get_int64(gval));
+ }
+ else if (tp == G_TYPE_DOUBLE)
+ {
+ g_message("Type %s value %f", "double", g_value_get_double(gval));
+ }
+ else if (tp == G_TYPE_BOOLEAN)
+ {
+ g_message("Type %s value %d", "boolean", g_value_get_boolean(gval));
+ }
+ else if (tp == ghb_array_get_type())
+ {
+ g_message("Type %s", "boolean");
+ }
+ else if (tp == ghb_dict_get_type())
+ {
+ g_message("Type %s", "dict");
+ }
+}
+
gint
ghb_value_int(const GValue *val)
{
if (val == NULL) return 0;
GValue xform = {0,};
- if (G_VALUE_TYPE(val) != G_TYPE_INT64)
+ if (G_VALUE_TYPE(val) != G_TYPE_INT)
{
- g_value_init(&xform, G_TYPE_INT64);
+ g_value_init(&xform, G_TYPE_INT);
if (!g_value_transform(val, &xform))
+ {
+ debug_show_type(G_VALUE_TYPE(val));
+ g_warning("int can't transform");
return 0;
- result = (gint)g_value_get_int64(&xform);
+ }
+ result = g_value_get_int(&xform);
g_value_unset(&xform);
}
else
{
- result = (gint)g_value_get_int64(val);
+ result = g_value_get_int(val);
}
return result;
}
{
g_value_init(&xform, G_TYPE_INT64);
if (!g_value_transform(val, &xform))
+ {
+ debug_show_type(G_VALUE_TYPE(val));
+ g_warning("int64 can't transform");
return 0;
+ }
result = g_value_get_int64(&xform);
g_value_unset(&xform);
}
{
g_value_init(&xform, G_TYPE_DOUBLE);
if (!g_value_transform(val, &xform))
+ {
+ debug_show_type(G_VALUE_TYPE(val));
+ g_warning("double can't transform");
return 0;
+ }
result = g_value_get_double(&xform);
g_value_unset(&xform);
}
{
g_value_init(&xform, G_TYPE_STRING);
if (!g_value_transform(val, &xform))
+ {
+ debug_show_type(G_VALUE_TYPE(val));
+ g_warning("string can't transform");
return NULL;
+ }
result = g_strdup(g_value_get_string(&xform));
g_value_unset(&xform);
}
{
g_value_init(&xform, G_TYPE_BOOLEAN);
if (!g_value_transform(val, &xform))
+ {
+ debug_show_type(G_VALUE_TYPE(val));
+ g_warning("boolean can't transform");
return FALSE;
+ }
result = g_value_get_boolean(&xform);
g_value_unset(&xform);
}
GType typa;
GType typb;
+ if ((vala == NULL && valb != NULL) || (vala != NULL && valb == NULL))
+ {
+ return 1;
+ }
typa = G_VALUE_TYPE(vala);
typb = G_VALUE_TYPE(valb);
- if (typa == ghb_combodata_get_type()) typa = G_TYPE_STRING;
- if (typb == ghb_combodata_get_type()) typb = G_TYPE_STRING;
if (typa != typb)
{
return 1;
}
GValue*
-ghb_combo_value_new(
- gint index,
- const gchar *option,
- const gchar *shortOpt,
- const gchar *svalue,
- gint ivalue)
-{
- GValue *gval = ghb_value_new(ghb_combodata_get_type());
- ghb_value_set_combodata(gval, index, option, shortOpt, svalue, ivalue);
- return gval;
-}
-
-GValue*
ghb_dict_value_new()
{
GHashTable *dict;
}
static gpointer
-combodata_copy(gpointer boxed)
-{
- const ghb_combodata_t *combodata = (const ghb_combodata_t*)boxed;
- ghb_combodata_t *copy = g_malloc0(sizeof(ghb_combodata_t));
- if (combodata->option)
- copy->option = g_strdup(combodata->option);
- if (combodata->shortOpt)
- copy->shortOpt = g_strdup(combodata->shortOpt);
- if (combodata->svalue)
- copy->svalue = g_strdup(combodata->svalue);
-
- copy->index = combodata->index;
- copy->ivalue = combodata->ivalue;
- return copy;
-}
-
-static void
-combodata_free(gpointer boxed)
-{
- ghb_combodata_t *combodata = (ghb_combodata_t*)boxed;
- if (combodata->option)
- g_free(combodata->option);
- if (combodata->shortOpt)
- g_free(combodata->shortOpt);
- if (combodata->svalue)
- g_free(combodata->svalue);
- g_free(combodata);
-}
-
-
-static void
-xform_combodata_to_string(const GValue *combo, GValue *sval)
-{
- const ghb_combodata_t *combodata = g_value_get_boxed(combo);
- g_value_set_string(sval, combodata->shortOpt);
-}
-
-static void
-xform_combodata_to_int64(const GValue *combo, GValue *ival)
-{
- const ghb_combodata_t *combodata = g_value_get_boxed(combo);
- g_value_set_int64(ival, combodata->ivalue);
-}
-
-static void
-xform_combodata_to_double(const GValue *combo, GValue *dval)
-{
- const ghb_combodata_t *combodata = g_value_get_boxed(combo);
- g_value_set_double(dval, (gdouble)combodata->ivalue);
-}
-
-GType
-ghb_combodata_get_type(void)
-{
- static GType type_id = 0;
- if (!type_id)
- {
- type_id = g_boxed_type_register_static(
- g_intern_static_string("GHBCombo"),
- (GBoxedCopyFunc) combodata_copy,
- (GBoxedFreeFunc) combodata_free);
- g_value_register_transform_func(type_id, G_TYPE_STRING,
- xform_combodata_to_string);
- g_value_register_transform_func(type_id, G_TYPE_INT64,
- xform_combodata_to_int64);
- g_value_register_transform_func(type_id, G_TYPE_DOUBLE,
- xform_combodata_to_double);
- }
- return type_id;
-}
-
-void
-ghb_value_set_combodata(
- GValue *gval,
- gint index,
- const gchar *option,
- const gchar *shortOpt,
- const gchar *svalue,
- gint ivalue)
-{
- ghb_combodata_t combodata;
- combodata.index = index;
- combodata.option = (gchar*)option;
- combodata.shortOpt = (gchar*)shortOpt;
- combodata.svalue = (gchar*)svalue;
- combodata.ivalue = ivalue;
- g_value_set_boxed(gval, &combodata);
-}
-
-static gpointer
rawdata_copy(gpointer boxed)
{
const ghb_rawdata_t *data = (const ghb_rawdata_t*)boxed;
}
GValue*
-ghb_dict_lookup(GValue *gval, const gchar *key)
+ghb_dict_lookup(const GValue *gval, const gchar *key)
{
GHashTable *dict = g_value_get_boxed(gval);
return g_hash_table_lookup(dict, key);
}
void
+ghb_array_insert(GValue *gval, guint ii, GValue *val)
+{
+ GArray *arr = g_value_get_boxed(gval);
+ // A little nastyness here. The array pointer
+ // can change when the array changes size. So
+ // I must re-box it in the GValue each time.
+ arr = g_array_insert_val(arr, ii, val);
+ memset(gval, 0, sizeof(GValue));
+ g_value_init(gval, ghb_array_get_type());
+ g_value_take_boxed(gval, arr);
+}
+
+void
ghb_array_append(GValue *gval, GValue *val)
{
GArray *arr = g_value_get_boxed(gval);
g_value_take_boxed(gval, arr);
}
+void
+ghb_array_replace(GValue *gval, guint ii, GValue *val)
+{
+ GArray *arr = g_value_get_boxed(gval);
+ // A little nastyness here. The array pointer
+ // can change when the array changes size. So
+ // I must re-box it in the GValue each time.
+ if (ii >= arr->len) return;
+ ghb_value_free(((GValue**)arr->data)[ii]);
+ ((GValue**)arr->data)[ii] = val;
+}
+
+void
+ghb_array_copy(GValue *arr1, GValue *arr2, gint count)
+{
+ gint len, ii;
+
+ // empty the first array if it is not already empty
+ len = ghb_array_len(arr1);
+ for (ii = 0; ii < len; ii++)
+ ghb_array_remove(arr1, 0);
+
+ len = ghb_array_len(arr2);
+ count = MIN(count, len);
+ for (ii = 0; ii < count; ii++)
+ ghb_array_append(arr1, ghb_value_dup(ghb_array_get_nth(arr2, ii)));
+}
+
gint
ghb_array_len(const GValue *gval)
{
return arr->len;
}
+static void
+xform_string_int(const GValue *sval, GValue *ival)
+{
+ gchar *end;
+
+ const gchar *str = g_value_get_string(sval);
+ gint val = g_strtod(str, &end);
+ if (*end)
+ val = (guint)(~0)>>1;
+ g_value_set_int(ival, val);
+}
+
+static void
+xform_string_int64(const GValue *sval, GValue *ival)
+{
+ gchar *end;
+ const gchar *str = g_value_get_string(sval);
+ gint64 val = g_strtod(str, &end);
+ if (*end)
+ val = (guint64)(~0L)>>1;
+ g_value_set_int64(ival, val);
+}
+
+static void
+xform_string_double(const GValue *sval, GValue *dval)
+{
+ const gchar *str = g_value_get_string(sval);
+ double val = g_strtod(str, NULL);
+ g_value_set_double(dval, val);
+}
+
+static void
+xform_boolean_double(const GValue *bval, GValue *dval)
+{
+ gboolean b = g_value_get_boolean(bval);
+ double val = b;
+ g_value_set_double(dval, val);
+}
+
+void
+ghb_register_transforms()
+{
+ g_value_register_transform_func(G_TYPE_STRING, G_TYPE_INT64,
+ xform_string_int64);
+ g_value_register_transform_func(G_TYPE_STRING, G_TYPE_INT,
+ xform_string_int);
+ g_value_register_transform_func(G_TYPE_STRING, G_TYPE_DOUBLE,
+ xform_string_double);
+ g_value_register_transform_func(G_TYPE_BOOLEAN, G_TYPE_DOUBLE,
+ xform_boolean_double);
+}