/** * Construct a new in-memory item of an Ini file. * @param parent the group we belong to * @param name the name of the item * @param last the last element of the name of the item */ public IniItem(IniGroup parent, string name) //, string last = null) { next = null; value = null; comment = null; this.name = name; //str_validate(this.name, this.name + strlen(this.name)); parent.items.Add(name, this); }
/** * Load the Ini file's data from the disk. * @param filename the file to load. * @param subdir the sub directory to load the file from. * @pre nothing has been loaded yet. */ public void LoadFromDisk(string filename, Subdirectory subdir) { Debug.Assert(groups.Any() == false); //FILE *in = this.OpenFile(filename, subdir, &end); //if (in == NULL) return; var path = filename; //TODO create IniGroup group = null; var commentBuilder = new StringBuilder(); var hasComment = false; /* for each line in the file */ foreach (var l in File.ReadLines(path, Encoding.UTF8)) { var line = l.Trim(); if (line.Any() == false) { continue; } var firstChar = line.First(); /* Skip comments and empty lines outside IGT_SEQUENCE groups. */ if ((group == null || group.type != IniGroupType.IGT_SEQUENCE) && (firstChar == '#' || firstChar == ';' || firstChar == '\0')) { commentBuilder.AppendLine(line); // comment newline hasComment = true; continue; } /* it's a group? */ if (firstChar == '[') { var lineLength = line.Length; if (line.Last() != ']') { this.ReportFileError("ini: invalid group name '", line, "'"); } else { lineLength--; } group = new IniGroup(this, line.Substring(1, lineLength - 1)); // skip [ if (hasComment) { group.comment = commentBuilder.ToString(); commentBuilder.Clear(); hasComment = false; } } else if (group != null) { if (group.type == IniGroupType.IGT_SEQUENCE) { /* A sequence group, use the line as item name without further interpretation. */ var itemInner = new IniItem(group, line); if (hasComment) { itemInner.comment = commentBuilder.ToString(); commentBuilder.Clear(); hasComment = false; } continue; } var index = 0; string name = null; /* find end of keyname */ if (firstChar == '\"') { index++; var length = line.IndexOf("\"", index); name = line.Substring(index, length); index += length + 1; } else { for (var i = 0; i < line.Length; i++) { var c = line[i]; if (Char.IsWhiteSpace(c) || c == '=') { name = line.Substring(index, i); index = i + 1; break; } } if (index == 0) { name = line; } } /* it's an item in an existing group */ var item = new IniItem(group, name); if (hasComment) { item.comment = commentBuilder.ToString(); commentBuilder.Clear(); hasComment = false; } /* find start of parameter */ for (; index < line.Length; index++) { var c = line[index]; if (Char.IsWhiteSpace(c) == false || c == '=') { break; } } bool quoted = (line[index] == '\"'); /* remove starting quotation marks */ if (quoted) { index++; } /* remove ending quotation marks */ var value = (string)null; if (index < line.Length - 1) { value = line.EndsWith("\"") ? line.Substring(index, line.Length - index - 1) : line.Substring(index); } /* If the value was not quoted and empty, it must be NULL */ item.value = value; //if (item.value != null) str_validate(item.value, item.value + strlen(item.value)); } else { /* it's an orphan item */ this.ReportFileError("ini: '", line, "' outside of group"); } } if (hasComment) { this.comment = commentBuilder.ToString(); commentBuilder.Clear(); hasComment = false; } }