/* This is -*- C -*- */ /* vim: set sw=2: */ /* $Id: guppi-xml.c,v 1.10 2001/09/28 06:41:09 trow Exp $ */ /* * guppi-xml.c * * Copyright (C) 2001 The Free Software Foundation, Inc. * * Developed by Jon Trowbridge */ /* * This program is free software; you can redistribute it and/or * modify it under the terms of the GNU General Public License as * published by the Free Software Foundation; either version 2 of the * License, or (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 * USA. */ #include #include "guppi-xml.h" #include #include #include "guppi-memory.h" #include "guppi-debug.h" typedef struct _CacheItem CacheItem; struct _CacheItem { gpointer ptr; GtkDestroyNotify destroy_fn; }; GuppiXMLDocument * guppi_xml_document_new (void) { GuppiXMLDocument *doc = guppi_new0 (GuppiXMLDocument, 1); doc->doc = xmlNewDoc ("1.0"); doc->ns = xmlNewNs (NULL, "http://www.gnome.org/guppi/xml-version/1.0", "gpi"); doc->version = GUPPI_XML_V1; doc->uniq_table = guppi_uniq_table_new (); return doc; } GuppiXMLDocument * guppi_xml_document_read_file (const gchar *filename) { GuppiXMLDocument *doc; if (filename == NULL) return NULL; doc = guppi_new0 (GuppiXMLDocument, 1); doc->uniq_table = guppi_uniq_table_new (); doc->doc = xmlParseFile (filename); if (doc->doc == NULL) { guppi_free (doc); return NULL; } /* This is very broken! */ if (doc->doc->root) doc->ns = doc->doc->root->ns; doc->version = GUPPI_XML_V1; return doc; } void guppi_xml_document_write_file (GuppiXMLDocument *doc, const gchar *filename) { g_return_if_fail (doc != NULL); g_return_if_fail (filename != NULL); xmlSaveFile(filename, doc->doc); } xmlNodePtr guppi_xml_document_get_root (GuppiXMLDocument *doc) { g_return_val_if_fail (doc != NULL, NULL); return xmlDocGetRootElement (doc->doc); } void guppi_xml_document_set_root (GuppiXMLDocument *doc, xmlNodePtr node) { g_return_if_fail (doc != NULL); xmlDocSetRootElement (doc->doc, node); } static void destroy_hash_fn (gpointer key, gpointer val, gpointer closure) { CacheItem *ci = val; if (ci->destroy_fn) ci->destroy_fn (ci->ptr); guppi_free (ci); } void guppi_xml_document_free (GuppiXMLDocument *doc) { if (doc) { xmlFreeDoc (doc->doc); doc->doc = NULL; g_hash_table_foreach (doc->uniq_table, destroy_hash_fn, NULL); guppi_uniq_table_destroy (doc->uniq_table); doc->uniq_table = NULL; guppi_free0 (doc); } } void guppi_xml_document_spew (GuppiXMLDocument *doc) { g_return_if_fail (doc); xmlDocDump (stdout, doc->doc); } void guppi_xml_document_cache (GuppiXMLDocument *doc, guppi_uniq_t uid, gpointer ptr) { return guppi_xml_document_cache_full (doc, uid, ptr, NULL); } void guppi_xml_document_cache_full (GuppiXMLDocument *doc, guppi_uniq_t uid, gpointer ptr, GtkDestroyNotify destroy_fn) { g_return_if_fail (doc != NULL); g_return_if_fail (uid != 0); if (! guppi_uniq_table_contains (doc->uniq_table, uid)) { CacheItem *ci = guppi_new0 (CacheItem, 1); ci->ptr = ptr; ci->destroy_fn = destroy_fn; guppi_uniq_table_add (doc->uniq_table, uid, ci); } else { gchar *s = guppi_uniq2str (uid); g_warning ("Hash collision w/ uid=%s", s); guppi_free (s); } } gboolean guppi_xml_document_has_cached (GuppiXMLDocument *doc, guppi_uniq_t uid) { g_return_val_if_fail (doc != NULL, FALSE); g_return_val_if_fail (uid != 0, FALSE); return guppi_uniq_table_contains (doc->uniq_table, uid); } gpointer guppi_xml_document_lookup (GuppiXMLDocument *doc, guppi_uniq_t uid) { CacheItem *ci; g_return_val_if_fail (doc != NULL, NULL); if (uid == 0) return NULL; ci = guppi_uniq_table_lookup (doc->uniq_table, uid); return ci ? ci->ptr : NULL; } /* ** ** ** ** ** ** ** ** ** ** ** ** ** ** ** ** ** ** ** ** ** ** ** ** */ xmlNodePtr guppi_xml_new_node (GuppiXMLDocument *doc, const gchar *node_name) { g_return_val_if_fail (doc != NULL, NULL); g_return_val_if_fail (node_name != NULL, NULL); return xmlNewNode (doc->ns, node_name); } xmlNodePtr guppi_xml_new_text_node (GuppiXMLDocument *doc, const gchar *node_name, const gchar *text) { xmlNodePtr node; g_return_val_if_fail (doc != NULL, NULL); g_return_val_if_fail (node_name != NULL, NULL); node = guppi_xml_new_node (doc, node_name); if (text) xmlAddChild (node, xmlNewText (text)); return node; } xmlNodePtr guppi_xml_new_text_nodef (GuppiXMLDocument *doc, const gchar *node_name, const gchar *text_format, ...) { gchar *str = NULL; xmlNodePtr node; va_list args; g_return_val_if_fail (doc != NULL, NULL); g_return_val_if_fail (node_name != NULL, NULL); if (text_format) { va_start (args, text_format); str = guppi_strdup_vprintf (text_format, args); va_end (args); } node = guppi_xml_new_text_node (doc, node_name, str); guppi_free (str); return node; } void guppi_xml_set_property (xmlNodePtr node, const gchar *name, const gchar *value) { g_return_if_fail (node != NULL); g_return_if_fail (name != NULL); g_return_if_fail (value != NULL); xmlNewProp (node, name, value); } void guppi_xml_set_propertyf (xmlNodePtr node, const gchar *name, const gchar *value_format, ...) { gchar *str = NULL; va_list args; g_return_if_fail (node != NULL); g_return_if_fail (name != NULL); g_return_if_fail (value_format != NULL); va_start (args, value_format); str = guppi_strdup_vprintf (value_format, args); va_end (args); guppi_xml_set_property (node, name, str); guppi_free (str); } void guppi_xml_set_property_bool (xmlNodePtr node, const gchar *name, gboolean value) { g_return_if_fail (node != NULL); g_return_if_fail (name != NULL); guppi_xml_set_property (node, name, value ? "true" : "false"); } void guppi_xml_set_property_int (xmlNodePtr node, const gchar *name, gint value) { g_return_if_fail (node != NULL); g_return_if_fail (name != NULL); guppi_xml_set_propertyf (node, name, "%d", value); } void guppi_xml_set_property_double (xmlNodePtr node, const gchar *name, double value) { g_return_if_fail (node != NULL); g_return_if_fail (name != NULL); guppi_xml_set_propertyf (node, name, "%g", value); } gchar * guppi_xml_get_property (xmlNodePtr node, const gchar *name) { gchar *str; gchar *strcpy; g_return_val_if_fail (node != NULL, NULL); g_return_val_if_fail (name != NULL, NULL); /* We do this to ensure that the returned string is g_free-able. */ str = xmlGetProp (node, name); strcpy = g_strdup (str); if (str) xmlFree (str); return strcpy; } gboolean guppi_xml_get_property_bool (xmlNodePtr node, const gchar *name, gboolean default_value) { gchar *str; gboolean x = default_value; g_return_val_if_fail (node != NULL, default_value); g_return_val_if_fail (name != NULL, default_value); str = xmlGetProp (node, name); if (str) { if (!g_strcasecmp (str, "true")) { x = TRUE; } else if (!g_strcasecmp (str, "false")) { x = FALSE; } xmlFree (str); } return x; } gint guppi_xml_get_property_int (xmlNodePtr node, const gchar *name, gint default_value) { gchar *str; gint x = default_value; g_return_val_if_fail (node != NULL, default_value); g_return_val_if_fail (name != NULL, default_value); str = xmlGetProp (node, name); if (str) { x = atoi (str); xmlFree (str); } return x; } double guppi_xml_get_property_double (xmlNodePtr node, const gchar *name, double default_value) { gchar *str; double x = default_value; g_return_val_if_fail (node != NULL, 0); g_return_val_if_fail (name != NULL, 0); str = xmlGetProp (node, name); if (str) { x = atof (str); xmlFree (str); } return x; }