📄 strings.vb
字号:
'' Strings.vb'' Author:' Mizrahi Rafael (rafim@mainsoft.com)' Boris Kirzner (borisk@mainsoft.com)''' Copyright (C) 2002-2006 Mainsoft Corporation.' Copyright (C) 2004-2006 Novell, Inc (http://www.novell.com)'' Permission is hereby granted, free of charge, to any person obtaining' a copy of this software and associated documentation files (the' "Software"), to deal in the Software without restriction, including' without limitation the rights to use, copy, modify, merge, publish,' distribute, sublicense, and/or sell copies of the Software, and to' permit persons to whom the Software is furnished to do so, subject to' the following conditions:' ' The above copyright notice and this permission notice shall be' included in all copies or substantial portions of the Software.' ' THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,' EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF' MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND' NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE' LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION' OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION' WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.'Imports SystemImports System.CollectionsImports System.TextImports System.GlobalizationImports Microsoft.VisualBasicImports Microsoft.VisualBasic.CompilerServicesNamespace Microsoft.VisualBasic Public Module Strings Private PredefinedNumericFormats As Hashtable Private PredefinedDateTimeFormats As Hashtable Private PredefinedNumbersAfterDigitalSign() As String = {".00", _ ".", _ ".0", _ ".00", _ ".000", _ ".0000", _ ".00000", _ ".000000", _ ".0000000", _ ".00000000", _ ".000000000", _ ".0000000000"} Sub New() PredefinedNumericFormats = New Hashtable PredefinedNumericFormats.Add("General Number", "{0:G}") PredefinedNumericFormats.Add("Currency", "{0:C}") PredefinedNumericFormats.Add("Fixed", "{0:F}") PredefinedNumericFormats.Add("Standard", "{0:N}") PredefinedNumericFormats.Add("Percent", "{0:0.00%}") PredefinedNumericFormats.Add("percent", "{0:0.00%}") PredefinedNumericFormats.Add("Scientific", "{0:0.00E+00}") PredefinedDateTimeFormats = New Hashtable PredefinedDateTimeFormats.Add("General Date", "{0:G}") PredefinedDateTimeFormats.Add("Long Date", "{0:D}") 'FIXME : check more of Medium Date PredefinedDateTimeFormats.Add("Medium Date", "{0:D}") PredefinedDateTimeFormats.Add("Short Date", "{0:d}") PredefinedDateTimeFormats.Add("Long Time", "{0:T}") 'FIXME : check more of Medium Time PredefinedDateTimeFormats.Add("Medium Time", "{0:T}") PredefinedDateTimeFormats.Add("Short Time", "{0:t}") End Sub Public Function Asc(ByVal c As Char) As Integer Dim enc As System.Text.Encoding enc = System.Text.Encoding.GetEncoding(Threading.Thread.CurrentThread.CurrentCulture.TextInfo.ANSICodePage) Dim bytes() As Byte bytes = enc.GetBytes(New Char() {c}) Return bytes(0) End Function Public Function AscW(ByVal c As Char) As Integer ' Compiled as if it were "Return CInt(c)" when /novbruntimeref is used; ' No AscW or other method is called. Return AscW(c) End Function Public Function Asc(ByVal s As String) As Integer If (s Is Nothing) Then Throw New ArgumentException("Length of argument 'String' must be greater than zero.") End If If (s.Length.Equals(0)) Then Throw New ArgumentException("Length of argument 'String' must be greater than zero.") End If Return Asc(s.Chars(0)) End Function Public Function AscW(ByVal s As String) As Integer If (s Is Nothing) Then Throw New ArgumentException("Length of argument 'String' must be greater than zero.") End If If (s.Length.Equals(0)) Then Throw New ArgumentException("Length of argument 'String' must be greater than zero.") End If Return AscW(s.Chars(0)) End Function 'MONOTODO: Chr should use the Encoding class in the System.Text. see the Chr documentation. Public Function Chr(ByVal CharCode As Integer) As Char 'FIXME: The docs state that CharCode can be: (CharCode >= -32768) OR (CharCode <= 65535) ' but .NET throws ArgumentException for: (CharCode < 0) AND (CharCode > 255) If ((CharCode < 0) Or (CharCode > 255)) Then Throw New System.ArgumentException("Procedure call or argument is not valid.") End If If ((CharCode < -32768) Or (CharCode > 65535)) Then Throw New ArgumentException("must be within the range of -32768 to 65535.", "CharCode") End If Return System.Convert.ToChar(CharCode) End Function Public Function ChrW(ByVal CharCode As Integer) As Char#If TRACE Then Console.WriteLine("ChrW (Integer): " & CharCode.ToString)#End If If ((CharCode < -32768) Or (CharCode > 65535)) Then Throw New ArgumentException("must be within the range of -32768 to 65535.", "CharCode") End If ' -32768 through -1 is the same as +32768 through +65535 If (CharCode >= -32768) And (CharCode <= -1) Then CharCode = CharCode + 65536 End If Return System.Convert.ToChar(CharCode) End Function Public Function Filter(ByVal Source() As Object, ByVal Match As String, Optional ByVal Include As Boolean = True, _ <OptionCompare()> Optional ByVal Compare As CompareMethod = CompareMethod.Binary) As String() Dim Temp(Source.Length-1) As String If Compare = CompareMethod.Text Then Match = Match.ToLower End If Dim j As Integer = 0 For i As Integer = 0 To Source.Length - 1 Dim s As String = CStr(Source(i)) If Compare = CompareMethod.Text Then s = s.ToLower End If Dim comparisonResult As Boolean = (s.IndexOf(Match) >= 0) If comparisonResult = Include Then Temp(j) = CStr(Source(i)) j = j + 1 End If Next ReDim Preserve Temp(j - 1) Return Temp End Function Public Function Filter(ByVal Source() As String, ByVal Match As String, Optional ByVal Include As Boolean = True, _ <OptionCompare()> Optional ByVal Compare As CompareMethod = CompareMethod.Binary) As String() Dim oarr() As Object = Source Return Filter(oarr, Match, Include, Compare) End Function Public Function Format(ByVal Expression As Object, Optional ByVal Style As String = "") As String If Expression Is Nothing Then Return String.Empty End If If Style Is Nothing Then Style = String.Empty End If Select Case (Type.GetTypeCode(Expression.GetType())) 'Case TypeCode.Boolean Case TypeCode.Byte, TypeCode.Decimal, TypeCode.Double, TypeCode.Int16, _ TypeCode.Int32, TypeCode.Int64, TypeCode.SByte, TypeCode.Single, _ TypeCode.UInt16, TypeCode.UInt32, TypeCode.UInt64 Return FormatNumeric(Expression, Style) 'Case TypeCode.Char Case TypeCode.DateTime Return FormatDateTime(Expression, Style) 'Case TypeCode.DBNull 'Case TypeCode.String 'Case Else End Select Return String.Empty End Function Private Function FormatDateTime(ByVal Expression As Object, ByVal Style As String) As String Dim PredefinedStyle As Object = PredefinedDateTimeFormats(Style) If Not PredefinedStyle Is Nothing Then Return String.Format(PredefinedStyle.ToString(), Expression) End If If Style = "" Then Return String.Format("{0}", Expression) Else Return String.Format("{0:" + Style + "}", Expression) End If End Function Private Function FormatNumeric(ByVal Expression As Object, ByVal Style As String) As String Dim PredefinedStyle As Object = PredefinedNumericFormats(Style) If Not PredefinedStyle Is Nothing Then Return String.Format(PredefinedStyle.ToString(), Expression) End If If String.Compare(Style, "Yes/No", True) = 0 Then If Expression.Equals(0) Then Return "No" Else Return "Yes" End If End If If String.Compare(Style, "True/False", True) = 0 Then If Expression.Equals(0) Then Return "False" Else Return "True" End If End If If String.Compare(Style, "On/Off", True) = 0 Then If Expression.Equals(0) Then Return "Off" Else Return "On" End If End If Return String.Format("{0:" + Style + "}", Expression) End Function Public Function FormatCurrency(ByVal Expression As Object, Optional ByVal NumDigitsAfterDecimal As Integer = -1, _ Optional ByVal IncludeLeadingDigit As TriState = TriState.UseDefault, _ Optional ByVal UseParensForNegativeNumbers As TriState = TriState.UseDefault, _ Optional ByVal GroupDigits As TriState = TriState.UseDefault) As String If (NumDigitsAfterDecimal > 99) Then Throw New ArgumentException(" Argument 'NumDigitsAfterDecimal' must be within the range 0 to 99.") End If Try If TypeOf Expression Is String Then Dim tmpstr1 As String Dim tmpstr2 As String = CStr(Expression) If ((tmpstr2.StartsWith("(")) And (tmpstr2.EndsWith(")"))) Then tmpstr1 = tmpstr2.Substring(1, tmpstr2.Length - 1) tmpstr2 = tmpstr1.Substring(0, tmpstr1.Length - 2) Dim obj As CultureInfo = System.Globalization.CultureInfo.CurrentCulture() Dim currSym As String = obj.NumberFormat.CurrencySymbol() Dim ch1 As Char = CChar(tmpstr2.Substring(0, 1)) If Not Char.IsDigit(ch1) Then tmpstr2.TrimStart(CChar(currSym)) End If End If Convert.ToDouble(tmpstr2) End If Catch ex As Exception Throw New InvalidCastException(" Cast from String to type 'Double' is not valid.") End Try If Not ((TypeOf Expression Is Short) Or (TypeOf Expression Is Integer) Or (TypeOf Expression Is Long) _ Or (TypeOf Expression Is Decimal) Or (TypeOf Expression Is Single) Or (TypeOf Expression Is Double) _ Or (TypeOf Expression Is Byte)) Then Throw New InvalidCastException(" Cast to type 'Currency' is not valid.") End If If NumDigitsAfterDecimal = -1 And IncludeLeadingDigit = TriState.Usedefault _ And UseParensForNegativeNumbers = TriState.UseDefault And GroupDigits = Tristate.UseDefault Then Return String.Format("{0:C}", Expression) End If ' FIXME If UseParensForNegativeNumbers = TriState.UseDefault Then UseParensForNegativeNumbers = TriState.True End If Dim sb As StringBuilder = New StringBuilder sb.Append("{"c).Append("0"c).Append(":"c) FormatCurrency(sb, Expression, NumDigitsAfterDecimal, IncludeLeadingDigit, UseParensForNegativeNumbers, GroupDigits) If (UseParensForNegativeNumbers = TriState.True) Then sb.Append(";"c).Append("("c) FormatCurrency(sb, Expression, NumDigitsAfterDecimal, IncludeLeadingDigit, UseParensForNegativeNumbers, GroupDigits) sb.Append(")"c) End If sb.Append("}"c) Return String.Format(sb.ToString, Expression) End Function Private Sub FormatCurrency(ByVal sb As StringBuilder, ByVal Expression As Object, ByVal NumDigitsAfterDecimal As Integer, _ ByVal IncludeLeadingDigit As TriState, ByVal UseParensForNegativeNumbers As TriState, _ ByVal GroupDigits As TriState) 'FIXME : use NumberFormatInfo.CurrencyNegativePattern and NumberFormatInfo.CurrencyPositivePattern Dim currencyChar As String = System.Globalization.CultureInfo.CurrentCulture.NumberFormat.CurrencySymbol sb.Append(currencyChar) FormatNumber(sb, Expression, NumDigitsAfterDecimal, IncludeLeadingDigit, UseParensForNegativeNumbers, GroupDigits) End Sub Public Function FormatDateTime(ByVal Expression As DateTime, Optional ByVal NamedFormat As DateFormat = DateFormat.GeneralDate) As String Dim format As String Select Case NamedFormat Case DateFormat.GeneralDate If Expression.Year <= 1 Then format = CultureInfo.CurrentCulture.DateTimeFormat.LongTimePattern ElseIf (Expression.Hour = 0 And Expression.Minute = 0 _ And Expression.Second = 0 And Expression.Millisecond = 0) Then format = CultureInfo.CurrentCulture.DateTimeFormat.ShortDatePattern Else format = "G" End If Case DateFormat.LongDate format = CultureInfo.CurrentCulture.DateTimeFormat.LongDatePattern Case DateFormat.ShortDate format = CultureInfo.CurrentCulture.DateTimeFormat.ShortDatePattern Case DateFormat.LongTime format = CultureInfo.CurrentCulture.DateTimeFormat.LongTimePattern Case DateFormat.ShortTime format = "HH:mm" 'MSDN states "24-hour format (hh:mm)" 'for some reason its not CultureInfo.CurrentCulture.DateTimeFormat.ShortTimePattern Case Else Throw New ArgumentException("Procedure call or argument is not valid.") End Select Return String.Format("{0:" + format + "}", Expression) End Function Public Function FormatNumber(ByVal Expression As Object, _ Optional ByVal NumDigitsAfterDecimal As Integer = -1, _ Optional ByVal IncludeLeadingDigit As TriState = TriState.UseDefault, _ Optional ByVal UseParensForNegativeNumbers As TriState = TriState.UseDefault, _ Optional ByVal GroupDigits As TriState = TriState.UseDefault) As String If (NumDigitsAfterDecimal > 99) Then Throw New ArgumentException("Argument 'NumDigitsAfterDecimal' must be within the range 0 to 99") End If Try If TypeOf Expression Is String Then Dim tmpstr2 As String = CStr(Expression) Convert.ToDouble(tmpstr2) End If Catch ex As Exception Throw New InvalidCastException(" Cast from String to type 'Double' is not valid.") End Try If Not ((TypeOf Expression Is Short) Or (TypeOf Expression Is Integer) Or (TypeOf Expression Is Long) _ Or (TypeOf Expression Is Decimal) Or (TypeOf Expression Is Single) Or (TypeOf Expression Is Double) _ Or (TypeOf Expression Is Byte)) Then Throw New InvalidCastException(" Cast to type 'Currency' is not valid.") End If ' FIXME : what affects default values If UseParensForNegativeNumbers = TriState.UseDefault Then UseParensForNegativeNumbers = TriState.False End If If GroupDigits = TriState.UseDefault Then GroupDigits = TriState.True
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -