00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026
00027
00028
00029
00030
00031
00032
00033
00034
00035
00036
00037
00038
00039
00040
00041
00042
00043
00044
00045
00046 #include <new>
00047
00048 #include "Configuration.h"
00049
00050 #include <stdio.h>
00051 #include <stdlib.h>
00052 #include <string.h>
00053
00054
00055
00056
00057
00058
00059
00060 CConfiguration::CConfiguration()
00061 {
00062 m_pchFileName = 0;
00063 m_nFileLength = 0;
00064
00065 m_ppVariables = 0;
00066 m_nVariableCount = 0;
00067 }
00068
00069 CConfiguration::CConfiguration(const char* pchFileName)
00070 {
00071 m_pchFileName = 0;
00072 m_nFileLength = 0;
00073
00074 m_ppVariables = 0;
00075 m_nVariableCount = 0;
00076
00077 SetFileName(pchFileName);
00078 }
00079
00080 CConfiguration::~CConfiguration()
00081 {
00082 if (m_pchFileName)
00083 delete [] m_pchFileName;
00084
00085 for(int v = 0 ; v < m_nVariableCount; v++)
00086 {
00087 delete [] m_ppVariables[v]->szName;
00088 delete [] m_ppVariables[v]->szValue;
00089
00090 delete m_ppVariables[v];
00091 }
00092
00093 delete m_ppVariables;
00094 }
00095
00096
00097
00098
00099
00100
00101 bool CConfiguration::Read(const char* pchFileName)
00102 {
00103 SetFileName(pchFileName);
00104
00105 return Read();
00106 }
00107
00108 bool CConfiguration::Read()
00109 {
00110 bool bResult;
00111
00112
00113 FILE* pCfgFile = fopen(m_pchFileName,"r");
00114 if (!pCfgFile)
00115 {
00116 printf("error: could not open config file '%s'\n",m_pchFileName);
00117 return false;
00118 }
00119
00120
00121 fseek(pCfgFile , 0 , SEEK_END);
00122 m_nFileLength = ftell(pCfgFile);
00123 rewind(pCfgFile);
00124
00125
00126 char *pchBuffer = new char[m_nFileLength];
00127 if (!pchBuffer)
00128 {
00129 printf("error: out of memory\n");
00130 fclose(pCfgFile);
00131 return false;
00132 }
00133
00134
00135 if (fread(pchBuffer, 1, m_nFileLength,pCfgFile) != m_nFileLength)
00136 {
00137 fclose(pCfgFile);
00138 return false;
00139 }
00140
00141
00142 fclose(pCfgFile);
00143
00144
00145 bResult = ParseBuffer(pchBuffer);
00146
00147
00148 delete [] pchBuffer;
00149
00150 return bResult;
00151
00152 }
00153
00154
00155 void CConfiguration::SetFileName(const char* pchFileName)
00156 {
00157 if (m_pchFileName)
00158 delete [] m_pchFileName;
00159
00160 m_pchFileName = new char[strlen(pchFileName) + 1];
00161 strcpy(m_pchFileName, pchFileName);
00162 }
00163
00164
00165 bool CConfiguration::GetString(char* szName, char*& szReturnString )
00166 {
00167 bool bResult = false;
00168 char* szString;
00169
00170 bResult = GetVarByName( szName, szString );
00171
00172 if(bResult)
00173 szReturnString = szString;
00174
00175 return bResult;
00176 }
00177
00178 bool CConfiguration::GetInt(char* szName, int& nReturnInt )
00179 {
00180 bool bResult = false;
00181 char* szInteger;
00182
00183 bResult = GetVarByName( szName, szInteger );
00184
00185 if(bResult) nReturnInt = atoi(szInteger);
00186
00187 return bResult;
00188 }
00189
00190 bool CConfiguration::GetFloat(char* szName, float& fReturnFloat )
00191 {
00192 bool bResult = false;
00193 char* szFloat;
00194
00195 bResult = GetVarByName( szName, szFloat );
00196 if (bResult) fReturnFloat = (float)atof(szFloat);
00197
00198 return bResult;
00199 }
00200
00201 bool CConfiguration::GetDouble(char* szName, double& dReturnDouble )
00202 {
00203 bool bResult = false;
00204 char* szDouble;
00205
00206 bResult = GetVarByName( szName, szDouble );
00207 if(bResult) dReturnDouble = atof(szDouble);
00208
00209 return bResult;
00210 }
00211
00212 bool CConfiguration::GetBool(char* szName, bool& bReturnBool )
00213 {
00214 char szOn[] = "on";
00215 char szTrue[] = "true";
00216
00217 bool bResult = false;
00218 char* szBool;
00219
00220 bResult = GetVarByName( szName, szBool );
00221
00222 if(bResult)
00223 {
00224 if(strcmp(szBool,szOn) == 0 ||
00225 strcmp(szBool,szTrue) == 0)
00226 {
00227 bReturnBool = true;
00228 } else {
00229 bReturnBool = false;
00230
00231 }
00232 }
00233 return bResult;
00234 }
00235
00236
00237 bool CConfiguration::ParseBuffer(char* pchBuffer)
00238 {
00239
00240 bool fExit = false;
00241 bool fError = false;
00242 int cnBufferPosition = 0;
00243 char* pchCurrentName = NULL;
00244 char* pchCurrentValue = NULL;
00245
00246 while(!fExit)
00247 {
00248
00249 do
00250 {
00251 fExit = !SeekNextContent(pchBuffer,cnBufferPosition);
00252 if(fExit) break;
00253 } while(CheckControlCharacter(pchBuffer,cnBufferPosition));
00254
00255
00256 fError = !ExtractName(pchBuffer,cnBufferPosition, pchCurrentName);
00257 if(fError)
00258 {
00259 printf("error: could not extract variable name in line %d\n", GetLineNumber(pchBuffer, cnBufferPosition));
00260 return false;
00261 }
00262
00263
00264 fExit = !SeekNextContent(pchBuffer,cnBufferPosition);
00265
00266
00267 fError = !ExtractValue(pchBuffer,cnBufferPosition, pchCurrentValue);
00268 if (fError)
00269 {
00270 printf("error: could not extract value of variable '%s' in line %d\n", pchCurrentName, GetLineNumber(pchBuffer,cnBufferPosition));
00271 return false;
00272 }
00273
00274
00275 AddVariable(pchCurrentName,pchCurrentValue);
00276
00277 }
00278
00279 return true;
00280 }
00281
00282 bool CConfiguration::CheckControlCharacter(char* pchBuffer, int& cnBufferPosition)
00283 {
00284 switch(pchBuffer[cnBufferPosition])
00285 {
00286 case '#':
00287 while(cnBufferPosition < m_nFileLength && pchBuffer[cnBufferPosition] != '\n')
00288 cnBufferPosition++;
00289 return true;
00290
00291 case '@':
00292 while (cnBufferPosition < m_nFileLength && pchBuffer[cnBufferPosition] != '\n')
00293 printf("%c", pchBuffer[cnBufferPosition++]);
00294 printf("\n");
00295 return true;
00296
00297 default:
00298 break;
00299 }
00300
00301 return false;
00302 }
00303
00304 bool CConfiguration::SeekNextContent(char* pchBuffer,int& cnBufferPosition)
00305 {
00306 while( cnBufferPosition < m_nFileLength &&
00307 ( pchBuffer[cnBufferPosition] == ' ' ||
00308 pchBuffer[cnBufferPosition] == '\t' ||
00309 pchBuffer[cnBufferPosition] == '\r' ||
00310 pchBuffer[cnBufferPosition] == '\n' ||
00311 pchBuffer[cnBufferPosition] == '\x27'
00312 )
00313 )
00314 cnBufferPosition++;
00315
00316 return cnBufferPosition != m_nFileLength;
00317 }
00318
00319 bool CConfiguration::ExtractName(char* pchBuffer, int& cnBufferPosition, char*& pchResultName)
00320 {
00321 int nNameStart = cnBufferPosition;
00322
00323 while( cnBufferPosition < m_nFileLength &&
00324 ( pchBuffer[cnBufferPosition] != ' ' &&
00325 pchBuffer[cnBufferPosition] != '\t' &&
00326 pchBuffer[cnBufferPosition] != '\r' &&
00327 pchBuffer[cnBufferPosition] != '\n' &&
00328 pchBuffer[cnBufferPosition] != '\x27'
00329 )
00330 )
00331 cnBufferPosition++;
00332
00333 int nNameEnd = cnBufferPosition;
00334
00335
00336 pchResultName = new char[nNameEnd - nNameStart + 1];
00337 strncpy(pchResultName, pchBuffer + nNameStart, nNameEnd - nNameStart);
00338 pchResultName[nNameEnd - nNameStart] = '\0';
00339
00340 return true;
00341 }
00342
00343 bool CConfiguration::ExtractValue(char* pchBuffer, int& cnBufferPosition, char*& pchResultValue)
00344 {
00345 int nValueStart = cnBufferPosition;
00346 bool fStringMode = false;
00347
00348 while (cnBufferPosition < m_nFileLength &&
00349 ( (pchBuffer[cnBufferPosition] != ' ' || fStringMode) &&
00350 (pchBuffer[cnBufferPosition] != '\t' || fStringMode) &&
00351 pchBuffer[cnBufferPosition] != '\r' &&
00352 pchBuffer[cnBufferPosition] != '\n' &&
00353 pchBuffer[cnBufferPosition] != '\x27' &&
00354 !(pchBuffer[cnBufferPosition] == '\"' && fStringMode)
00355 )
00356 )
00357 {
00358 if (pchBuffer[cnBufferPosition] == '\"')
00359 fStringMode = true;
00360
00361 cnBufferPosition++;
00362 }
00363
00364 int nValueEnd = cnBufferPosition;
00365 int nAdjust = 0;
00366
00367
00368 if (fStringMode)
00369 {
00370 nAdjust = 1;
00371 cnBufferPosition++;
00372 }
00373
00374
00375 pchResultValue = new char[nValueEnd - nValueStart + 1 - nAdjust];
00376 strncpy(pchResultValue, pchBuffer + nValueStart + nAdjust, nValueEnd - nValueStart - nAdjust);
00377 pchResultValue[nValueEnd - nValueStart - nAdjust] = '\0';
00378
00379 return true;
00380 }
00381
00382 void CConfiguration::AddVariable(char* pchCurrentName, char* pchCurrentValue)
00383 {
00384 if (pchCurrentName[0] == '\0' || pchCurrentValue[0] == '\0')
00385 {
00386 delete [] pchCurrentName;
00387 delete [] pchCurrentValue;
00388 return;
00389 }
00390
00391 m_nVariableCount++;
00392
00393
00394 TVariableMap **ppNewMap = new TVariableMap*[m_nVariableCount];
00395
00396
00397 if (m_ppVariables)
00398 {
00399 for (int v = 0 ; v < (m_nVariableCount - 1) ; v++)
00400 ppNewMap[v] = m_ppVariables[v];
00401
00402
00403 delete [] m_ppVariables;
00404 }
00405
00406
00407 TVariableMap *pVariable = new TVariableMap();
00408
00409 pVariable->szName = pchCurrentName;
00410 pVariable->szValue = pchCurrentValue;
00411 ppNewMap[m_nVariableCount - 1] = pVariable;
00412
00413
00414 m_ppVariables = ppNewMap;
00415 }
00416
00417 int CConfiguration::GetLineNumber(char* pchBuffer, int cnBufferPosition)
00418 {
00419 int nLines = 0;
00420
00421 for (int pos = 0 ; pos < cnBufferPosition ; pos++)
00422 {
00423 if (pchBuffer[pos] == '\r')
00424 {
00425 pos++;
00426 nLines++;
00427 }
00428 else if (pchBuffer[pos] == '\n')
00429 {
00430 nLines++;
00431 }
00432 }
00433
00434 return nLines+1;
00435 }
00436
00437 bool CConfiguration::GetVarByName(char* szName, char*& szReturnString)
00438 {
00439 for (int v = 0 ; v < m_nVariableCount ; v++)
00440 {
00441 if (strcmp(szName,m_ppVariables[v]->szName) == 0)
00442 {
00443 szReturnString = m_ppVariables[v]->szValue;
00444 return true;
00445 }
00446 }
00447
00448 return false;
00449 }