コード例 #1
0
        public static bool TryGetValue <T>(this IIniSection iniSection, string propertyName, out T propertyValue)
        {
            IIniProperty property = iniSection.GetProperty(propertyName);

            // Only attempt to convert the string if the property isn't empty, because some types will get an unexpected value (e.g. bools will be false).

            if (!string.IsNullOrWhiteSpace(property?.Value))
            {
                try {
                    Type convertType = typeof(T);

                    if (convertType.IsNullableType())
                    {
                        convertType = Nullable.GetUnderlyingType(convertType);
                    }

                    object convertedPropertyValue = Convert.ChangeType(property.Value, convertType, CultureInfo.InvariantCulture);

                    if (!(convertedPropertyValue is null))
                    {
                        propertyValue = (T)convertedPropertyValue;

                        return(true);
                    }
                }
                catch (FormatException) { }
            }

            propertyValue = default;

            return(false);
        }
コード例 #2
0
        private IniFileContainer CreateContainer(string iniFileName, IIniSection iniSection)
        {
            var iniFileConfig = IniFileConfigBuilder.Create()
                                .WithApplicationName("Dapplo")
                                .WithFilename(iniFileName)
                                .WithoutSaveOnExit()
                                .WithFixedDirectory(@"RestTests\IniTestFiles")
                                .BuildIniFileConfig();

            return(new IniFileContainer(iniFileConfig, new[] { iniSection }));
        }
コード例 #3
0
        /// <summary>
        /// Returns an Ini-section if it exists, or generates a new one using the provided generateSection method.
        /// </summary>
        /// <param name="section">Name of the section</param>
        /// <param name="generateSection">Function to generate a new section if it does not exist. Parameter is the Section</param>
        /// <returns>Implementation of IIniSection</returns>
        public IIniSection GetOrAddSection(string section, Func <string, IIniSection> generateSection)
        {
            IIniSection sec = GetSection(section);

            if (sec == null)
            {
                sec = generateSection(section);
                lock (_ini)
                    _ini.Add(sec);
            }
            return(sec);
        }
コード例 #4
0
        /// <summary>
        /// Creates a new <see cref="IIniDocument"/> using data from a <see cref="TextReader"/>.
        /// </summary>
        /// <param name='reader'>
        /// A <see cref="TextReader"/> that will supply the input data.
        /// </param>
        public static IIniDocument Read(TextReader reader)
        {
            IIniDocument output         = new IniDocument();
            IIniSection  currentSection = output;
            bool         endOfStream    = false;
            int          lineNumber     = 0;

            while (!endOfStream)
            {
                string currentLine = reader.ReadLine();
                Match  currentMatch;

                lineNumber++;

                // If we get a null response then we are at the end of the stream and can exit
                if (currentLine == null)
                {
                    endOfStream = true;
                    continue;
                }

                // We silently skip over empty lines
                if (EmptyLine.Match(currentLine).Success || CommentLine.Match(currentLine).Success)
                {
                    continue;
                }

                // If we find a 'new section' line then we create a new section and begin dealing with it
                currentMatch = SectionLine.Match(currentLine);
                if (currentMatch.Success)
                {
                    string sectionName = currentMatch.Groups[1].Value.Trim();
                    currentSection = new IniSection();
                    output.Sections.Add(sectionName, currentSection);
                    continue;
                }

                // If we find a value line then we store it within the current section.
                currentMatch = ValueLine.Match(currentLine);
                if (currentMatch.Success)
                {
                    string key   = currentMatch.Groups[1].Value.Trim();
                    string value = currentMatch.Groups[2].Value.Trim();
                    currentSection[key] = value;
                    continue;
                }

                throw new FormatException(String.Format("Invalid INI data at line {0}.", lineNumber));
            }

            return(output);
        }
コード例 #5
0
        public static bool TryGetValue <T>(this IIniDocument document, string sectionName, string propertyName, out T propertyValue)
        {
            IIniSection section = document.GetSection(sectionName);

            if (!(section is null))
            {
                return(section.TryGetValue(propertyName, out propertyValue));
            }

            propertyValue = default;

            return(false);
        }
コード例 #6
0
        /// <summary>
        ///     Automatically call the update action when the Saved fires
        ///     If the is called on a DI object, make sure it's available.
        /// </summary>
        /// <param name="iniSection">IIniSection</param>
        /// <param name="eventAction">Action to call on events, argument is the IniSectionEventArgs</param>
        /// <returns>an IDisposable, calling Dispose on this will stop everything</returns>
        public static IDisposable OnSaved(this IIniSection iniSection, Action <IniSectionEventArgs> eventAction)
        {
            if (iniSection == null)
            {
                throw new ArgumentNullException(nameof(iniSection));
            }
            if (eventAction == null)
            {
                throw new ArgumentNullException(nameof(eventAction));
            }
            var observable = Observable.FromEventPattern <EventHandler <IniSectionEventArgs>, IniSectionEventArgs>(h => iniSection.Saved += h, h => iniSection.Saved -= h);

            return(observable.Subscribe(pce => eventAction(pce.EventArgs)));
        }
