most functionality to splashdwon, find neutral and start mission. short timeouts still in code for testing, will adjust to go directly to sit_idle after splashdown

Dependencies:   mbed MODSERIAL FATFileSystem

Embed: (wiki syntax)

« Back to documentation index

Show/hide line numbers ConfigFile.cpp Source File

ConfigFile.cpp

00001 /**
00002  * Configuration file interface class (Version 0.0.1)
00003  *
00004  * Copyright (C) 2010 Shinichiro Nakamura (CuBeatSystems)
00005  * http://shinta.main.jp/
00006  */
00007 #include "ConfigFile.h"
00008 
00009 #define NEWLINE_UNIX "\n"
00010 #define NEWLINE_DOS "\r\n"
00011 #define NEWLINE_MAC "\r"
00012 
00013 /**
00014  * Create a configuration file class.
00015  */
00016 ConfigFile::ConfigFile() {
00017     /*
00018      * Allocation for a config_t list.
00019      */
00020     configlist = (config_t **)malloc(sizeof(config_t *) * MAXCONFIG);
00021     for (int i = 0; i < MAXCONFIG; i++) {
00022         configlist[i] = NULL;
00023     }
00024 }
00025 
00026 /**
00027  * Destroy a configuration file class.
00028  */
00029 ConfigFile::~ConfigFile() {
00030     /*
00031      * Remove all storage and the contents.
00032      */
00033     for (int i = 0; i < MAXCONFIG; i++) {
00034         config_t *cfg = configlist[i];
00035         if (cfg != NULL) {
00036             free(cfg->key);
00037             free(cfg->value);
00038             free(cfg);
00039         }
00040         configlist[i] = NULL;
00041     }
00042 
00043     /*
00044      * Remove cnofig_t list.
00045      */
00046     free(configlist);
00047     configlist = NULL;
00048 }
00049 
00050 /**
00051  * Get a value for a key.
00052  *
00053  * @param key A target key name.
00054  * @param value A pointer to a value storage.
00055  * @param siz A size of a value storage.
00056  * @return A value or NULL.
00057  */
00058 bool ConfigFile::getValue(char *key, char *value, size_t siz) {
00059     /*
00060      * Null check.
00061      */
00062     if (key == NULL) {
00063         return false;
00064     }
00065 
00066     /*
00067      * Search a config_t object from the key.
00068      */
00069     config_t *p = search(key);
00070     if (p == NULL) {
00071         return false;
00072     }
00073 
00074     /*
00075      * Check the storage size.
00076      */
00077     if (siz <= strlen(p->value)) {
00078         return false;
00079     }
00080 
00081     /*
00082      * Copy the value to the storage.
00083      */
00084     strcpy(value, p->value);
00085     return true;
00086 }
00087 
00088 /**
00089  * Set a set of a key and value.
00090  *
00091  * @param key A key.
00092  * @param value A value.
00093  *
00094  * @return True if it succeed.
00095  */
00096 bool ConfigFile::setValue(char *key, char *value) {
00097     /*
00098      * Null check.
00099      */
00100     if ((key == NULL) || (value == NULL)) {
00101         return false;
00102     }
00103 
00104     /*
00105      * Size check.
00106      */
00107     if ((MAXLEN_KEY < strlen(key)) || (MAXLEN_VALUE < strlen(value))) {
00108         return false;
00109     }
00110 
00111     /*
00112      * Search a config_t object from the key.
00113      */
00114     config_t *p = search(key);
00115     if (p == NULL) {
00116         /*
00117          * Allocation a memory for a new key.
00118          */
00119         char *k = (char *)malloc(sizeof(char) * (strlen(key) + 1));
00120         if (k == NULL) {
00121             return false;
00122         }
00123         strcpy(k, key);
00124 
00125         /*
00126          * Allocation a memory for a new value.
00127          */
00128         char *v = (char *)malloc(sizeof(char) * (strlen(value) + 1));
00129         if (v == NULL) {
00130             free(k);
00131             return false;
00132         }
00133         strcpy(v, value);
00134 
00135         /*
00136          * Allocation a memory for a new configuration.
00137          */
00138         config_t *cfg = (config_t *)malloc(sizeof(config_t) * 1);
00139         if (cfg == NULL) {
00140             free(k);
00141             free(v);
00142             return false;
00143         }
00144         cfg->key = k;
00145         cfg->value = v;
00146 
00147         /*
00148          * Add the new configuration.
00149          */
00150         if (!add(cfg)) {
00151             free(k);
00152             free(v);
00153             free(cfg);
00154             return false;
00155         }
00156 
00157         return true;
00158     } else {
00159         /*
00160          * The value is same.
00161          */
00162         if (strcmp(value, p->value) == 0) {
00163             return true;
00164         }
00165 
00166         /*
00167          * Free a memory for the value.
00168          */
00169         free(p->value);
00170         p->value = NULL;
00171 
00172         /*
00173          * Allocation memory for the new value.
00174          */
00175         char *v = (char *)malloc(sizeof(char) * (strlen(value) + 1));
00176         if (v == NULL) {
00177             return false;
00178         }
00179 
00180         /*
00181          * Store it.
00182          */
00183         strcpy(v, value);
00184         p->value = v;
00185 
00186         return true;
00187     }
00188 }
00189 
00190 /**
00191  * Remove a config.
00192  *
00193  * @param key A key.
00194  *
00195  * @return True if it succeed.
00196  */
00197 bool ConfigFile::remove(char *key) {
00198     if (key == NULL) {
00199         return false;
00200     }
00201     for (int i = 0; i < MAXCONFIG; i++) {
00202         config_t *cfg = configlist[i];
00203         if (cfg != NULL) {
00204             if (strcmp(cfg->key, key) == 0) {
00205                 free(cfg->key);
00206                 free(cfg->value);
00207                 free(cfg);
00208                 configlist[i] = NULL;
00209                 return true;
00210             }
00211         }
00212     }
00213     return false;
00214 }
00215 
00216 /**
00217  * Remove all config.
00218  *
00219  * @return True if it succeed.
00220  */
00221 bool ConfigFile::removeAll(void) {
00222     for (int i = 0; i < MAXCONFIG; i++) {
00223         config_t *p = configlist[i];
00224         if (p != NULL) {
00225             free(p->key);
00226             free(p->value);
00227         }
00228         free(p);
00229         configlist[i] = NULL;
00230     }
00231     return true;
00232 }
00233 
00234 /**
00235  * Get a number of configuration sets.
00236  *
00237  * @return number of configuration sets.
00238  */
00239 int ConfigFile::getCount() {
00240     int cnt = 0;
00241     for (int i = 0; i < MAXCONFIG; i++) {
00242         config_t *p = configlist[i];
00243         if (p != NULL) {
00244             cnt++;
00245         }
00246     }
00247     return cnt;
00248 }
00249 
00250 /**
00251  * Get a key and a value.
00252  *
00253  * @param index Index number of this list.
00254  * @param key A pointer to a buffer for key.
00255  * @param keybufsiz A size of the key buffer.
00256  * @param value A pointer to a buffer for value.
00257  * @param valuebufsiz A size of the value buffer.
00258  *
00259  * @return true if it succeed.
00260  */
00261 bool ConfigFile::getKeyAndValue(int index, char *key, size_t keybufsiz, char *value, size_t valuebufsiz) {
00262     int cnt = 0;
00263     for (int i = 0; i < MAXCONFIG; i++) {
00264         config_t *p = configlist[i];
00265         if (p != NULL) {
00266             if (cnt == index) {
00267                 if ((strlen(p->key) < keybufsiz) && (strlen(p->value) < valuebufsiz)) {
00268                     strcpy(key, p->key);
00269                     strcpy(value, p->value);
00270                     return true;
00271                 }
00272                 return false;
00273             }
00274             cnt++;
00275         }
00276     }
00277     return false;
00278 }
00279 
00280 /**
00281  * Read from the target file.
00282  *
00283  * @param file A target file name.
00284  */
00285 bool ConfigFile::read(char *file) {
00286     /*
00287      * Open the target file.
00288      */
00289     FILE *fp = fopen(file, "r");
00290     if (fp == NULL) {
00291         return false;
00292     }
00293 
00294     /*
00295      * Remove all configuration.
00296      */
00297     removeAll();
00298 
00299     /*
00300      * Read from a file.
00301      */
00302     char buf[MAXLEN_KEY + 8 + MAXLEN_VALUE];
00303     while (fgets(buf, sizeof(buf), fp) != NULL) {
00304         /*
00305          * Ignore a comment.
00306          */
00307         if (buf[0] == '#') {
00308             continue;
00309         }
00310 
00311         /*
00312          * Trim a return.
00313          */
00314         const size_t len = strlen(buf);
00315         for (int i = 0; i < len; i++) {
00316             if ((buf[i] == '\r') || (buf[i] == '\n')) {
00317                 buf[i] = '\0';
00318             }
00319         }
00320 
00321         /*
00322          * Separate key and value.
00323          */
00324         char k[MAXLEN_KEY];
00325         char v[MAXLEN_VALUE];
00326         char *sp = strchr(buf, SEPARATOR);
00327         if (sp != NULL) {
00328             strcpy(v, sp + 1);
00329             *sp = '\0';
00330             strcpy(k, buf);
00331             setValue(k, v);
00332         }
00333     }
00334     fclose(fp);
00335     return true;
00336 }
00337 
00338 /**
00339  * Write from the target file.
00340  *
00341  * @param file A pointer to a file name.
00342  * @param header A pointer to a header.
00343  * @param ff File format.
00344  */
00345 bool ConfigFile::write(char *file, char *header, FileFormat ff) {
00346     /*
00347      * Open the target file.
00348      */
00349     FILE *fp = fopen(file, "w");
00350     if (fp == NULL) {
00351         return false;
00352     }
00353 
00354     /*
00355      * Set a type of new line.
00356      */
00357     char *newline = NEWLINE_UNIX;
00358     switch (ff) {
00359         case UNIX:
00360             newline = NEWLINE_UNIX;
00361             break;
00362         case MAC:
00363             newline = NEWLINE_MAC;
00364             break;
00365         case DOS:
00366             newline = NEWLINE_DOS;
00367             break;
00368         default:
00369             newline = NEWLINE_UNIX;
00370             break;
00371     }
00372 
00373     /*
00374      * Write the header.
00375      */
00376     if (header != NULL) {
00377         fprintf(fp, "%s%s", header, newline);
00378     }
00379 
00380     /*
00381      * Write the data.
00382      */
00383     for (int i = 0; i < MAXCONFIG; i++) {
00384         config_t *cfg = configlist[i];
00385         if (cfg != NULL) {
00386             fprintf(fp, "%s=%s%s", cfg->key, cfg->value, newline);
00387         }
00388     }
00389     fclose(fp);
00390     return true;
00391 }
00392 
00393 ConfigFile::config_t *ConfigFile::search(char *key) {
00394     if (key == NULL) {
00395         return NULL;
00396     }
00397     for (int i = 0; i < MAXCONFIG; i++) {
00398         if (configlist[i] != NULL) {
00399             if (strcmp(configlist[i]->key, key) == 0) {
00400                 return configlist[i];
00401             }
00402         }
00403     }
00404     return NULL;
00405 }
00406 
00407 bool ConfigFile::add(config_t *cfg) {
00408     for (int i = 0; i < MAXCONFIG; i++) {
00409         if (configlist[i] == NULL) {
00410             configlist[i] = cfg;
00411             return true;
00412         }
00413     }
00414     return false;
00415 }