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
+