コード例 #7
0
        public static async Task DepraseAsync(this IIniSection @this, TextWriter writer)
        {
            await writer.WriteAsync($"[{@this.Name}]");

            if (!string.IsNullOrEmpty(@this.Summary))
            {
                await writer.WriteAsync($"; {@this.Summary}");
            }
            await writer.WriteLineAsync();

            foreach (var item in @this)
            {
                await item.DepraseAsync(writer);

                await writer.WriteLineAsync();
            }
        }
コード例 #8
0
        public static bool TryGetValue <T>(this IIniSection iniSection, string propertyName, out T propertyValue)
        {
            IIniProperty property = iniSection.GetProperty(propertyName);

            // Only attempt to convert the string if the property isn't empty, because some types will get an unexpected value (e.g. bools will be false).

            if (!string.IsNullOrWhiteSpace(property?.Value))
            {
                try {
                    return(TypeUtilities.TryCast(property.Value, out propertyValue));
                }
                catch (FormatException) { }
            }

            propertyValue = default;

            return(false);
        }
コード例 #9
0
        /// <summary>
        ///     Helper method to fill the values of one section
        /// </summary>
        /// <param name="iniSection"></param>
        private void FillSection(IIniSection iniSection)
        {
            if (_saveTimer != null)
            {
                _saveTimer.Enabled = false;
            }

            // Make sure there is no write protection
            iniSection.RemoveWriteProtection();

            // Defaults:
            if (_defaults != null)
            {
                FillSection(_defaults, iniSection);
            }
            // Ini:
            if (_ini != null)
            {
                FillSection(_ini, iniSection);
            }
            // Constants:
            if (_constants != null)
            {
                iniSection.StartWriteProtecting();
                FillSection(_constants, iniSection);
                iniSection.StopWriteProtecting();
            }

            // After load
            iniSection.AfterLoad();

            iniSection.ResetHasChanges();

            if (_saveTimer != null)
            {
                _saveTimer.Enabled = true;
            }
        }
コード例 #10
0
 public static string GetValue(this IIniSection iniSection, string propertyName)
 {
     return(iniSection.GetValue <string>(propertyName));
 }
コード例 #11
0
 /// <summary>
 ///     The constructor of an IniValue
 /// </summary>
 /// <param name="iniSection">IIniSection</param>
 /// <param name="propertyInfo">PropertyInfo</param>
 public IniValue(IIniSection iniSection, PropertyInfo propertyInfo)
 {
     _iniSection   = iniSection;
     _propertyInfo = propertyInfo;
 }
コード例 #12
0
        /// <summary>
        ///     Put the values from the iniProperties to the proxied object
        /// </summary>
        /// <param name="iniSections"></param>
        /// <param name="iniSection"></param>
        private void FillSection(IDictionary <string, IDictionary <string, string> > iniSections, IIniSection iniSection)
        {
            var sectionName = iniSection.GetSectionName();

            // Might be null
            iniSections.TryGetValue(sectionName, out var iniProperties);

            var iniValues = from iniValue in iniSection.GetIniValues().Values.ToList()
                            where iniValue.Behavior.Read
                            select iniValue;

            foreach (var iniValue in iniValues)
            {
                ITypeDescriptorContext context = null;
                try
                {
                    var propertyDescription = TypeDescriptor.GetProperties(iniSection.GetType()).Find(iniValue.PropertyName, true);
                    context = new TypeDescriptorContext(iniSection, propertyDescription);
                }
                catch (Exception ex)
                {
                    Log.Warn().WriteLine(ex.Message);
                }

                // Test if there is a separate section for this inivalue, this is used for Dictionaries
                if (iniSections.TryGetValue($"{sectionName}-{iniValue.IniPropertyName}", out var value))
                {
                    try
                    {
                        iniValue.Value = iniValue.ValueType.ConvertOrCastValueToType(value, iniValue.Converter, context);
                        continue;
                    }
                    catch (Exception ex)
                    {
                        Log.Warn().WriteLine(ex.Message);
                    }
                }
                // Skip if the iniProperties doesn't have anything
                if (iniProperties is null || iniProperties.Count == 0)
                {
                    continue;
                }

                // Skip values that don't have a property
                if (!iniProperties.TryGetValue(iniValue.IniPropertyName, out var stringValue))
                {
                    continue;
                }

                // convert
                try
                {
                    iniValue.Value = iniValue.ValueType.ConvertOrCastValueToType(stringValue, iniValue.Converter, context);
                }
                catch (Exception ex)
                {
                    Log.Warn().WriteLine(ex.Message);
                }
            }
        }
