/***************************************************************************** * * rbgconf-util.c: Ruby GConf interface utility functions. * * Copyright (C) 2002,2003 Nikolai :: lone-star :: Weibull . * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public * License as published by the Free Software Foundation; either * version 2.1 of the License, or (at your option) any later version. * * This library 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 * Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public * License along with this library; if not, write to the Free Software * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA * * $Author: ggc $ * * $Date: 2007/07/13 16:07:28 $ * *****************************************************************************/ /* Includes ******************************************************************/ #include "rbgconf.h" /* Defines *******************************************************************/ /* Type Definitions **********************************************************/ /* Function Declarations *****************************************************/ /* Global Variables **********************************************************/ /* Function Implementations **************************************************/ /* * convert a Ruby array to a GSList of GConfValues. */ static GSList * rb_ary_to_gconfval_list(ary_val, list_type) VALUE ary_val; GConfValueType *list_type; { GSList *list = NULL; GConfValueType type = GCONF_VALUE_INVALID; GConfValue *val; int i, n; /* loop over the array and convert to GConfValues and store in list */ Check_Type(ary_val, T_ARRAY); n = RARRAY(ary_val)->len; for (i = 0; i < n; i++) { val = rb_value_to_gconf_value(rb_ary_entry(ary_val, i)); /* uh, oh. not all elements were of the same type. */ if (type != GCONF_VALUE_INVALID && type != val->type) { *list_type = GCONF_VALUE_INVALID; return list; } type = val->type; list = g_slist_append(list, val); } *list_type = type; return list; } /* * convert a Ruby VALUE to a GConfValue. */ GConfValue * rb_value_to_gconf_value(val) VALUE val; { GConfValue *gval; switch (TYPE(val)) { case T_STRING: gval = gconf_value_new(GCONF_VALUE_STRING); gconf_value_set_string(gval, RVAL2CSTR(val)); break; case T_FIXNUM: case T_BIGNUM: gval = gconf_value_new(GCONF_VALUE_INT); gconf_value_set_int(gval, NUM2INT(val)); break; case T_FLOAT: gval = gconf_value_new(GCONF_VALUE_FLOAT); gconf_value_set_float(gval, NUM2DBL(val)); break; case T_TRUE: case T_FALSE: gval = gconf_value_new(GCONF_VALUE_BOOL); gconf_value_set_bool(gval, RVAL2CBOOL(val)); break; case T_ARRAY: { GConfValueType type; GSList *list; list = rb_ary_to_gconfval_list(val, &type); if (type == GCONF_VALUE_INVALID) { GSList *i; for (i = list; i != NULL; i = i->next) { gconf_value_free((GConfValue *)i->data); } g_slist_free(list); rb_raise(rb_eArgError, "all elements must be of same type"); } else if (g_slist_length(list) == 2) { gval = gconf_value_new(GCONF_VALUE_PAIR); gconf_value_set_car_nocopy(gval, (GConfValue *)g_slist_nth_data(list, 0)); gconf_value_set_cdr_nocopy(gval, (GConfValue *)g_slist_nth_data(list, 1)); g_slist_free(list); } else { gval = gconf_value_new(GCONF_VALUE_LIST); gconf_value_set_list_type(gval, type); gconf_value_set_list_nocopy(gval, list); } break; } default: if (RVAL2GTYPE(val) == GCONF_TYPE_SCHEMA) { gval = gconf_value_new(GCONF_VALUE_SCHEMA); gconf_value_set_schema_nocopy(gval, RVAL2GCSCHEMA(val)); } else { rb_raise(rb_eTypeError, "invalid GConfValue type"); } break; } return gval; } /* * convert a list of GConfValues to a Ruby array. */ static VALUE gconfval_list_to_rb_ary(list) GSList *list; { VALUE ary; ary = rb_ary_new2(g_slist_length(list)); while (list != NULL) { rb_ary_push(ary, gconf_value_to_rb_value((GConfValue *)list->data)); list = list->next; } return ary; } /* * convert a pair of GConfValues to a Ruby array. */ static VALUE gconfval_pair_to_rb_ary(car, cdr) GConfValue *car, *cdr; { return rb_assoc_new(gconf_value_to_rb_value(car), gconf_value_to_rb_value(cdr)); } /* * convert a GConfValue to a Ruby VALUE. */ VALUE gconf_value_to_rb_value(gval) GConfValue *gval; { VALUE val = Qnil; if (gval == NULL) { return Qnil; } if (!GCONF_VALUE_TYPE_VALID(gval->type)) { rb_bug("Found a bogus GConfValueType `%d'; please report.", gval->type); } switch (gval->type) { case GCONF_VALUE_STRING: val = CSTR2RVAL(gconf_value_get_string(gval)); break; case GCONF_VALUE_INT: val = INT2NUM(gconf_value_get_int(gval)); break; case GCONF_VALUE_FLOAT: val = rb_float_new(gconf_value_get_float(gval)); break; case GCONF_VALUE_BOOL: val = CBOOL2RVAL(gconf_value_get_bool(gval)); break; case GCONF_VALUE_SCHEMA: val = GCSCHEMA2RVAL(gconf_value_get_schema(gval)); break; case GCONF_VALUE_LIST: val = gconfval_list_to_rb_ary(gconf_value_get_list(gval)); break; case GCONF_VALUE_PAIR: val = gconfval_pair_to_rb_ary(gconf_value_get_car(gval), gconf_value_get_cdr(gval)); break; default: /* in case the bastards add yet another useless type */ rb_notimplement(); break; } return val; } /* vim: set sts=0 sw=8 ts=8: *************************************************/