1 #Region "Microsoft.VisualBasic::88db7a47dcf4f850c6ec7720b67b9a75, Microsoft.VisualBasic.Core\ComponentModel\Settings\Inf\INIProfile.vb"
2
3     ' Author:
4     
5     '       asuka (amethyst.asuka@gcmodeller.org)
6     '       xie (genetics@smrucc.org)
7     '       xieguigang (xie.guigang@live.com)
8     
9     ' Copyright (c) 2018 GPL3 Licensed
10     
11     
12     ' GNU GENERAL PUBLIC LICENSE (GPL3)
13     
14     
15     ' This program is free software: you can redistribute it and/or modify
16     ' it under the terms of the GNU General Public License as published by
17     ' the Free Software Foundation, either version 3 of the License, or
18     ' (at your option) any later version.
19     
20     ' This program is distributed in the hope that it will be useful,
21     ' but WITHOUT ANY WARRANTY; without even the implied warranty of
22     ' MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
23     ' GNU General Public License for more details.
24     
25     ' You should have received a copy of the GNU General Public License
26     ' along with this program. If not, see <http://www.gnu.org/licenses/>.
27
28
29
30     ' /********************************************************************************/
31
32     ' Summaries:
33
34     '     Module INIProfile
35     
36     '         Function: __isCommentsOrBlank, GetValue
37     
38     '         SubSetValue
39     
40     
41     ' /********************************************************************************/
42
43 #End Region
44
45 Imports System.Text.RegularExpressions
46 Imports System.Text
47 Imports Microsoft.VisualBasic.Scripting.MetaData
48 Imports Microsoft.VisualBasic.CommandLine.Reflection
49
50 Namespace ComponentModel.Settings.Inf
51
52     ''' <summary>
53     ''' Wrapper class for *.ini and *.inf configure file.(可能文件中的注释行会受到影响,所以请尽量使用本类型中的两个静态函数来操作INI文件)
54     ''' </summary>
55     ''' <remarks></remarks>
56     ''' 
57     <Package("Settings.Inf",
58                       Description:="Wrapper class for *.ini and *.inf configure file.", Url:="http://gcmodeller.org", Publisher:="xie.guigang@live.com")>
59     Public Module INIProfile
60
61         Const REGEX_SECTION_HEAD As String = "^\s*\[[^]]+\]\s*$"
62         Const REGEX_KEY_VALUE_ITEM As String = "^\s*[^=]+\s*=\s*.*$"
63
64         ''' <summary>
65         ''' Get the value from a specific section/key in a file of path 
66         ''' </summary>
67         ''' <param name="path"></param>
68         ''' <param name="key"></param>
69         ''' <returns></returns>
70         ''' <remarks></remarks>
71         ''' 
72         <ExportAPI("GetValue",
73                    Info:="Get profile data from the ini file which the data is stores in a specific path like:  section/key")>
74         Public Function GetValue(path As String, Section As String, key As StringAs String
75             Dim strLines As String() = (From line As String In IO.File.ReadAllLines(path)
76                                         Let strLine As String = line.Trim
77                                         Where Not __isCommentsOrBlank(strLine)
78                                         Select strLine).ToArray
79             Dim LQuery = (From line As String In strLines
80                           Where Regex.Match(line, String.Format("^\s*\[{0}\]\s*$", Section)).Success
81                           Select line).ToArray
82             Dim Index As Integer = If(LQuery.IsNullOrEmpty, -1, Array.IndexOf(strLines, LQuery.First))
83
84             If Index = -1 Then Return ""
85
86             For Index = Index + 1 To strLines.Length - 1
87                 Dim strLine As String = strLines(Index)
88                 If Regex.Match(strLine.Trim, String.Format("^\s*{0}\s*=\s*.*$", key)).Success Then
89                     Dim p = InStr(strLine, "=")
90                     strLine = Mid(strLine, p + 1).Trim
91                     Return strLine
92                 ElseIf Regex.Match(strLine.Trim, REGEX_SECTION_HEAD).Success Then
93                     Return ""  '没有找到,则返回空值
94                 End If
95             Next
96
97             Return ""
98         End Function
99
100         Private Function __isCommentsOrBlank(strLine As StringAs Boolean
101             Return String.IsNullOrEmpty(strLine) OrElse (strLine.First = ";"OrElse strLine.First = "#"c)
102         End Function
103
104         <ExportAPI("SetValue",
105                    Info:="Setting profile data from the ini file which the data is stores in a specific path like:  section/key. If the path is not exists, the function will create new.")>
106         Public Sub SetValue(path As String, Section As String, key As String, value As String)
107             Dim strLines As String() = IO.File.ReadAllLines(path)
108             Dim sectionFind As String = $"^\s*\[{Section}\]\s*$"
109             Dim LQuery = (From line As String In strLines
110                           Let strLine As String = line.Trim
111                           Where Not __isCommentsOrBlank(strLine) AndAlso Regex.Match(line, sectionFind).Success
112                           Select line).ToArray
113             Dim index As Integer = If(LQuery.IsNullOrEmpty, -1, Array.IndexOf(strLines, LQuery.First))
114
115             If index = -1 Then '没有找到该Section,则进行新建
116                 Dim sBuilder As StringBuilder = New StringBuilder(1024)
117                 Call sBuilder.AppendLine()
118                 Call sBuilder.AppendLine($"[{Section}]")
119                 Call sBuilder.AppendLine($"{key}={value}")
120                 Call FileIO.FileSystem.WriteAllText(path, sBuilder.ToString, append:=True)
121             Else            '当存在该Section的时候,则从该Index位置处开始进行key的搜索
122                 Dim keyFind As String = $"^\s*{key}\s*=\s*.*$"
123
124                 For index = index + 1 To strLines.Length - 1
125                     Dim strLine As String = strLines(index)
126                     If Regex.Match(strLine.Trim, keyFind).Success Then
127                         strLines(index) = $"{key}={value}"
128                         Call IO.File.WriteAllLines(path, strLines)
129                     ElseIf Regex.Match(strLine.Trim, REGEX_SECTION_HEAD).Success Then
130                         GoTo NEW_KEY    '没有找到,则进行新建
131                     End If
132                 Next
133
134 NEW_KEY:        Dim List = strLines.AsList
135                 Call List.Insert(index, $"{key}={value}")
136                 Call IO.File.WriteAllLines(path, List.ToArray)
137
138             End If
139         End Sub
140     End Module
141 End Namespace