Index: trunk/ab5.0/ablib/src/Classes/System/String.ab
===================================================================
--- trunk/ab5.0/ablib/src/Classes/System/String.ab	(revision 621)
+++ trunk/ab5.0/ablib/src/Classes/System/String.ab	(revision 634)
@@ -128,103 +128,134 @@
 
 		Const Function Operator == (y As String) As Boolean
-			Return Compare(This, y) = 0
+			Return CompareOrdinal(This, y) = 0
 		End Function
 
 		Const Function Operator == (y As *Char) As Boolean
-			Return Compare(This, y) = 0
+			Return CompareOrdinal(This, y) = 0
 		End Function
 
 		Const Function Operator <> (y As String) As Boolean
-			Return Compare(This, y) <> 0
+			Return CompareOrdinal(This, y) <> 0
 		End Function
 
 		Const Function Operator <> (y As *Char) As Boolean
-			Return Compare(This, y) <> 0
+			Return CompareOrdinal(This, y) <> 0
 		End Function
 
 		Const Function Operator < (y As String) As Boolean
-			Return Compare(This, y) < 0
+			Return CompareOrdinal(This, y) < 0
 		End Function
 
 		Const Function Operator < (y As *Char) As Boolean
-			Return Compare(This, y) < 0
+			Return CompareOrdinal(This, y) < 0
 		End Function
 
 		Const Function Operator > (y As String) As Boolean
-			Return Compare(This, y) > 0
+			Return CompareOrdinal(This, y) > 0
 		End Function
 
 		Const Function Operator > (y As *Char) As Boolean
-			Return Compare(This, y) > 0
+			Return CompareOrdinal(This, y) > 0
 		End Function
 
 		Const Function Operator <= (y As String) As Boolean
-			Return Compare(This, y) <= 0
+			Return CompareOrdinal(This, y) <= 0
 		End Function
 
 		Const Function Operator <= (y As *Char) As Boolean
-			Return Compare(This, y) <= 0
+			Return CompareOrdinal(This, y) <= 0
 		End Function
 
 		Const Function Operator >= (y As String) As Boolean
-			Return Compare(This, y) >= 0
+			Return CompareOrdinal(This, y) >= 0
 		End Function
 
 		Const Function Operator >= (y As *Char) As Boolean
-			Return Compare(This, y) >= 0
-		End Function
-
+			Return CompareOrdinal(This, y) >= 0
+		End Function
+
+		/*!
+		@brief 単語順での文字列比較
+		@auther Egtra
+		*/
 		Static Function Compare(x As String, y As String) As Long
-			Return CompareOrdinal(x, y)
-		End Function
-
-	Public
-		'Compareなどで、x.Charsではなく、StrPtr(x)と書く理由は、xがNothingの場合のため。
+			Return Compare(x, y, False)
+		End Function
+
+		Static Function Compare(x As String, y As String, ignoreCase As Boolean) As Long
+			Dim lhs = removeNull(x)
+			Dim rhs = removeNull(y)
+			Return compareImpl(lhs.Chars, lhs.Length, rhs.Chars, rhs.Length, ignoreCase)
+		End Function
 
 		Static Function Compare(x As String, indexX As Long, y As String, indexY As Long, length As Long) As Long
-			Return CompareOrdinal(x, indexX, y, indexY, length)
-		End Function
-
+			Return Compare(x, indexX, y, indexY, length, False)
+		End Function
+
+		Static Function Compare(x As String, indexX As Long, y As String, indexY As Long, length As Long, ignoreCase As Boolean) As Long
+			Dim lhs = removeNull(x)
+			Dim rhs = removeNull(y)
+			If lhs.Length > indexX Or indexX < 0 Then
+				Throw New ArgumentOutOfRangeException("indexX")
+			ElseIf rhs.Length > indexY Or indexY < 0 Then
+				Throw New ArgumentOutOfRangeException("indexY")
+			ElseIf length < 0 Then
+				Throw New ArgumentOutOfRangeException("length")
+			End If
+			Dim cmpLen = Math.Min(Math.Min(lhs.Length - indexX, rhs.Length - indexY), length)
+			Return compareImpl(VarPtr(lhs.Chars[indexX]), cmpLen, VarPtr(rhs.Chars[indexY]), cmpLen, ignoreCase)
+		End Function
+
+		/*!
+		@brief 序数での文字列比較
+		*/
 		Static Function CompareOrdinal(x As String, y As String) As Long
