Closed erdirectoor closed 5 years ago
I would also like functions to update a value in the ini-file, such as setIniValue(...). Makes it in an ESP8266 with Webinterface much easier to save configs :-)
No, its not possible. I've updated README.md with information about this.
I have written an Insert value function for the ini library. I hope this helps Ted
I am using the Adafruit_SPIFlash library (v2.02) and running on a Sparkfun Red Turbo board which has SPI flash on board. The underlying file system is FatFS. You may need to edit for other file systems.
An extract from my test application:
/* three tests on the ini file
1 Replace value of existing key
2 Add a key and value to an existing section
3 Add a key and value to a new section
1 and 2 will write then rename a new file so is not fast
3 will just append to the existing file
uncomment each to test
*/
//Serial.println(" insertValue 'network', 'gateway', '192.168.1.10");
//ini.insertValue("network", "gateway","192.168.1.10",buffer, bufferLen);
Serial.println(" insertValue 'misc', 'gateway', '192.168.1.10");
ini.insertValue("misc", "gateway","192.168.1.10",buffer, bufferLen) ;
//Serial.println(" insertValue 'network3', 'gateway', '192.168.1.10");
//ini.insertValue("network3", "gateway","192.168.1.10",buffer, bufferLen) ;
ini.close();Serial.println();
bool IniFile::insertValue(const char* section, const char* key,const char* value,char* buffer, size_t len)
{
Adafruit_SPIFlash_FAT::File _filefrom;
Adafruit_SPIFlash_FAT::File _fileto; //used when writing a copy of the file for update purpose
char tofilename[INI_FILE_MAX_FILENAME_LEN];
char c;
uint8_t index =0;
IniFileState state;
int foundposition = 0, newpos = 0 , line=1;
error_t errin , errout;
// Call fatfs activate to make it the active chip that receives low level fatfs
// Be sure to call activate before you call any fatfs functions yourself!
fatfs.activate();
while (!getValue(section, key, buffer, len, state)) { foundposition = state.readLinePosition;};
#ifdef INIDEBUG
Serial.print(section);Serial.print('\t'); Serial.print(key);Serial.print('\t');
Serial.print(state.getValueState);Serial.print('\t'); Serial.print( foundposition );Serial.print('\t');
Serial.print(state.readLinePosition);Serial.print('\t'); Serial.print(_error);Serial.print('\t');
Serial.println(strlen(buffer));
#endif
// close ini file //
_file.close();
//open ini file and temp file
//open from file read only
_filefrom = fatfs.open(_filename, FILE_READ);
if (!_filefrom) {
Serial.println("Error, failed to open _file for reading!");
_error = errorFileNotOpen;
return false;
}
//open to file in write mode - create a temp file name that can be renamed on success
do {
tofilename[index]=_filename[index++];
} while (_filename[index-1]!= '\0');
tofilename[index-2] = '~';
#ifdef INIDEBUG //#endif
Serial.print("From: ");Serial.println(_filename);
Serial.print(" To: ");Serial.println(tofilename);
#endif
if (fatfs.exists(tofilename)) fatfs.remove(tofilename);
_fileto = fatfs.open(tofilename, FILE_WRITE); //Creates a new file to write;
if (!_fileto) {
Serial.println("Error, failed to open _fileto for writing!");
_error = errorFileNotOpen;
return false;
}
_filefrom.seek(0); //start at beginning
_fileto.seek(0); //start at beginning
switch ( _error) {
case errorNoError:
case errorKeyNotFound:
{
/* key found in section, copy to temp file from 0 upto found position, insert new key value line,
if key exists then skip a line then copy to temp file from readline position to end of file */
//CopyPartFile(_filefrom, _fileto,0, previousposition);
// move to our start point in from file
_filefrom.seek(0);
// test for reaching end point
#ifdef INIDEBUG //#endif
Serial.print(section);Serial.print('\t'); Serial.print(key);
Serial.print("From ");Serial.print(0);Serial.print(" to "); Serial.println(foundposition);
#endif
while ((errin = readLine(_filefrom, buffer, len, newpos)) == errorNoError){
uint8_t i = 0;
#ifdef INIDEBUG //#endif
Serial.print(line++);Serial.print('\t');Serial.print(newpos);Serial.print('\t');Serial.print(foundposition);Serial.print('\t');
Serial.println(buffer);
#endif
_fileto.println(buffer);
if (newpos==foundposition) break;}
if ( _error==errorNoError ) {
#ifdef INIDEBUG //#endif
Serial.println(";Section and key were found, replaced key=value");
_fileto.println(";Section and key were found, replaced key=value");
line += 2;//inserted 2 lines
#endif
readLine(_filefrom, buffer, len, newpos);//skip the old line with the value if errorNoError
}
else {
#ifdef INIDEBUG //#endif
Serial.println(";Section found but no key, new key=value");
_fileto.println(";Section found but no key, new key=value");
line += 2;//inserted 2 lines
#endif
}
_fileto.print(key);_fileto.print(" = ");_fileto.print(value);_fileto.print('\n');//add new key=value to the temp file
#ifdef INIDEBUG //#endif
Serial.print("Error is: ");Serial.println(_error);// 0 key found, 5 no section, 6 no key
Serial.print("From ");Serial.print(newpos);Serial.print(" to "); Serial.println(_filefrom.fileSize());
#endif
while ((errin = readLine(_filefrom, buffer, len, newpos)) == errorNoError){
uint8_t i = 0;
#ifdef INIDEBUG //#endif
Serial.print(line++);Serial.print('\t');Serial.print(newpos);Serial.print('\t');
Serial.println(buffer);
#endif
_fileto.println(buffer); //add line to temp file
if (newpos==_filefrom.fileSize()) break;} //end of input
_fileto.println();
#ifdef INIDEBUG //#endif
Serial.print("Case noError - Error is: ");Serial.println(_error);
#endif
_filefrom.close();_fileto.close();
fatfs.remove(_filename); //fatfs function uses file path
fatfs.rename(tofilename,_filename) ;
break;
}
case errorSectionNotFound: {
/* if section NOT found, append new section to existing file needs to be writable */
_filefrom.close();
_filefrom = fatfs.open(_filename, FILE_WRITE);
Serial.print(section);Serial.println(" Not Found ");
_filefrom.print('[');_filefrom.print(section);_filefrom.print(']');_filefrom.print('\n');
_filefrom.println(";A New Section.");
_filefrom.print(key);_filefrom.print('=');_filefrom.print(value);_filefrom.print('\n');
// close files //
_filefrom.close();_fileto.close();
break;
}
}
_file = fatfs.open(_filename, FILE_READ); //re open inifile
;
return _error == errorNoError;
}
For completeness this code will delete a key and a whole section if key is "". This has the same health warning. The function writes to a temporary file then renames it to the original.
bool IniFile::removeValue(const char* section, const char* key,char* buffer, size_t len)
{
Adafruit_SPIFlash_FAT::File _filefrom;
Adafruit_SPIFlash_FAT::File _fileto; //used when writing a copy of the file for update purpose
char tofilename[INI_FILE_MAX_FILENAME_LEN];
char c;
uint8_t index =0;
IniFileState state;
int previouspos, foundposition = 0, newpos = 0 , line=1;
error_t errin , errout;
//if key is blank we will delete the section
bool deletesection = (strlen(key)>0 ) ;
// Call fatfs activate to make it the active chip that receives low level fatfs
// Be sure to call activate before you call any fatfs functions yourself!
fatfs.activate();
while (!getValue(section, key, buffer, len, state)) {previouspos= foundposition ; foundposition = state.readLinePosition;};
#ifdef INIDEBUG
Serial.print(section);Serial.print('\t'); Serial.print(key);Serial.print('\t');
Serial.print(state.getValueState);Serial.print('\t'); Serial.print( foundposition );Serial.print('\t');
Serial.print(state.readLinePosition);Serial.print('\t'); Serial.print(_error);Serial.print('\t');
Serial.println(strlen(buffer));
#endif
// close ini file //
_file.close();
//open ini file and temp file
//open from file read only
_filefrom = fatfs.open(_filename, FILE_READ);
if (!_filefrom) {
Serial.println("Error, failed to open _file for reading!");
_error = errorFileNotOpen;
return false;
}
//open to file in write mode - create a temp file name that can be renamed on success
do {
tofilename[index]=_filename[index++];
} while (_filename[index-1]!= '\0');
tofilename[index-2] = '~';
#ifdef INIDEBUG //#endif
Serial.print("From: ");Serial.println(_filename);
Serial.print(" To: ");Serial.println(tofilename);
#endif
if (fatfs.exists(tofilename)) fatfs.remove(tofilename);
_fileto = fatfs.open(tofilename, FILE_WRITE); //Creates a new file to write;
if (!_fileto) {
Serial.println("Error, failed to open _fileto for writing!");
_error = errorFileNotOpen;
return false;
}
_filefrom.seek(0); //start at beginning
_fileto.seek(0); //start at beginning
switch ( _error) {
case errorNoError:
case errorKeyNotFound:
{
/* key found in section, copy to temp file from 0 upto found position, insert new key value line,
if key exists then skip a line then copy to temp file from readline position to end of file */
//CopyPartFile(_filefrom, _fileto,0, previousposition);
// move to our start point in from file
_filefrom.seek(0);
// test for reaching end point
#ifdef INIDEBUG //#endif
Serial.print(section);Serial.print('\t'); Serial.print(key);
Serial.print("From ");Serial.print(0);Serial.print(" to "); Serial.println(foundposition);
#endif
while ((errin = readLine(_filefrom, buffer, len, newpos)) == errorNoError){
uint8_t i = 0;
#ifdef INIDEBUG //#endif
Serial.print(line++);Serial.print('\t');
Serial.print(newpos);Serial.print('\t');
Serial.print(foundposition);Serial.print('\t');
Serial.println(buffer);
#endif
_fileto.println(buffer);
if (newpos==foundposition) break;}
if ( _error==errorNoError ) { //found the key
#ifdef INIDEBUG //#endif
Serial.println(";Section and key were found, remove key");
_fileto.println(";Section and key were found, remove key");
//line += 2;//inserted 2 lines
#endif
readLine(_filefrom, buffer, len, newpos);//skip the old line with the value if errorNoError
}
else {
#ifdef INIDEBUG //#endif
Serial.println(";Section found but not blank key");
Serial.print(foundposition);Serial.print('\t');
Serial.print(_filefrom.position());Serial.print('\t');
Serial.println(_fileto.position());
_fileto.println(";Section found but not blank key");
// where did this key start foundposition and where is next key
//truncate file ? //backup write position
// rewind seek to foundposition then find the next '['
//reset _fileto and copy up to foundposition
_fileto.seek(previouspos);
_filefrom.readStringUntil('[');
//continue reading writing lines from here
newpos = _filefrom.position()-1;
Serial.print(foundposition);Serial.print('\t');
Serial.print(_filefrom.position());Serial.print('\t');
Serial.println(_fileto.position());
//line += 2;//inserted 2 lines
#endif
}
//_fileto.print(key);_fileto.print(" = ");_fileto.print(value);_fileto.print('\n');//don't write the key
#ifdef INIDEBUG //#endif
Serial.print("Error is: ");Serial.println(_error);// 0 key found, 5 no section, 6 no key
Serial.print("From ");Serial.print(newpos);Serial.print(" to "); Serial.println(_filefrom.fileSize());
#endif
while ((errin = readLine(_filefrom, buffer, len, newpos)) == errorNoError){
uint8_t i = 0;
#ifdef INIDEBUG //#endif
Serial.print(line++);Serial.print('\t');Serial.print(newpos);Serial.print('\t');
Serial.println(buffer);
#endif
_fileto.println(buffer); //add line to temp file
if (newpos==_filefrom.fileSize()) break;} //end of input
_fileto.println();
#ifdef INIDEBUG //#endif
Serial.print("Case noError - Error is: ");Serial.println(_error);
#endif
_filefrom.close();_fileto.close();
fatfs.remove(_filename); //fatfs function uses file path
fatfs.rename(tofilename,_filename) ;
break;
}
case errorSectionNotFound: {
/* if section NOT found do nothing*/
_filefrom.close();
_filefrom = fatfs.open(_filename, FILE_WRITE);
Serial.print(section);Serial.println(" Not Found ");
// close files //
_filefrom.close();_fileto.close();
break;
}
}
_file = fatfs.open(_filename, FILE_READ); //re open inifile
;
return _error == errorNoError;
}
Hi, i will like know if is possible update the value on file .ini
Thanks