/* This is -*- C -*- */ /* $Id: guppi-struct-core.c,v 1.1 2002/01/08 06:29:00 trow Exp $ */ /* * guppi-struct-core-impl.c * * Copyright (C) 2000 EMC Capital Management, Inc. * Copyright (C) 2001 The Free Software Foundation * * Developed by Jon Trowbridge and * Havoc Pennington . * * 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-struct-core.h" #include #include #include #include #include static GtkObjectClass *parent_class = NULL; typedef struct _GuppiStructField GuppiStructField; struct _GuppiStructField { GtkType type; GuppiData *data; }; static void hash_free (gpointer key, gpointer val, gpointer user_data) { GuppiStructField *f = (GuppiStructField *) val; guppi_unref0 (f->data); guppi_free (key); guppi_free (val); } static void guppi_struct_core_destroy (GtkObject *obj) { GuppiStructCore *core = GUPPI_STRUCT_CORE (obj); if (parent_class->destroy) parent_class->destroy (obj); g_hash_table_foreach (core->fields, hash_free, NULL); g_hash_table_destroy (core->fields); g_list_free (core->field_names); core->fields = NULL; } static void guppi_struct_core_finalize (GtkObject *obj) { if (parent_class->finalize) parent_class->finalize (obj); } /***************************************************************************/ static gboolean v_struct_add_field (GuppiStruct *str, const gchar *field, GtkType t) { GuppiStructCore *core = GUPPI_STRUCT_CORE (str); GuppiStructField *p; gchar *dup_field; p = (GuppiStructField *) g_hash_table_lookup (core->fields, field); if (p != NULL) return FALSE; ++core->field_count; dup_field = guppi_strdup (field); core->field_names = g_list_append (core->field_names, dup_field); p = guppi_new (GuppiStructField, 1); p->type = t; p->data = NULL; g_hash_table_insert (core->fields, dup_field, p); return TRUE; } static GtkType v_struct_field_type (GuppiStruct *str, const gchar *field) { GuppiStructCore *core = GUPPI_STRUCT_CORE (str); GuppiStructField *p; p = (GuppiStructField *) g_hash_table_lookup (core->fields, field); if (p == NULL) return (GtkType) 0; return p->type; } static GuppiData * v_struct_get (GuppiStruct *str, const gchar *field) { GuppiStructCore *core = GUPPI_STRUCT_CORE (str); GuppiStructField *p; p = (GuppiStructField *) g_hash_table_lookup (core->fields, field); return p ? p->data : NULL; } static gboolean v_struct_set (GuppiStruct *str, const gchar *field, GuppiData *data) { GuppiStructCore *core = GUPPI_STRUCT_CORE (str); GuppiStructField *p; p = (GuppiStructField *) g_hash_table_lookup (core->fields, field); if (p == NULL) return FALSE; if (p->type && !gtk_type_is_a (GTK_OBJECT_TYPE (data), p->type)) return FALSE; guppi_refcounting_assign (p->data, data); return TRUE; } static void v_struct_foreach (GuppiStruct *str, GuppiStructFn fn, gpointer user_data) { GuppiStructCore *core = GUPPI_STRUCT_CORE (str); GList *iter = core->field_names; GuppiData *d; /* By doing this rather than using the g_hash_table_foreach function, we can make sure that our function gets called in the same order as the objects have been added to the struct. */ while (iter) { d = v_struct_get (str, (gchar *)iter->data); fn ((gchar *)iter->data, d, user_data); iter = g_list_next (iter); } } /***************************************************************************/ static void guppi_struct_core_class_init (GuppiStructCoreClass *klass) { GtkObjectClass *object_class = (GtkObjectClass *) klass; GuppiDataClass *data_class = GUPPI_DATA_CLASS (klass); GuppiStructClass *struct_class = GUPPI_STRUCT_CLASS (klass); parent_class = gtk_type_class (GUPPI_TYPE_STRUCT); object_class->destroy = guppi_struct_core_destroy; object_class->finalize = guppi_struct_core_finalize; struct_class->add_field = v_struct_add_field; struct_class->field_type = v_struct_field_type; struct_class->get = v_struct_get; struct_class->set = v_struct_set; struct_class->foreach = v_struct_foreach; data_class->is_leaf_type = TRUE; } static void guppi_struct_core_init (GuppiStructCore *obj) { obj->fields = g_hash_table_new (g_str_hash, g_str_equal); } GtkType guppi_struct_core_get_type (void) { static GtkType guppi_struct_core_type = 0; if (!guppi_struct_core_type) { static const GtkTypeInfo guppi_struct_core_info = { "GuppiStructCore", sizeof (GuppiStructCore), sizeof (GuppiStructCoreClass), (GtkClassInitFunc) guppi_struct_core_class_init, (GtkObjectInitFunc) guppi_struct_core_init, NULL, NULL, (GtkClassInitFunc) NULL }; guppi_struct_core_type = gtk_type_unique (GUPPI_TYPE_STRUCT, &guppi_struct_core_info); } return guppi_struct_core_type; } /* ** ** ** ** ** ** ** ** ** ** ** ** ** ** ** ** ** ** ** ** ** ** ** ** */ GuppiStruct * guppi_struct_core_new (void) { return GUPPI_STRUCT (guppi_type_new (guppi_struct_core_get_type ())); } /* $Id: guppi-struct-core.c,v 1.1 2002/01/08 06:29:00 trow Exp $ */