-			Return CompareOrdinal(StrPtr(x), StrPtr(y))
+			Dim lhs = removeNull(x)
+			Dim rhs = removeNull(y)
+			Return compareOrdinalImpl(lhs.Chars, lhs.Length, rhs.Chars, rhs.Length)
 		End Function
 
 		Static Function CompareOrdinal(x As String, indexX As Long, y As String, indexY As Long, length As Long) As Long
-			Return CompareOrdinal(StrPtr(x), indexX, StrPtr(y), indexY, length)
-		End Function
+			Dim lhs = removeNull(x)
+			Dim rhs = removeNull(y)
+			If lhs.Length > indexX Or indexX < 0 Then
+				Throw New ArgumentOutOfRangeException("indexX")
+			ElseIf rhs.Length > indexY Or indexY < 0 Then
+				Throw New ArgumentOutOfRangeException("indexY")
+			ElseIf length < 0 Then
+				Throw New ArgumentOutOfRangeException("length")
+			End If
+			Dim cmpLen = Math.Min(Math.Min(lhs.Length - indexX, rhs.Length - indexY), length)
+			Return compareOrdinalImpl(VarPtr(lhs.Chars[indexX]), cmpLen, VarPtr(rhs.Chars[indexY]), cmpLen)
+		End Function
+
+		Static Function CompareOrdinal(x As String, y As *Char) As Long
+			Dim lhs = removeNull(x)
+			Return compareOrdinalImpl(lhs.Chars, lhs.Length, y, lstrlen(y))
+		End Function
+		
 	Private
-		Static Function Compare(x As String, y As *Char) As Long
-			Return CompareOrdinal(x, y)
-		End Function
-
-		Static Function CompareOrdinal(x As String, y As *Char) As Long
-			Return CompareOrdinal(StrPtr(x), y)
-		End Function
-
-		Static Function CompareOrdinal(x As *Char, y As *Char) As Long
-			If x = 0 Then
-				If y = 0 Then
-					Return 0
-				Else
-					Return -1
-				End If
-			ElseIf y = 0 Then
-				Return 1
-			End If
-			Return ActiveBasic.Strings.StrCmp(x, y)
-		End Function
-
-		Static Function CompareOrdinal(x As *Char, indexX As Long, y As *Char, indexY As Long, length As Long) As Long
-			If x = 0 Then
-				If y = 0 Then
-					Return 0
-				Else
-					Return -1
-				End If
-			ElseIf y = 0 Then
-				Return 1
-			End If
-			Return ActiveBasic.Strings.ChrCmp(VarPtr(x[indexX]), VarPtr(y[indexY]), length As SIZE_T)
-		End Function
+		Static Function compareImpl(x As *Char, lenX As Long, y As *Char, lenY As Long, ignoreCase As Boolean) As Long
+			Dim flags = 0 As DWord
+			If ignoreCase Then
+				flags = NORM_IGNORECASE
+			End If
+			Dim ret = CompareString(LOCALE_USER_DEFAULT, ignoreCase, x, lenX, y, lenY)
+			Select Case ret
+				Case CSTR_LESS_THAN
+					compareImpl = -1
+				Case CSTR_EQUAL
+					compareImpl = 0
+				Case CSTR_GREATER_THAN
+					compareImpl = 1
+				Case Else
+					ActiveBasic.Windows.ThrowWithLastError("String.Compare")
+			End Select
+		End Function
+
+		Static Function compareOrdinalImpl(x As *Char, lenX As Long, y As *Char, lenY As Long) As Long
+			Return ActiveBasic.Strings.ChrCmp(x, lenX As SIZE_T, y, lenY As SIZE_T)
+		End Function
+
 	Public
 		Function CompareTo(y As String) As Long
