A simple .ini file interface.
Dependents: Smart-WiFly-WebServer SignalGenerator WattEye X10Svr
Diff: IniManager.cpp
- Revision:
- 18:282ed56d983b
- Parent:
- 15:3fc2b87a234d
- Parent:
- 17:01c0ee144433
- Child:
- 20:392d1ec637eb
--- a/IniManager.cpp Sun Dec 11 14:05:17 2016 +0000 +++ b/IniManager.cpp Wed Dec 28 00:21:01 2016 +0000 @@ -31,10 +31,24 @@ #define INFO(x, ...) #endif -INI::INI(const char * file) +// 2 versions, to translate new return values to old format +// return RetXLate[new value][version] +INI::INI_Return RetXLate[INI::INI_INTERNAL_ERROR+1][2] = { +// Ver1, Ver2 return values. + INI::INI_V1_SUCCESS, INI::INI_SUCCESS, /// Success - operation succeeded + INI::INI_V1_FAIL, INI::INI_NO_FILE_SPEC, /// Fail - no file was specified + INI::INI_V1_FAIL, INI::INI_FILE_NOT_FOUND, /// Fail - ini file not found, or failed to open + INI::INI_V1_FAIL, INI::INI_SECTION_NOT_FOUND, /// Fail - section not found + INI::INI_V1_FAIL, INI::INI_KEY_NOT_FOUND, /// Fail - key not found + INI::INI_V1_FAIL, INI::INI_BUF_TOO_SMALL, /// Fail - buffer to small for value + INI::INI_V1_FAIL, INI::INI_INTERNAL_ERROR /// Fail - internal error - can't alloc buffers +}; + +INI::INI(const char * file, int Version) : iniFile(0) { SetFile(file); + version = (Version == 2) ? 1 : 0; // Version 1 or 2 is return value index 0 or 1 } @@ -161,9 +175,10 @@ } -bool INI::SetFile(const char * file) +bool INI::SetFile(const char * file, int Version) { - INFO("SetFile(%s)", file); + INFO("SetFile(%s,%d)", file, Version); + version = (Version == 2) ? 1 : 0; // Version 1 or 2 is return value index 0 or 1 if (file) { if (iniFile) swFree(iniFile); @@ -181,18 +196,22 @@ return false; } -bool INI::ReadString(const char * section, const char * key, char * buffer, size_t bufferSize, const char * defaultString) +INI::INI_Return INI::ReadString(const char * section, const char * key, char * buffer, size_t bufferSize, const char * defaultString) { + INI_Return retVal; bool found = false; + if (!iniFile) - return found; + return RetXLate[INI_NO_FILE_SPEC][version]; CleanUp(); INFO("ReadString from %s", iniFile); FILE * fp = fopen(iniFile,"rt"); - if (fp) { + if (!fp) { + return RetXLate[INI_FILE_NOT_FOUND][version]; + } else { char buf[INTERNAL_BUF_SIZE]; bool inSection = (section == NULL) ? true : false; - + retVal = RetXLate[INI_SECTION_NOT_FOUND][version]; // assume we won't find the section, until we do. while(fgets(buf, sizeof(buf), fp)) { int x = strlen(buf) - 1; // remove trailing \r\n combinations while (x >= 0 && buf[x] < ' ') @@ -205,21 +224,32 @@ char * eq = strchr(buf, '='); if (eq) { *eq++ = '\0'; - if ( (strcmp(buf,key) == 0) && (strlen(eq) <= bufferSize) ) { - strcpy(buffer, eq); - memset(buf, 0, INTERNAL_BUF_SIZE); // secure the memory space - found = true; + if (strcmp(buf,key) == 0) { // Found the key of interest + if (strlen(eq) < bufferSize) { + strcpy(buffer, eq); + memset(buf, 0, INTERNAL_BUF_SIZE); // secure the memory space + found = true; + retVal = RetXLate[INI_SUCCESS][version]; + } else { + retVal = RetXLate[INI_BUF_TOO_SMALL][version]; + } break; } } } else { if (buf[0] == '[') { char * br = strchr(buf, ']'); - inSection = false; - if (br) { - *br = '\0'; - if (strcmp(buf+1, section) == 0) - inSection = true; + if (inSection) { // we were in the section of interest and just hit the next section... + break; + } else { + inSection = false; + if (br) { + *br = '\0'; + if (strcmp(buf+1, section) == 0) { + inSection = true; + retVal = RetXLate[INI_KEY_NOT_FOUND][version]; // assume we won't find the key, until we do + } + } } } } @@ -227,14 +257,17 @@ fclose(fp); } if (!found && defaultString != NULL && *defaultString) { - strncpy(buffer, defaultString, bufferSize); - buffer[bufferSize-1] = '\0'; - INFO(" sub %s.", buffer); - found = true; + if (strlen(defaultString) < bufferSize) { + strcpy(buffer, defaultString); + retVal = RetXLate[INI_SUCCESS][version]; + } else { + retVal = RetXLate[INI_BUF_TOO_SMALL][version]; + } } - return found; + return retVal; } + long int INI::ReadLongInt(const char * section, const char * key, long int defaultValue) { char localBuf[16]; @@ -282,28 +315,42 @@ // once complete, if something actually changed, then rename the .ini to .bak and rename the .new to .ini // once complete, if nothing actually changed, then delete the .new // -bool INI::WriteString(const char * section, const char * key, const char * value) +INI::INI_Return INI::WriteString(const char * section, const char * key, const char * value, int len) { bool found = false; bool fileChanged = false; - + INI_Return retVal; + + if (len == -1) + len = strlen(value); INFO("WriteString(%s,%s,%s)", section, key, value); - if (!iniFile || (value != NULL && strlen(value) > INTERNAL_BUF_SIZE)) - return found; + if (!iniFile) + return RetXLate[INI_NO_FILE_SPEC][version]; + + if (strlen(value) > INTERNAL_BUF_SIZE) + return RetXLate[INI_INTERNAL_ERROR][version]; char * newFile = (char *)swMalloc(strlen(iniFile)+1); + if (!newFile) + return RetXLate[INI_INTERNAL_ERROR][version]; // no memory char * bakFile = (char *)swMalloc(strlen(iniFile)+1); - if (!newFile) - return found; // no memory if (!bakFile) { swFree(newFile); - return found; + return RetXLate[INI_INTERNAL_ERROR][version]; } + char * valBuf = (char *)swMalloc(len+1); + if (!valBuf) { + swFree(bakFile); + swFree(newFile); + return RetXLate[INI_INTERNAL_ERROR][version]; + } + strcpy(bakFile, iniFile); strcpy(newFile, iniFile); strcpy(bakFile + strlen(bakFile) - 4, ".bak"); strcpy(newFile + strlen(newFile) - 4, ".new"); - + strncpy(valBuf, value, len); + valBuf[len] = '\0'; CleanUp(); INFO(" Opening [%s] and [%s]", iniFile, newFile); @@ -328,20 +375,22 @@ if (eq) { *eq++ = '\0'; if (strcmp(buf,key) == 0) { - if (value != NULL && strcmp(eq, value) != 0) { + // delete, or replace the old record + if (valBuf != NULL && strcmp(eq, valBuf) != 0) { // replace the old record - if (value != NULL) { - fprintf(fo, "%s=%s\n", key, value); - printf("write: %s=%s\r\n", key, value); - INFO(" write: %s=%s", key, value); + if (valBuf != NULL) { + fprintf(fo, "%s=%s\r\n", key, valBuf); + printf("write: %s=%s\r\n", key, valBuf); + INFO(" write: %s=%s", key, valBuf); } } + retVal = RetXLate[INI_SUCCESS][version]; fileChanged = true; inSection = false; found = true; } else { // write old record - fprintf(fo, "%s=%s\n", buf, eq); + fprintf(fo, "%s=%s\r\n", buf, eq); INFO(" write: %s=%s", buf, eq); } } else { @@ -353,12 +402,13 @@ char * br = strchr(buf, ']'); if (inSection) { // found next section while in good section // Append new record to desired section - if (value != NULL) { - fprintf(fo, "%s=%s\r\n", key, value); - INFO(" write: %s=%s", key, value); + if (valBuf != NULL) { + fprintf(fo, "%s=%s\r\n", key, valBuf); + INFO(" write: %s=%s", key, valBuf); fileChanged = true; } found = true; + retVal = RetXLate[INI_SUCCESS][version]; } inSection = false; // write old record @@ -385,21 +435,23 @@ } if (!found) { // No old file, just create it now - if (value != NULL) { + if (valBuf != NULL) { if (!inSection) { - fprintf(fo, "[%s]\r\n", section); + fprintf(fo, "\r\n[%s]\r\n", section); INFO(" write: [%s]", section); } - fprintf(fo, "%s=%s\r\n", key, value); - INFO(" write: %s=%s", key, value); + fprintf(fo, "%s=%s\r\n", key, valBuf); + INFO(" write: %s=%s", key, valBuf); fileChanged = true; } found = true; + retVal = RetXLate[INI_SUCCESS][version]; } INFO(" close %s", newFile); fclose(fo); } else { ERR("*** Failed to open %s", newFile); + retVal = RetXLate[INI_FILE_NOT_FOUND][version]; } if (fileChanged) { INFO(" File changed: remove bak, rename ini to bak, rename new to ini"); @@ -416,9 +468,10 @@ #endif INFO(" d"); } + swFree(valBuf); swFree(newFile); swFree(bakFile); - return found; + return retVal; } @@ -480,6 +533,27 @@ } +const char * INI::GetReturnMessage(INI_Return retVal) { + if (version == 0) { + switch (retVal) { + default: + case INI_V1_FAIL: return "INI Fail"; + case INI_V1_SUCCESS: return "INI Success"; + } + } else { + switch (retVal) { + case INI_SUCCESS: return "INI Success - operation succeeded"; + case INI_NO_FILE_SPEC: return "INI Fail - no file was specified"; + case INI_FILE_NOT_FOUND: return "INI Fail - ini file not found, or failed to open"; + case INI_SECTION_NOT_FOUND: return "INI Fail - section not found"; + case INI_KEY_NOT_FOUND: return "INI Fail - key not found"; + case INI_BUF_TOO_SMALL: return "INI Fail - buffer to small for value"; + case INI_INTERNAL_ERROR: return "INI Fail - internal error - can't malloc"; + default: return "INI Fail - Code Unknown"; + } + } +} + #if 0 // Test code for basic regression testing // @@ -534,3 +608,4 @@ #endif +