gvir_config_[gs]et_memory have an optional 'unit' attribute which indicates the unit used to express the memory size. This commit adds support for parsing this unit, and adjusting the returned value accordingly. --- libvirt-gconfig/libvirt-gconfig-domain.c | 81 ++++++++++++++++++++++++++++++-- 1 file changed, 76 insertions(+), 5 deletions(-) diff --git a/libvirt-gconfig/libvirt-gconfig-domain.c b/libvirt-gconfig/libvirt-gconfig-domain.c index e6f22bd..dd4e232 100644 --- a/libvirt-gconfig/libvirt-gconfig-domain.c +++ b/libvirt-gconfig/libvirt-gconfig-domain.c @@ -275,13 +275,70 @@ const char *gvir_config_domain_get_description(GVirConfigDomain *domain) * @domain: a #GVirConfigDomain * @description: (allow-none): */ -void gvir_config_domain_set_description(GVirConfigDomain *domain, const char *description) +void gvir_config_domain_set_description(GVirConfigDomain *domain, + const char *description) { gvir_config_object_set_node_content(GVIR_CONFIG_OBJECT(domain), "description", description); g_object_notify(G_OBJECT(domain), "description"); } +static void insert_base(GHashTable *unit_bases, + const char *unit, + guint64 unit_base) +{ + guint64 *base; + base = g_slice_alloc(sizeof(*base)); + *base = unit_base; + g_hash_table_insert(unit_bases, (gpointer)unit, base); +} + +static gpointer set_unit_bases(G_GNUC_UNUSED gpointer user_data) +{ + GHashTable *unit_bases; + + unit_bases = g_hash_table_new(g_str_hash, g_str_equal); + + insert_base(unit_bases, "b", 1); + insert_base(unit_bases, "bytes", 1); + insert_base(unit_bases, "KB", 1000); + insert_base(unit_bases, "k", 1024); + insert_base(unit_bases, "KiB", 1024); + insert_base(unit_bases, "MB", 1000*1000); + insert_base(unit_bases, "M", 1024*1024); + insert_base(unit_bases, "MiB", 1024*1024); + insert_base(unit_bases, "GB", 1000*1000*1000); + insert_base(unit_bases, "G", 1024*1024*1024); + insert_base(unit_bases, "GiB", 1024*1024*1024); + insert_base(unit_bases, "TB", (guint64)1000*1000*1000*1000); + insert_base(unit_bases, "T", (guint64)1024*1024*1024*1024); + insert_base(unit_bases, "TiB", (guint64)1024*1024*1024*1024); + + return unit_bases; +} + +static guint64 get_unit_base(const char *unit, guint64 default_base) +{ + static GOnce set_unit_bases_once = G_ONCE_INIT; + GHashTable *unit_bases; + guint64 *unit_base; + + if (unit == NULL) { + return default_base; + } + + unit_bases = g_once (&set_unit_bases_once, set_unit_bases, &unit_bases); + g_return_val_if_fail (unit_bases != NULL, default_base); + + unit_base = g_hash_table_lookup(unit_bases, unit); + if (unit_base == NULL) { + /* unknown unit, fall back to the default unit */ + g_return_val_if_reached(default_base); + } + + return *unit_base; +} + /** * gvir_config_domain_get_memory: * @domain: a #GVirConfigDomain @@ -290,8 +347,17 @@ void gvir_config_domain_set_description(GVirConfigDomain *domain, const char *de */ guint64 gvir_config_domain_get_memory(GVirConfigDomain *domain) { - return gvir_config_object_get_node_content_uint64(GVIR_CONFIG_OBJECT(domain), - "memory"); + const char *unit; + guint64 unit_base; + guint64 memory; + + unit = gvir_config_object_get_attribute(GVIR_CONFIG_OBJECT(domain), "memory", "unit"); + unit_base = get_unit_base(unit, 1024); + + memory = gvir_config_object_get_node_content_uint64(GVIR_CONFIG_OBJECT(domain), + "memory"); + + return memory * unit_base / 1024; } /** @@ -304,8 +370,13 @@ guint64 gvir_config_domain_get_memory(GVirConfigDomain *domain) */ void gvir_config_domain_set_memory(GVirConfigDomain *domain, guint64 memory) { - gvir_config_object_set_node_content_uint64(GVIR_CONFIG_OBJECT(domain), - "memory", memory); + GVirConfigObject *node; + + node = gvir_config_object_replace_child(GVIR_CONFIG_OBJECT(domain), "memory"); + gvir_config_object_set_node_content_uint64(GVIR_CONFIG_OBJECT(node), NULL, memory); + gvir_config_object_set_attribute(GVIR_CONFIG_OBJECT(node), + "unit", "KiB", + NULL); g_object_notify(G_OBJECT(domain), "memory"); } -- 1.7.11.4 -- libvir-list mailing list libvir-list@xxxxxxxxxx https://www.redhat.com/mailman/listinfo/libvir-list