void INIFile::readfile(SDL_RWops * file) { SectionRoot = new Section("",0,0); Section* curSection = SectionRoot; std::string completeLine; int lineNum = 0; bool SyntaxError = false; INIFileLine* curLine = NULL; INIFileLine* newINIFileLine; Section* newSection; Key* newKey; bool readfinished = false; while(!readfinished) { lineNum++; completeLine = ""; unsigned char tmp; int readbytes; while(1) { readbytes = SDL_RWread(file,&tmp,1,1); if(readbytes <= 0) { readfinished = true; break; } else if(tmp == '\n') { break; } else if(tmp != '\r') { completeLine += tmp; } } const unsigned char* line = (const unsigned char*) completeLine.c_str(); SyntaxError = false; int ret; ret = getNextChar(line,0); if(ret == -1) { // empty line or comment newINIFileLine = new INIFileLine(completeLine); if(curLine == NULL) { FirstLine = newINIFileLine; curLine = newINIFileLine; } else { curLine->nextLine = newINIFileLine; newINIFileLine->prevLine = curLine; curLine = newINIFileLine; } } else { if(line[ret] == '[') { // section line int sectionstart = ret+1; int sectionend = skipName(line,ret+1); if((line[sectionend] != ']') || (getNextChar(line,sectionend+1) != -1)) { SyntaxError = true; } else { // valid section line newSection = new Section(completeLine,sectionstart,sectionend-sectionstart); if(curLine == NULL) { FirstLine = newSection; curLine = newSection; } else { curLine->nextLine = newSection; newSection->prevLine = curLine; curLine = newSection; } InsertSection(newSection); curSection = newSection; } } else { // might be key/value line int keystart = ret; int keyend = skipKey(line,keystart); if(keystart == keyend) { SyntaxError = true; } else { ret = getNextChar(line,keyend); if((ret == -1) ||(line[ret] != '=')) { SyntaxError = true; } else { int valuestart = getNextChar(line,ret+1); if(valuestart == -1) { SyntaxError = true; } else { if(line[valuestart] == '"') { // now get the next '"' int valueend = getNextQuote(line,valuestart+1); if((valueend == -1) || (getNextChar(line,valueend+1) != -1)) { SyntaxError = true; } else { // valid key/value line newKey = new Key(completeLine,keystart,keyend-keystart,valuestart+1,valueend-valuestart-1); if(FirstLine == NULL) { FirstLine = newKey; curLine = newKey; } else { curLine->nextLine = newKey; newKey->prevLine = curLine; curLine = newKey; } curSection->InsertKey(newKey); } } else { int valueend = skipValue(line,valuestart); if(getNextChar(line,valueend) != -1) { SyntaxError = true; } else { // valid key/value line newKey = new Key(completeLine,keystart,keyend-keystart,valuestart,valueend-valuestart); if(FirstLine == NULL) { FirstLine = newKey; curLine = newKey; } else { curLine->nextLine = newKey; newKey->prevLine = curLine; curLine = newKey; } curSection->InsertKey(newKey); } } } } } } } if(SyntaxError == true) { if(completeLine.size() < 100) { // there are some buggy ini-files which have a lot of waste at the end of the file // and it makes no sense to print all this stuff out. just skip it std::cerr << "INIFile: Syntax-Error in line " << lineNum << ":" << completeLine << " !" << std::endl; } // save this line as a comment newINIFileLine = new INIFileLine(completeLine); if(curLine == NULL) { FirstLine = newINIFileLine; curLine = newINIFileLine; } else { curLine->nextLine = newINIFileLine; newINIFileLine->prevLine = curLine; curLine = newINIFileLine; } } } }
void IniFile::readFile() { if((SectionRoot = new SectionEntry("",0,0)) == nullptr) throw(std::bad_alloc()); SectionEntry *curSectionEntry = SectionRoot; std::string completeLine; int lineNum = 0; bool SyntaxError = false; CommentEntry *curEntry = nullptr; CommentEntry *newCommentEntry; SectionEntry *newSectionEntry; KeyEntry *newKeyEntry; bool readfinished = false; while(!readfinished) { lineNum++; completeLine = ""; uint8_t tmp; size_t size = _stream.sizeg(); while(static_cast<uint32_t>(_stream.tellg()) < size-1) { tmp = _stream.get(); if(static_cast<uint32_t>(_stream.tellg()) == size-1) { readfinished = true; break; } else if(tmp == '\n') { break; } else if(tmp != '\r') { completeLine += tmp; } } const uint8_t *line = reinterpret_cast<const uint8_t*>(completeLine.c_str()); SyntaxError = false; int ret; ret = getNextChar(line,0); if(ret == -1) { // empty line or comment if((newCommentEntry = new CommentEntry(completeLine)) == nullptr) throw(std::bad_alloc()); if(curEntry == nullptr) { FirstLine = newCommentEntry; curEntry = newCommentEntry; } else { curEntry->nextEntry = newCommentEntry; newCommentEntry->prevEntry = curEntry; curEntry = newCommentEntry; } } else { if(line[ret] == '[') { // section line int sectionstart = ret+1; int sectionend = skipName(line,ret+1); if((line[sectionend] != ']') || (getNextChar(line,sectionend+1) != -1)) { SyntaxError = true; } else { // valid section line if((newSectionEntry = new SectionEntry(completeLine,sectionstart,sectionend-sectionstart)) == nullptr) throw(std::bad_alloc()); if(curEntry == nullptr) { FirstLine = newSectionEntry; curEntry = newSectionEntry; } else { curEntry->nextEntry = newSectionEntry; newSectionEntry->prevEntry = curEntry; curEntry = newSectionEntry; } InsertSection(newSectionEntry); curSectionEntry = newSectionEntry; } } else { // might be key/value line int keystart = ret; int keyend = skipKey(line,keystart); if(keystart == keyend) { SyntaxError = true; } else { ret = getNextChar(line,keyend); if((ret == -1) ||(line[ret] != '=')) { SyntaxError = true; } else { int valuestart = getNextChar(line,ret+1); int valueend; if(valuestart == -1) { SyntaxError = true; } else { if(line[valuestart] == '"') { // now get the next '"' valueend = getNextQuote(line,valuestart+1); if((valueend == -1) || (getNextChar(line,valueend+1) != -1)) { SyntaxError = true; } else { // valid key/value line if((newKeyEntry = new KeyEntry(completeLine,keystart,keyend-keystart,valuestart+1,valueend-valuestart-1)) == nullptr) throw(std::bad_alloc()); if(FirstLine == nullptr) { FirstLine = newKeyEntry; curEntry = newKeyEntry; } else { curEntry->nextEntry = newKeyEntry; newKeyEntry->prevEntry = curEntry; curEntry = newKeyEntry; } InsertKey(curSectionEntry,newKeyEntry); } } else { valueend = skipValue(line,valuestart); if(getNextChar(line,valueend) != -1) { SyntaxError = true; } else { // valid key/value line if((newKeyEntry = new KeyEntry(completeLine,keystart,keyend-keystart,valuestart,valueend-valuestart)) == nullptr) throw(std::bad_alloc()); if(FirstLine == nullptr) { FirstLine = newKeyEntry; curEntry = newKeyEntry; } else { curEntry->nextEntry = newKeyEntry; newKeyEntry->prevEntry = curEntry; curEntry = newKeyEntry; } InsertKey(curSectionEntry,newKeyEntry); } } } } } } } if(SyntaxError == true) { if(completeLine.size() < 100) { // there are some buggy ini-files which have a lot of waste at the end of the file // and it makes no sense to print all this stuff out. just skip it std::cerr << "IniFile: Syntax-Error in line " << lineNum << ":" << completeLine << " !" << std::endl; } // save this line as a comment if((newCommentEntry = new CommentEntry(completeLine)) == nullptr) throw(std::bad_alloc()); if(curEntry == nullptr) { FirstLine = newCommentEntry; curEntry = newCommentEntry; } else { curEntry->nextEntry = newCommentEntry; newCommentEntry->prevEntry = curEntry; curEntry = newCommentEntry; } } } }