libConfiguration.h

Go to the documentation of this file.
00001 #ifndef __LIBCONFIGURATION_H__
00002 #define __LIBCONFIGURATION_H__
00003 
00004 #include "HashTable.h"
00005 #include "String.h"
00006 
00007 class Configuration
00008 {
00009   static String g_sfl;
00010   static bool g_bRead;
00011   static HashSS g_h;
00012 
00013 private:
00014   static bool IsWhitespace(char ch)
00015   {
00016     return ch == ' ' || ch == '\n' || ch == '\r' || ch == '\t';
00017   }
00018 
00019   static void ReadConfigFile()
00020   {
00021     UD("READING CONFIGURATION FILE: %s", g_sfl.V());
00022     g_bRead = true;
00023 
00024     FILE *pfl = fopen(g_sfl, "r");
00025     char s[4096];
00026     while (fgets(s, sizeof(s) - 1, pfl) != NULL)
00027       {
00028       // trim off trailing whitespace
00029       int nch = strlen(s) - 1;
00030       while (nch >= 0 && IsWhitespace(s[nch]))
00031         {
00032         nch--;
00033         }
00034       s[nch + 1] = 0;
00035 
00036       // split
00037       char sParam[4096];
00038       int cch;
00039       if (sscanf(s, " %4095s %n", sParam, &cch) == 1)
00040         {
00041         if (sParam[0] != '#')
00042           {
00043           String sKey = ConfigEvalString(sParam);
00044           String sVar = ConfigEvalString(&s[cch]);
00045           g_h.Set(sKey, sVar);
00046           }
00047         }
00048       }
00049     fclose(pfl);
00050   }
00051 
00052   static String ConfigEvalStringInternal(const char *&pch) __attribute__((noinline))
00053   {
00054     // TODO: consider speeding this up using strrchr to quickly jump through the string
00055     VectorOf<char> vecch;
00056     while (*pch != 0)
00057       {
00058       if (*pch == '{')
00059         {
00060         pch++;
00061         String sT = ConfigEvalStringInternal(pch);
00062         if (sT.V()[0] == '$')
00063           {
00064           sT = g_h.Get(String(&sT.V()[1]), "");
00065           }
00066         else if (sT.V()[0] == '+')
00067           {
00068           ASSERT(sT.V()[1] == '+'); // assume ++
00069           String sVal = g_h.Get(String(&sT.V()[2]), "");
00070           sVal = String(sVal.AsInt() + 1);
00071           g_h.Set(String(&sT.V()[2]), sVal);
00072           sT = sVal + "";
00073           }
00074         /*
00075          TODO: implement functionals
00076 
00077          else if (sT.V()[0]=='+'){
00078          vecs=ListFromString(String(&sT.V()[1]));
00079          Real r=0;
00080          for (int n=0; n<vecs.C(); n++){
00081          r=r+AsNumber(vecs[n]);
00082          }
00083          sT=String(r);
00084          }
00085          */
00086         vecch.Append(sT.V(), sT.C());
00087         }
00088       else if (*pch == '}')
00089         {
00090         vecch.Append('\0');
00091         return String(vecch.V());
00092         }
00093       else
00094         {
00095         vecch.Append(*pch);
00096         }
00097       pch++;
00098       }
00099     vecch.Append('\0');
00100     return String(vecch.V());
00101   }
00102 
00103   static String ConfigEvalString(const char *pch)
00104   {
00105     return ConfigEvalStringInternal(pch);
00106   }
00107 
00108 public:
00109   static String Describe()
00110   {
00111     if (!g_bRead)
00112       {
00113       ReadConfigFile();
00114       }
00115 
00116     String s;
00117     String sKey;
00118     String sVal;
00119 
00120     forhash(sKey,sVal,g_h)
00121       {
00122       s+=_LINE + StringF("%60s",sKey.V()) + " := " + sVal + LINE_;
00123       }
00124 
00125     return s;
00126   }
00127 
00128   static void SetConfigFile(String sfl)
00129   {
00130     g_sfl = sfl;
00131     g_bRead = false;
00132   }
00133 
00134   static String GetConfigFile()
00135   {
00136     return g_sfl;
00137   }
00138 
00139   static const char* ConfigValue(const char *s, const char* sDefault)
00140   {
00141     if (!g_bRead)
00142       {
00143       ReadConfigFile();
00144       }
00145 
00146     String sOut;
00147 
00148     if (g_h.GetInto(s, &sOut))
00149       {
00150       return sOut;
00151       }
00152     return sDefault;
00153   }
00154 
00155   static Real ConfigValue(const char *s, const double& rDefault)
00156   {
00157     if (!g_bRead)
00158       {
00159       ReadConfigFile();
00160       }
00161 
00162     String sOut;
00163 
00164     if (g_h.GetInto(s, &sOut))
00165       {
00166       return sOut.AsReal();
00167       }
00168     return rDefault;
00169   }
00170 
00171   static Real ConfigValue(const char *s, const float& rDefault)
00172   {
00173     if (!g_bRead)
00174       {
00175       ReadConfigFile();
00176       }
00177 
00178     String sOut;
00179 
00180     if (g_h.GetInto(s, &sOut))
00181       {
00182       return sOut.AsReal();
00183       }
00184     return rDefault;
00185   }
00186 
00187   static int ConfigValue(const char *s, const int& zDefault)
00188   {
00189     if (!g_bRead)
00190       {
00191       ReadConfigFile();
00192       }
00193 
00194     String sOut;
00195 
00196     if (g_h.GetInto(s, &sOut))
00197       {
00198       return sOut.AsInt();
00199       }
00200     return zDefault;
00201   }
00202 
00203   static bool ConfigValue(const char *s, const bool& bDefault)
00204   {
00205     if (!g_bRead)
00206       {
00207       ReadConfigFile();
00208       }
00209 
00210     String sOut;
00211 
00212     if (g_h.GetInto(s, &sOut))
00213       {
00214       return sOut == "true" || sOut == "yes";
00215       }
00216     return bDefault;
00217   }
00218 };
00219 
00220 inline void SetConfigFile(String sfl)
00221 {
00222   Configuration::SetConfigFile(sfl);
00223 }
00224 
00225 inline String GetConfigFile()
00226 {
00227   return Configuration::GetConfigFile();
00228 }
00229 
00230 inline String DescribeConfiguration()
00231 {
00232   return Configuration::Describe();
00233 }
00234 
00235 inline const char* ConfigValue(const char *s, const char* tDefault)
00236 {
00237   return Configuration::ConfigValue(s, tDefault);
00238 }
00239 template<class T>
00240 inline T ConfigValue(const char *s, const T& tDefault)
00241 {
00242   return Configuration::ConfigValue(s, tDefault);
00243 }
00244 
00245 #endif //__LIBCONFIGURATION_H__

Generated on 6 Apr 2011 for Slicer3 by  doxygen 1.6.1