// ############################################################################################# // file IO // ############################################################################################# /** **************************************************************************************** * Clears all configuration data and reads the file. It might happen that lines are * ignored or otherwise marked as faulty. All numbers of such lines get collected in * field LinesWithReadErrors. * @return Returns the #Status of the operation. ******************************************************************************************/ public IniFile.Status ReadFile() { Clear(); LastStatus = Status.OK; // read all variables StreamReader file; try { file = new StreamReader(FileName.ToString()); } catch (Exception) { return(LastStatus = Status.ERROR_OPENING_FILE); } String lineS; AString name = new AString(); AString value = new AString(); AString comments = new AString(); Section actSection = Sections[0]; Substring line = new Substring(); Tokenizer tn = new Tokenizer(); int lineNo = 0; bool fileHeaderRead = false; LinesWithReadErrors.Clear(); while ((lineS = file.ReadLine()) != null) { lineNo = 0; // place in AString line.Set(lineS).Trim(); // empty line? if (line.IsEmpty()) { // already collecting a comment? if (comments.IsNotEmpty()) { // first empty line in file found? if (!fileHeaderRead) { //store comments belonging to file fileHeaderRead = true; FileComments = comments; comments = new AString(); continue; } comments.NewLine(); } continue; } // comments line: find comment character '#', ';' or // if (startsWithCommentSymbol(line)) { //gather in comments string if (comments.IsNotEmpty()) { comments.NewLine(); } line.CopyTo(comments, true); continue; } // section line if (line.Consume('[')) { fileHeaderRead = true; // we do not care if there is no closing bracket. But if there is one, we remove it. if (!line.ConsumeFromEnd(']')) { LinesWithReadErrors.Add(lineNo); } // search the section in our section list (if section existed already, new comments // are dropped) actSection = SearchOrCreateSection(line, comments); comments.Clear(); continue; } // variable line? If not, we just drop the line! tn.Set(line, '='); tn.Next(); if (!tn.HasNext()) { LinesWithReadErrors.Add(lineNo); continue; } tn.Actual.CopyTo(name); if (tn.GetRest().IsEmpty()) { LinesWithReadErrors.Add(lineNo); continue; } value.Clear(); Substring valueRead = tn.Actual; // read continues as long as lines end with '\' (must not be '\\') char delim = '\0'; while (valueRead.CharAtEnd() == '\\' && valueRead.CharAtEnd(1) != '\\') { // search end before '\'. The first of all broken lines determines the delimiter valueRead.End--; valueRead.TrimEnd(); if (delim == 0) { delim = valueRead.CharAtEnd(); if (delim == '\"' || char.IsLetterOrDigit(delim)) { delim = '\0'; } } removeEscapeSequences(valueRead, value); if ((lineS = file.ReadLine()) == null) { // last line of the file ended with '\' ! valueRead.Clear(); break; } valueRead.Set(lineS).Trim(); } removeEscapeSequences(valueRead, value); actSection.Insert(name, value, comments).Delim = delim; comments.Clear(); } file.Close(); return(LastStatus); }