public static bool FromString(string Value) { throw null; }
}
[System.ComponentModel.EditorBrowsableAttribute(System.ComponentModel.EditorBrowsableState.Never)]
+ public sealed partial class CharArrayType
+ {
+ internal CharArrayType() { }
+ public static char[] FromObject(object Value) { throw null; }
+ public static char[] FromString(string Value) { throw null; }
+ }
+ [System.ComponentModel.EditorBrowsableAttribute(System.ComponentModel.EditorBrowsableState.Never)]
public sealed partial class Conversions
{
internal Conversions() { }
public StaticLocalInitFlag() { }
}
[System.ComponentModel.EditorBrowsableAttribute(System.ComponentModel.EditorBrowsableState.Never)]
+ public sealed partial class StringType
+ {
+ internal StringType() { }
+ public static string FromBoolean(bool Value) { throw null; }
+ public static string FromByte(byte Value) { throw null; }
+ public static string FromChar(char Value) { throw null; }
+ public static string FromDate(System.DateTime Value) { throw null; }
+ public static string FromDecimal(decimal Value) { throw null; }
+ public static string FromDecimal(decimal Value, System.Globalization.NumberFormatInfo NumberFormat) { throw null; }
+ public static string FromDouble(double Value) { throw null; }
+ public static string FromDouble(double Value, System.Globalization.NumberFormatInfo NumberFormat) { throw null; }
+ public static string FromInteger(int Value) { throw null; }
+ public static string FromLong(long Value) { throw null; }
+ public static string FromObject(object Value) { throw null; }
+ public static string FromShort(short Value) { throw null; }
+ public static string FromSingle(float Value) { throw null; }
+ public static string FromSingle(float Value, System.Globalization.NumberFormatInfo NumberFormat) { throw null; }
+ public static void MidStmtStr(ref string sDest, int StartPosition, int MaxInsertLength, string sInsert) { throw null; }
+ public static int StrCmp(string sLeft, string sRight, bool TextCompare) { throw null; }
+ public static bool StrLike(string Source, string Pattern, Microsoft.VisualBasic.CompareMethod CompareOption) { throw null; }
+ public static bool StrLikeBinary(string Source, string Pattern) { throw null; }
+ public static bool StrLikeText(string Source, string Pattern) { throw null; }
+ }
+ [System.ComponentModel.EditorBrowsableAttribute(System.ComponentModel.EditorBrowsableState.Never)]
public sealed partial class Utils
{
internal Utils() { }
<Compile Include="Microsoft\VisualBasic\FileIO\FileSystem.Unix.vb" />
</ItemGroup>
<ItemGroup>
- <Compile Include="Microsoft\VisualBasic\CallType.vb" />
- <Compile Include="Microsoft\VisualBasic\Collection.vb" />
<Compile Include="Microsoft\VisualBasic\ApplicationServices\StartupEventArgs.vb" />
<Compile Include="Microsoft\VisualBasic\ApplicationServices\StartupNextInstanceEventArgs.vb" />
<Compile Include="Microsoft\VisualBasic\ApplicationServices\UnhandledExceptionEventArgs.vb" />
+ <Compile Include="Microsoft\VisualBasic\CallType.vb" />
+ <Compile Include="Microsoft\VisualBasic\Collection.vb" />
+ <Compile Include="Microsoft\VisualBasic\ComClassAttribute.vb" />
<Compile Include="Microsoft\VisualBasic\CompilerServices\BooleanType.vb" />
+ <Compile Include="Microsoft\VisualBasic\CompilerServices\CharArrayType.vb" />
<Compile Include="Microsoft\VisualBasic\CompilerServices\ConversionResolution.vb" />
<Compile Include="Microsoft\VisualBasic\CompilerServices\Conversions.vb" />
<Compile Include="Microsoft\VisualBasic\CompilerServices\DecimalType.vb" />
<Compile Include="Microsoft\VisualBasic\CompilerServices\DesignerGeneratedAttribute.vb" />
+ <Compile Include="Microsoft\VisualBasic\CompilerServices\DoubleType.vb" />
<Compile Include="Microsoft\VisualBasic\CompilerServices\ExceptionUtils.vb" />
<Compile Include="Microsoft\VisualBasic\CompilerServices\IDOBinder.vb" />
<Compile Include="Microsoft\VisualBasic\CompilerServices\IncompleteInitialization.vb" />
<Compile Include="Microsoft\VisualBasic\CompilerServices\ProjectData.vb" />
<Compile Include="Microsoft\VisualBasic\CompilerServices\StandardModuleAttribute.vb" />
<Compile Include="Microsoft\VisualBasic\CompilerServices\StaticLocalInitFlag.vb" />
+ <Compile Include="Microsoft\VisualBasic\CompilerServices\StringType.vb" />
<Compile Include="Microsoft\VisualBasic\CompilerServices\StructUtils.vb" />
<Compile Include="Microsoft\VisualBasic\CompilerServices\Symbols.vb" />
<Compile Include="Microsoft\VisualBasic\CompilerServices\Utils.LateBinder.vb" />
<Compile Include="Microsoft\VisualBasic\CompilerServices\Utils.vb" />
<Compile Include="Microsoft\VisualBasic\CompilerServices\Versioned.vb" />
+ <Compile Include="Microsoft\VisualBasic\Constants.vb" />
+ <Compile Include="Microsoft\VisualBasic\ControlChars.vb" />
+ <Compile Include="Microsoft\VisualBasic\DateAndTime.vb" />
+ <Compile Include="Microsoft\VisualBasic\Devices\NetworkAvailableEventArgs.vb" />
+ <Compile Include="Microsoft\VisualBasic\ErrObject.vb" />
<Compile Include="Microsoft\VisualBasic\FileIO\FileSystem.vb" />
<Compile Include="Microsoft\VisualBasic\FileIO\MalformedLineException.vb" />
<Compile Include="Microsoft\VisualBasic\FileIO\SpecialDirectories.vb" />
<Compile Include="Microsoft\VisualBasic\FileIO\TextFieldParser.vb" />
<Compile Include="Microsoft\VisualBasic\Globals.vb" />
- <Compile Include="Microsoft\VisualBasic\Devices\NetworkAvailableEventArgs.vb" />
- <Compile Include="Microsoft\VisualBasic\ComClassAttribute.vb" />
- <Compile Include="Microsoft\VisualBasic\Constants.vb" />
- <Compile Include="Microsoft\VisualBasic\ControlChars.vb" />
<Compile Include="Microsoft\VisualBasic\Helpers\ForEachEnum.vb" />
- <Compile Include="Microsoft\VisualBasic\CompilerServices\DoubleType.vb" />
- <Compile Include="Microsoft\VisualBasic\DateAndTime.vb" />
- <Compile Include="Microsoft\VisualBasic\ErrObject.vb" />
<Compile Include="Microsoft\VisualBasic\HideModuleNameAttribute.vb" />
<Compile Include="Microsoft\VisualBasic\Information.vb" />
<Compile Include="Microsoft\VisualBasic\Interaction.vb" />
--- /dev/null
+' Licensed to the .NET Foundation under one or more agreements.
+' The .NET Foundation licenses this file to you under the MIT license.
+' See the LICENSE file in the project root for more information.
+
+Imports System
+Imports Microsoft.VisualBasic.CompilerServices.Utils
+
+Namespace Microsoft.VisualBasic.CompilerServices
+
+ <System.ComponentModel.EditorBrowsableAttribute(System.ComponentModel.EditorBrowsableState.Never)>
+ Public NotInheritable Class CharArrayType
+ ' Prevent creation.
+ Private Sub New()
+ End Sub
+
+ Public Shared Function FromString(ByVal Value As String) As Char()
+
+ If Value Is Nothing Then
+ Value = ""
+ End If
+
+ Return Value.ToCharArray()
+
+ End Function
+
+ Public Shared Function FromObject(ByVal Value As Object) As Char()
+
+ If Value Is Nothing Then
+ Return "".ToCharArray()
+ End If
+
+ Dim CharArray As Char() = TryCast(Value, Char())
+
+ If CharArray IsNot Nothing AndAlso CharArray.Rank = 1 Then
+ Return CharArray
+
+ Else
+ Dim ValueInterface As IConvertible
+ ValueInterface = TryCast(Value, IConvertible)
+
+ If Not ValueInterface Is Nothing Then
+ If (ValueInterface.GetTypeCode() = TypeCode.String) Then
+ Return ValueInterface.ToString(Nothing).ToCharArray()
+ End If
+ End If
+
+ End If
+
+ Throw New InvalidCastException(GetResourceString(SR.InvalidCast_FromTo, VBFriendlyName(Value), "Char()"))
+
+ End Function
+
+ End Class
+
+End Namespace
+
+
--- /dev/null
+' Licensed to the .NET Foundation under one or more agreements.
+' The .NET Foundation licenses this file to you under the MIT license.
+' See the LICENSE file in the project root for more information.
+
+Imports System
+Imports System.Globalization
+Imports System.Text
+Imports Microsoft.VisualBasic.CompilerServices.ExceptionUtils
+Imports Microsoft.VisualBasic.CompilerServices.Utils
+
+Namespace Microsoft.VisualBasic.CompilerServices
+
+ <System.ComponentModel.EditorBrowsableAttribute(System.ComponentModel.EditorBrowsableState.Never)> _
+ Public NotInheritable Class StringType
+ ' Prevent creation.
+ Private Sub New()
+ End Sub
+
+ Private Const GENERAL_FORMAT As String = "G"
+
+ '============================================================================
+ ' Coercion to functions.
+ '============================================================================
+ Public Shared Function FromBoolean(ByVal Value As Boolean) As String
+ If Value Then
+ Return System.Boolean.TrueString
+ Else
+ Return System.Boolean.FalseString
+ End If
+ End Function
+
+ Public Shared Function FromByte(ByVal Value As Byte) As String
+ Return Value.ToString(Nothing, Nothing)
+ End Function
+
+ Public Shared Function FromChar(ByVal Value As Char) As String
+ Return Value.ToString()
+ End Function
+
+ Public Shared Function FromShort(ByVal Value As Short) As String
+ Return Value.ToString(Nothing, Nothing)
+ End Function
+
+ Public Shared Function FromInteger(ByVal Value As Integer) As String
+ Return Value.ToString(Nothing, Nothing)
+ End Function
+
+ Public Shared Function FromLong(ByVal Value As Long) As String
+ Return Value.ToString(Nothing, Nothing)
+ End Function
+
+ Public Shared Function FromSingle(ByVal Value As Single) As String
+ Return FromSingle(Value, Nothing)
+ End Function
+
+ Public Shared Function FromDouble(ByVal Value As Double) As String
+ Return FromDouble(Value, Nothing)
+ End Function
+
+ 'Change to this code after the NDP drop includes the formatting changes
+ Public Shared Function FromSingle(ByVal Value As Single, ByVal NumberFormat As NumberFormatInfo) As String
+ Return Value.ToString(Nothing, NumberFormat)
+ End Function
+
+ Public Shared Function FromDouble(ByVal Value As Double, ByVal NumberFormat As NumberFormatInfo) As String
+ Return Value.ToString("G", NumberFormat)
+ End Function
+
+ Public Shared Function FromDate(ByVal Value As Date) As String
+ Dim TimeTicks As Long = Value.TimeOfDay.Ticks
+
+ If (TimeTicks = Value.Ticks) OrElse
+ (Value.Year = 1899 AndAlso Value.Month = 12 AndAlso Value.Day = 30) Then 'OA Date with no date is 1899-12-30
+ 'No date (1/1/1)
+ 'UNDONE: REVIEW OA DATE HACK
+ Return Value.ToString("T", Nothing)
+ ElseIf TimeTicks = 0 Then
+ 'No time, or is midnight
+ Return Value.ToString("d", Nothing)
+ Else
+ Return Value.ToString(GENERAL_FORMAT, Nothing)
+ End If
+ End Function
+
+ Public Shared Function FromDecimal(ByVal Value As Decimal) As String
+ Return FromDecimal(Value, Nothing)
+ End Function
+
+ Public Shared Function FromDecimal(ByVal Value As Decimal, ByVal NumberFormat As NumberFormatInfo) As String
+ Return Value.ToString("G", NumberFormat)
+ End Function
+
+ Public Shared Function FromObject(ByVal Value As Object) As String
+
+ If Value Is Nothing Then
+ Return Nothing
+
+ Else
+ Dim StringValue As String = TryCast(Value, String)
+
+ If StringValue IsNot Nothing Then
+ Return StringValue
+ End If
+ End If
+
+ Dim ValueInterface As IConvertible
+ Dim ValueTypeCode As TypeCode
+
+ ValueInterface = TryCast(Value, IConvertible)
+
+ If Not ValueInterface Is Nothing Then
+
+ ValueTypeCode = ValueInterface.GetTypeCode()
+
+ Select Case ValueTypeCode
+ Case TypeCode.Boolean
+ Return FromBoolean(ValueInterface.ToBoolean(Nothing))
+
+ Case TypeCode.Byte
+ Return FromByte(ValueInterface.ToByte(Nothing))
+
+ Case TypeCode.Int16
+ Return FromShort(ValueInterface.ToInt16(Nothing))
+
+ Case TypeCode.Int32
+ Return FromInteger(ValueInterface.ToInt32(Nothing))
+
+ Case TypeCode.Int64
+ Return FromLong(ValueInterface.ToInt64(Nothing))
+
+ Case TypeCode.Single
+ Return FromSingle(ValueInterface.ToSingle(Nothing))
+
+ Case TypeCode.Double
+ Return FromDouble(ValueInterface.ToDouble(Nothing))
+
+ Case TypeCode.Decimal
+ Return FromDecimal(ValueInterface.ToDecimal(Nothing))
+
+ Case TypeCode.String
+ Return ValueInterface.ToString(Nothing)
+
+ Case TypeCode.Char
+ Return FromChar(ValueInterface.ToChar(Nothing))
+
+ Case TypeCode.DateTime
+ Return FromDate(ValueInterface.ToDateTime(Nothing))
+
+ Case Else
+ ' Fall through to error
+ End Select
+
+ Else
+ Dim CharArray As Char() = TryCast(Value, Char())
+
+ If CharArray IsNot Nothing AndAlso CharArray.Rank = 1 Then
+ Return New String(CharArrayType.FromObject(Value))
+ End If
+ End If
+
+ Throw New InvalidCastException(GetResourceString(SR.InvalidCast_FromTo, VBFriendlyName(Value), "String"))
+
+ End Function
+
+ '============================================================================
+ ' Compare/concat/len functions.
+ '============================================================================
+ Public Shared Function StrCmp(ByVal sLeft As String, ByVal sRight As String, ByVal TextCompare As Boolean) As Integer
+
+ If sLeft Is sRight Then
+ Return 0
+ End If
+
+ If sLeft Is Nothing Then
+ If sRight.Length() = 0 Then
+ Return 0
+ End If
+
+ Return -1
+ End If
+
+ If sRight Is Nothing Then
+ If sLeft.Length() = 0 Then
+ Return 0
+ End If
+
+ Return 1
+ End If
+
+ If TextCompare Then
+ Return GetCultureInfo().CompareInfo.Compare(sLeft, sRight, OptionCompareTextFlags)
+ Else
+ Return System.String.CompareOrdinal(sLeft, sRight)
+ End If
+
+ End Function
+
+ Public Shared Function StrLike(ByVal Source As String, ByVal Pattern As String, ByVal CompareOption As CompareMethod) As Boolean
+ If CompareOption = CompareMethod.Binary Then
+ Return StrLikeBinary(Source, Pattern)
+ Else
+ Return StrLikeText(Source, Pattern)
+ End If
+ End Function
+
+ Public Shared Function StrLikeBinary(ByVal Source As String, ByVal Pattern As String) As Boolean
+ 'Match Source to Pattern using "?*#[!a-g]" pattern matching characters
+ Dim SourceIndex As Integer
+ Dim PatternIndex As Integer
+ Dim SourceEndIndex As Integer
+ Dim PatternEndIndex As Integer
+ Dim p As Char
+ Dim s As Char
+ Dim InsideBracket As Boolean
+ Dim SeenHyphen As Boolean
+ Dim StartRangeChar As Char
+ Dim EndRangeChar As Char
+ Dim Match As Boolean
+ Dim SeenLiteral As Boolean
+ Dim SeenNot As Boolean
+ Dim Skip As Integer
+ Const NullChar As Char = ChrW(0)
+ Dim LiteralIsRangeEnd As Boolean = False
+
+ ' Options = CompareOptions.Ordinal
+
+ If Pattern Is Nothing Then
+ PatternEndIndex = 0
+ Else
+ PatternEndIndex = Pattern.Length
+ End If
+
+ If Source Is Nothing Then
+ SourceEndIndex = 0
+ Else
+ SourceEndIndex = Source.Length
+ End If
+
+ If SourceIndex < SourceEndIndex Then
+ s = Source.Chars(SourceIndex)
+ End If
+
+ Do While PatternIndex < PatternEndIndex
+ p = Pattern.Chars(PatternIndex)
+
+ If p = "*"c AndAlso (Not InsideBracket) Then 'If Then Else has faster performance the Select Case
+ 'Determine how many source chars to skip
+ Skip = AsteriskSkip(Pattern.Substring(PatternIndex + 1), Source.Substring(SourceIndex), SourceEndIndex - SourceIndex, CompareMethod.Binary, m_InvariantCompareInfo)
+
+ If Skip < 0 Then
+ Return False
+ ElseIf Skip > 0 Then
+ SourceIndex += Skip
+ If SourceIndex < SourceEndIndex Then
+ s = Source.Chars(SourceIndex)
+ End If
+ End If
+
+ ElseIf p = "?"c AndAlso (Not InsideBracket) Then
+ 'Match any character
+ SourceIndex = SourceIndex + 1
+ If SourceIndex < SourceEndIndex Then
+ s = Source.Chars(SourceIndex)
+ End If
+
+ ElseIf p = "#"c AndAlso (Not InsideBracket) Then
+ If Not System.Char.IsDigit(s) Then
+ Exit Do
+ End If
+ SourceIndex = SourceIndex + 1
+ If SourceIndex < SourceEndIndex Then
+ s = Source.Chars(SourceIndex)
+ End If
+
+ ElseIf p = "-"c AndAlso _
+ (InsideBracket AndAlso SeenLiteral AndAlso (Not LiteralIsRangeEnd) AndAlso (Not SeenHyphen)) AndAlso _
+ (((PatternIndex + 1) >= PatternEndIndex) OrElse (Pattern.Chars(PatternIndex + 1) <> "]"c)) Then
+
+ SeenHyphen = True
+
+ ElseIf p = "!"c AndAlso _
+ (InsideBracket AndAlso (Not SeenNot)) Then
+
+ SeenNot = True
+ Match = True
+
+ ElseIf p = "["c AndAlso (Not InsideBracket) Then
+ InsideBracket = True
+ StartRangeChar = NullChar
+ EndRangeChar = NullChar
+ SeenLiteral = False
+
+ ElseIf p = "]"c AndAlso InsideBracket Then
+ InsideBracket = False
+
+ If SeenLiteral Then
+ If Match Then
+ SourceIndex += 1
+ If SourceIndex < SourceEndIndex Then
+ s = Source.Chars(SourceIndex)
+ End If
+ Else
+ Exit Do
+ End If
+ ElseIf SeenHyphen Then
+ If Not Match Then
+ Exit Do
+ End If
+ ElseIf SeenNot Then
+ '[!] should be matched to literal ! same as if outside brackets
+ If "!"c <> s Then
+ Exit Do
+ End If
+ SourceIndex += 1
+ If SourceIndex < SourceEndIndex Then
+ s = Source.Chars(SourceIndex)
+ End If
+ End If
+
+ Match = False
+ SeenLiteral = False
+ SeenNot = False
+ SeenHyphen = False
+
+ Else
+ 'Literal character
+ SeenLiteral = True
+ LiteralIsRangeEnd = False
+
+ If InsideBracket Then
+ If SeenHyphen Then
+ SeenHyphen = False
+ LiteralIsRangeEnd = True
+ EndRangeChar = p
+
+ If StartRangeChar > EndRangeChar Then
+ Throw VbMakeException(vbErrors.BadPatStr)
+ ElseIf (SeenNot AndAlso Match) OrElse (Not SeenNot AndAlso Not Match) Then
+ 'Calls to ci.Compare are expensive, avoid them for good performance
+ Match = (s > StartRangeChar) AndAlso (s <= EndRangeChar)
+
+ If SeenNot Then
+ Match = Not Match
+ End If
+ End If
+ Else
+ StartRangeChar = p
+
+ 'This compare handles non range chars such as the "abc" and "uvw"
+ 'and the first char of a range such as "d" in "[abcd-tuvw]".
+ Match = StrLikeCompareBinary(SeenNot, Match, p, s)
+ End If
+ Else
+ If p <> s AndAlso Not SeenNot Then
+ Exit Do
+ End If
+
+ SeenNot = False
+ SourceIndex += 1
+
+ If SourceIndex < SourceEndIndex Then
+ s = Source.Chars(SourceIndex)
+ ElseIf SourceIndex > SourceEndIndex Then
+ Return False
+ End If
+ End If
+ End If
+
+ PatternIndex += 1
+ Loop
+
+ If InsideBracket Then
+ If SourceEndIndex = 0 Then
+ Return False
+ Else
+ Throw New ArgumentException(GetResourceString(SR.Argument_InvalidValue1, "Pattern"))
+ End If
+ Else
+ Return (PatternIndex = PatternEndIndex) AndAlso (SourceIndex = SourceEndIndex)
+ End If
+ End Function
+
+ Public Shared Function StrLikeText(ByVal Source As String, ByVal Pattern As String) As Boolean
+ 'Match Source to Pattern using "?*#[!a-g]" pattern matching characters
+ Dim SourceIndex As Integer
+ Dim PatternIndex As Integer
+ Dim SourceEndIndex As Integer
+ Dim PatternEndIndex As Integer
+ Dim p As Char
+ Dim s As Char
+ Dim InsideBracket As Boolean
+ Dim SeenHyphen As Boolean
+ Dim StartRangeChar As Char
+ Dim EndRangeChar As Char
+ Dim Match As Boolean
+ Dim SeenLiteral As Boolean
+ Dim SeenNot As Boolean
+ Dim Skip As Integer
+ Dim Options As CompareOptions
+ Dim ci As CompareInfo
+ Const NullChar As Char = ChrW(0)
+ Dim LiteralIsRangeEnd As Boolean = False
+
+ If Pattern Is Nothing Then
+ PatternEndIndex = 0
+ Else
+ PatternEndIndex = Pattern.Length
+ End If
+
+ If Source Is Nothing Then
+ SourceEndIndex = 0
+ Else
+ SourceEndIndex = Source.Length
+ End If
+
+ If SourceIndex < SourceEndIndex Then
+ s = Source.Chars(SourceIndex)
+ End If
+
+ ci = GetCultureInfo().CompareInfo
+ Options = CompareOptions.IgnoreCase Or _
+ CompareOptions.IgnoreWidth Or _
+ CompareOptions.IgnoreNonSpace Or _
+ CompareOptions.IgnoreKanaType
+
+ Do While PatternIndex < PatternEndIndex
+ p = Pattern.Chars(PatternIndex)
+
+ If p = "*"c AndAlso (Not InsideBracket) Then 'If Then Else has faster performance the Select Case
+ 'Determine how many source chars to skip
+ Skip = AsteriskSkip(Pattern.Substring(PatternIndex + 1), Source.Substring(SourceIndex), SourceEndIndex - SourceIndex, CompareMethod.Text, ci)
+
+ If Skip < 0 Then
+ Return False
+ ElseIf Skip > 0 Then
+ SourceIndex += Skip
+ If SourceIndex < SourceEndIndex Then
+ s = Source.Chars(SourceIndex)
+ End If
+ End If
+
+ ElseIf p = "?"c AndAlso (Not InsideBracket) Then
+ 'Match any character
+ SourceIndex = SourceIndex + 1
+ If SourceIndex < SourceEndIndex Then
+ s = Source.Chars(SourceIndex)
+ End If
+
+ ElseIf p = "#"c AndAlso (Not InsideBracket) Then
+ If Not System.Char.IsDigit(s) Then
+ Exit Do
+ End If
+ SourceIndex = SourceIndex + 1
+ If SourceIndex < SourceEndIndex Then
+ s = Source.Chars(SourceIndex)
+ End If
+
+ ElseIf p = "-"c AndAlso _
+ (InsideBracket AndAlso SeenLiteral AndAlso (Not LiteralIsRangeEnd) AndAlso (Not SeenHyphen)) AndAlso _
+ (((PatternIndex + 1) >= PatternEndIndex) OrElse (Pattern.Chars(PatternIndex + 1) <> "]"c)) Then
+
+ SeenHyphen = True
+
+ ElseIf p = "!"c AndAlso _
+ (InsideBracket AndAlso Not SeenNot) Then
+ SeenNot = True
+ Match = True
+
+ ElseIf p = "["c AndAlso (Not InsideBracket) Then
+ InsideBracket = True
+ StartRangeChar = NullChar
+ EndRangeChar = NullChar
+ SeenLiteral = False
+
+ ElseIf p = "]"c AndAlso InsideBracket Then
+ InsideBracket = False
+
+ If SeenLiteral Then
+ If Match Then
+ SourceIndex += 1
+ If SourceIndex < SourceEndIndex Then
+ s = Source.Chars(SourceIndex)
+ End If
+ Else
+ Exit Do
+ End If
+ ElseIf SeenHyphen Then
+ If Not Match Then
+ Exit Do
+ End If
+ ElseIf SeenNot Then
+ '[!] should be matched to literal ! same as if outside brackets
+ If (ci.Compare("!", s) <> 0) Then
+ Exit Do
+ End If
+ SourceIndex += 1
+ If SourceIndex < SourceEndIndex Then
+ s = Source.Chars(SourceIndex)
+ End If
+ End If
+
+ Match = False
+ SeenLiteral = False
+ SeenNot = False
+ SeenHyphen = False
+
+ Else
+ 'Literal character
+ SeenLiteral = True
+ LiteralIsRangeEnd = False
+
+ If InsideBracket Then
+ If SeenHyphen Then
+ SeenHyphen = False
+ LiteralIsRangeEnd = True
+ EndRangeChar = p
+
+ If StartRangeChar > EndRangeChar Then
+ Throw VbMakeException(vbErrors.BadPatStr)
+ ElseIf (SeenNot AndAlso Match) OrElse (Not SeenNot AndAlso Not Match) Then
+ 'Calls to ci.Compare are expensive, avoid them for good performance
+ If Options = CompareOptions.Ordinal Then
+ Match = (s > StartRangeChar) AndAlso (s <= EndRangeChar)
+ Else
+ Match = (ci.Compare(StartRangeChar, s, Options) < 0) AndAlso (ci.Compare(EndRangeChar, s, Options) >= 0)
+ End If
+
+ If SeenNot Then
+ Match = Not Match
+ End If
+ End If
+ Else
+ StartRangeChar = p
+
+ 'This compare handles non range chars such as the "abc" and "uvw"
+ 'and the first char of a range such as "d" in "[abcd-tuvw]".
+ Match = StrLikeCompare(ci, SeenNot, Match, p, s, Options)
+ End If
+ Else
+ If Options = CompareOptions.Ordinal Then
+ If p <> s AndAlso Not SeenNot Then
+ Exit Do
+ End If
+ Else
+ ' Slurp up the diacritical marks, if any (both non-spacing marks and modifier symbols)
+ ' Note that typically, we'll only have at most one diacritical mark. Therefore, I'm not
+ ' using StringBuilder here, since the minimal overhead of appending a character doesn't
+ ' justify invoking a couple of instances of StringBuilder. .
+ Dim pstr As String = p
+ Dim sstr As String = s
+ Do While PatternIndex + 1 < PatternEndIndex AndAlso _
+ (UnicodeCategory.ModifierSymbol = Char.GetUnicodeCategory(Pattern.Chars(PatternIndex + 1)) OrElse _
+ UnicodeCategory.NonSpacingMark = Char.GetUnicodeCategory(Pattern.Chars(PatternIndex + 1)))
+ pstr = pstr & Pattern.Chars(PatternIndex + 1)
+ PatternIndex = PatternIndex + 1
+ Loop
+ Do While SourceIndex + 1 < SourceEndIndex AndAlso _
+ (UnicodeCategory.ModifierSymbol = Char.GetUnicodeCategory(Source.Chars(SourceIndex + 1)) OrElse _
+ UnicodeCategory.NonSpacingMark = Char.GetUnicodeCategory(Source.Chars(SourceIndex + 1)))
+ sstr = sstr & Source.Chars(SourceIndex + 1)
+ SourceIndex = SourceIndex + 1
+ Loop
+
+ If (ci.Compare(pstr, sstr, OptionCompareTextFlags) <> 0) AndAlso Not SeenNot Then
+ Exit Do
+ End If
+ End If
+
+ SeenNot = False
+ SourceIndex += 1
+
+ If SourceIndex < SourceEndIndex Then
+ s = Source.Chars(SourceIndex)
+ ElseIf SourceIndex > SourceEndIndex Then
+ Return False
+ End If
+ End If
+ End If
+
+ PatternIndex += 1
+ Loop
+
+ If InsideBracket Then
+ If SourceEndIndex = 0 Then
+ Return False
+ Else
+ Throw New ArgumentException(GetResourceString(SR.Argument_InvalidValue1, "Pattern"))
+ End If
+ Else
+ Return (PatternIndex = PatternEndIndex) AndAlso (SourceIndex = SourceEndIndex)
+ End If
+ End Function
+
+ Private Shared Function StrLikeCompareBinary(ByVal SeenNot As Boolean, ByVal Match As Boolean, ByVal p As Char, ByVal s As Char) As Boolean
+ If SeenNot AndAlso Match Then
+ Return p <> s
+ ElseIf Not SeenNot AndAlso Not Match Then
+ Return p = s
+ Else
+ Return Match
+ End If
+ End Function
+
+ Private Shared Function StrLikeCompare(ByVal ci As CompareInfo, ByVal SeenNot As Boolean, ByVal Match As Boolean, ByVal p As Char, ByVal s As Char, ByVal Options As CompareOptions) As Boolean
+ If SeenNot AndAlso Match Then
+ If Options = CompareOptions.Ordinal Then
+ Return p <> s
+ Else
+ Return Not (ci.Compare(p, s, Options) = 0)
+ End If
+ ElseIf Not SeenNot AndAlso Not Match Then
+ If Options = CompareOptions.Ordinal Then
+ Return p = s
+ Else
+ Return (ci.Compare(p, s, Options) = 0)
+ End If
+ Else
+ Return Match
+ End If
+ End Function
+
+ Private Shared Function AsteriskSkip(ByVal Pattern As String, ByVal Source As String, ByVal SourceEndIndex As Integer, _
+ ByVal CompareOption As CompareMethod, ByVal ci As CompareInfo) As Integer
+
+ 'Returns the number of source characters to skip over to handle an asterisk in the pattern.
+ 'When there's only a single asterisk in the pattern, it computes how many pattern equivalent chars
+ 'follow the *: [a-z], [abcde], ?, # each count as one char.
+ 'Pattern contains the substring following the *
+ 'Source contains the substring not yet matched.
+
+ Dim p As Char
+ Dim SeenLiteral As Boolean
+ Dim SeenSpecial As Boolean 'Remembers if we've seen #, ?, [abd-eg], or ! when they have their special meanings
+ Dim InsideBracket As Boolean
+ Dim Count As Integer
+ Dim PatternEndIndex As Integer
+ Dim PatternIndex As Integer
+ Dim TruncatedPattern As String
+ Dim Options As CompareOptions
+
+ PatternEndIndex = Len(Pattern)
+
+ 'Determine how many pattern equivalent chars follow the *, and if there are multiple *s
+ '[a-z], [abcde] each count as one char.
+ Do While PatternIndex < PatternEndIndex
+ p = Pattern.Chars(PatternIndex)
+
+ Select Case p
+ Case "*"c
+ If Count > 0 Then
+ 'We found multiple asterisks with an intervening pattern
+ If SeenSpecial Then
+ 'Pattern uses special characters which means we can't compute easily how far to skip.
+ Count = MultipleAsteriskSkip(Pattern, Source, Count, CompareOption)
+ Return SourceEndIndex - Count
+ Else
+ 'Pattern uses only literals, so we can directly search for the pattern in the source
+ 'TODO: Handle cases where pattern could be replicated in the source.
+ TruncatedPattern = Pattern.Substring(0, PatternIndex) 'Remove the second * and everything trailing
+
+ If CompareOption = CompareMethod.Binary Then
+ Options = CompareOptions.Ordinal
+ Else
+ Options = CompareOptions.IgnoreCase Or CompareOptions.IgnoreWidth Or CompareOptions.IgnoreNonSpace Or CompareOptions.IgnoreKanaType
+ End If
+
+ 'Count = Source.LastIndexOf(TruncatedPattern)
+ Count = ci.LastIndexOf(Source, TruncatedPattern, Options)
+ Return Count
+ End If
+
+ Else
+ 'Do nothing, which colalesces multiple asterisks together
+ End If
+
+ Case "-"c
+ If Pattern.Chars(PatternIndex + 1) = "]"c Then
+ SeenLiteral = True
+ End If
+
+ Case "!"c
+ If Pattern.Chars(PatternIndex + 1) = "]"c Then
+ SeenLiteral = True
+ Else
+ SeenSpecial = True
+ End If
+
+ Case "["c
+ If InsideBracket Then
+ SeenLiteral = True
+ Else
+ InsideBracket = True
+ End If
+
+ Case "]"c
+ If SeenLiteral OrElse Not InsideBracket Then
+ Count += 1
+ SeenSpecial = True
+ End If
+ SeenLiteral = False
+ InsideBracket = False
+
+ Case "?"c, "#"c
+ If InsideBracket Then
+ SeenLiteral = True
+ Else
+ Count += 1
+ SeenSpecial = True
+ End If
+
+ Case Else
+ If InsideBracket Then
+ SeenLiteral = True
+ Else
+ Count += 1
+ End If
+ End Select
+
+ PatternIndex += 1
+ Loop
+
+ Return SourceEndIndex - Count
+ End Function
+
+ Private Shared Function MultipleAsteriskSkip(ByVal Pattern As String, ByVal Source As String, ByVal Count As Integer, ByVal CompareOption As CompareMethod) As Integer
+ 'Multiple asterisks with intervening chars were found in the pattern, such as "*<chars>*".
+ 'Use a recursive approach to determine how many source chars to skip.
+ 'Start near the end of Source and move backwards one char at a time until a match is found or we reach start of Source.
+
+ Dim SourceEndIndex As Integer
+ Dim NewSource As String
+ Dim Result As Boolean
+
+ SourceEndIndex = Len(Source)
+
+ Do While Count < SourceEndIndex
+ NewSource = Source.Substring(SourceEndIndex - Count)
+
+ Try
+ Result = StrLike(NewSource, Pattern, CompareOption)
+ Catch ex As StackOverflowException
+ Throw ex
+ Catch ex As OutOfMemoryException
+ Throw ex
+ Catch ex As System.Threading.ThreadAbortException
+ Throw ex
+ Catch
+ Result = False
+ End Try
+
+ If Result Then
+ Exit Do
+ End If
+
+ Count += 1
+ Loop
+
+ Return Count
+ End Function
+
+ Public Shared Sub MidStmtStr(ByRef sDest As String, ByVal StartPosition As Integer, ByVal MaxInsertLength As Integer, ByVal sInsert As String)
+ Dim DestLength As Integer
+ Dim InsertLength As Integer
+ Dim EndSegmentLength As Integer
+
+ If sDest Is Nothing Then
+ 'DestLength = 0
+ Else
+ DestLength = sDest.Length
+ End If
+
+ If sInsert Is Nothing Then
+ 'InsertLength = 0
+ Else
+ InsertLength = sInsert.Length
+ End If
+
+ 'Zero base the index
+ StartPosition -= 1
+
+ If StartPosition < 0 OrElse StartPosition >= DestLength Then
+ Throw New ArgumentException(GetResourceString(SR.Argument_InvalidValue1, "Start"))
+ End If
+
+ If MaxInsertLength < 0 Then
+ Throw New ArgumentException(GetResourceString(SR.Argument_InvalidValue1, "Length"))
+ End If
+
+ ' first, limit the length of the source string
+ ' to lenChange
+
+ If (InsertLength > MaxInsertLength) Then
+ InsertLength = MaxInsertLength
+ End If
+
+ ' second, limit the length to the available space
+ ' in the destination string
+
+ If (InsertLength > DestLength - StartPosition) Then
+ InsertLength = DestLength - StartPosition
+ End If
+
+ If InsertLength = 0 Then
+ 'Destination string remains unchanged
+ Exit Sub
+ End If
+
+ 'This looks a bit complex for removing and inserting strings
+ 'but when manipulating long strings, it should provide
+ 'better performance because of fewer memcpys
+
+ Dim sb As StringBuilder
+
+ sb = New StringBuilder(DestLength)
+
+ If StartPosition > 0 Then
+ 'Append first part of destination string
+ sb.Append(sDest, 0, StartPosition)
+ End If
+
+ 'Append InsertString
+ sb.Append(sInsert, 0, InsertLength)
+ EndSegmentLength = DestLength - (StartPosition + InsertLength)
+
+ If EndSegmentLength > 0 Then
+ 'Append remainder of destination string
+ sb.Append(sDest, StartPosition + InsertLength, EndSegmentLength)
+ End If
+
+ sDest = sb.ToString()
+ End Sub
+
+ End Class
+
+End Namespace
+
Assert.Throws<InvalidOperationException>(() => Conversions.ToChar(value));
}
+ public static IEnumerable<object[]> ToString_IConvertible_TestData()
+ {
+ // byte.
+ yield return new object[] { byte.MinValue, "0" };
+ yield return new object[] { (byte)1, "1" };
+ yield return new object[] { byte.MaxValue, "255" };
+ yield return new object[] { (ByteEnum)byte.MinValue, "0" };
+ yield return new object[] { (ByteEnum)1, "1" };
+ yield return new object[] { (ByteEnum)byte.MaxValue, "255" };
+
+ // sbyte.
+ yield return new object[] { sbyte.MinValue, "-128" };
+ yield return new object[] { (sbyte)(-1), "-1" };
+ yield return new object[] { (sbyte)0, "0" };
+ yield return new object[] { (sbyte)1, "1" };
+ yield return new object[] { sbyte.MaxValue, "127" };
+ yield return new object[] { (SByteEnum)sbyte.MinValue, "-128" };
+ yield return new object[] { (SByteEnum)(-1), "-1" };
+ yield return new object[] { (SByteEnum)0, "0" };
+ yield return new object[] { (SByteEnum)1, "1" };
+ yield return new object[] { (SByteEnum)sbyte.MaxValue, "127" };
+
+ // ushort.
+ yield return new object[] { ushort.MinValue, "0" };
+ yield return new object[] { (ushort)1, "1" };
+ yield return new object[] { ushort.MaxValue, "65535" };
+ yield return new object[] { (UShortEnum)ushort.MinValue, "0" };
+ yield return new object[] { (UShortEnum)1, "1" };
+ yield return new object[] { (UShortEnum)ushort.MaxValue, "65535" };
+
+ // short.
+ yield return new object[] { short.MinValue, "-32768" };
+ yield return new object[] { (short)(-1), "-1" };
+ yield return new object[] { (short)0, "0" };
+ yield return new object[] { (short)1, "1" };
+ yield return new object[] { short.MaxValue, "32767" };
+ yield return new object[] { (ShortEnum)short.MinValue, "-32768" };
+ yield return new object[] { (ShortEnum)(-1), "-1" };
+ yield return new object[] { (ShortEnum)0, "0" };
+ yield return new object[] { (ShortEnum)1, "1" };
+ yield return new object[] { (ShortEnum)short.MaxValue, "32767" };
+
+ // uint.
+ yield return new object[] { uint.MinValue, "0" };
+ yield return new object[] { (uint)1, "1" };
+ yield return new object[] { uint.MaxValue, "4294967295" };
+ yield return new object[] { (UIntEnum)uint.MinValue, "0" };
+ yield return new object[] { (UIntEnum)1, "1" };
+ yield return new object[] { (UIntEnum)uint.MaxValue, "4294967295" };
+
+ // int.
+ yield return new object[] { int.MinValue, "-2147483648" };
+ yield return new object[] { -1, "-1" };
+ yield return new object[] { 0, "0" };
+ yield return new object[] { 1, "1" };
+ yield return new object[] { int.MaxValue, "2147483647" };
+ yield return new object[] { (IntEnum)int.MinValue, "-2147483648" };
+ yield return new object[] { (IntEnum)(-1), "-1" };
+ yield return new object[] { (IntEnum)0, "0" };
+ yield return new object[] { (IntEnum)1, "1" };
+ yield return new object[] { (IntEnum)int.MaxValue, "2147483647" };
+
+ // ulong.
+ yield return new object[] { ulong.MinValue, "0" };
+ yield return new object[] { (ulong)1, "1" };
+ yield return new object[] { ulong.MaxValue, "18446744073709551615" };
+ yield return new object[] { (ULongEnum)ulong.MinValue, "0" };
+ yield return new object[] { (ULongEnum)1, "1" };
+ yield return new object[] { (ULongEnum)ulong.MaxValue, "18446744073709551615" };
+
+ // long.
+ yield return new object[] { long.MinValue, "-9223372036854775808" };
+ yield return new object[] { (long)(-1), "-1" };
+ yield return new object[] { (long)0, "0" };
+ yield return new object[] { (long)1, "1" };
+ yield return new object[] { long.MaxValue, "9223372036854775807" };
+ yield return new object[] { (LongEnum)long.MinValue, "-9223372036854775808" };
+ yield return new object[] { (LongEnum)(-1), "-1" };
+ yield return new object[] { (LongEnum)0, "0" };
+ yield return new object[] { (LongEnum)1, "1" };
+ yield return new object[] { (LongEnum)long.MaxValue, "9223372036854775807" };
+
+ // float.
+ yield return new object[] { (float)(-1), "-1" };
+ yield return new object[] { (float)0, "0" };
+ yield return new object[] { (float)1, "1" };
+ yield return new object[] { float.PositiveInfinity, float.PositiveInfinity.ToString() };
+ yield return new object[] { float.NegativeInfinity, float.NegativeInfinity.ToString() };
+ yield return new object[] { float.NaN, "NaN" };
+
+ // double.
+ yield return new object[] { (double)(-1), "-1" };
+ yield return new object[] { (double)0, "0" };
+ yield return new object[] { (double)1, "1" };
+ yield return new object[] { double.PositiveInfinity, double.PositiveInfinity.ToString() };
+ yield return new object[] { double.NegativeInfinity, double.NegativeInfinity.ToString() };
+ yield return new object[] { double.NaN, "NaN" };
+
+ // decimal.
+ yield return new object[] { decimal.MinValue, decimal.MinValue.ToString() };
+ yield return new object[] { (decimal)(-1), "-1" };
+ yield return new object[] { (decimal)0, "0" };
+ yield return new object[] { (decimal)1, "1" };
+ yield return new object[] { decimal.MaxValue, decimal.MaxValue.ToString() };
+
+ // bool.
+ yield return new object[] { true, "True" };
+ yield return new object[] { false, "False" };
+ if (ReflectionEmitSupported)
+ {
+ yield return new object[] { BoolEnum, "False" };
+ }
+
+ // string.
+ yield return new object[] { "", "" };
+ yield return new object[] { "abc", "abc" };
+
+ // null.
+ yield return new object[] { null, (string)null };
+
+ // char.
+ yield return new object[] { char.MinValue, "\0" };
+ yield return new object[] { (char)1, "\u0001" };
+ yield return new object[] { 'a', "a" };
+ yield return new object[] { char.MaxValue, char.MaxValue.ToString() };
+
+ // DateTime.
+ yield return new object[] { new DateTime(10), new DateTime(10).ToString("T", null) };
+ }
+
+ [Theory]
+ [MemberData(nameof(ToString_IConvertible_TestData))]
+ public void ToString_IConvertible_ReturnsExpected(IConvertible value, string expected)
+ {
+ AssertEqual(expected, Conversions.ToString(value));
+ if (value != null)
+ {
+ AssertEqual(expected, Conversions.ToString(new ConvertibleWrapper(value)));
+ }
+ }
+
+ public static IEnumerable<object[]> ToString_Object_TestData()
+ {
+ // char[]
+ yield return new object[] { new char[0], "" };
+ yield return new object[] { new char[] { (char)0 }, "\0" };
+ yield return new object[] { new char[] { 'A', 'B' }, "AB" };
+ }
+
+ [Theory]
+ [MemberData(nameof(ToString_Object_TestData))]
+ public void ToString_Object_ReturnsExpected(object value, string expected)
+ {
+ AssertEqual(expected, Conversions.ToString(value));
+ }
+
+ public static IEnumerable<object[]> ToString_InvalidObject_TestData()
+ {
+ yield return new object[] { new object() };
+ }
+
+ [Theory]
+ [MemberData(nameof(ToString_InvalidObject_TestData))]
+ public void ToString_InvalidObject_ThrowsInvalidCastException(object value)
+ {
+ Assert.Throws<InvalidCastException>(() => Conversions.ToString(value));
+ }
+
+ [Theory]
+ [MemberData(nameof(InvalidBool_TestData))]
+ public void ToString_InvalidBool_ThrowsInvalidOperationException(object value)
+ {
+ Assert.Throws<InvalidOperationException>(() => Conversions.ToString(value));
+ }
+
private static object s_floatEnum;
public static object FloatEnum
Assert.Equal(expected, actual);
}
}
+ }
- public enum ByteEnum : byte { Value = 1 }
+ public enum ByteEnum : byte { Value = 1 }
- public enum SByteEnum : sbyte { Value = 1 }
+ public enum SByteEnum : sbyte { Value = 1 }
- public enum UShortEnum : ushort { Value = 1 }
+ public enum UShortEnum : ushort { Value = 1 }
- public enum ShortEnum : short { Value = 1 }
+ public enum ShortEnum : short { Value = 1 }
- public enum UIntEnum : uint { Value = 1 }
+ public enum UIntEnum : uint { Value = 1 }
- public enum IntEnum : int { Value = 1 }
+ public enum IntEnum : int { Value = 1 }
- public enum ULongEnum : ulong { Value = 1 }
+ public enum ULongEnum : ulong { Value = 1 }
- public enum LongEnum : long { Value = 1 }
- }
+ public enum LongEnum : long { Value = 1 }
}
<Compile Include="UtilsTests.cs" />
<Compile Include="VBMathTests.cs" />
<Compile Include="StringsTests.cs" />
+ <Compile Include="StringTypeTests.cs" />
</ItemGroup>
<ItemGroup>
<EmbeddedResource Include="Resources\$(AssemblyName).rd.xml" />
--- /dev/null
+// Licensed to the .NET Foundation under one or more agreements.
+// The .NET Foundation licenses this file to you under the MIT license.
+// See the LICENSE file in the project root for more information.
+
+using Microsoft.VisualBasic.CompilerServices;
+using Microsoft.VisualBasic.Tests;
+using System;
+using System.Collections.Generic;
+using System.Globalization;
+using Xunit;
+
+namespace Microsoft.VisualBasic.CompilerServices.Tests
+{
+ public class StringTypeTests
+ {
+ [Theory]
+ [MemberData(nameof(FromBoolean_TestData))]
+ public void FromBoolean(bool value, string expected)
+ {
+ Assert.Equal(expected, StringType.FromBoolean(value));
+ }
+
+ [Theory]
+ [MemberData(nameof(FromByte_TestData))]
+ public void FromByte(byte value, string expected)
+ {
+ Assert.Equal(expected, StringType.FromByte(value));
+ }
+
+ [Theory]
+ [MemberData(nameof(FromChar_TestData))]
+ public void FromChar(char value, string expected)
+ {
+ Assert.Equal(expected, StringType.FromChar(value));
+ }
+
+ [Theory]
+ [MemberData(nameof(FromDateTime_TestData))]
+ public void FromDate(DateTime value, string expected)
+ {
+ Assert.Equal(expected, StringType.FromDate(value));
+ }
+
+ [Theory]
+ [MemberData(nameof(FromDecimal_TestData))]
+ public void FromDecimal(decimal value, string expected)
+ {
+ Assert.Equal(expected, StringType.FromDecimal(value));
+ Assert.Equal(expected, StringType.FromDecimal(value, default(NumberFormatInfo)));
+ }
+
+ [Theory]
+ [MemberData(nameof(FromDecimal_Format_TestData))]
+ public void FromDecimal(decimal value, NumberFormatInfo format, string expected)
+ {
+ Assert.Equal(expected, StringType.FromDecimal(value, format));
+ }
+
+ [Theory]
+ [MemberData(nameof(FromDouble_TestData))]
+ public void FromDouble(double value, string expected)
+ {
+ Assert.Equal(expected, StringType.FromDouble(value));
+ Assert.Equal(expected, StringType.FromDouble(value, default(NumberFormatInfo)));
+ }
+
+ [Theory]
+ [MemberData(nameof(FromDouble_Format_TestData))]
+ public void FromDouble(double value, NumberFormatInfo format, string expected)
+ {
+ Assert.Equal(expected, StringType.FromDouble(value, format));
+ }
+
+ [Theory]
+ [MemberData(nameof(FromInt32_TestData))]
+ public void FromInteger(int value, string expected)
+ {
+ Assert.Equal(expected, StringType.FromInteger(value));
+ }
+
+ [Theory]
+ [MemberData(nameof(FromInt64_TestData))]
+ public void FromLong(long value, string expected)
+ {
+ Assert.Equal(expected, StringType.FromLong(value));
+ }
+
+ [Theory]
+ [MemberData(nameof(FromByte_TestData))]
+ [MemberData(nameof(FromInt16_TestData))]
+ [MemberData(nameof(FromInt32_TestData))]
+ [MemberData(nameof(FromInt64_TestData))]
+ [MemberData(nameof(FromSingle_TestData))]
+ [MemberData(nameof(FromDouble_TestData))]
+ [MemberData(nameof(FromDecimal_TestData))]
+ [MemberData(nameof(FromBoolean_TestData))]
+ [MemberData(nameof(FromString_TestData))]
+ [MemberData(nameof(FromNull_TestData))]
+ [MemberData(nameof(FromChar_TestData))]
+ [MemberData(nameof(FromCharArray_TestData))]
+ [MemberData(nameof(FromDateTime_TestData))]
+ public void FromObject(object value, string expected)
+ {
+ Assert.Equal(expected, StringType.FromObject(value));
+ }
+
+ // The following should be supported but are not.
+ [Theory]
+ [MemberData(nameof(FromSByte_TestData))]
+ [MemberData(nameof(FromUInt16_TestData))]
+ [MemberData(nameof(FromUInt32_TestData))]
+ [MemberData(nameof(FromUInt64_TestData))]
+ public void FromObject_Unexpected(object value, string expected)
+ {
+ Assert.Throws<InvalidCastException>(() => StringType.FromObject(value));
+ }
+
+ [Theory]
+ [MemberData(nameof(FromObject_TestData))]
+ public void FromObject_InvalidCastException(object value)
+ {
+ Assert.Throws<InvalidCastException>(() => StringType.FromObject(value));
+ }
+
+ [Theory]
+ [MemberData(nameof(FromInt16_TestData))]
+ public void FromShort(short value, string expected)
+ {
+ Assert.Equal(expected, StringType.FromShort(value));
+ }
+
+ [Theory]
+ [MemberData(nameof(FromSingle_TestData))]
+ public void FromSingle(float value, string expected)
+ {
+ Assert.Equal(expected, StringType.FromSingle(value));
+ Assert.Equal(expected, StringType.FromSingle(value, default(NumberFormatInfo)));
+ }
+
+ [Theory]
+ [MemberData(nameof(FromSingle_Format_TestData))]
+ public void FromSingle(float value, NumberFormatInfo format, string expected)
+ {
+ Assert.Equal(expected, StringType.FromSingle(value, format));
+ }
+
+ private static IEnumerable<object[]> FromByte_TestData()
+ {
+ yield return new object[] { byte.MinValue, "0" };
+ yield return new object[] { (byte)1, "1" };
+ yield return new object[] { byte.MaxValue, "255" };
+ yield return new object[] { (ByteEnum)byte.MinValue, "0" };
+ yield return new object[] { (ByteEnum)1, "1" };
+ yield return new object[] { (ByteEnum)byte.MaxValue, "255" };
+ }
+
+ private static IEnumerable<object[]> FromSByte_TestData()
+ {
+ yield return new object[] { sbyte.MinValue, "-128" };
+ yield return new object[] { (sbyte)(-1), "-1" };
+ yield return new object[] { (sbyte)0, "0" };
+ yield return new object[] { (sbyte)1, "1" };
+ yield return new object[] { sbyte.MaxValue, "127" };
+ yield return new object[] { (SByteEnum)sbyte.MinValue, "-128" };
+ yield return new object[] { (SByteEnum)(-1), "-1" };
+ yield return new object[] { (SByteEnum)0, "0" };
+ yield return new object[] { (SByteEnum)1, "1" };
+ yield return new object[] { (SByteEnum)sbyte.MaxValue, "127" };
+ }
+
+ private static IEnumerable<object[]> FromUInt16_TestData()
+ {
+ yield return new object[] { ushort.MinValue, "0" };
+ yield return new object[] { (ushort)1, "1" };
+ yield return new object[] { ushort.MaxValue, "65535" };
+ yield return new object[] { (UShortEnum)ushort.MinValue, "0" };
+ yield return new object[] { (UShortEnum)1, "1" };
+ yield return new object[] { (UShortEnum)ushort.MaxValue, "65535" };
+ }
+
+ private static IEnumerable<object[]> FromInt16_TestData()
+ {
+ yield return new object[] { short.MinValue, "-32768" };
+ yield return new object[] { (short)(-1), "-1" };
+ yield return new object[] { (short)0, "0" };
+ yield return new object[] { (short)1, "1" };
+ yield return new object[] { short.MaxValue, "32767" };
+ yield return new object[] { (ShortEnum)short.MinValue, "-32768" };
+ yield return new object[] { (ShortEnum)(-1), "-1" };
+ yield return new object[] { (ShortEnum)0, "0" };
+ yield return new object[] { (ShortEnum)1, "1" };
+ yield return new object[] { (ShortEnum)short.MaxValue, "32767" };
+ }
+
+ private static IEnumerable<object[]> FromUInt32_TestData()
+ {
+ yield return new object[] { uint.MinValue, "0" };
+ yield return new object[] { (uint)1, "1" };
+ yield return new object[] { uint.MaxValue, "4294967295" };
+ yield return new object[] { (UIntEnum)uint.MinValue, "0" };
+ yield return new object[] { (UIntEnum)1, "1" };
+ yield return new object[] { (UIntEnum)uint.MaxValue, "4294967295" };
+ }
+
+ private static IEnumerable<object[]> FromInt32_TestData()
+ {
+ yield return new object[] { int.MinValue, "-2147483648" };
+ yield return new object[] { -1, "-1" };
+ yield return new object[] { 0, "0" };
+ yield return new object[] { 1, "1" };
+ yield return new object[] { int.MaxValue, "2147483647" };
+ yield return new object[] { (IntEnum)int.MinValue, "-2147483648" };
+ yield return new object[] { (IntEnum)(-1), "-1" };
+ yield return new object[] { (IntEnum)0, "0" };
+ yield return new object[] { (IntEnum)1, "1" };
+ yield return new object[] { (IntEnum)int.MaxValue, "2147483647" };
+ }
+
+ private static IEnumerable<object[]> FromUInt64_TestData()
+ {
+ yield return new object[] { ulong.MinValue, "0" };
+ yield return new object[] { (ulong)1, "1" };
+ yield return new object[] { ulong.MaxValue, "18446744073709551615" };
+ yield return new object[] { (ULongEnum)ulong.MinValue, "0" };
+ yield return new object[] { (ULongEnum)1, "1" };
+ yield return new object[] { (ULongEnum)ulong.MaxValue, "18446744073709551615" };
+ }
+
+ private static IEnumerable<object[]> FromInt64_TestData()
+ {
+ yield return new object[] { long.MinValue, "-9223372036854775808" };
+ yield return new object[] { (long)(-1), "-1" };
+ yield return new object[] { (long)0, "0" };
+ yield return new object[] { (long)1, "1" };
+ yield return new object[] { long.MaxValue, "9223372036854775807" };
+ yield return new object[] { (LongEnum)long.MinValue, "-9223372036854775808" };
+ yield return new object[] { (LongEnum)(-1), "-1" };
+ yield return new object[] { (LongEnum)0, "0" };
+ yield return new object[] { (LongEnum)1, "1" };
+ yield return new object[] { (LongEnum)long.MaxValue, "9223372036854775807" };
+ }
+
+ private static IEnumerable<object[]> FromSingle_TestData()
+ {
+ yield return new object[] { (float)(-1), "-1" };
+ yield return new object[] { (float)0, "0" };
+ yield return new object[] { (float)1, "1" };
+ yield return new object[] { float.PositiveInfinity, float.PositiveInfinity.ToString() };
+ yield return new object[] { float.NegativeInfinity, float.NegativeInfinity.ToString() };
+ yield return new object[] { float.NaN, "NaN" };
+ }
+
+ private static IEnumerable<object[]> FromDouble_TestData()
+ {
+ yield return new object[] { (double)(-1), "-1" };
+ yield return new object[] { (double)0, "0" };
+ yield return new object[] { (double)1, "1" };
+ yield return new object[] { double.PositiveInfinity, double.PositiveInfinity.ToString() };
+ yield return new object[] { double.NegativeInfinity, double.NegativeInfinity.ToString() };
+ yield return new object[] { double.NaN, "NaN" };
+ }
+
+ private static IEnumerable<object[]> FromDecimal_TestData()
+ {
+ yield return new object[] { decimal.MinValue, decimal.MinValue.ToString() };
+ yield return new object[] { (decimal)(-1), "-1" };
+ yield return new object[] { (decimal)0, "0" };
+ yield return new object[] { (decimal)1, "1" };
+ yield return new object[] { decimal.MaxValue, decimal.MaxValue.ToString() };
+ }
+
+ private static IEnumerable<object[]> FromBoolean_TestData()
+ {
+ yield return new object[] { true, "True" };
+ yield return new object[] { false, "False" };
+ }
+
+ private static IEnumerable<object[]> FromString_TestData()
+ {
+ yield return new object[] { "", "" };
+ yield return new object[] { "abc", "abc" };
+ }
+
+ private static IEnumerable<object[]> FromNull_TestData()
+ {
+ yield return new object[] { null, (string)null };
+ }
+
+ private static IEnumerable<object[]> FromChar_TestData()
+ {
+ yield return new object[] { char.MinValue, "\0" };
+ yield return new object[] { (char)1, "\u0001" };
+ yield return new object[] { 'a', "a" };
+ yield return new object[] { char.MaxValue, char.MaxValue.ToString() };
+ }
+
+ private static IEnumerable<object[]> FromCharArray_TestData()
+ {
+ yield return new object[] { new char[0], "" };
+ yield return new object[] { new char[] { (char)0 }, "\0" };
+ yield return new object[] { new char[] { 'A', 'B' }, "AB" };
+ }
+
+ private static IEnumerable<object[]> FromDateTime_TestData()
+ {
+ yield return new object[] { new DateTime(10), new DateTime(10).ToString("T", null) };
+ }
+
+ private static IEnumerable<object[]> FromObject_TestData()
+ {
+ yield return new object[] { new object() };
+ }
+
+ private static IEnumerable<object[]> FromSingle_Format_TestData()
+ {
+ yield return new object[] { (float)(-1), default(NumberFormatInfo), "-1" };
+ yield return new object[] { (float)(-1), new NumberFormatInfo() { NegativeSign = "#" }, "#1" };
+ }
+
+ private static IEnumerable<object[]> FromDouble_Format_TestData()
+ {
+ yield return new object[] { (double)(-1), default(NumberFormatInfo), "-1" };
+ yield return new object[] { (double)(-1), new NumberFormatInfo() { NegativeSign = "#" }, "#1" };
+ }
+
+ private static IEnumerable<object[]> FromDecimal_Format_TestData()
+ {
+ yield return new object[] { (decimal)(-1), default(NumberFormatInfo), "-1" };
+ yield return new object[] { (decimal)(-1), new NumberFormatInfo() { NegativeSign = "#" }, "#1" };
+ }
+
+ [Theory]
+ [InlineData("a", 1, 0, null, "a")]
+ [InlineData("a", 1, 0, "", "a")]
+ [InlineData("a", 1, 1, "", "a")]
+ [InlineData("a", 1, 0, "b", "a")]
+ [InlineData("a", 1, 1, "b", "b")]
+ [InlineData("a", 1, 2, "b", "b")]
+ [InlineData("abc", 2, 0, "def", "abc")]
+ [InlineData("abc", 2, 1, "def", "adc")]
+ [InlineData("abc", 2, 2, "def", "ade")]
+ [InlineData("abc", 2, 3, "def", "ade")]
+ public void MidStmtStr(string str, int start, int length, string insert, string expected)
+ {
+ StringType.MidStmtStr(ref str, start, length, insert);
+ Assert.Equal(expected, str);
+ }
+
+ [Theory]
+ [InlineData(null, 1, 0, null)]
+ [InlineData(null, 1, 0, "")]
+ [InlineData("", 1, 0, null)]
+ [InlineData("", -1, 0, "")]
+ [InlineData("", 0, 0, "")]
+ [InlineData("", 1, 0, "")]
+ [InlineData("", 2, 0, "")]
+ [InlineData("", 1, -1, "")]
+ [InlineData("abc", -1, 0, "")]
+ [InlineData("abc", 0, 0, "")]
+ [InlineData("abc", 4, 0, "")]
+ [InlineData("abc", 1, -3, "")]
+ public void MidStmtStr_ArgumentException(string str, int start, int length, string insert)
+ {
+ Assert.Throws<ArgumentException>(() => StringType.MidStmtStr(ref str, start, length, insert));
+ }
+
+ [Theory]
+ [InlineData(null, null, 0, 0)]
+ [InlineData(null, "", 0, 0)]
+ [InlineData("", null, 0, 0)]
+ [InlineData(null, "a", -1, -1)]
+ [InlineData("a", null, 1, 1)]
+ [InlineData("", "a", -97, -1)]
+ [InlineData("a", "", 97, 1)]
+ [InlineData("a", "a", 0, 0)]
+ [InlineData("a", "b", -1, -1)]
+ [InlineData("b", "a", 1, 1)]
+ [InlineData("a", "ABC", 32, -1)]
+ [InlineData("ABC", "a", -32, 1)]
+ [InlineData("abc", "ABC", 32, 0)]
+ public void StrCmp(string left, string right, int expectedBinaryCompare, int expectedTextCompare)
+ {
+ Assert.Equal(expectedBinaryCompare, StringType.StrCmp(left, right, TextCompare: false));
+ Assert.Equal(expectedTextCompare, StringType.StrCmp(left, right, TextCompare: true));
+ }
+
+ [Theory]
+ [InlineData(null, null, true, true)]
+ [InlineData("", null, true, true)]
+ [InlineData("", "*", true, true)]
+ [InlineData("", "?", false, false)]
+ [InlineData("a", "?", true, true)]
+ [InlineData("a3", "[A-Z]#", false, true)]
+ [InlineData("A3", "[a-z]#", false, true)]
+ public void StrLike(string source, string pattern, bool expectedBinaryCompare, bool expectedTextCompare)
+ {
+ Assert.Equal(expectedBinaryCompare, StringType.StrLike(source, pattern, CompareMethod.Binary));
+ Assert.Equal(expectedTextCompare, StringType.StrLike(source, pattern, CompareMethod.Text));
+ Assert.Equal(expectedBinaryCompare, StringType.StrLikeBinary(source, pattern));
+ Assert.Equal(expectedTextCompare, StringType.StrLikeText(source, pattern));
+ }
+
+ [Theory]
+ [InlineData(null, "*")]
+ public void StrLike_NullReferenceException(string source, string pattern)
+ {
+ Assert.Throws<NullReferenceException>(() => StringType.StrLike(source, pattern, CompareMethod.Binary));
+ Assert.Throws<NullReferenceException>(() => StringType.StrLike(source, pattern, CompareMethod.Text));
+ Assert.Throws<NullReferenceException>(() => StringType.StrLikeBinary(source, pattern));
+ Assert.Throws<NullReferenceException>(() => StringType.StrLikeText(source, pattern));
+ }
+ }
+}