243 lines
		
	
	
		
			6.9 KiB
		
	
	
	
		
			C++
		
	
	
	
	
	
			
		
		
	
	
			243 lines
		
	
	
		
			6.9 KiB
		
	
	
	
		
			C++
		
	
	
	
	
	
| #include "CFGFileParser.h"
 | |
| 
 | |
| CFGFileParser::CFGFileParser(SDCardManager &sdCardManager, const char *file):AbstractParser(file), _state(LINE_BREAK), _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);
 | |
|     //We check if the file name is not NULL :-)
 | |
|     if(!file)
 | |
|     {
 | |
|       delete dictioRef;
 | |
|       return NULL;
 | |
|     }
 | |
| 	
 | |
| 	  _state = LINE_BREAK;
 | |
|     while(file.available())
 | |
|     {
 | |
|       readChar = (char)file.read();
 | |
|       
 | |
|         //Do work
 | |
|         switch(_state)
 | |
|         {
 | |
|         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) || readChar == '-' || readChar == '_')
 | |
|             {
 | |
|                 _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 == '-' || (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 == '-' || (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) || readChar == '-' || readChar == '_')
 | |
|             {
 | |
|                 _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;
 | |
|         default:
 | |
|             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;
 | |
|         default:
 | |
|             break;
 | |
|   	}
 | |
|   }
 | |
|   
 | |
|   if(!file.truncate(truncateHere))
 | |
|   {
 | |
|   	file.close();
 | |
|   	return false;
 | |
|   }
 | |
|   
 | |
|   //Let's write the settings
 | |
|   for(unsigned 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;
 | |
| }
 |