configfile.h 4.51 KB
Newer Older
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163
#ifndef SRC_COMMON_MODELCONFIG_CONFIGFILE_H
#define SRC_COMMON_MODELCONFIG_CONFIGFILE_H

#include <malloc.h>
#include <stddef.h>  /* size_t */
#include <stdlib.h>

#ifdef __cplusplus
extern "C" {
#endif


/**
 * A config file is contains (possibly nested) sections, 
 * where each section groups entries. 
 * An entry is either another section, a key or a multikey.
 *
 * A key is a (name, value) string pair, while a multikey is a 
 * (name, value, value, value, ...) tuple.
 */
typedef void * SectionHandle;


enum { SE_SECTION  = 1,
       SE_KEY      = 2,
       SE_MULTIKEY = 3
     };

typedef struct
{
   char * name;
   unsigned int type;
} SectionEntry;

#define ROOT_SECTION ((SectionHandle) 0)

typedef struct
{
   /* Returns number of characters in key or < 0 if an error occured 
    * (such as key is missing) 
    *
    * Calling this function with a NULL buf ptr and 0 bufsize will
    * return the keysize, not including terminating 0.
    *
    * */
   int (*getKey) (void *  handle, SectionHandle section, const char * key,
         char * buf, size_t bufsize);

   /*
    * Reads list entries: after the function returns, buf will be set to 
    * a pointer pointing to an array of e char * pointers.
    * Needs to be freed with free() (array + pointers) 
    * Returns < 0 if error */
   int (*getMultiKey) (void * handle, SectionHandle section, const char * key,
         char *** buf, size_t * e);
   /*
    * Outputs number of entries written in maxentries, retrieves at most
    * maxentries (input val).
    * Returns total number of entries in section. 
    */
   int (*listSection) (void * handle, SectionHandle section, 
         SectionEntry * entries, size_t * maxentries);

   /* Returns -1 if failed, >=0 if ok */
   int (*openSection) (void * handle, SectionHandle section, const char *
         sectionname, SectionHandle * newsection);

   /* Return the number of entries in a section in count,
    * return code is <0 if error */
   int (*getSectionSize) (void * handle, SectionHandle section, unsigned int *
         count);

   /* Returns < 0 if error */
   int (*closeSection) (void * handle, SectionHandle section);

   /* Returns < 0 if error */
   int (*createSection) (void * handle, SectionHandle section, const
         char * name, SectionHandle * newsection);

   /* Returns < 0 if error */
   int (*createKey) (void * handle, SectionHandle section, const char * key,
         const char ** data, unsigned int count); 

   void (*free) (void * handle);

   void * data; 

} ConfigVTable; 

typedef ConfigVTable * ConfigHandle; 

/* utility debug function: write config tree to stdout;
 * If all OK: ret >= 0, otherwise ret < 0 and *err is set
 * to error message
 * */
int cf_dump (ConfigHandle cf, SectionHandle h, char ** err);

/* Compare two config trees: return true if equal, false if not */
int cf_equal (ConfigHandle h1, ConfigHandle h2);

static inline int cf_free (ConfigHandle cf)
{
   if (!cf)
      return 1;

   cf->free (cf->data);
   free (cf);
   return 1;
}

static inline int cf_getSectionSize (ConfigHandle cf, SectionHandle section, 
      unsigned int * count)
{
   return cf->getSectionSize (cf->data, section, count); 
}

static inline int cf_closeSection (ConfigHandle cf, SectionHandle section)
{
   return cf->closeSection (cf->data, section);
}

static inline int cf_openSection (ConfigHandle cf, SectionHandle section, 
      const char * sectionname, SectionHandle * newsection)
{
   return cf->openSection (cf->data, section, sectionname, newsection);
}

static inline int cf_getKey (ConfigHandle cf, SectionHandle section, 
      const char * keyname, char * buf, size_t maxbuf)
{
   return cf->getKey (cf->data, section, keyname, buf, maxbuf);
}

static inline int cf_getMultiKey (ConfigHandle cf, SectionHandle section,
      const char * keyname, char *** buf, size_t * e)
{
   return cf->getMultiKey (cf->data, section, keyname, buf, e);
}

static inline int cf_listSection (ConfigHandle cf, SectionHandle section, 
         SectionEntry * entries, size_t * maxentries)
{
   return cf->listSection (cf->data, section, entries, maxentries);
}

static inline int cf_createSection (ConfigHandle handle, SectionHandle
      section, const char * name, SectionHandle * newsection)
{
   return handle->createSection (handle->data, section, name, 
         newsection);
}

static inline int cf_createKey (ConfigHandle handle, SectionHandle section,
      const char * key, const char ** data, unsigned int count)
{
   return handle->createKey (handle->data, section, key, data, count);
}

#ifdef __cplusplus
} /* extern "C" */
#endif

#endif