avs.c

Go to the documentation of this file.
00001 /*                           A V S . C
00002  * BRL-CAD
00003  *
00004  * Copyright (c) 2004-2006 United States Government as represented by
00005  * the U.S. Army Research Laboratory.
00006  *
00007  * This library is free software; you can redistribute it and/or
00008  * modify it under the terms of the GNU Lesser General Public License
00009  * as published by the Free Software Foundation; either version 2 of
00010  * the License, or (at your option) any later version.
00011  *
00012  * This library is distributed in the hope that it will be useful, but
00013  * WITHOUT ANY WARRANTY; without even the implied warranty of
00014  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
00015  * Library General Public License for more details.
00016  *
00017  * You should have received a copy of the GNU Lesser General Public
00018  * License along with this file; see the file named COPYING for more
00019  * information.
00020  */
00021 
00022 /** @addtogroup avs */
00023 /*@{*/
00024 /** @file avs.c
00025  *  @brief
00026  *  Routines to manage attribute/value sets.
00027  *
00028  *  @Author Michael John Muuss
00029  *
00030  *  @par Source -
00031  *      The U. S. Army Research Laboratory                      @n
00032  *      Aberdeen Proving Ground, Maryland  21005-5068  USA
00033  */
00034 
00035 #ifndef lint
00036 static const char RCSid[] = "@(#)$Header: /cvsroot/brlcad/brlcad/src/libbu/avs.c,v 14.11 2006/08/31 05:50:24 lbutler Exp $ (ARL)";
00037 #endif
00038 
00039 #include "common.h"
00040 
00041 #include <stdio.h>
00042 #ifdef HAVE_STRING_H
00043 #  include <string.h>
00044 #else
00045 #  include <strings.h>
00046 #endif
00047 
00048 #include "machine.h"
00049 #include "bu.h"
00050 
00051 
00052 /**
00053  *                      B U _ A V S _ I N I T _ E M P T Y
00054  *
00055  * @brief 
00056  *      initialize an empty avs
00057  */
00058 void
00059 bu_avs_init_empty( struct bu_attribute_value_set *avsp )
00060 {
00061         avsp->magic = BU_AVS_MAGIC;
00062         avsp->count = 0;
00063         avsp->max = 0;
00064         avsp->avp = (struct bu_attribute_value_pair *)NULL;
00065         avsp->readonly_min = avsp->readonly_max = NULL;
00066 }
00067 
00068 /**
00069  *                      B U _ A V S _ I N I T
00070  *
00071  * @brief 
00072  *      initialize avs with storage for len entries
00073  */
00074 void
00075 bu_avs_init(struct bu_attribute_value_set *avsp, int len, const char *str)
00076 {
00077         if (bu_debug & BU_DEBUG_AVS)
00078                 bu_log("bu_avs_init(%8x, len=%d, %s)\n", avsp, len, str);
00079 
00080         avsp->magic = BU_AVS_MAGIC;
00081         if( len <= 0 )  len = 32;
00082         avsp->count = 0;
00083         avsp->max = len;
00084         avsp->avp = (struct bu_attribute_value_pair *)bu_calloc(avsp->max,
00085                 sizeof(struct bu_attribute_value_pair), str);
00086         avsp->readonly_min = avsp->readonly_max = NULL;
00087 }
00088 
00089 /**                     B U _ A V S _ N E W
00090  *
00091  *  @brief 
00092  *      Allocate storage for a new attribute/value set, with at least
00093  *      'len' slots pre-allocated.
00094  */
00095 struct bu_attribute_value_set   *
00096 bu_avs_new(int len, const char *str)
00097 {
00098         struct bu_attribute_value_set   *avsp;
00099 
00100         BU_GETSTRUCT( avsp, bu_attribute_value_set );
00101         bu_avs_init( avsp, len, "bu_avs_new" );
00102 
00103         if (bu_debug & BU_DEBUG_AVS)
00104                 bu_log("bu_avs_new(len=%d, %s) = x%x\n", len, str, avsp);
00105 
00106         return avsp;
00107 }
00108 
00109 /**
00110  *                      B U _ A V S _ A D D
00111  *
00112  *  If the given attribute exists it will recieve the new value,
00113  *  othwise the set will be extended to have a new attribute/value pair.
00114  *
00115  *  Returns -
00116  *      1       existing attribute updated with new value
00117  *      2       set extended with new attribute/value pair
00118  */
00119 int
00120 bu_avs_add(struct bu_attribute_value_set *avsp, const char *attribute, const char *value)
00121 {
00122         struct bu_attribute_value_pair *app;
00123 
00124         BU_CK_AVS(avsp);
00125 
00126         if( avsp->count ) {
00127                 for( BU_AVS_FOR(app, avsp) )  {
00128                         if( strcmp( app->name, attribute ) != 0 )  continue;
00129                         if( app->value && AVS_IS_FREEABLE(avsp, app->value) )
00130                                 bu_free( (genptr_t)app->value, "app->value" );
00131                         if( value )
00132                                 app->value = bu_strdup( value );
00133                         else
00134                                 app->value = (char *)NULL;
00135                         return 1;
00136                 }
00137         }
00138 
00139         if( avsp->count >= avsp->max )  {
00140                 /* Allocate more space first */
00141                 avsp->max += 4;
00142                 if( avsp->avp ) {
00143                         avsp->avp = (struct bu_attribute_value_pair *)bu_realloc(
00144                           avsp->avp,  avsp->max * sizeof(struct bu_attribute_value_pair),
00145                                 "attribute_value_pair.avp[] (add)" );
00146                 } else {
00147                         avsp->avp = (struct bu_attribute_value_pair *)bu_calloc(
00148                                 avsp->max, sizeof(struct bu_attribute_value_pair ),
00149                                "attribute_value_pair.avp[] (add)" );
00150                 }
00151         }
00152 
00153         app = &avsp->avp[avsp->count++];
00154         app->name = bu_strdup(attribute);
00155         if( value )
00156                 app->value = bu_strdup(value);
00157         else
00158                 app->value = (char *)NULL;
00159         return 2;
00160 }
00161 
00162 /*
00163  *                      B U _ A V S _ A D D _ V L S
00164  */
00165 int
00166 bu_avs_add_vls(struct bu_attribute_value_set *avsp, const char *attribute, const struct bu_vls *value_vls)
00167 {
00168         BU_CK_AVS(avsp);
00169         BU_CK_VLS(value_vls);
00170 
00171         return bu_avs_add( avsp, attribute, bu_vls_addr(value_vls) );
00172 }
00173 
00174 /**
00175  *                      B U _ A V S _ M E R G E
00176  *
00177  *  @brief 
00178  *      Take all the attributes from 'src' and merge them into 'dest'.
00179  */
00180 void
00181 bu_avs_merge( struct bu_attribute_value_set *dest, const struct bu_attribute_value_set *src )
00182 {
00183         struct bu_attribute_value_pair *app;
00184 
00185         BU_CK_AVS(dest);
00186         BU_CK_AVS(src);
00187 
00188         if( src->count ) {
00189                 for( BU_AVS_FOR( app, src ) )  {
00190                         (void)bu_avs_add( dest, app->name, app->value );
00191                 }
00192         }
00193 }
00194 
00195 /*
00196  *                      B U _ A V S _ G E T
00197  */
00198 const char *
00199 bu_avs_get( const struct bu_attribute_value_set *avsp, const char *attribute )
00200 {
00201         struct bu_attribute_value_pair *app;
00202 
00203         BU_CK_AVS(avsp);
00204 
00205         if( avsp->count < 1 )
00206                 return NULL;
00207 
00208         for( BU_AVS_FOR(app, avsp) )  {
00209                 if( strcmp( app->name, attribute ) != 0 )  continue;
00210                 return app->value;
00211         }
00212         return NULL;
00213 }
00214 
00215 /**
00216  *                      B U _ A V S _ R E M O V E
00217  *
00218  * @brief
00219  *      Remove the given attribute from the set
00220  *
00221  * @Return
00222  *      -1      attribute not found in set
00223  * @Return
00224  *       0      OK
00225  */
00226 int
00227 bu_avs_remove(struct bu_attribute_value_set *avsp, const char *attribute)
00228 {
00229         struct bu_attribute_value_pair *app, *epp;
00230 
00231         BU_CK_AVS(avsp);
00232 
00233         if( avsp->count ) {
00234                 for( BU_AVS_FOR(app, avsp) )  {
00235                         if( strcmp( app->name, attribute ) != 0 )  continue;
00236                         if( app->name && AVS_IS_FREEABLE( avsp, app->name ) )
00237                                 bu_free( (genptr_t)app->name, "app->name" );
00238                         app->name = NULL;       /* sanity */
00239                         if( app->value && AVS_IS_FREEABLE( avsp, app->value ) )
00240                                 bu_free( (genptr_t)app->value, "app->value" );
00241                         app->value = NULL;      /* sanity */
00242 
00243                         /* Move last one down to replace it */
00244                         epp = &avsp->avp[--avsp->count];
00245                         if( app != epp )  {
00246                                 *app = *epp;            /* struct copy */
00247                         }
00248                         epp->name = NULL;                       /* sanity */
00249                         epp->value = NULL;
00250                         return 0;
00251                 }
00252         }
00253         return -1;
00254 }
00255 
00256 /*
00257  *                      B U _ A V S _ F R E E
00258  */
00259 void
00260 bu_avs_free( struct bu_attribute_value_set *avsp )
00261 {
00262     struct bu_attribute_value_pair *app;
00263 
00264     BU_CK_AVS(avsp);
00265 
00266     if( avsp->max < 1 )
00267         return;
00268 
00269     if( avsp->count ) {
00270         for( BU_AVS_FOR(app, avsp) )  {
00271             if( app->name && AVS_IS_FREEABLE( avsp, app->name ) ) {
00272                 bu_free( (genptr_t)app->name, "app->name" );
00273             }
00274             app->name = NULL;   /* sanity */
00275             if( app->value && AVS_IS_FREEABLE( avsp, app->value ) ) {
00276                 bu_free( (genptr_t)app->value, "app->value" );
00277             }
00278             app->value = NULL;  /* sanity */
00279         }
00280         avsp->count = 0;
00281     }
00282     if ( avsp->avp ) {
00283         bu_free( (genptr_t)avsp->avp, "bu_avs_free avsp->avp" );
00284         avsp->avp = NULL; /* sanity */
00285         avsp->max = 0;
00286     }
00287 }
00288 
00289 
00290 /*
00291  *                      B U _ A V S _ P R I N T
00292  */
00293 void
00294 bu_avs_print( const struct bu_attribute_value_set *avsp, const char *title )
00295 {
00296         struct bu_attribute_value_pair  *avpp;
00297         int i;
00298 
00299         BU_CK_AVS(avsp);
00300 
00301         bu_log("bu_avs_print: %s\n", title);
00302 
00303         avpp = avsp->avp;
00304         for( i = 0; i < avsp->count; i++, avpp++ )  {
00305                 bu_log(" %s = %s\n", avpp->name, avpp->value );
00306         }
00307 }
00308 
00309 /**
00310  *                      B U _ A V S _ A D D _ N O N U N I Q U E
00311  *
00312  * @brief
00313  *      Add a name/value pair even if the name already exists in this AVS
00314  */
00315 void
00316 bu_avs_add_nonunique( struct bu_attribute_value_set *avsp, char *attribute, char *value )
00317 {
00318         struct bu_attribute_value_pair *app;
00319 
00320         BU_CK_AVS(avsp);
00321 
00322         if( avsp->count >= avsp->max )  {
00323                 /* Allocate more space first */
00324                 avsp->max += 4;
00325                 if( avsp->avp ) {
00326                         avsp->avp = (struct bu_attribute_value_pair *)bu_realloc(
00327                           avsp->avp,  avsp->max * sizeof(struct bu_attribute_value_pair),
00328                                 "attribute_value_pair.avp[] (add)" );
00329                 } else {
00330                         avsp->avp = (struct bu_attribute_value_pair *)bu_malloc(
00331                                 avsp->max * sizeof(struct bu_attribute_value_pair ),
00332                                "attribute_value_pair.avp[] (add)" );
00333                 }
00334         }
00335 
00336         app = &avsp->avp[avsp->count++];
00337         app->name = bu_strdup(attribute);
00338         if( value )
00339                 app->value = bu_strdup(value);
00340         else
00341                 app->value = (char *)NULL;
00342 }
00343 /*@}*/
00344 /*
00345  * Local Variables:
00346  * mode: C
00347  * tab-width: 8
00348  * c-basic-offset: 4
00349  * indent-tabs-mode: t
00350  * End:
00351  * ex: shiftwidth=4 tabstop=8
00352  */

Generated on Mon Sep 18 01:24:47 2006 for BRL-CAD by  doxygen 1.4.6