/* 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 <trow@gnu.org>
*/
/*
* 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 <config.h>
#include "guppi-xml.h"
#include <stdlib.h>
#include <gnome-xml/parser.h>
#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;
}
syntax highlighted by Code2HTML, v. 0.9.1