/// <summary> /// Create new scoped indent options. /// </summary> /// <param name="scopePrefix"> /// The text (if any) to write before opening the scope. /// </param> /// <param name="scopePrefixNewLines"> /// The new-line settings for the scope prefix. /// </param> /// <param name="scopePostfix"> /// The text (if any) to write before closing the scope. /// </param> /// <param name="scopePostfixNewLines"> /// The new-line settings for the scope suffix. /// </param> ScopedIndentOptions(string scopePrefix = null, NewLines scopePrefixNewLines = NewLines.None, string scopePostfix = null, NewLines scopePostfixNewLines = NewLines.None) { _scopePrefix = scopePrefix; _scopePrefixNewLines = scopePrefixNewLines; _scopePostfix = scopePostfix; _scopePostfixNewLines = scopePostfixNewLines; }
public void Read(string file) { if (NewLines == null) { Assert.Fail("NewLines has no listeners"); } var lines = File.ReadLines(file).Select(x => new Line("Power", x)); NewLines.Invoke(new NewLinesEventArgs(lines)); }
private TriggerConditionSet ParseTriggerConditionSet(StreamReader sr, bool prevCompose = false) { var conditions = new List <TriggerCondition>(); var conditionSets = new List <TriggerConditionSet>(); var composeOr = prevCompose; var modifierNot = false; // Loop over properties while (true) { var character = (char)sr.Read(); character = SkipUntilNot(sr, character, NewLines.Concat(Spaces)); if (character == ObjectClose) { break; } string propName; (character, propName) = ReadPropertyName(sr, character); if (character == ObjectOpen) { if (propName.Equals("not", StringComparison.OrdinalIgnoreCase)) { modifierNot = true; } else if (propName.Equals("or", StringComparison.OrdinalIgnoreCase)) { composeOr = true; } else if (propName.Equals("and", StringComparison.OrdinalIgnoreCase)) { composeOr = false; } var cs = ParseTriggerConditionSet(sr, composeOr); cs.ComposeOr = composeOr; cs.ModifierNot = modifierNot; conditionSets.Add(cs); } else { string propValue; (character, propValue) = ReadPropertyStringValue(sr, character); conditions.Add(new TriggerCondition { Name = propName, Value = propValue }); } } return(new TriggerConditionSet { Conditions = conditions, ConditionSets = conditionSets }); }
internal async void Start(string hearthstonePath, string logDirectory = "Logs") { if (_running) { return; } Starting?.Invoke(); var fullPath = Path.Combine(hearthstonePath, "Logs"); var startingPoint = GetStartingPoint(fullPath); Log.Debug($"Starting log readers in \"{fullPath}\", at [{startingPoint}]"); foreach (var logReader in _watchers) { logReader.Start(fullPath, logReader.Info.Name == "Decks" ? startingPoint.Decks : startingPoint.Default); } _running = true; _stop = false; var newLines = new SortedList <DateTime, List <Line> >(); while (!_stop) { await Task.Factory.StartNew(() => { foreach (var logReader in _watchers) { var lines = logReader.Collect(); foreach (var line in lines) { if (!newLines.TryGetValue(line.Time, out var logLines)) { newLines.Add(line.Time, logLines = new List <Line>()); } logLines.Add(line); } } }); NewLines?.Invoke(new NewLinesEventArgs(newLines.Values.SelectMany(x => x))); newLines.Clear(); await Task.Delay(UpdateDelay); } _running = false; }
private object ParseColor(StreamReader sr) { string red, green, blue; var character = (char)sr.Read(); // Skip any leading spaces var spaceChars = NewLines.Concat(Spaces); character = SkipUntilNot(sr, character, spaceChars); (character, red) = ReadUntil(sr, character, spaceChars); character = SkipUntilNot(sr, character, spaceChars); (character, green) = ReadUntil(sr, character, spaceChars); character = SkipUntilNot(sr, character, spaceChars); (character, blue) = ReadUntil(sr, character, spaceChars.Concat(new[] { ObjectClose })); SkipUntil(sr, character, new[] { ObjectClose }); return(new Color { Red = int.Parse(red), Green = int.Parse(green), Blue = int.Parse(blue) }); }
/// <summary> /// Create <see cref="ScopedIndentOptions"/> that represent an indented block delimited with the specified prefix and suffix (with a new line before each one). /// </summary> /// <param name="prefix"> /// The block prefix (written before the block is opened). /// </param> /// <param name="suffix"> /// The block suffix (written after the block is closed). /// </param> /// <param name="prefixNewLines"> /// Optional new-line settings for the scope prefix. /// /// Defaults to <see cref="NewLines.Before"/>. /// </param> /// <param name="suffixNewlines"> /// Optional new-line settings for the scope suffix. /// /// Defaults to <see cref="NewLines.Before"/>. /// </param> /// <returns> /// The scoped indent options. /// </returns> public static ScopedIndentOptions DelimitedBlock(string prefix, string suffix, NewLines prefixNewLines = NewLines.Before, NewLines suffixNewlines = NewLines.Before) { return new ScopedIndentOptions( prefix, prefixNewLines, suffix, suffixNewlines ); }
/// <summary> /// Parses an object into a ReadOnlyCollection /// - An IReadOnlyCollection of value types will expect no prop seperators, just values /// - An IReadOnlyCollection of key/value pairs or IReadOnlyDictionary will /// map all key/values as expected /// - An IReadOnlyCollection of objects will read the seperate objects /// </summary> /// <param name="sr">The stream reader, having just read the object start.</param> /// <param name="type">The type of the collection.</param> /// <returns></returns> private object ParseObjectAsCollection(StreamReader sr, Type type) { var genericTypeArguments = type.GetGenericArguments(); if (genericTypeArguments.Length == 2 && type.IsAssignableFrom(typeof(IReadOnlyDictionary <,>).MakeGenericType(genericTypeArguments[0], genericTypeArguments[1]))) { // Dictionary var t1 = type.GetGenericArguments()[0]; var t2 = type.GetGenericArguments()[1]; var dictType = typeof(Dictionary <,>).MakeGenericType(t1, t2); var instance = dictType.GetConstructor(new Type[0]).Invoke(new object[0]); var kvPairType = typeof(KeyValuePair <,>).MakeGenericType(t1, t2); var add = dictType.GetMethod("Add"); while (true) { var kvPair = kvPairType .GetConstructor(new Type[0]).Invoke(new object[0]); var character = (char)sr.Read(); character = SkipUntilNot(sr, character, NewLines.Concat(Spaces)); if (character == ObjectClose) { break; } string propName; (character, propName) = ReadPropertyName(sr, character); if (t2 == typeof(string) || t2.IsValueType) { string propValue; (character, propValue) = ReadPropertyStringValue(sr, character); kvPairType.GetProperty("Key").SetValue(kvPair, propName); kvPairType.GetProperty("Value").SetValue(kvPair, propValue); add.Invoke(instance, new[] { kvPair }); } else { character = SkipUntil(sr, character, new[] { ObjectOpen }); var propValue = Parse(sr, t2, propName); kvPairType.GetProperty("Key").SetValue(kvPair, propName); kvPairType.GetProperty("Value").SetValue(kvPair, propValue); add.Invoke(instance, new[] { kvPair }); } } return(instance); } else { var genericType = type.GetGenericArguments()[0]; var genericTypeGenericArgs = genericType.GetGenericArguments(); if (genericTypeGenericArgs.Count() == 2 && genericType.IsAssignableFrom(typeof(KeyValuePair <,>).MakeGenericType( genericTypeGenericArgs[0], genericTypeGenericArgs[1]))) { var t1 = genericType.GetGenericArguments()[0]; var t2 = genericType.GetGenericArguments()[1]; // collection of k/v pairs var listType = typeof(List <>).MakeGenericType(genericType); var instance = listType.GetConstructor(new Type[0]).Invoke(new object[0]); var kvPairType = typeof(KeyValuePair <,>).MakeGenericType(t1, t2); var add = listType.GetMethod("Add"); while (true) { var character = (char)sr.Read(); character = SkipUntilNot(sr, character, NewLines.Concat(Spaces)); if (character == ObjectClose || character == Eof) { break; } string propName; (character, propName) = ReadPropertyName(sr, character); if (t2 == typeof(string) || t2.IsValueType) { string propValue; (character, propValue) = ReadPropertyStringValue(sr, character); var kvPair = kvPairType .GetConstructor(new Type[] { t1, t2 }).Invoke(new object[] { propName, propValue }); add.Invoke(instance, new[] { kvPair }); } else { character = SkipUntil(sr, character, new[] { ObjectOpen }); var propValue = Parse(sr, t2, propName); var kvPair = kvPairType .GetConstructor(new Type[] { t1, t2 }).Invoke(new object[] { propName, propValue }); add.Invoke(instance, new[] { kvPair }); } } return(instance); } else if (genericType == typeof(string) || genericType.IsValueType) { // List of value types var listType = typeof(List <>).MakeGenericType(genericType); var list = listType.GetConstructor(new Type[0]).Invoke(new object[0]); var add = listType.GetMethod("Add"); while (true) { var character = (char)sr.Read(); character = SkipUntilNot(sr, character, NewLines.Concat(Spaces)); if (character == ObjectClose || character == Eof) { break; } string propValue; (character, propValue) = ReadPropertyStringValue(sr, character); add.Invoke(list, new[] { ParseStringValue(propValue, genericType) }); } return(list); } else { // List of objects var listType = typeof(List <>).MakeGenericType(genericType); var list = listType.GetConstructor(new Type[0]).Invoke(new object[0]); var add = listType.GetMethod("Add"); while (true) { var character = (char)sr.Read(); character = SkipUntilNot(sr, character, NewLines.Concat(Spaces)); if (character == ObjectClose || character == Eof) { break; } string propName; (character, propName) = ReadPropertyName(sr, character); var value = Parse(sr, genericType, propName); add.Invoke(list, new[] { value }); } return(list); } } }
private object ParseObject(StreamReader sr, Type type, string objPropName) { var instance = type.GetConstructor(new Type[0]).Invoke(new object[0]); if (!propAttributeDetails.ContainsKey(type)) { propAttributeDetails[type] = new PropAttributeDetails(type); } var propDetails = propAttributeDetails[type]; if (propDetails.PropertyName != null) { propDetails.PropertyName.SetValue(instance, objPropName); } object remainingList = null; MethodInfo add = null; Type remainingGenericType = null; Type secondGenericType = null; if (propDetails.Remaining.Item2 != null) { var propType = propDetails.Remaining.Item2.PropertyType; var propGenericTypeArguments = propType.GetGenericArguments(); remainingGenericType = propGenericTypeArguments[0]; if (propGenericTypeArguments.Length == 2 && propType.IsAssignableFrom(typeof(IReadOnlyDictionary <,>).MakeGenericType(remainingGenericType, propGenericTypeArguments[1]))) { secondGenericType = propGenericTypeArguments[1]; var kvpType = typeof(KeyValuePair <,>).MakeGenericType(remainingGenericType, secondGenericType); var listType = typeof(List <>).MakeGenericType(kvpType); remainingList = listType.GetConstructor(new Type[0]).Invoke(new object[0]); add = listType.GetMethod("Add"); } else { var listType = typeof(List <>).MakeGenericType(remainingGenericType); remainingList = listType.GetConstructor(new Type[0]).Invoke(new object[0]); add = listType.GetMethod("Add"); } } while (true) { var character = (char)sr.Read(); character = SkipUntilNot(sr, character, NewLines.Concat(Spaces)); if (character == ObjectClose || character == Eof) { break; } string propName; (character, propName) = ReadPropertyName(sr, character); PropertyInfo prop = null; bool remaining = false; if (propDetails.Names.ContainsKey(propName)) { prop = propDetails.Names[propName]; } else if (propDetails.Remaining.Item1 != null && !propDetails.Remaining.Item1.Contains(propName)) { remaining = true; } if (character == ObjectOpen) { if (prop != null) { var value = Parse(sr, prop.PropertyType, propName); prop.SetValue(instance, value); } else if (remaining) { if (secondGenericType != null) { var value = Parse(sr, secondGenericType, propName); var kvpType = typeof(KeyValuePair <,>).MakeGenericType(remainingGenericType, secondGenericType); var kvp = kvpType.GetConstructor(new Type[] { remainingGenericType, secondGenericType }) .Invoke(new object[] { propName, value }); add.Invoke(remainingList, new[] { kvp }); } else { var value = Parse(sr, remainingGenericType, propName); add.Invoke(remainingList, new[] { value }); } } else { (character) = SkipUntil(sr, character, new[] { ObjectClose, Eof }); } } else { if (prop != null) { string propValue; (character, propValue) = ReadPropertyStringValue(sr, character); if (prop.PropertyType.IsGenericType && prop.PropertyType.GetGenericTypeDefinition() == typeof(IReadOnlyCollection <>)) { var gt = prop.PropertyType.GetGenericArguments()[0]; var listType = typeof(List <>).MakeGenericType(gt); var addToList = listType.GetMethod("Add"); object list = prop.GetValue(instance); if (list == null) { list = listType.GetConstructor(new Type[0]).Invoke(new object[0]); } addToList.Invoke(list, new[] { ParseStringValue(propValue, gt) }); prop.SetValue(instance, list); } else { prop.SetValue(instance, ParseStringValue(propValue, prop.PropertyType)); } } else if (remaining) { string propValue; (character, propValue) = ReadPropertyStringValue(sr, character); if (secondGenericType != null) { var kvpType = typeof(KeyValuePair <,>).MakeGenericType(remainingGenericType, secondGenericType); var kvp = kvpType.GetConstructor(new Type[] { remainingGenericType, secondGenericType }) .Invoke(new object[] { propName, propValue }); add.Invoke(remainingList, new[] { kvp }); } else { add.Invoke(remainingList, new[] { ParseStringValue(propValue, remainingGenericType) }); } } else { (character, _) = ReadPropertyStringValue(sr, character); } } } if (remainingList != null) { if (secondGenericType != null) { // We have a dictionary var dictType = typeof(IDictionary <,>).MakeGenericType(remainingGenericType, secondGenericType); var kvEnumType = typeof(IEnumerable <>).MakeGenericType(typeof(KeyValuePair <,>).MakeGenericType(remainingGenericType, secondGenericType)); var dict = typeof(Dictionary <,>).MakeGenericType(remainingGenericType, secondGenericType).GetConstructor(new Type[] { kvEnumType }) .Invoke(new[] { remainingList }); remainingList = typeof(ReadOnlyDictionary <,>).MakeGenericType(remainingGenericType, secondGenericType).GetConstructor(new Type[] { dictType }).Invoke(new[] { dict }); } propDetails.Remaining.Item2.SetValue(instance, remainingList); } return(instance); }
private JToken ParseObject(StreamReader sr, string filename = null) { var obj = new JObject(); var properties = new List <KeyValuePair <string, object> >(); if (!string.IsNullOrEmpty(filename)) { properties.Add(new KeyValuePair <string, object>("_filename", filename)); } while (true) { var character = (char)sr.Read(); // Get the stream to the start of something interesting character = SkipUntilNot(sr, character, NewLines.Concat(Spaces)); // We have reached the end of the object, end the loop if (character == ObjectClose || character == Eof) { break; } string propName; // Read until we reach something which tells us the property name is done, or the object has closed (character, propName) = ReadUntil(sr, character, new[] { PropertySeperator, ObjectClose }); if (propName.Trim() == "I03_surface_research_initiative") { var a = 2; } if (character == ObjectClose) { // We've reached the end of the object, without finding a property seperator // It's a value list var values = SplitList(propName); var jarray = JArray.FromObject(values); return(jarray); } else if (character == PropertySeperator) { // It's a kv pair, read the value side, either as a value or another object character = SkipUntilNot(sr, character, NewLines.Concat(Spaces).Concat(new[] { PropertySeperator })); if (character == ObjectOpen) { var objValue = ParseObject(sr); properties.Add(new KeyValuePair <string, object>(propName.Trim(), objValue)); } else { string propValue; (character, propValue) = ReadPropertyStringValue(sr, character); properties.Add(new KeyValuePair <string, object>(propName.Trim(), propValue.Trim())); } } } var groupedProperties = properties.GroupBy(x => x.Key); foreach (var groupedProp in groupedProperties) { if (_ignore.Should(groupedProp.Key)) { continue; } if (groupedProp.Count() == 1) { obj[groupedProp.Key] = JToken.FromObject(groupedProp.Single().Value); } else { var values = groupedProp.Select(x => x.Value); obj[groupedProp.Key] = JArray.FromObject(values); } } return(obj); }