public static PdxSublist ReadFileOld(string filePath, string firstLine = null) { State = ReadState.normal; //TODO: write a much more sophisticated file reader var file = new StreamReader(filePath, Encoding.Default); string line; if (firstLine != null) { line = file.ReadLine(); if (line != firstLine) { throw new Exception("Not a valid file"); } } var rootList = new PdxSublist(null, filePath); var currentList = rootList; //var lineNumber = 0; while ((line = file.ReadLine()) != null) { //lineNumber++; //if (lineNumber == 1513567) //{ // Console.WriteLine("Oh"); //} currentList = RunLine(line, currentList); } if (currentList != rootList) { throw new Exception("An unknown error occurred."); } file.Close(); return(rootList); }
private static void SingleLineKeyValuePairs(string key, string value, PdxSublist currentList) { string k = string.Empty; string v = string.Empty; bool readingKey = true; bool inQuotes = false; foreach (var ch in value) { if (ch == '"') { //toggle whether we're currently reading inside quotes inQuotes = !inQuotes; continue; } //if we're not in quotes, special characters apply if (!inQuotes) { if (char.IsWhiteSpace(ch)) { //if we're not in quotes, are currently reading the value, have a whitespace and value is not empty then this indicates the value is finished if (!readingKey && !string.IsNullOrEmpty(v)) { readingKey = true; currentList.AddValue(k, v); k = string.Empty; v = string.Empty; } //whitespace not added to the value when not in quotes continue; } //= sign indicates we've finished reading the key and are now reading the value if (ch == '=') { readingKey = false; continue; } } //if we're reading the key, add the character to the key else add it to the value if (readingKey) { k += ch; } else { v += ch; } //currentList.AddString(key, val); } //last entry leftover if (!readingKey && !string.IsNullOrEmpty(v)) { currentList.AddValue(k, v); } }
public PdxSublist(PdxSublist parent = null, string key = null) { this.Key = key; this.Parent = parent; keyValuePairs = new Dictionary <string, List <string> >(); KeyValuePairs = new PseudoDictionary <string, string>(keyValuePairs); BoolValues = new Dictionary <string, List <bool> >(); FloatValues = new Dictionary <string, List <float> >(); sublists = new Dictionary <string, List <PdxSublist> >(); Sublists = new PseudoDictionary <string, PdxSublist>(sublists); KeylessSublists = new List <PdxSublist>(); }
public static PdxSublist FromList(List <string> strs, PdxSublist parent = null) { var data = new PdxSublist(parent); strs.ForEach((s) => { data.AddValue(s); } ); return(data); }
public void AddSublist(string key, PdxSublist value) { if (key == null) { KeylessSublists.Add(value); } else { value.Key = key; if (!Sublists.ContainsKey(key)) { sublists[key] = new List <PdxSublist>(); } sublists[key].Add(value); } value.Parent = this; }
private static void SingleLineArray(string key, string value, PdxSublist currentList) { var numValues = new List <string>(); var inQuotes = false; var nextVal = new StringBuilder(); foreach (var ch in value) { if (ch == '}') { break; } if (!inQuotes && char.IsWhiteSpace(ch)) { if (nextVal.Length > 0) { numValues.Add(nextVal.ToString()); } nextVal = new StringBuilder(); continue; } if (ch == '"') { inQuotes = !inQuotes; continue; } nextVal.Append(ch); } if (nextVal.Length > 0) { numValues.Add(nextVal.ToString()); } foreach (var val in numValues) { currentList.AddValue(null, val); } }
private static void Terminate(PdxSublist currentList, StringBuilder key, StringBuilder value, char?ch = null) { switch (State) { //determine what to do about current thing case ReadState.key: case ReadState.postKey: currentList.AddValue(string.Empty, key.ToString()); break; case ReadState.value: currentList.AddValue(key.ToString(), value.ToString()); break; case ReadState.preValue: case ReadState.preKey: case ReadState.comment: break; default: var unexpected = ch.HasValue ? ch.Value.ToString() : "EoF"; throw new Exception($"Syntax error: Unexcepted '{unexpected}'"); } }
public static PdxSublist RunLine(string line, PdxSublist currentList) { if (line.Contains('#')) { //filter out comment line = line.Substring(0, line.IndexOf('#')); } if (string.IsNullOrWhiteSpace(line)) { return(currentList); } string key = null; if (State == ReadState.value) { key = ReadKey; } var value = line.Substring(line.IndexOf('=') + 1).Trim(); if (line.Contains('=')) { key = RemoveWhitespace(line.Substring(0, line.IndexOf('='))); } else if (value == "}") { return(currentList.Parent); } if (string.IsNullOrWhiteSpace(value)) { State = ReadState.value; ReadKey = key; } var parent = 0; if (value.Contains('}')) { parent = value.Count(c => c == '}'); value = value.Substring(0, value.IndexOf('}')).Trim(); } if (value.FirstOrDefault() == '{') { var list = new PdxSublist(currentList, key); if (line.Contains('}')) { if (line.IndexOf('}') < line.IndexOf('{')) { currentList = currentList.Parent; key = key.Substring(key.IndexOf('}') + 1); list.Key = key; list.Parent = currentList; } else { parent = 1; var open = line.IndexOf('{'); value = line.Substring(open + 1, line.IndexOf('}') - open - 1); if (value.Contains('=')) { SingleLineKeyValuePairs(key, value, list); } else { SingleLineArray(key, value, list); } } } currentList.AddSublist(key, list); currentList = list; } else if (key == null) { // awkward single line array of numbers value = line.Substring(line.IndexOf('=') + 1).Trim(); SingleLineArray(key, value, currentList); } else { currentList.AddValue(key, value); } for (var i = 0; i < parent; i++) { currentList = currentList.Parent; } return(currentList); }
public static PdxSublist ReadFile(string filePath, string firstLine = null) { var rootList = new PdxSublist(null, filePath); var currentList = rootList; using (var file = new StreamReader(filePath, Encoding.Default)) { if (firstLine != null) { var line = file.ReadLine(); if (line != firstLine) { throw new Exception("Not a valid file"); } } char ch; State = ReadState.preKey; var inQuotes = false; var key = new StringBuilder(); var value = new StringBuilder(); //var total = new StringBuilder(); var prevState = State; while (!file.EndOfStream) { ch = Convert.ToChar(file.Read()); //total.Append(ch); if (State == ReadState.comment) { if (Environment.NewLine.Contains(ch)) { State = prevState; } continue; } if (!inQuotes) { if (ch == '#') { prevState = State; State = ReadState.comment; continue; } if (ch == '{') { Terminate(currentList, key, value, ch); // open sublist var sub = new PdxSublist(currentList, State == ReadState.preValue ? key.ToString() : null); key = new StringBuilder(); value = new StringBuilder(); currentList = sub; State = ReadState.preKey; continue; } if (ch == '=') { // expecting next non-whitespace character to be the start of the key State = ReadState.preValue; continue; } if (ch == '}') { // end of sublist, go up a level Terminate(currentList, key, value, ch); key = new StringBuilder(); value = new StringBuilder(); //todo: do something about the special case if (currentList.Parent == null && firstLine == "CK2txt") { return(rootList); } currentList.Parent.AddSublist(currentList.Key, currentList); currentList = currentList.Parent; State = ReadState.preKey; continue; } if (char.IsWhiteSpace(ch)) { if (State == ReadState.value) { //append to list currentList.AddValue(key.ToString(), value.ToString()); key = new StringBuilder(); value = new StringBuilder(); State = ReadState.preKey; } else if (State == ReadState.key) { // no longer reading the key, expecting = or a new value if list State = ReadState.postKey; } continue; } else if (State == ReadState.preValue) { State = ReadState.value; } else if (State == ReadState.postKey) { //this must be a list currentList.AddValue(string.Empty, key.ToString()); key = new StringBuilder(); State = ReadState.key; } else if (State == ReadState.preKey) { State = ReadState.key; } } if (ch == '"') { inQuotes = !inQuotes; continue; } if (State == ReadState.key) { key.Append(ch); } if (State == ReadState.value) { value.Append(ch); } } Terminate(currentList, key, value); } if (currentList != rootList) { throw new Exception("An unknown error occurred."); } return(rootList); }