00001
00002
00003
00004
00005
00011 #ifndef HSETTINGS_H
00012 #define HSETTINGS_H
00013
00014 #ifndef HBASE_H
00015 # error HBase.h must be included BEFORE HSettings.h
00016 #endif
00017
00018 #include "HFile.h"
00053 class HSettings : public HFile
00054 {
00055 typedef HFile base_class;
00056 static StringPtr ClassName(void) { return "HSettings"; }
00057
00058 typedef HMap<HString, HString> HSettingsMap;
00059
00060
00061
00062 protected:
00063 bool m_bDirty;
00064 HSettingsMap m_map;
00065
00066
00067
00068 public:
00069 HSettings(void) : m_bDirty(false)
00070 { }
00071 ~HSettings(void)
00072 { RemoveAll(); }
00073
00074
00075
00076 public:
00086 ErrCode
00087 Load(const HFilename & fs)
00088 {
00089 Text szLine[1024] = { 0x00 };
00090 ErrCode ec = HError::NoError();
00091
00092 if (!fs.IsValid())
00093 ec = HError::Set(ERR_BAD_PARAMETER, __FILE__, __LINE__);
00094 else if ((ec = Open(fs, O_RDONLY)) == NO_ERROR)
00095 {
00096 for (uint32 uLine = 1; ReadLine(szLine, 1023) >= 0; ++uLine)
00097 parseLine(uLine, szLine);
00098
00099
00100
00101
00102 m_bDirty = false;
00103 ec = Close();
00104 }
00105
00106 return ec;
00107 }
00113 ErrCode
00114 Remove(StringPtr pstrKey)
00115 {
00116 ErrCode ec = HError::NoError();
00117 HString strKey(pstrKey);
00118
00119 if (strKey.Trim().IsNotEmpty())
00120 ec = m_map.Remove(strKey.GetString());
00121 else
00122 ec = HError::Set(ERR_BAD_PARAMETER, __FILE__, __LINE__);
00123
00124 return ec;
00125 }
00134 ErrCode
00135 Save(const HFilename & fs)
00136 {
00137 ErrCode ec = HError::NoError();
00138
00139 if (!fs.IsValid())
00140 ec = HError::Set(ERR_BAD_PARAMETER, __FILE__, __LINE__);
00141 else if (!m_bDirty)
00142 {
00143 DEBUG_LOG("HSettings::Save(%s) => not dirty\n", fs.GetString());
00144 }
00145 else if ((ec = Open(fs, O_CREAT|O_WRONLY)) == NO_ERROR)
00146 {
00147 writeToFile();
00148 m_bDirty = false;
00149 ec = Close();
00150 }
00151
00152 return ec;
00153 }
00154
00155 protected:
00162 void
00163 parseLine(const uint32 uLine, TextPtr pszLine)
00164 {
00165 TextPtr psz,
00166 pszKey;
00167
00168 ASSERT_PTR(pszLine);
00169
00170 for (psz = pszLine; *psz; ++psz)
00171 if (!isspace(*psz))
00172 break;
00173
00174 if (STR_EMPTY(psz) || ispunct(*psz))
00175 return;
00176
00177 for (pszKey = psz; *psz != '='; ++psz)
00178 if (STR_EMPTY(psz))
00179 {
00180 DEBUG_LOG("HSettings::parseLine() => no '=' on line #%lu\n", uLine);
00181 return;
00182 }
00183
00184 *psz++ = '\0';
00185 if (STR_EMPTY(psz))
00186 {
00187 DEBUG_LOG("HSettings::parseLine() => no value on line #%lu\n", uLine);
00188 return;
00189 }
00190
00191 (void) setValue(pszKey, psz);
00192 }
00197 ErrCode
00198 writeToFile(void)
00199 {
00200 HString strLine;
00201 ErrCode ec = HError::NoError();
00202
00203 for (HSettingsMap::const_iterator it = m_map.begin(); it != m_map.end(); ++it)
00204 {
00205 ASSERT( it != NULL );
00206
00207 strLine = it->first + "=" + it->second;
00208 DEBUG_LOG("HSettings::writeToFile() => \"%s\"\n", strLine.GetString());
00209 WriteLine( strLine.GetString() );
00210 }
00211
00212 return ec;
00213 }
00214
00215
00216
00217 public:
00225 int32 Get(StringPtr pstrKey, int32 nDefault)
00226 {
00227 ASSERT_STR(pstrKey);
00228
00229 StringPtr pstrValue = getValue(pstrKey);
00230
00231 return STR_EMPTY(pstrValue) ?
00232 Set(pstrKey, nDefault) :
00233 STR_TO_INT(pstrValue);
00234 }
00242 StringPtr Get(StringPtr pstrKey, StringPtr pstrDefault)
00243 {
00244 ASSERT_STR(pstrKey);
00245 ASSERT_STR(pstrDefault);
00246
00247 StringPtr pstrValue = getValue(pstrKey);
00248
00249 return STR_EMPTY(pstrValue) ?
00250 Set(pstrKey, pstrDefault) :
00251 pstrValue;
00252 }
00267 bool GetFlag(StringPtr pstrKey, const bool bDefault)
00268 {
00269 ASSERT( STR_VALID(pstrKey) );
00270
00271 StringPtr pstrValue = getValue(pstrKey);
00272
00273 return STR_EMPTY(pstrValue) ?
00274 SetFlag(pstrKey, bDefault) :
00275 (STR_TO_INT(pstrValue) != 0 ||
00276 STR_ICMP(pstrValue, ".T.") == 0 ||
00277 STR_ICMP(pstrValue, "TRUE") == 0 ||
00278 STR_ICMP(pstrValue, "YES") == 0);
00279 }
00287 int32 Set(StringPtr pstrKey, const int32 nValue)
00288 {
00289 ASSERT_STR(pstrKey);
00290
00291 HStrTmp strTmp;
00292
00293 strTmp.Format("%ld", nValue);
00294 (void) setValue(pstrKey, StringPtr(strTmp));
00295 return nValue;
00296 }
00304 StringPtr Set(StringPtr pstrKey, StringPtr pstrValue)
00305 {
00306 ASSERT_STR(pstrKey);
00307 ASSERT_STR(pstrValue);
00308
00309 (void) setValue(pstrKey, pstrValue);
00310 return pstrValue;
00311 }
00321 bool SetFlag(StringPtr pstrKey, const bool bValue)
00322 {
00323 ASSERT_STR(pstrKey);
00324
00325 (void) setValue(pstrKey, (bValue ? "true" : "false"));
00326 return bValue;
00327 }
00328
00329 protected:
00336 StringPtr getValue(StringPtr pstrKey) const
00337 {
00338 HString strKey(pstrKey),
00339 strValue;
00340
00341 if (strKey.Trim().IsEmpty() ||
00342 m_map.Get(strKey, strValue) != NO_ERROR)
00343 {
00344 DEBUG_LOG( "HSettings::getValue(\"%s\") => NOT FOUND\n",
00345 strKey.GetString());
00346 }
00347 else
00348 {
00349 DEBUG_LOG( "HSettings::getValue(\"%s\") => \"%s\"\n",
00350 strKey.GetString(), strValue.GetString());
00351 }
00352
00353 return strValue.IsEmpty() ? NULL : strValue.GetString();
00354 }
00362 ErrCode setValue(StringPtr pstrKey, StringPtr pstrValue)
00363 {
00364 HString strKey(pstrKey),
00365 strValue(pstrValue);
00366 ErrCode ec = HError::NoError();
00367
00368 if (strKey.Trim().IsEmpty() || strValue.Trim().IsEmpty())
00369 ec = HError::Set(ERR_BAD_PARAMETER, __FILE__, __LINE__);
00370 else if ((ec = m_map.Set(strKey, strValue)) == NO_ERROR)
00371 {
00372 m_bDirty = true;
00373 DEBUG_LOG( "HSettings::setValue() => \"%s\" set to \"%s\"\n",
00374 pstrKey, pstrValue);
00375 }
00376
00377 return ec;
00378 }
00379
00380
00381
00382 public:
00385 inline bool IsEmpty(void) const
00386 { return m_map.IsEmpty(); }
00389 inline bool IsNotEmpty(void) const
00390 { return m_map.IsNotEmpty(); }
00393 inline ErrCode RemoveAll(void)
00394 { return m_map.RemoveAll(); }
00395 };
00396
00397 #endif // HSETTINGS_H
00398
00399
00400
00401
00402
00403
00404
00405
00406
00407
00408
00409
00410
00411
00412
00413
00414
00415
00416
00417
00418
00419
00420
00421
00422
00423
00424