Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- ' ***********************************************************************
- ' Author : Elektro
- ' Modified : 17-December-2015
- ' ***********************************************************************
- #Region " Imports "
- Imports System
- Imports System.Collections.Generic
- Imports System.ComponentModel
- Imports System.Diagnostics
- Imports System.IO
- Imports System.Linq
- Imports System.Text
- #End Region
- #Region " INI Manager "
- Namespace Types
- ''' ----------------------------------------------------------------------------------------------------
- ''' <summary>
- ''' Manages an INI file to build sections and keys, to save or load application settings.
- ''' </summary>
- ''' ----------------------------------------------------------------------------------------------------
- Public NotInheritable Class IniManager : Implements IDisposable
- #Region " Private Fields "
- ''' ----------------------------------------------------------------------------------------------------
- ''' <summary>
- ''' The INI <see cref="FileStream"/>.
- ''' </summary>
- ''' ----------------------------------------------------------------------------------------------------
- Private fs As FileStream
- #End Region
- #Region " Properties "
- ''' ----------------------------------------------------------------------------------------------------
- ''' <summary>
- ''' Gets the initialization file (INI) path.
- ''' </summary>
- ''' ----------------------------------------------------------------------------------------------------
- ''' <value>
- ''' The initialization file (INI) path.
- ''' </value>
- ''' ----------------------------------------------------------------------------------------------------
- Public ReadOnly Property FilePath As String
- <DebuggerStepThrough>
- Get
- Return Me.filepathB
- End Get
- End Property
- ''' ----------------------------------------------------------------------------------------------------
- ''' <summary>
- ''' ( Backing field )
- ''' The initialization file (INI) path.
- ''' </summary>
- ''' ----------------------------------------------------------------------------------------------------
- Private ReadOnly filepathB As String
- ''' ----------------------------------------------------------------------------------------------------
- ''' <summary>
- ''' Gets the initialization file (INI) encoding.
- ''' </summary>
- ''' ----------------------------------------------------------------------------------------------------
- ''' <value>
- ''' The initialization file (INI) encoding.
- ''' </value>
- ''' ----------------------------------------------------------------------------------------------------
- Public ReadOnly Property Encoding As Encoding
- <DebuggerStepThrough>
- Get
- Return Me.encodingB
- End Get
- End Property
- ''' ----------------------------------------------------------------------------------------------------
- ''' <summary>
- ''' ( Backing field )
- ''' The initialization file (INI) encoding.
- ''' </summary>
- ''' ----------------------------------------------------------------------------------------------------
- Private ReadOnly encodingB As Encoding
- ''' ----------------------------------------------------------------------------------------------------
- ''' <summary>
- ''' Gets or sets the initialization file (INI) sections.
- ''' </summary>
- ''' ----------------------------------------------------------------------------------------------------
- ''' <value>
- ''' The initialization file (INI) sections.
- ''' </value>
- ''' ----------------------------------------------------------------------------------------------------
- Public Property Sections As IniSectionCollection
- <DebuggerStepThrough>
- Get
- Return Me.sectionsB
- End Get
- <DebuggerStepThrough>
- Set(ByVal value As IniSectionCollection)
- Me.sectionsB = value
- End Set
- End Property
- ''' ----------------------------------------------------------------------------------------------------
- ''' <summary>
- ''' ( Backing field )
- ''' The initialization file (INI) sections.
- ''' </summary>
- ''' ----------------------------------------------------------------------------------------------------
- Private sectionsB As IniSectionCollection
- ''' ----------------------------------------------------------------------------------------------------
- ''' <summary>
- ''' Gets the initialization file (INI) section names.
- ''' </summary>
- ''' ----------------------------------------------------------------------------------------------------
- ''' <value>
- ''' The initialization file (INI) section names.
- ''' </value>
- ''' ----------------------------------------------------------------------------------------------------
- Public ReadOnly Property SectionNames As String()
- <DebuggerStepThrough>
- Get
- Return Me.GetIniSectionNames()
- End Get
- End Property
- #End Region
- #Region " Constructors "
- ''' ----------------------------------------------------------------------------------------------------
- ''' <summary>
- ''' Prevents a default instance of the <see cref="IniManager"/> class from being created.
- ''' </summary>
- ''' ----------------------------------------------------------------------------------------------------
- <DebuggerNonUserCode>
- Private Sub New()
- End Sub
- ''' ----------------------------------------------------------------------------------------------------
- ''' <summary>
- ''' Initializes a new instance of the <see cref="IniManager"/> class.
- ''' </summary>
- ''' ----------------------------------------------------------------------------------------------------
- ''' <param name="filepath">
- ''' The initialization file (INI) path.
- ''' </param>
- '''
- ''' <param name="enc">
- ''' The encoding to read/write the INI file.
- ''' </param>
- ''' ----------------------------------------------------------------------------------------------------
- <DebuggerStepThrough>
- Public Sub New(ByVal filepath As String,
- Optional ByVal enc As Encoding = Nothing)
- Me.New(New FileInfo(filepath), enc)
- End Sub
- ''' ----------------------------------------------------------------------------------------------------
- ''' <summary>
- ''' Initializes a new instance of the <see cref="IniManager"/> class.
- ''' </summary>
- ''' ----------------------------------------------------------------------------------------------------
- ''' <param name="fileinfo">
- ''' The initialization file (INI).
- ''' </param>
- '''
- ''' <param name="enc">
- ''' The encoding to read/write the INI file.
- ''' </param>
- ''' ----------------------------------------------------------------------------------------------------
- <DebuggerStepThrough>
- Public Sub New(ByVal fileinfo As FileInfo,
- Optional ByVal enc As Encoding = Nothing)
- If String.IsNullOrEmpty(fileinfo.Name) Then
- Throw New ArgumentNullException(paramName:="fileinfo")
- Else
- If (enc Is Nothing) Then
- enc = Global.System.Text.Encoding.Default
- End If
- Me.filepathB = fileinfo.FullName
- Me.encodingB = enc
- Me.fs = New FileStream(fileinfo.FullName, FileMode.OpenOrCreate, FileAccess.ReadWrite, FileShare.Read, bufferSize:=4096)
- Me.sectionsB = Me.GetIniSections()
- End If
- End Sub
- #End Region
- #Region " Operator Overloads "
- ''' ----------------------------------------------------------------------------------------------------
- ''' <summary>
- ''' Returns a <see cref="System.String"/> that represents this instance.
- ''' </summary>
- ''' ----------------------------------------------------------------------------------------------------
- ''' <returns>
- ''' A <see cref="System.String"/> that represents this instance.
- ''' </returns>
- ''' ----------------------------------------------------------------------------------------------------
- <DebuggerStepThrough>
- Public Overrides Function ToString() As String
- Return Me.BuildIniContent()
- End Function
- #End Region
- #Region " Public Methods "
- ''' ----------------------------------------------------------------------------------------------------
- ''' <summary>
- ''' Clears the INI content.
- ''' </summary>
- ''' ----------------------------------------------------------------------------------------------------
- <DebuggerStepThrough>
- Public Sub Clear()
- Me.fs.Seek(0, SeekOrigin.Begin)
- Me.fs.SetLength(0)
- Me.sectionsB.Clear()
- End Sub
- ''' ----------------------------------------------------------------------------------------------------
- ''' <summary>
- ''' Saves the INI changes to file.
- ''' </summary>
- ''' ----------------------------------------------------------------------------------------------------
- <DebuggerStepThrough>
- Public Sub Save()
- Using ms As New MemoryStream
- Using sw As New StreamWriter(ms, Me.encodingB, bufferSize:=4096)
- sw.Write(Me.BuildIniContent)
- sw.Flush()
- ms.Seek(0, SeekOrigin.Begin)
- ms.CopyTo(Me.fs)
- Me.fs.Seek(0, SeekOrigin.Begin)
- End Using
- End Using
- End Sub
- #End Region
- #Region " Private Methods "
- ''' ----------------------------------------------------------------------------------------------------
- ''' <summary>
- ''' Gets the initialization file (INI) sections.
- ''' </summary>
- ''' ----------------------------------------------------------------------------------------------------
- ''' <returns>
- ''' An <see cref="IniSectionCollection"/> collection that contains the INI sections.
- ''' </returns>
- ''' ----------------------------------------------------------------------------------------------------
- <DebuggerStepThrough>
- Private Function GetIniSections() As IniSectionCollection
- Dim content As List(Of String) =
- Me.GetIniContent.Split({Environment.NewLine}, StringSplitOptions.RemoveEmptyEntries).ToList
- Dim sectionName As String = ""
- Dim section As IniSection
- Dim sections As New IniSectionCollection()
- Dim keyName As String = ""
- Dim keyValue As String = ""
- Dim keyComment As New StringBuilder
- Dim searchSectionNameFunc As Predicate(Of String) =
- Function(line As String)
- Return (line.TrimStart Like "[[]?*[]]*")
- End Function
- Dim sectionStartIndex As Integer
- ' Dim sectionEndIndex As Integer
- Dim keyStartIndex As Integer
- Do While True
- sectionStartIndex = content.FindIndex(sectionStartIndex, searchSectionNameFunc)
- ' sectionEndIndex = content.FindIndex(sectionStartIndex + 1, searchSectionNameFunc)
- If (sectionStartIndex <> -1) Then
- sectionName = content(sectionStartIndex).Trim({"["c, "]"c, " "c})
- section = New IniSection(sectionName)
- keyStartIndex = (sectionStartIndex + 1)
- Do While True
- If (content.Count > keyStartIndex) Then
- Dim line As String = content(keyStartIndex).Trim
- ' If line is not like "[section name]"...
- If Not (line Like "[[]?*[]]*") Then
- ' If line is like "name=value"...
- If (line Like "?*[=]?*") Then
- keyName = line.Substring(0, line.IndexOf("="c)).TrimEnd
- keyvalue = line.Substring(line.IndexOf("="c) + 1).TrimStart
- ElseIf line.StartsWith(";"c, StringComparison.Ordinal) Then
- keyComment.AppendLine(line.TrimStart(";"c))
- keyStartIndex += 1
- Continue Do
- Else ' line is not like "name=value" neither is not a comment-line...
- keyName = line.TrimEnd("="c)
- keyValue = String.Empty
- End If
- section.Keys.Add(New IniKey(keyName, keyValue, keyComment.ToString.TrimEnd))
- keyName = ""
- keyValue = ""
- keyComment.Clear()
- Else ' line is like "[section name]"
- Exit Do
- End If
- keyStartIndex += 1
- Else ' (content.Count <= keyStartIndex)
- Exit Do
- End If
- Loop
- sections.Add(section)
- sectionStartIndex += 1
- Else
- Exit Do
- End If
- Loop
- Return sections
- End Function
- ''' ----------------------------------------------------------------------------------------------------
- ''' <summary>
- ''' Gets the INI section names.
- ''' </summary>
- ''' ----------------------------------------------------------------------------------------------------
- ''' <returns>
- ''' The INI section names.
- ''' </returns>
- ''' ----------------------------------------------------------------------------------------------------
- <DebuggerStepThrough>
- Private Function GetIniSectionNames() As String()
- Return (From section As IniSection In Me.sectionsB
- Select section.Name).ToArray
- End Function
- ''' ----------------------------------------------------------------------------------------------------
- ''' <summary>
- ''' Builds the new INI content
- ''' </summary>
- ''' ----------------------------------------------------------------------------------------------------
- <DebuggerStepThrough>
- Private Function BuildIniContent() As String
- Dim sb As New StringBuilder
- For Each section As IniSection In Me.sectionsB
- ' Write section name.
- sb.AppendLine(String.Format("[{0}]", section.Name))
- If section.Keys.Any Then
- ' Get section keys.
- For Each key As IniKey In section.Keys
- If Not String.IsNullOrEmpty(key.CommentLine) Then
- ' Get commentline(s).
- Dim commentLines As String() =
- key.CommentLine.Split({Environment.NewLine}, StringSplitOptions.RemoveEmptyEntries)
- ' Fix commentlines starting character.
- For Each commentLine As String In commentLines
- If Not commentLine.StartsWith(";"c, StringComparison.InvariantCulture) Then
- commentLine = commentLine.Insert(0, ";"c)
- End If
- ' Write commentline.
- sb.AppendLine(commentLine)
- Next commentLine
- End If
- ' Write key.
- sb.AppendLine(String.Format("{0}={1}", key.Name, key.Value))
- Next key
- Else
- sb.AppendLine()
- End If
- sb.AppendLine()
- Next section
- Return sb.ToString.TrimEnd
- End Function
- ''' ----------------------------------------------------------------------------------------------------
- ''' <summary>
- ''' Gets the INI content as string.
- ''' </summary>
- ''' ----------------------------------------------------------------------------------------------------
- <DebuggerStepThrough>
- Private Function GetIniContent() As String
- Using ms As New MemoryStream()
- Me.fs.CopyTo(ms, bufferSize:=4096)
- Me.fs.Seek(0, SeekOrigin.Begin)
- ms.Seek(0, SeekOrigin.Begin)
- Using sr As New StreamReader(ms, Me.encodingB, detectEncodingFromByteOrderMarks:=False, bufferSize:=4096)
- Return sr.ReadToEnd
- End Using
- End Using
- End Function
- #End Region
- #Region " IDisposable Implementation "
- ''' ----------------------------------------------------------------------------------------------------
- ''' <summary>
- ''' To detect redundant calls when disposing.
- ''' </summary>
- ''' ----------------------------------------------------------------------------------------------------
- Private isDisposed As Boolean
- ''' ----------------------------------------------------------------------------------------------------
- ''' <summary>
- ''' Releases all the resources used by this instance.
- ''' </summary>
- ''' ----------------------------------------------------------------------------------------------------
- <DebuggerStepThrough>
- Public Sub Dispose() Implements IDisposable.Dispose
- Me.Dispose(isDisposing:=True)
- GC.SuppressFinalize(obj:=Me)
- End Sub
- ''' ----------------------------------------------------------------------------------------------------
- ''' <summary>
- ''' Performs application-defined tasks associated with freeing, releasing, or resetting unmanaged resources.
- ''' Releases unmanaged and - optionally - managed resources.
- ''' </summary>
- ''' ----------------------------------------------------------------------------------------------------
- ''' <param name="isDisposing">
- ''' <see langword="True"/> to release both managed and unmanaged resources;
- ''' <see langword="False"/> to release only unmanaged resources.
- ''' </param>
- ''' ----------------------------------------------------------------------------------------------------
- <DebuggerStepThrough>
- Private Sub Dispose(ByVal isDisposing As Boolean)
- If (Not Me.isDisposed) AndAlso (isDisposing) Then
- Me.fs.Dispose()
- Me.fs = Nothing
- Me.sectionsB.Clear()
- Me.sectionsB = Nothing
- End If
- Me.isDisposed = True
- End Sub
- #End Region
- End Class
- End Namespace
- #End Region
Add Comment
Please, Sign In to add comment