Beispiel #1
0
 /// <summary>
 /// Register a custom option parser.
 /// </summary>
 /// <param name="parser">Registers the parser, if the associated type does not already have a parser registered.</param>
 /// <param name="replace">If set to true, the parser will be registered in place of an existing parser for its type.</param>
 public static void RegisterParser(ParserBase parser, bool replace = false)
 {
     if (replace || !Parsers.ContainsKey(parser.Type))
     {
         Parsers[parser.Type] = parser;
     }
 }
Beispiel #2
0
        /// <summary>
        /// Converts a config file text to the a config object of the specified type.
        /// </summary>
        /// <typeparam name="T"></typeparam>
        /// <param name="lines">The lines of the config file to be converted</param>
        /// <returns>The converted config object</returns>
        public static T Parse <T>(IEnumerable <string> lines) where T : new()
        {
            T config = (T)Activator.CreateInstance(typeof(T));

            foreach (string line in lines)
            {
                Match match = Regex.Match(line, $"^<{_allowedCharacters}>\\[{_allowedCharacters}\\]:");
                if (match.Success)
                {
                    string optionString = match.Value;
                    string valueString  = line.Substring(optionString.Length);

                    string typeTag = Regex.Match(optionString, $"<{_allowedCharacters}>").Value;
                    typeTag = typeTag.Substring(1, typeTag.Length - 2);
                    string optionName = Regex.Match(optionString, $"\\[{_allowedCharacters}\\]").Value;
                    optionName = optionName.Substring(1, optionName.Length - 2);

                    bool successflag = false;
                    foreach (PropertyInfo property in typeof(T).GetProperties())
                    {
                        ParserBase parser = null;
                        foreach (ParserBase p in Parsers.Values)
                        {
                            if (p.Tag.Equals(typeTag))
                            {
                                parser = p;
                                break;
                            }
                        }
                        if (parser == null)
                        {
                            throw new ConfigException($"No parser found with tag '{typeTag}'");
                        }

                        object[] attr            = property.GetCustomAttributes(typeof(Option), true);
                        Option   optionAttribute = attr.Length > 0 ? (Option)attr[0] : null;
                        //if ((optionAttribute != null && ((optionAttribute.Name != null && optionName.Equals(optionAttribute.Name)) || )) || (configAttribute.UseAllProperties && property.Name.Equals(optionName)))
                        if (optionAttribute != null)
                        {
                            if (!string.IsNullOrEmpty(optionAttribute.Name))
                            {
                                if (optionAttribute.Name.Equals(optionName))
                                {
                                    property.SetValue(config, parser.Decode(valueString.Trim()));
                                    successflag = true;
                                    break;
                                }
                            }
                            else
                            {
                                if (property.Name.Equals(optionName))
                                {
                                    property.SetValue(config, parser.Decode(valueString.Trim()));
                                    successflag = true;
                                    break;
                                }
                            }
                        }
                        else
                        {
                            if (property.Name.Equals(optionName))
                            {
                                property.SetValue(config, parser.Decode(valueString.Trim()));
                                successflag = true;
                                break;
                            }
                        }
                    }
                    if (!successflag)
                    {
                        throw new ConfigException($"Failed to map option {optionName} to a property of {typeof(T)}");
                    }
                }
            }
            return(config);
        }
Beispiel #3
0
        /// <summary>
        /// Serializes a config
        /// </summary>
        /// <typeparam name="T"></typeparam>
        /// <param name="config">The config object to serialize</param>
        /// <returns>An array of lines that make up the config file text</returns>
        public static string[] Serialize <T>(T config)
        {
            Config configAttribute = GetAttribute <T>();

            //Get options
            List <string> regions = new List <string> {
                ""
            };
            List <KeyValuePair <PropertyInfo, Option> > options = new List <KeyValuePair <PropertyInfo, Option> >();

            foreach (PropertyInfo member in typeof(T).GetProperties())
            {
                object[] attr            = member.GetCustomAttributes(typeof(Option), true);
                Option   optionAttribute = attr.Length > 0 ? (Option)attr[0] : null;
                if (optionAttribute != null || configAttribute.UseAllProperties)
                {
                    options.Add(new KeyValuePair <PropertyInfo, Option>(member, (optionAttribute == null ? new Option() : optionAttribute)));
                    if (optionAttribute != null && !regions.Contains(optionAttribute.Region))
                    {
                        regions.Add(optionAttribute.Region);
                    }
                }
            }
            options.Sort((a, b) =>
            {
                if (a.Value.Region.CompareTo(b.Value.Region) != 0)
                {
                    return(a.Value.Region.CompareTo(b.Value.Region));
                }
                else
                {
                    string aName = string.IsNullOrEmpty(a.Key.Name) ? a.Key.Name : a.Key.Name;
                    string bName = string.IsNullOrEmpty(b.Key.Name) ? b.Key.Name : b.Key.Name;
                    return(aName.CompareTo(bName));
                }
            });

            //Get comments
            List <KeyValuePair <string, string> > comments = new List <KeyValuePair <string, string> >();

            foreach (object attr in typeof(T).GetCustomAttributes(typeof(Comment), true))
            {
                Comment comment = (Comment)attr;
                comments.Add(new KeyValuePair <string, string>(comment.Region, comment.Text));
                if (!regions.Contains(comment.Region))
                {
                    regions.Contains(comment.Region);
                }
            }
            comments.Sort((a, b) =>
            {
                return(a.Key.CompareTo(b.Key));
            });

            regions.Sort();

            //Write content
            List <string> lines = new List <string>();

            if (!string.IsNullOrEmpty(configAttribute.Header))
            {
                Writer.Header(lines, configAttribute.Header);
            }

            foreach (string r in regions)
            {
                if (!string.IsNullOrEmpty(r))
                {
                    Writer.Region(lines, r);
                }

                foreach (var comment in comments.Where(c => c.Key.Equals(r)))
                {
                    Writer.Comment(lines, comment.Value);
                }

                foreach (var option in options.Where(o => o.Value.Region.Equals(r)))
                {
                    if (!string.IsNullOrEmpty(option.Value.Comment))
                    {
                        Writer.Comment(lines, option.Value.Comment);
                    }

                    Type   type = option.Key.PropertyType;
                    string name = string.IsNullOrEmpty(option.Value.Name) ? option.Key.Name : option.Value.Name;
                    if (!Parsers.ContainsKey(type))
                    {
                        throw new ConfigException($"No parser registered for type {type}!");
                    }
                    ParserBase parser = Parsers[type];
                    if (!Regex.IsMatch(name, $"^{_allowedCharacters}$"))
                    {
                        throw new ConfigException($"The specified option name ({name}) is invalid.");
                    }
                    if (!Regex.IsMatch(parser.Tag, $"^{_allowedCharacters}$"))
                    {
                        throw new ConfigException($"The supplied parser for type {type} has an invalid tag: '{parser.Tag}' contains illegal characters.");
                    }
                    string value = parser.Encode(option.Key.GetValue(config));
                    lines.Add($"<{parser.Tag}>[{name}]: {value}");
                }
            }

            return(lines.ToArray());
        }