256 lines
7.3 KiB
C++
256 lines
7.3 KiB
C++
#include "CFGFileParser.h"
|
|
|
|
CFGFileParser::CFGFileParser(SDCardManager &sdCardManager, const char *file):AbstractParser(file), _state(INIT), _type(PARAMETER), _quotedParameter(false), _quotedValue(false), _sdCardManager(sdCardManager)
|
|
{
|
|
|
|
}
|
|
|
|
void *CFGFileParser::parseFile()
|
|
{
|
|
//Here is the logic for the file parser
|
|
File file;
|
|
|
|
CFGDictionary<CFGParameterValue> *dictioRef = new CFGDictionary<CFGParameterValue>;
|
|
char readChar(0), *parsedParameter(NULL), *parsedValue(NULL);
|
|
|
|
if(!_sdCardManager.isMounted()) return NULL;
|
|
|
|
file = _sdCardManager.open(_resource);
|
|
if(!file)
|
|
{
|
|
delete dictioRef;
|
|
return NULL;
|
|
}
|
|
|
|
_state = INIT;
|
|
while(file.available())
|
|
{
|
|
readChar = (char)file.read();
|
|
|
|
//Do work
|
|
switch(_state)
|
|
{
|
|
case INIT:
|
|
if(readChar == '#') _state = COMMENT_SECTION;
|
|
else if((readChar >= 65 && readChar <= 90) || (readChar >= 97 && readChar <= 122) || (readChar >= 48 && readChar <= 57))
|
|
{
|
|
_state = PARAM_SECTION;
|
|
parsedParameter = addChar(parsedParameter, readChar);
|
|
if(parsedParameter == NULL)
|
|
_state = ERROR;
|
|
//printf("%c",readChar);
|
|
}
|
|
else if(readChar == '\'')
|
|
{
|
|
_state = OPENING_QUOTE;
|
|
_type = PARAMETER;
|
|
}
|
|
else
|
|
_state = ERROR;
|
|
break;
|
|
case COMMENT_SECTION:
|
|
if(readChar == '\r' || readChar == '\n') _state = LINE_BREAK;
|
|
break;
|
|
case LINE_BREAK:
|
|
if(readChar == '#')
|
|
_state = COMMENT_SECTION;
|
|
else if(readChar == '\r' || readChar == '\n') _state = LINE_BREAK;
|
|
else if((readChar >= 65 && readChar <= 90) || (readChar >= 97 && readChar <= 122) || (readChar >= 48 && readChar <= 57))
|
|
{
|
|
_state = PARAM_SECTION;
|
|
//printf("%c",readChar);
|
|
_type = PARAMETER;
|
|
parsedParameter = addChar(parsedParameter, readChar);
|
|
if(parsedParameter == NULL)
|
|
_state = ERROR;
|
|
}
|
|
else if(readChar == '\'')
|
|
{
|
|
_state = OPENING_QUOTE;
|
|
_type = PARAMETER;
|
|
}
|
|
else
|
|
_state = ERROR;
|
|
break;
|
|
case PARAM_SECTION:
|
|
if(readChar == '\'')_state = OPENING_QUOTE;
|
|
else if(readChar == ':') _state = SEPARATION;
|
|
else if(readChar == '\r' || readChar == '\n')
|
|
{
|
|
_state = LINE_BREAK;
|
|
if(parsedParameter != NULL)
|
|
{
|
|
//printf("%s --> %s\n", parsedParameter, parsedValue);
|
|
dictioRef->add(parsedParameter, new CFGParameterValue(parsedParameter, parsedValue == NULL ? "":parsedValue, _quotedParameter, _quotedValue));
|
|
free(parsedParameter);free(parsedValue);
|
|
parsedParameter = NULL;parsedValue = NULL;
|
|
_quotedParameter = false;_quotedValue = false;
|
|
|
|
}
|
|
}
|
|
else if(readChar == ' ') _state = PARAM_SECTION;
|
|
else if((readChar >= 65 && readChar <= 90) || (readChar >= 97 && readChar <= 122) || readChar == '_' || (readChar >= 48 && readChar <= 57))
|
|
{
|
|
if(_type == PARAMETER)
|
|
{
|
|
parsedParameter = addChar(parsedParameter, readChar);
|
|
if(parsedParameter == NULL)
|
|
_state = ERROR;
|
|
}
|
|
else
|
|
{
|
|
parsedValue = addChar(parsedValue, readChar);
|
|
if(parsedValue == NULL)
|
|
_state = ERROR;
|
|
}
|
|
//printf("%c",readChar);
|
|
}
|
|
else
|
|
_state = ERROR;
|
|
break;
|
|
case OPENING_QUOTE:
|
|
if(readChar == '\'')
|
|
{
|
|
_state = PARAM_SECTION;
|
|
if(_type == PARAMETER)
|
|
_quotedParameter = true;
|
|
else
|
|
_quotedValue = true;
|
|
}
|
|
else if((readChar >= 65 && readChar <= 90) || (readChar >= 97 && readChar <= 122) || readChar == ' ' || readChar == '_' || (readChar >= 48 && readChar <= 57))
|
|
{
|
|
//printf("%c",readChar);
|
|
if(_type == PARAMETER)
|
|
{
|
|
parsedParameter = addChar(parsedParameter, readChar);
|
|
if(parsedParameter == NULL)
|
|
_state = ERROR;
|
|
}
|
|
else
|
|
{
|
|
parsedValue = addChar(parsedValue, readChar);
|
|
if(parsedValue == NULL)
|
|
_state = ERROR;
|
|
}
|
|
}
|
|
else
|
|
_state = ERROR;
|
|
break;
|
|
case SEPARATION:
|
|
_type = VALUE;
|
|
if(readChar == '\'')_state = OPENING_QUOTE;
|
|
else if(readChar == ' ') _state = PARAM_SECTION;
|
|
else if((readChar >= 65 && readChar <= 90) || (readChar >= 97 && readChar <= 122) || (readChar >= 48 && readChar <= 57))
|
|
{
|
|
_state = PARAM_SECTION;
|
|
|
|
parsedValue = addChar(parsedValue, readChar);
|
|
if(parsedValue == NULL)
|
|
_state = ERROR;
|
|
}
|
|
else _state = ERROR;
|
|
break;
|
|
case ERROR:
|
|
dictioRef->dispose();
|
|
delete dictioRef;
|
|
free(parsedValue);
|
|
free(parsedParameter);
|
|
parsedValue = NULL;
|
|
parsedParameter = NULL;
|
|
return NULL;
|
|
break;
|
|
}
|
|
}
|
|
|
|
file.close();
|
|
return dictioRef;
|
|
}
|
|
|
|
boolean CFGFileParser::save(void *data)
|
|
{
|
|
if(data == NULL) return false;
|
|
|
|
Dictionary<CFGParameterValue> *ref = (Dictionary<CFGParameterValue> *) data;
|
|
uint64_t truncateHere(0);
|
|
char readChar(0);
|
|
|
|
if(!_sdCardManager.isMounted()) return NULL;
|
|
|
|
File file = _sdCardManager.open(_resource, FILE_READWRITE);
|
|
|
|
if(!file)
|
|
{
|
|
return false;
|
|
}
|
|
|
|
file.seek(0);
|
|
_state = INIT;
|
|
|
|
//We find out where to truncate the file
|
|
while(file.available())
|
|
{
|
|
readChar = (char)file.read();
|
|
switch(_state)
|
|
{
|
|
case INIT:
|
|
if(readChar == '#')
|
|
{
|
|
truncateHere++;
|
|
_state = COMMENT_SECTION;
|
|
}
|
|
else
|
|
_state = DONE;
|
|
break;
|
|
case COMMENT_SECTION:
|
|
truncateHere++;
|
|
if(readChar == '\n') _state = LINE_BREAK;
|
|
break;
|
|
case LINE_BREAK:
|
|
truncateHere++;
|
|
if(readChar == '#')
|
|
_state = COMMENT_SECTION;
|
|
else if(readChar == '\n') _state = DONE;
|
|
break;
|
|
}
|
|
}
|
|
|
|
if(!file.truncate(truncateHere))
|
|
{
|
|
file.close();
|
|
return false;
|
|
}
|
|
|
|
//Let's write the settings
|
|
for(int i = 0; i < ref->count(); i++)
|
|
{
|
|
CFGParameterValue *cfgPV = ref->getAt(i);
|
|
|
|
if(cfgPV->isQuotedParameter())
|
|
{
|
|
file.write('\'');
|
|
file.print(cfgPV->getParameter());
|
|
file.write('\'');
|
|
}
|
|
else
|
|
{
|
|
file.print(cfgPV->getParameter());
|
|
}
|
|
|
|
file.print(F(" : "));
|
|
|
|
if(cfgPV->isQuotedValue())
|
|
{
|
|
file.write('\'');
|
|
file.print(cfgPV->stringValue());
|
|
file.println('\'');
|
|
}
|
|
else
|
|
{
|
|
file.println(cfgPV->stringValue());
|
|
}
|
|
}
|
|
|
|
file.close();
|
|
return true;
|
|
}
|