GridLab
Grid Application Toolkit

A simple API for Grid Applications
GAT

Menu



Main Page   Alphabetical List   Compound List   File List   Compound Members   File Members  

GATPreferences.c

Go to the documentation of this file.
00001 /** @file GATPreferences.c
00002  * Main file for the GATPreferences class.
00003  * 
00004  * A GATPreferences instance represents the user's preferences for
00005  * selecting adaptors. Currently this class is a place holder for the user 
00006  * preferences, the structure of which is in development.
00007  * 
00008  * @date Tue Sep 2 2003
00009  * 
00010  * @version $Header: /export/cvs-gridlab/wp-1/Codes/GATEngine/C-reference/src/GATPreferences.c,v 1.28 2004/05/10 15:17:32 hartmutkaiser Exp $
00011  *
00012  *  Copyright (C) Tom Goodale
00013  *  This file is part of the GAT Engine.
00014  *  Contributed by Tom Goodale <goodale@aei.mpg.de>.
00015  *
00016  *  Use, modification and distribution is subject to the Gridlab Software
00017  *  License. (See accompanying file GLlicense.txt or copy at
00018  *  http://www.gridlab.org/GLlicense.txt)
00019  */
00020 
00021 static const char *rcsid = "$Header: /export/cvs-gridlab/wp-1/Codes/GATEngine/C-reference/src/GATPreferences.c,v 1.28 2004/05/10 15:17:32 hartmutkaiser Exp $";
00022 
00023 /* System Header Files */
00024 
00025 #include <stdlib.h>
00026 #include <strings.h>
00027 
00028 /* GAT Header Files */
00029 
00030 #include "GATType.h"
00031 #include "GATTable.h"
00032 #include "GATErrors.h"
00033 #include "GATInternal.h"
00034 #include "regex.h"
00035 #include "GATPreferences.h"
00036 
00037 /* Macros */
00038 
00039 /* Structures, unions and enums */
00040 
00041 /* define the vtable types */
00042 GATOBJECT_DEFINE_VTABLE(GATPreferences);
00043 
00044 /* Declare the converters to/from GATObject */
00045 GATOBJECT_DEFINE_CONVERTERS(GATPreferences);
00046 
00047 struct GATPreferences_S
00048 {
00049   GATPreferences_vtable *__vtable;
00050   GATTable table;
00051 };
00052 
00053 /* Static function prototypes */
00054 
00055 /*
00056  * This function determines if the two NULL terminated
00057  * arrays of strings are equivalent as sets. For the
00058  * two arrays to be equivalent as sets each string
00059  * in the first set must appear in the second set
00060  * and each string in the second set must appear
00061  * in the first. Equivalence between strings is
00062  * determined using strcmp.
00063  *
00064  * @return 1 if equal 0 otherwise
00065  */
00066 static GATBool 
00067   GATPreferences_Internal_StringSets_Equal( char **this, char **that );
00068 
00069 /* File scope variables */
00070 static GATPreferences_vtable GATPreferences__vtable = {
00071   GATPreferences_GetType,
00072   GATPreferences_Destroy,
00073   GATPreferences_Equals,
00074   GATPreferences_Clone,
00075   GATPreferences_GetInterface,
00076   NULL
00077 };
00078 
00079 /* External functions */
00080 
00081 /**
00082  * Creates a new GATPreferences instance.
00083  *
00084  * @return A GATPreferences instance
00085  */
00086 GATPreferences GATPreferences_Create(void)
00087 {
00088   GATPreferences this;
00089 
00090   this = (GATPreferences) malloc(sizeof(*this));
00091 
00092   if(NULL != this)
00093   {
00094     this->__vtable = &GATPreferences__vtable;
00095     this->table = GATTable_Create();
00096 
00097     if(!this->table)
00098     {
00099       free(this);
00100     }
00101   }
00102 
00103   return this;
00104 }
00105 
00106 /**
00107  * This function returns the type, a #GATType of the passed 
00108  * #GATPreferences_const. This function will always return 
00109  * #GATType_GATPreferences.
00110  *
00111  * @param this The #GATPreferences_const to query
00112  * @return The #GATType of the passed @c this
00113  */
00114 GATType GATPreferences_GetType(GATPreferences_const this)
00115 {
00116   GAT_UNUSED_PARAMETER(this);
00117   return GATType_GATPreferences;
00118 }
00119 
00120 /**
00121  * Tests this #GATPreferences_const for equality with the passed 
00122  * #GATPreferences_const instance. Two #GATPreferences_const instances 
00123  * are considered equal if they contain the same set of name/value 
00124  * pairs.
00125  *
00126  * @param this The first #GATPreferences_const to compare
00127  * @param that The second #GATPreferences_const to compare
00128  * @param isequal Result of comparison
00129  * @return Completion status
00130  */
00131 GATResult 
00132 GATPreferences_Equals(GATPreferences_const this, GATPreferences_const that, 
00133   GATBool *isequal)
00134 {
00135   return GATTable_Equals(this->table, that->table, isequal);
00136 }
00137                    
00138 /**
00139  * Destroys this GATPreferences instance.
00140  *
00141  * @param this The GATPreferences to destroy
00142  */
00143 void GATPreferences_Destroy(GATPreferences *this)
00144 {
00145   if( (NULL != this) && (NULL != (*this)) )
00146   {
00147     GATTable_Destroy( &((*this)->table) );
00148     
00149     free(*this);
00150     *this = NULL;
00151   }
00152 }
00153 
00154 
00155 /** GATResult GATPreferences_GetInterface(GATPreferences_const table, GATInterface iftype, void const **ifp)
00156  *  @brief Get an interface supported by a GATPreferences
00157  *
00158  *  The function GATPreferences_GetInterface allows to get a pointer to an 
00159  *  additional interface supported by this GATPreferences.
00160  *
00161  *  @param object The object to be asked for the new interface.
00162  *  @param iftype The interface the object is to be asked for.
00163  *  @param ifp The pointer, through which the result is to be returned.
00164  *
00165  *  @return An error type.
00166  */
00167 GATResult 
00168 GATPreferences_GetInterface(GATPreferences_const object, GATInterface iftype, 
00169   void const **ifp)
00170 {
00171   GATResult retval = GAT_INVALID_PARAMETER;
00172   
00173   GAT_UNUSED_PARAMETER(object);
00174   GAT_UNUSED_PARAMETER(iftype);
00175 
00176   if (NULL != ifp)
00177   {
00178     *ifp = NULL;
00179     retval = GAT_NO_INTERFACE;
00180   }
00181   return retval;
00182 }
00183 
00184 /**
00185  * This adds a name/value pair in which the name is a String and the
00186  * value is a String to this GATPreferences instance.
00187  *
00188  * @param this The GATPreferences to modify
00189  * @param name Name  of the attribute to add
00190  * @param value Value of the attribute to add
00191  * @return An int indicating the GATError return code
00192  */
00193 GATResult 
00194 GATPreferences_Add(GATPreferences this, const char *name, const char *value)
00195 {
00196   return GATTable_Add_String(this->table, name, value);
00197 }
00198 
00199 /**
00200  * Removes the name/value pair with the passed name from this
00201  * GATPreferences instance.
00202  *
00203  * @param this The GATPreferences to modify
00204  * @param name Name of the name/value to remove.
00205  * @return An int indicating the GATError return code
00206  */
00207 GATResult 
00208 GATPreferences_Remove(GATPreferences this, const char *name)
00209 {
00210   return GATTable_Remove(this->table, name);
00211 }
00212 
00213 /**
00214  * Sets the given GATTable of name/value pairs as preferences.
00215  *
00216  * @param this The GATPreferences to modify
00217  * @param preferences Table of name/value pairs to be used as
00218  * preferences.
00219  * @return An int indicating the GATError return code
00220  */
00221 GATResult 
00222 GATPreferences_Set(GATPreferences this, GATTable preferences)
00223 {
00224    GATTable tempTable = NULL;
00225   
00226    GATResult result = GATTable_Clone( preferences, &tempTable );
00227    
00228    if(GAT_SUCCESS == result)
00229    {
00230      GATTable_Destroy( &(this->table) );
00231      this->table = tempTable;
00232    }
00233   
00234    return result;
00235 }
00236 
00237 
00238 /**
00239  * Gets the current preferences as name/value pairs in a GATTable.
00240  *
00241  * @param this The GATPreferences to query
00242  * @param preferences Table of name/value pairs containing the
00243  * current preferences. 
00244  */
00245 GATTable_const GATPreferences_Get(GATPreferences_const this)
00246 {
00247   return this->table;
00248 }
00249 
00250 /**
00251  * Matches the GATPreferences instance against another GATPreferences
00252  * instance expressing criteria.  For Match to return true, all keys
00253  * present in the criteria table must be present in the original and
00254  * must match: a string-valued value in the original table is matched by
00255  * a regular expression in the criteria table, and a numeric-valued value
00256  * in the original table by a string holding an arithmetical expression
00257  * (e.g., "$ < 5 $") in the criteria table.
00258  *
00259  * @param this The GATPreferences to query
00260  * @param criteria Matching criteria.
00261  * @param 1 upon match 0 otherwise
00262  */
00263 GATBool 
00264 GATPreferences_Match(GATPreferences_const this, GATPreferences_const criteria)
00265 {  
00266   GATBool match;             /* Boolean indicating match */
00267   regex_t fsa;               /* Pattern matcher */
00268   int criteriaCounter;       /* Counter for looping over criteriaKeyArray */
00269   void **thisKeyArray;       /* Array of this->table keys */
00270   char thisValue[1024];      /* Value from this->table */
00271   void **criteriaKeyArray;   /* Array of criteria->table keys */
00272   char criteriaValue[1024];  /* Value from this->table */
00273   
00274   match = GATFalse;
00275 
00276   if(! criteria)
00277   {
00278     match = GATTrue;
00279     
00280   }
00281   else
00282   {
00283     thisKeyArray = GATTable_GetKeys( this->table );
00284     criteriaKeyArray = GATTable_GetKeys( criteria->table );
00285     
00286     if( (NULL == thisKeyArray) && (NULL == criteriaKeyArray) )
00287     {
00288     /* No keys match no criteria */
00289       match = GATTrue;
00290     }
00291     else if( (NULL == thisKeyArray) && (NULL != criteriaKeyArray) )
00292     {
00293       /* No keys do not match arbitrary critera */
00294       match = GATFalse;
00295     }
00296     else if( (NULL != thisKeyArray) && (NULL == criteriaKeyArray) )
00297     {
00298       /* Arbitrary keys match no critera */
00299       match = GATTrue;
00300     }
00301     else if ( GATFalse == GATPreferences_Internal_StringSets_Equal( 
00302       (char **) thisKeyArray, (char **) criteriaKeyArray ) )
00303     {
00304       /* All keys must match   */
00305       match = GATFalse;
00306     }
00307     else
00308     {
00309       /* Assume match */
00310       match = GATTrue;
00311   
00312       /* Find matches */
00313       criteriaCounter = 0;
00314       while((GATTrue == match) && (NULL != criteriaKeyArray[criteriaCounter]))
00315       {
00316         /* Determine if type is String and if so, obtain String */
00317         if (0 < GATTable_Get_String(this->table, 
00318           criteriaKeyArray[criteriaCounter], thisValue, 1024) )
00319         {
00320           /* Obtain criteria String */
00321           if( 0 < GATTable_Get_String( criteria->table, 
00322             criteriaKeyArray[criteriaCounter], criteriaValue, 1024) )
00323           {
00324             /* Compile regex */
00325             if( 0 != regcomp( &fsa, criteriaValue, 0) )
00326             {
00327               /* Compilation failed we need to flag this as an error !!! */
00328               match = GATFalse;
00329             }
00330             
00331             /* Match with regex */
00332             if( REG_NOMATCH ==  regexec( &fsa, thisValue, 0, NULL, 0) )
00333             {
00334               /* Match failed */
00335               match = GATFalse;
00336             }
00337             
00338             /* We need errors for other results of regexec !!! */
00339             
00340             /* Free regex */
00341             regfree(&fsa);
00342           }
00343         }
00344     
00345         /* If the type is not String and the doc does not specify enough detail 
00346            to write code for this case !!! */
00347         criteriaCounter++;
00348       }
00349     }
00350   
00351     /* free the returned arrays of keys */
00352     GATTable_ReleaseKeys(this->table, &thisKeyArray);
00353     GATTable_ReleaseKeys(criteria->table, &criteriaKeyArray);
00354   }
00355 
00356   return match;
00357 }
00358 
00359 /**
00360  * This function returns a "deep clone" of the passed #GATPreferences_const @c this. 
00361  * This "deep clone" is returned in the variable @c thisClone. Furthermore,
00362  * this function returns its completion status, through its return value.
00363  *
00364  * @param  this The #GATPreferences_const to clone
00365  * @param thisClone The cloned #GATPreferences_const
00366  * @return The completion status of this function
00367  */
00368 GATResult
00369 GATPreferences_Clone(GATPreferences_const this, GATPreferences *thisClone)
00370 {
00371   GATResult result = GAT_INVALID_PARAMETER;
00372   
00373   if( (NULL != this) && (NULL != thisClone) )
00374   {
00375     GATPreferences temp = (GATPreferences) malloc( sizeof(struct GATPreferences_S) );
00376     (*thisClone) = NULL;
00377     
00378     if( NULL != temp )
00379     {
00380       temp->__vtable = this->__vtable;
00381       result = GATTable_Clone( this->table, &(temp->table) );
00382 
00383       if( GAT_SUCCESS != result )
00384       {
00385         GATPreferences_Destroy( &temp );
00386       }
00387       else
00388       {
00389         (*thisClone) = temp;
00390         result = GAT_SUCCESS;
00391       }
00392     }
00393     else
00394     {
00395       result = GAT_MEMORYFAILURE;
00396     }
00397   }
00398   
00399   return result;
00400 }
00401 
00402 /* Local functions */
00403 
00404 /*
00405  * This function determines if the two NULL terminated
00406  * arrays of strings are equivalent as sets. For the
00407  * two arrays to be equivalent as sets each string
00408  * in the first set must appear in the second set
00409  * and each string in the second set must appear
00410  * in the first. Equivalence between strings is
00411  * determined using strcmp.
00412  *
00413  * @return 1 if equal 0 otherwise
00414  */
00415 static GATBool 
00416 GATPreferences_Internal_StringSets_Equal( char **this, char **that )
00417 {
00418   int contained;
00419   int thisCounter;
00420   int thatCounter;
00421   
00422   /* Count number of strings */
00423   thisCounter = 0;
00424   while(NULL != this[thisCounter])
00425   {
00426     thisCounter++;
00427   }
00428   
00429   /* Count number of strings */
00430   thatCounter = 0;
00431   while(NULL != that[thatCounter])
00432   {
00433     thatCounter++;
00434   }
00435   
00436   /* Cardinality must be equal */
00437   if(thisCounter != thatCounter)
00438   {
00439     return GATFalse;
00440   }
00441   
00442   /* Check details */
00443   thisCounter = 0;
00444   while(NULL != this[thisCounter])
00445   {
00446     contained = 0;
00447     
00448     thatCounter = 0;
00449     while( (0 == contained) && (NULL != that[thatCounter]) )
00450     {
00451       if( 0 == strcmp(this[thisCounter], that[thatCounter]) )
00452       {
00453         contained = 1;
00454       }
00455       
00456       thatCounter++;
00457     }
00458     
00459     if(0 == contained)
00460     {
00461       return GATFalse;
00462     }
00463     
00464     thisCounter++;
00465   }
00466   
00467   return GATTrue;
00468 }