ini_reader.c

Go to the documentation of this file.
00001 
00039 #include "ini_reader.h"
00040 #include "cfg/cfg_ini_reader.h"
00041 #include <string.h>
00042 #include <stdio.h>
00043 #include <ctype.h>
00044 
00045 /*
00046  * Returns when the line containing the section is found.
00047  * The file pointer is positioned at the start of the next line.
00048  * Returns EOF if no section was found, 0 otherwise.
00049  */
00050 static int findSection(KFile *fd, const char *section, size_t section_len, char *line, size_t size)
00051 {
00052     while (kfile_gets(fd, line, size) != EOF)
00053     {
00054         char *ptr = line;
00055         unsigned i;
00056         /* accept only sections that begin at first char */
00057         if (*ptr++ != '[')
00058             continue;
00059 
00060         /* find the end-of-section character */
00061         for (i = 0; i < size && *ptr != ']'; ++i, ++ptr)
00062             ;
00063 
00064         /* The found section could be long that our section key */
00065         if (section_len != i)
00066             continue;
00067 
00068         /* did we find the correct section? */
00069         if(strncmp(&line[1], section, section_len))
00070             continue;
00071         else
00072             return 0;
00073     }
00074     return EOF;
00075 }
00076 
00077 /*
00078  * Fills the argument with the key found in line
00079  */
00080 static char *getKey(const char *line, char *key, size_t size)
00081 {
00082     /* null-terminated string */
00083     while (isspace(*line))
00084         ++line;
00085     int i = 0;
00086     while (*line != '=' && !isspace(*line) && size)
00087     {
00088         key[i++] = *line;
00089         ++line;
00090         --size;
00091     }
00092     size ? (key[i] = '\0') : (key[i-1] = '\0');
00093     return key;
00094 }
00095 
00096 /*
00097  * Fills the argument with the value found in line.
00098  */
00099 static char *getValue(const char *line, char *value, size_t size)
00100 {
00101     while (*line++ != '=')
00102         ;
00103     while (isspace(*line))
00104         ++line;
00105     int i = 0;
00106     while (*line && size)
00107     {
00108         value[i++] = *line++;
00109         --size;
00110     }
00111     size ? (value[i] = '\0') : (value[i-1] = '\0');
00112     return value;
00113 }
00114 
00122 static int findKey(KFile *fd, const char *key, char *line, size_t size)
00123 {
00124     int err;
00125     do
00126     {
00127         err = kfile_gets(fd, line, size);
00128         char curr_key[30];
00129         getKey(line, curr_key, 30);
00130         /* check key */
00131         if (!strcmp(curr_key, key))
00132             return 0;
00133     }
00134     while (err != EOF && *line != '[');
00135     return EOF;
00136 }
00137 
00138 /*
00139  * On errors, the function returns EOF and fills the buffer with the default value.
00140  */
00141 int ini_getString(KFile *fd, const char *section, const char *key, const char *default_value, char *buf, size_t size)
00142 {
00143     char line[CONFIG_INI_MAX_LINE_LEN];
00144 
00145     if (kfile_seek(fd, 0, KSM_SEEK_SET) == EOF)
00146         goto error;
00147 
00148     if (findSection(fd, section, strlen(section), line, CONFIG_INI_MAX_LINE_LEN) == EOF)
00149         goto error;
00150 
00151     if (findKey(fd, key, line, CONFIG_INI_MAX_LINE_LEN) == EOF)
00152         goto error;
00153     else
00154         getValue(line, buf, size);
00155     return 0;
00156 
00157 error:
00158     strncpy(buf, default_value, size);
00159     if (size > 0)
00160         buf[size - 1] = '\0';
00161     return EOF;
00162 }