コード例 #13
0
        /// <summary>
        ///     Helper method to create ini section values for writing.
        ///     The actual values are stored in the _ini
        /// </summary>
        /// <param name="iniSection">Section to write</param>
        /// <param name="iniSectionsComments">Comments</param>
        private void CreateSaveValues(IIniSection iniSection, IDictionary <string, IDictionary <string, string> > iniSectionsComments)
        {
            // This flag tells us if the header for the section is already written
            var isSectionCreated = false;
            var sectionName      = iniSection.GetSectionName();

            var sectionProperties = new SortedDictionary <string, string>();
            var sectionComments   = new SortedDictionary <string, string>();

            // Loop over the ini values, this automatically skips all NonSerialized properties
            foreach (var iniValue in iniSection.GetIniValues().Values.ToList())
            {
                // Check if we need to write the value, this is not needed when it has the default or if write is disabled
                if (!iniValue.IsWriteNeeded)
                {
                    // Remove the value, if it's still in the cache
                    if (_ini.ContainsKey(sectionName) && _ini[sectionName].ContainsKey(iniValue.PropertyName))
                    {
                        _ini[sectionName].Remove(iniValue.PropertyName);
                    }
                    continue;
                }

                // Before we are going to write, we need to check if the section header "[Sectionname]" is already written.
                // If not, do so now before writing the properties of the section itself
                if (!isSectionCreated)
                {
                    if (_ini.ContainsKey(sectionName))
                    {
                        _ini.Remove(sectionName);
                    }
                    _ini.Add(sectionName, sectionProperties);
                    iniSectionsComments.Add(sectionName, sectionComments);

                    var description = iniSection.GetSectionDescription();
                    if (!string.IsNullOrEmpty(description))
                    {
                        sectionComments.Add(sectionName, description);
                    }
                    // Mark section as created!
                    isSectionCreated = true;
                }

                // Check if the property has a description, if so write it in the ini comment before the property
                if (!string.IsNullOrEmpty(iniValue.Description))
                {
                    sectionComments.Add(iniValue.IniPropertyName, iniValue.Description);
                }

                ITypeDescriptorContext context = null;
                try
                {
                    var propertyDescription = TypeDescriptor.GetProperties(iniSection.GetType()).Find(iniValue.PropertyName, true);
                    context = new TypeDescriptorContext(iniSection, propertyDescription);
                }
                catch (Exception ex)
                {
                    Log.Warn().WriteLine(ex.Message);
                }

                // Get specified converter
                var converter = iniValue.Converter;

                // Special case, for idictionary derrivated types
                if (iniValue.ValueType.IsGenericType && iniValue.ValueType.GetGenericTypeDefinition() == typeof(IDictionary <,>))
                {
                    var subSection = TypeExtensions.ConvertOrCastValueToType <IDictionary <string, string> >(iniValue.Value, converter, context, false);
                    if (subSection != null)
                    {
                        try
                        {
                            // Use this to build a separate "section" which is called "[section-propertyname]"
                            string dictionaryIdentifier = $"{sectionName}-{iniValue.IniPropertyName}";
                            if (_ini.ContainsKey(dictionaryIdentifier))
                            {
                                _ini.Remove(dictionaryIdentifier);
                            }
                            _ini.Add(dictionaryIdentifier, subSection);
                            if (!string.IsNullOrWhiteSpace(iniValue.Description))
                            {
                                var dictionaryComments = new SortedDictionary <string, string>
                                {
                                    { dictionaryIdentifier, iniValue.Description }
                                };
                                iniSectionsComments.Add(dictionaryIdentifier, dictionaryComments);
                            }
                        }
                        catch (Exception ex)
                        {
                            Log.Warn().WriteLine(ex.Message);
                            //WriteErrorHandler(iniSection, iniValue, ex);
                        }
                        continue;
                    }
                }

                try
                {
                    // Convert the value to a string
                    var writingValue = TypeExtensions.ConvertOrCastValueToType <string>(iniValue.Value, converter, context, false);
                    // And write the value with the IniPropertyName (which does NOT have to be the property name) to the file
                    sectionProperties.Add(iniValue.IniPropertyName, writingValue);
                }
                catch (Exception ex)
                {
                    Log.Warn().WriteLine(ex.Message);
                    //WriteErrorHandler(iniSection, iniValue, ex);
                }
            }
        }
コード例 #14
0
 public static void SetValue <T>(this IIniSection iniSection, string propertyName, T propertyValue)
 {
     iniSection.AddProperty(new IniProperty(propertyName, Convert.ToString(propertyValue, CultureInfo.InvariantCulture)));
 }
コード例 #15
0
 public static void AddProperty(this IIniSection iniSection, string name, string value)
 {
     iniSection.AddProperty(new IniProperty(name, value));
 }
コード例 #16
0
        public static T GetValue <T>(this IIniSection iniSection, string propertyName)
        {
            iniSection.TryGetValue(propertyName, out T propertyValue);

            return(propertyValue);
        }
コード例 #17
0
 public static bool HasProperty(this IIniSection iniSection, string name)
 {
     return(!(iniSection.GetProperty(name) is null));
 }