src/midgard_type.c

00001 /* 
00002  * Copyright (C) 2005 Piotr Pokora <piotr.pokora@infoglob.pl>
00003  *
00004  * This program is free software; you can redistribute it and/or modify it
00005  * under the terms of the GNU Lesser General Public License as published
00006  * by the Free Software Foundation; either version 2 of the License, or
00007  * (at your option) any later version.
00008  * 
00009  * This program is distributed in the hope that it will be useful,
00010  * but WITHOUT ANY WARRANTY; without even the implied warranty of
00011  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
00012  * GNU General Public License for more details.
00013  * 
00014  * You should have received a copy of the GNU General Public License
00015  * along with this program; if not, write to the Free Software
00016  * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
00017  */
00018 
00019 #include "midgard/midgard_type.h"
00020 #include <string.h>
00021 #include <glib.h>
00022 #include <gobject/gvaluecollector.h>
00023 
00024 /* MIDGARD_TYPE_LONGTEXT */
00025 
00026 /* Copied from glib's gvaluetypes */
00027 static void _init_string (GValue *value)
00028 {
00029         value->data[0].v_pointer = NULL;
00030 }
00031 
00032 static void _free_string (GValue *value)
00033 {
00034         if (!(value->data[1].v_uint & G_VALUE_NOCOPY_CONTENTS))
00035                 g_free (value->data[0].v_pointer);
00036 }
00037 
00038 static void _copy_string (const GValue *src_value, GValue *dest_value)
00039 {
00040         dest_value->data[0].v_pointer = g_strdup (src_value->data[0].v_pointer);
00041 }
00042 
00043 static gpointer _peek_pointer0 (const GValue *value)
00044 {
00045         return value->data[0].v_pointer;
00046 }
00047 
00048 static gchar* _collect_string (GValue    *value,
00049                 guint        n_collect_values,
00050                 GTypeCValue *collect_values,
00051                 guint        collect_flags)
00052 {
00053           if (!collect_values[0].v_pointer)
00054                   value->data[0].v_pointer = NULL;
00055           else if (collect_flags & G_VALUE_NOCOPY_CONTENTS){
00056                   value->data[0].v_pointer = collect_values[0].v_pointer;
00057                   value->data[1].v_uint = G_VALUE_NOCOPY_CONTENTS;
00058           }
00059           else  
00060                   value->data[0].v_pointer = g_strdup (collect_values[0].v_pointer);
00061           return NULL;
00062 }
00063 
00064 static gchar* _lcopy_string (const GValue *value,
00065                 guint         n_collect_values,
00066                 GTypeCValue  *collect_values,
00067                 guint         collect_flags)
00068 {
00069         gchar **string_p = collect_values[0].v_pointer;
00070         
00071         if (!string_p)
00072                 return g_strdup_printf ("value location for `%s' passed as NULL", G_VALUE_TYPE_NAME (value));
00073         if (!value->data[0].v_pointer)
00074                 *string_p = NULL;
00075         else if (collect_flags & G_VALUE_NOCOPY_CONTENTS)
00076                 *string_p = value->data[0].v_pointer;
00077         else
00078                 *string_p = g_strdup (value->data[0].v_pointer);
00079         
00080         return NULL;
00081 }
00082 
00083 /* Register midgard_longtext fundamental type */
00084 GType midgard_longtext_get_type(void) {
00085         static GType type = 0;
00086         if (type == 0) {
00087                 static const GTypeValueTable value_table = {
00088                         _init_string,  /* value_init */
00089                         _free_string,  /* value_free */
00090                         _copy_string,  /* value_copy */
00091                         _peek_pointer0,  /* value_peek_pointer */
00092                         "p",      /* collect_format */
00093                         _collect_string, /* collect_value */
00094                         "p",      /* lcopy_format */
00095                         _lcopy_string, /* lcopy_value */
00096                 };
00097                 static const GTypeInfo info = {
00098                         0,                         /* class_size */
00099                         NULL,                      /* base_init */
00100                         NULL,                      /* base_destroy */
00101                         NULL,                      /* class_init */ 
00102                         NULL,                      /* class_destroy */
00103                         NULL,                      /* class_data */
00104                         0,                         /* instance_size */
00105                         0,                         /* n_preallocs */
00106                         NULL,                      /* instance_init */
00107                         &value_table               /* value_table */
00108                 };
00109                 static const GTypeFundamentalInfo finfo = {
00110                         G_TYPE_FLAG_DERIVABLE
00111                 };
00112                 type = g_type_register_fundamental(
00113                                 g_type_fundamental_next(), "MgdTypeLongtext",
00114                                 &info, &finfo, 0);
00115         }
00116         return type;
00117 }                                       
00118 
00119 /* MIDGARD_TYPE_PARAM_LONGTEXT */
00120 struct _MgdParamSpecLongtext {
00121         GParamSpec    parent_instance;
00122         gchar        *default_value;
00123         gchar        *cset_first;
00124         gchar        *cset_nth;
00125         gchar         substitutor;
00126         guint         null_fold_if_empty : 1;
00127         guint         ensure_non_null : 1;
00128 };
00129 
00130 static void _param_string_init (GParamSpec *pspec)
00131 {
00132         MgdParamSpecLongtext *ltspec = MGD_PARAM_SPEC_LONGTEXT (pspec);
00133         
00134         ltspec->default_value = NULL;
00135         ltspec->cset_first = NULL;
00136         ltspec->cset_nth = NULL;
00137         ltspec->substitutor = '_'; 
00138         ltspec->null_fold_if_empty = FALSE;
00139         ltspec->ensure_non_null = FALSE;
00140 }
00141 
00142 static void _param_string_finalize (GParamSpec *pspec)  
00143 {
00144         MgdParamSpecLongtext *ltspec = MGD_PARAM_SPEC_LONGTEXT (pspec);
00145         GParamSpecClass *parent_class = g_type_class_peek (g_type_parent (MGD_TYPE_PARAM_LONGTEXT));
00146 
00147         g_free (ltspec->default_value);
00148         g_free (ltspec->cset_first);
00149         g_free (ltspec->cset_nth);
00150         ltspec->default_value = NULL;
00151         ltspec->cset_first = NULL;
00152         ltspec->cset_nth = NULL;
00153         
00154         parent_class->finalize (pspec);
00155 }   
00156   
00157 static void _param_string_set_default (GParamSpec *pspec, GValue *value)
00158 {
00159         value->data[0].v_pointer = g_strdup (MGD_PARAM_SPEC_LONGTEXT (pspec)->default_value);
00160 }
00161 
00162 static gboolean _param_string_validate (GParamSpec *pspec, GValue *value)
00163 {
00164         MgdParamSpecLongtext *ltspec = MGD_PARAM_SPEC_LONGTEXT (pspec);
00165         gchar *string = value->data[0].v_pointer;
00166         guint changed = 0;
00167 
00168         if (string && string[0]){
00169                 
00170                 gchar *s;
00171 
00172                 if (ltspec->cset_first && !strchr (ltspec->cset_first, string[0])){
00173                         
00174                         string[0] = ltspec->substitutor;
00175                         changed++;
00176                 }
00177                 
00178                 if (ltspec->cset_nth)
00179                         for (s = string + 1; *s; s++)
00180                                 if (!strchr (ltspec->cset_nth, *s))
00181                                 {
00182                                         *s = ltspec->substitutor;
00183                                         changed++;
00184                                 }
00185         }
00186 
00187         if (ltspec->null_fold_if_empty && string && string[0] == 0){
00188                 
00189                 g_free (value->data[0].v_pointer);
00190                 value->data[0].v_pointer = NULL;
00191                 changed++;
00192                 string = value->data[0].v_pointer;
00193         }
00194         
00195         if (ltspec->ensure_non_null && !string){
00196                 
00197                 value->data[0].v_pointer = g_strdup ("");
00198                 changed++;
00199                 string = value->data[0].v_pointer;
00200         }
00201         
00202         return changed;
00203 }
00204 
00205 
00206 static gint _param_string_values_cmp (GParamSpec *pspec, const GValue *value1, const GValue *value2)
00207 {
00208         if (!value1->data[0].v_pointer)
00209                 return value2->data[0].v_pointer != NULL ? -1 : 0;
00210         else if (!value2->data[0].v_pointer)
00211                 return value1->data[0].v_pointer != NULL;
00212         else
00213                 return strcmp (value1->data[0].v_pointer, value2->data[0].v_pointer);
00214 }
00215 
00216 
00217 /* Register midgard_longtext paramspec */
00218 GType midgard_param_longtext_get_type(void) 
00219 {
00220         static GType type = 0;
00221         if (type == 0) {
00222                 {
00223                         const GParamSpecTypeInfo pspec_info = {
00224                                 sizeof (MgdParamSpecLongtext),     /* instance_size */
00225                                 16,                                /* n_preallocs */
00226                                 _param_string_init,                /* instance_init */
00227                                 MGD_TYPE_LONGTEXT,                 /* value_type */
00228                                 _param_string_finalize,            /* finalize */
00229                                 _param_string_set_default,         /* value_set_default */
00230                                 _param_string_validate,            /* value_validate */
00231                                 _param_string_values_cmp,          /* values_cmp */
00232                         };
00233                         type = g_param_type_register_static ("MgdParamLongtext", &pspec_info);
00234                 }
00235         }
00236         return type;    
00237 }
00238 
00239 /* Register MGD_TYPE_GUID type */
00240 GType midgard_guid_get_type(void)
00241 {
00242         static GType type = 0;
00243         if(type == 0) {
00244                 
00245                 GTypeInfo info = {
00246                         0,             /* class size */
00247                         NULL,          /* base_init */
00248                         NULL,          /* base_finalize */
00249                         NULL,          /* class_init */
00250                         NULL,          /* class_finalize */
00251                         NULL,          /* class_data */
00252                         0,
00253                         0,             /* n_preallocs */
00254                         NULL           /* instance_init */
00255                 };
00256                 type = g_type_register_static(
00257                                 G_TYPE_STRING, 
00258                                 "MgdTypeGuid", 
00259                                 &info, 0);
00260         }
00261         return type;
00262 }

Generated on Thu Feb 22 06:15:18 2007 for midgard-core by  doxygen 1.4.6