1 #Region "Microsoft.VisualBasic::16d56d95c70290312862145033f163f9, Microsoft.VisualBasic.Core\ApplicationServices\Terminal\STDIO__\STDIO.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 STDIO
35     
36     '         Function: __testEquals, MsgBox, scanf, ZeroFill
37     
38     '         Sub: cat, fprintf, print, printf
39     '         Delegate Function
40     
41     '             FunctionInputPassword, Read
42     
43     '             Sub: Write, WriteLine
44     
45     
46     
47     ' /********************************************************************************/
48
49 #End Region
50
51 Imports System.IO
52 Imports System.Runtime.CompilerServices
53 Imports Microsoft.VisualBasic.CommandLine.Reflection
54 Imports Microsoft.VisualBasic.Language.C
55 Imports Microsoft.VisualBasic.Scripting.MetaData
56 Imports Microsoft.VisualBasic.Terminal.Utility
57 Imports Microsoft.VisualBasic.Text
58
59 Namespace Terminal
60
61     ''' <summary>
62     ''' A standard input/output compatibility package that makes VisualBasic console
63     ''' program easily running on the Linux server or mac osx operating system.
64     ''' (一个用于让VisualBasic应用程序更加容易的运行于Linux服务器或者MAC系统之上的标准输入输出流的系统兼容包)
65     ''' </summary>
66     ''' <remarks></remarks>
67     <Package("STDIO", Description:="A standard input/output compatibility package that makes VisualBasic console program easily running on the Linux server or mac osx operating system.",
68                       Publisher:="xie.guigang@live.com",
69                       Revision:=569,
70                       Url:="http://gcmodeller.org")>
71     Public Module STDIO
72
73         ''' <summary>
74         ''' A dictionary list of the escape characters.(转义字符列表)
75         ''' </summary>
76         ''' <remarks></remarks>
77         Dim escapings As New Dictionary(Of StringString) From {
78  _
79             {"\o"String.Empty},
80             {"\n", vbCrLf},
81             {"\r", vbCr},
82             {"\t", vbTab},
83             {"\v"String.Empty},
84             {"\b", vbBack},
85             {"\f", vbFormFeed},
86             {"\'", ASCII.Quot},
87             {"\" & ASCII.Quot, ASCII.Quot}
88         }
89
90 #Region "printf"
91
92         ''' <summary>
93         ''' Output the string to the console using a specific formation.(按照指定的格式将字符串输出到终端窗口之上,请注意,这个函数除了将数据流输出到标准终端之外,还会输出到调试终端)
94         ''' </summary>
95         ''' <param name="s">A string to print on the console window.(输出到终端窗口之上的字符串)</param>
96         ''' <param name="args">Formation parameters.(格式化参数)</param>
97         ''' <remarks></remarks>
98         '''
99         <ExportAPI("printf"Info:="Output the string to the console using a specific formation.")>
100         Public Sub printf(s As StringParamArray args As Object())
101             s = sprintf(s, args)
102
103             Console.Write(s)
104             Call Trace.Write(s)
105             Call Debug.Write(s)
106         End Sub
107 #End Region
108
109         <Extension>
110         Public Sub fprintf(Destination As TextWriter, Format As StringParamArray Parameters As Object())
111             Destination.Write(sprintf(Format, Parameters))
112         End Sub
113
114         Public Sub print(s As StringOptional color As ConsoleColor = ConsoleColor.White)
115             Dim cl As ConsoleColor = Console.ForegroundColor
116             Console.ForegroundColor = color
117             Console.Write(s)
118             Console.ForegroundColor = cl
119         End Sub
120
121         ''' <summary>
122         ''' Alias for the <see cref="Console.Write"/>.(不换行)
123         ''' </summary>
124         ''' <param name="out"></param>
125         ''' <remarks></remarks>
126         Public Sub cat(ParamArray out As String())
127             Dim s As String = String.Join("", out)
128             Call Console.Write(s)
129         End Sub
130
131         ''' <summary>
132         ''' Read the string that user input on the console to the function paramenter.
133         ''' (将用户在终端窗口之上输入的数据赋值给一个字符串变量)
134         ''' </summary>
135         ''' <param name="s"></param>
136         ''' <returns></returns>
137         ''' <remarks></remarks>
138         Public Function scanf(ByRef s As StringOptional color As ConsoleColor = ConsoleColor.White) As String
139             Dim cl As ConsoleColor = Console.ForegroundColor
140             Call Console.Write(s)
141             Console.ForegroundColor = color
142             s = Console.ReadLine
143             Console.ForegroundColor = cl
144             Return s
145         End Function
146
147         Const ____ZERO As String =
148                 "000000000000000000000000000000000000000000000000000000000000" &
149                 "000000000000000000000000000000000000000000000000000000000000" &
150                 "000000000000000000000000000000000000000000000000000000000000" &
151                 "000000000000000000000000000000000000000000000000000000000000" &
152                 "000000000000000000000000000000000000000000000000000000000000"
153
154         ''' <summary>
155         ''' Fill the number string with specific length of ZERO sequence to generates the fixed width string.
156         ''' </summary>
157         ''' <param name="sn"></param>
158         ''' <param name="len"></param>
159         ''' <returns></returns>
160         <ExportAPI("ZeroFill"Info:="Fill the number string with specific length of ZERO sequence to generates the fixed width string.")>
161         Public Function ZeroFill(sn As String, len As IntegerAs String
162             If sn.Length >= len Then
163                 Return sn
164             Else
165                 Dim d As Integer = len - sn.Length
166                 Dim zr As String = ____ZERO.Substring(0, d)
167                 Return zr & sn
168             End If
169         End Function
170
171         ''' <summary>
172         '''
173         ''' </summary>
174         ''' <param name="prompt"></param>
175         ''' <param name="style">
176         ''' Value just allow:
177         ''' <see cref="MsgBoxStyle.AbortRetryIgnore"/>,
178         ''' <see cref="MsgBoxStyle.OkCancel"/>,
179         ''' <see cref="MsgBoxStyle.OkOnly"/>,
180         ''' <see cref="MsgBoxStyle.RetryCancel"/>,
181         ''' <see cref="MsgBoxStyle.YesNo"/>,
182         ''' <see cref="MsgBoxStyle.YesNoCancel"/></param>
183         ''' <returns></returns>
184         Public Function MsgBox(prompt As StringOptional style As MsgBoxStyle = MsgBoxStyle.YesNo) As MsgBoxResult
185             Dim [default] As String = ""
186
187             Call Console.WriteLine(prompt)
188
189             If style = MsgBoxStyle.AbortRetryIgnore Then
190                 Call Console.Write("Abort/Retry/Ignore?(a/r/i) [R]")
191                 [default] = "R"
192             ElseIf style = MsgBoxStyle.OkCancel Then
193                 Call Console.Write("Ok/Cancel?(o/c) [O]")
194                 [default] = "O"
195             ElseIf style = MsgBoxStyle.OkOnly Then
196                 Call Console.WriteLine("Press any key to continute...")
197                 Call Console.ReadKey()
198                 Return MsgBoxResult.Ok
199             ElseIf style = MsgBoxStyle.RetryCancel Then
200                 Call Console.Write("Retry/Cancel?(r/c) [R]")
201                 [default] = "R"
202             ElseIf style = MsgBoxStyle.YesNo Then
203                 Call Console.Write("Yes/No?(y/n) [Y]")
204                 [default] = "Y"
205             ElseIf style = MsgBoxStyle.YesNoCancel Then
206                 Call Console.Write("Yes/No/Cancel?(y/n/c) [Y]")
207                 [default] = "Y"
208             End If
209
210             Call Console.Write("  ")
211
212             Dim input As String = Console.ReadLine
213             If String.IsNullOrEmpty(input) Then
214                 input = [default]
215             Else
216                 input = input.ToUpper
217             End If
218
219             If style = MsgBoxStyle.AbortRetryIgnore Then
220                 If __testEquals(input, "A"c) Then
221                     Return MsgBoxResult.Abort
222                 ElseIf __testEquals(input, "R"c) Then
223                     Return MsgBoxResult.Retry
224                 ElseIf __testEquals(input, "I"c) Then
225                     Return MsgBoxResult.Ignore
226                 Else
227                     Return MsgBoxResult.Retry
228                 End If
229             ElseIf style = MsgBoxStyle.OkCancel Then
230
231                 If __testEquals(input, "O"c) Then
232                     Return MsgBoxResult.Ok
233                 ElseIf __testEquals(input, "C"c) Then
234                     Return MsgBoxResult.Cancel
235                 Else
236                     Return MsgBoxResult.Ok
237                 End If
238             ElseIf style = MsgBoxStyle.OkOnly Then
239                 Return MsgBoxResult.Ok
240             ElseIf style = MsgBoxStyle.RetryCancel Then
241
242                 If __testEquals(input, "R"c) Then
243                     Return MsgBoxResult.Retry
244                 ElseIf __testEquals(input, "C"c) Then
245                     Return MsgBoxResult.Cancel
246                 Else
247                     Return MsgBoxResult.Retry
248                 End If
249             ElseIf style = MsgBoxStyle.YesNo Then
250
251                 If __testEquals(input, "Y"c) Then
252                     Return MsgBoxResult.Yes
253                 ElseIf __testEquals(input, "N"c) Then
254                     Return MsgBoxResult.No
255                 Else
256                     Return MsgBoxResult.Yes
257                 End If
258             ElseIf style = MsgBoxStyle.YesNoCancel Then
259
260                 If __testEquals(input, "Y"c) Then
261                     Return MsgBoxResult.Yes
262                 ElseIf __testEquals(input, "N"c) Then
263                     Return MsgBoxResult.No
264                 ElseIf __testEquals(input, "C"c) Then
265                     Return MsgBoxResult.Cancel
266                 Else
267                     Return MsgBoxResult.Yes
268                 End If
269             Else
270                 Return MsgBoxResult.Ok
271             End If
272         End Function
273
274         ''' <summary>
275         '''
276         ''' </summary>
277         ''' <param name="input"></param>
278         ''' <param name="compare">大写的</param>
279         ''' <returns></returns>
280         Private Function __testEquals(input As String, compare As CharAs Boolean
281             If String.IsNullOrEmpty(input) Then
282                 Return False
283             End If
284             Return Asc(input.First) = Asc(compare)
285         End Function
286
287         Public Delegate Function TryParseDelegate(Of T)(str$, ByRef val As T) As Boolean
288
289         ''' <summary>
290         ''' Read Method with Generics &amp; Delegate
291         ''' 
292         ''' In a console application there is often the need to ask (and validate) some data from users. 
293         ''' For this reason I have created a function that make use of generics and delegates to 
294         ''' speed up programming.
295         ''' 
296         ''' > http://www.codeproject.com/Tips/1108772/Read-Method-with-Generics-Delegate
297         ''' </summary>
298         ''' <typeparam name="T"></typeparam>
299         ''' <param name="msg"></param>
300         ''' <param name="parser"></param>
301         ''' <param name="_default"></param>
302         ''' <returns></returns>
303         Public Function Read(Of T)(msg$, parser As TryParseDelegate(Of T), Optional _default$ = NothingAs T
304             Dim line As String
305             Dim value As T
306             Do
307                 Call Console.Write(msg)
308
309                 If Not _default.StringEmpty Then
310                     Call Console.Write($" <default={_default}>")
311                 End If
312
313                 Call Console.Write(": ")
314
315                 line = Console.ReadLine()
316
317                 If String.IsNullOrWhiteSpace(line) Then
318                     line = _default?.ToString()
319                 End If
320             Loop While Not parser(line, value)
321             Return value
322         End Function
323
324         ''' <summary>
325         ''' Writes the text representation of the specified object to the standard output
326         ''' stream.
327         ''' </summary>
328         ''' <param name="o">The value to write, or null.</param>
329         Public Sub Write(o As Object)
330             If VBDebugger.ForceSTDError Then
331                 Call Console.Error.Write(o)
332             Else
333                 Call Console.Write(o)
334             End If
335         End Sub
336
337         ''' <summary>
338         ''' Writes the text representation of the specified object, followed by the current
339         ''' line terminator, to the standard output stream.
340         ''' </summary>
341         ''' <param name="o">The value to write.</param>
342         Public Sub WriteLine(Optional o As Object = Nothing)
343             If VBDebugger.ForceSTDError Then
344                 Call Console.Error.WriteLine(o)
345             Else
346                 Call Console.WriteLine(o)
347             End If
348         End Sub
349
350         Public Function InputPassword(Optional prompt$ = "input your password"Optional maxLength% = 20) As String
351             Dim pass$ = Nothing
352             Call Console.Write(prompt & ": ")
353             Call New ConsolePasswordInput().PasswordInput(pass, maxLength)
354             Return pass
355         End Function
356     End Module
357 End Namespace