int INIFile::skipName(const unsigned char* line,int startpos) { while(line[startpos] != '\0') { if(isNormalChar(line[startpos]) || (line[startpos] == ' ') || (line[startpos] == '\t')) { startpos++; } else { return startpos; } } return startpos; }
bool INIFile::isValidKeyName(const std::string& keyname) { for(unsigned int i = 0; i < keyname.size(); i++) { if( (!isNormalChar(keyname[i])) && (!isWhitespace(keyname[i])) ) { return false; } } if(isWhitespace(keyname[0]) || isWhitespace(keyname[keyname.size()-1])) { return false; } return true; }
bool INIFile::isValidSectionName(const std::string& sectionname) { for(unsigned int i = 0; i < sectionname.size(); i++) { if( (!isNormalChar(sectionname[i])) && (!isWhitespace(sectionname[i])) ) { return false; } } if(isWhitespace(sectionname[0]) || isWhitespace(sectionname[sectionname.size()-1])) { return false; } else { return true; } }
bool INIFile::Key::escapingValueNeeded(const std::string& value) { if(value == "") { return true; } else { // test for non normal char for(unsigned int i = 0; i < value.size(); i++) { if(!isNormalChar(value[i])) { return true; } } return false; } }
int INIFile::skipKey(const unsigned char* line,int startpos) { int i = startpos; while(line[i] != '\0') { if(isNormalChar(line[i]) || isWhitespace(line[i])) { i++; } else if((line[i] == ';') || (line[i] == '#') || (line[i] == '=')) { // begin of a comment or '=' break; } else { // some invalid character return i; } } // now we go backwards while(i >= startpos) { if(isNormalChar(line[i])) { return i+1; } i--; } return startpos+1; }
//-------------------------------------------------------------------------------------- // Name: constuctor // Desc: //-------------------------------------------------------------------------------------- Tag::Tag(const char** readPointer, const char* end) : m_Type(TYPE_BEGIN) { m_Attributes.clear(); // temp value to save attribute string name; string value; int state=0; // state bool done = false; // to break while loop while( *readPointer < end ) { char c = **readPointer; // save the char value ++(*readPointer); // move cursor to the next switch(state) { // initial state case 0: // read the first charactor switch(c) { case '/': m_Type = TYPE_END; break; default: m_Name += c; // add first char of Element name to m_Name state = 1; break; } break; case 1: if(c == '>') done = true; else if(isNormalChar(c)) m_Name += c; else state = 2; // it means whitespace, ',', '"', or invalid char break; // char after Element name case 2: if(c == '>') done = true; else if(isNormalChar(c)) { name += c; // it's attribute's name. state = 3; } break; case 3: switch(c) { case '=': state = 4; break; default: name+=c; break; // 현재는 = 앞의 공백도 문자로 인식한다. } break; case 4: switch(c) { case '"': state = 5; break; // value값은 항상 "안에 있다. default: break; } break; case 5: switch(c) { case '"': state = 2; m_Attributes.push_back( (new Attribute(name.c_str(), value.c_str())) ); name.clear(); value.clear(); break; default: value += c; // 현재는 공백도 문자로 인식한다. break; } break; } if(done) break; } }
/** Sets the std::string that is adressed by the section/key pair to value. If the section and/or the key does not exist it will be created. A valid sectionname/keyname is not allowed to contain '[',']',';' or '#' and can not start or end with whitespaces (' ' or '\\t'). \param section sectionname \param key keyname \param value value that should be set */ void IniFile::setStringValue(std::string section, std::string key, std::string value) { CommentEntry *curEntry = nullptr; SectionEntry *curSection = getSection(section); if(curSection == nullptr) { // create new section // test for valid section name bool NonNormalCharFound = false; for(unsigned int i = 0; i < section.size(); i++) { if( (!isNormalChar(section[i])) && (!isWhitespace(section[i])) ) { NonNormalCharFound = true; } } if(isWhitespace(section[0]) || isWhitespace(section[section.size()-1])) { NonNormalCharFound = true; } if(NonNormalCharFound == true) { std::cerr << "IniFile: Cannot create section with name " << section << "!" << std::endl; return; } std::string completeLine = "[" + section + "]"; if((curSection = new SectionEntry(completeLine,1,section.size())) == nullptr) throw(std::bad_alloc()); if(FirstLine == nullptr) { FirstLine = curSection; } else { curEntry = FirstLine; while(curEntry->nextEntry != nullptr) { curEntry = curEntry->nextEntry; } curEntry->nextEntry = curSection; curSection->prevEntry = curEntry; curEntry = curSection; } InsertSection(curSection); } KeyEntry *curKey = getKey(curSection,key); if(curKey == nullptr) { // create new key // test for valid key name bool NonNormalCharFound = false; for(unsigned int i = 0; i < key.size(); i++) { if( (!isNormalChar(key[i])) && (!isWhitespace(key[i])) ) { NonNormalCharFound = true; } } if(isWhitespace(key[0]) || isWhitespace(key[key.size()-1])) { NonNormalCharFound = true; } if(NonNormalCharFound == true) { std::cerr << "IniFile: Cannot create key with name " << key << "!" << std::endl; return; } std::string completeLine; int KeyStringStart; int KeyStringLength; int ValueStringStart; int ValueStringLength; if(value == "") { completeLine = key + " = \"" + value + "\"" ; KeyStringStart = 0; KeyStringLength = key.size(); ValueStringStart = key.size()+4; ValueStringLength = value.size(); } else { // test for non normal char NonNormalCharFound = false; for(unsigned int i = 0; i < value.size(); i++) { if(!isNormalChar(value[i])) { NonNormalCharFound = true; } } if(NonNormalCharFound == true) { completeLine = key + " = \"" + value + "\"" ; KeyStringStart = 0; KeyStringLength = key.size(); ValueStringStart = key.size()+4; ValueStringLength = value.size(); } else { completeLine = key + " = " + value; KeyStringStart = 0; KeyStringLength = key.size(); ValueStringStart = key.size()+3; ValueStringLength = value.size(); } } if((curKey = new KeyEntry(completeLine,KeyStringStart,KeyStringLength,ValueStringStart,ValueStringLength)) == nullptr) throw(std::bad_alloc()); if(curEntry != nullptr) { curEntry->nextEntry = curKey; curKey->prevEntry = curEntry; } else { KeyEntry *pKey = curSection->KeyRoot; if(pKey == nullptr) { // Section has no key yet if(curSection->nextEntry == nullptr) { // no line after this section declaration curSection->nextEntry = curKey; curKey->prevEntry = curSection; } else { // lines after this section declaration curSection->nextEntry->prevEntry = curKey; curKey->nextEntry = curSection->nextEntry; curSection->nextEntry = curKey; curKey->prevEntry = curSection; } } else { // Section already has some keys while(pKey->nextKey != nullptr) { pKey = pKey->nextKey; } if(pKey->nextEntry == nullptr) { // no line after this key pKey->nextEntry = curKey; curKey->prevEntry = pKey; } else { // lines after this section declaration pKey->nextEntry->prevEntry = curKey; curKey->nextEntry = pKey->nextEntry; pKey->nextEntry = curKey; curKey->prevEntry = pKey; } } } InsertKey(curSection,curKey); } else { curKey->CompleteLine.replace(curKey->ValueStringBegin,curKey->ValueStringLength,value); } }