'Classes/ActiveBasic/Strings/Strings.ab

#ifndef __ACTIVEBASIC_STRINGS_STRINGS_AB__
#define __ACTIVEBASIC_STRINGS_STRINGS_AB__

#require <Classes/System/Math.ab>
#require <Classes/System/Collections/ArrayList.ab>

Namespace ActiveBasic
Namespace Strings

Sub ChrFill(p As PWSTR, n As SIZE_T, c As WCHAR)
	Dim i As SIZE_T
	For i = 0 To ELM(n)
		p[i] = c
	Next
End Sub

Sub ChrFill(p As PSTR, n As SIZE_T, c As SByte)
	Dim i As SIZE_T
	For i = 0 To ELM(n)
		p[i] = c
	Next
End Sub

Function ChrCopy(dst As PCWSTR, src As PCWSTR, size As SIZE_T) As PCWSTR
	memcpy(dst, src, size * SizeOf (WCHAR))
	Return dst
End Function

Function ChrCopy(dst As PCSTR, src As PCSTR, size As SIZE_T) As PCSTR
	memcpy(dst, src, size)
	Return dst
End Function

Function ChrMove(dst As PCWSTR, src As PCWSTR, size As SIZE_T) As PCWSTR
	MoveMemory(dst, src, size * SizeOf (WCHAR))
	Return dst
End Function

Function ChrMove(dst As PCSTR, src As PCSTR, size As SIZE_T) As PCSTR
	MoveMemory(dst, src, size)
	Return dst
End Function

Function StrCmp(s1 As PCWSTR, s2 As PCWSTR) As Long
	Dim i = 0 As SIZE_T
	While s1[i] = s2[i]
		If s1[i] = 0 Then
			Exit While
		End If
		i++
	Wend
	Return s1[i] As Long - s2[i]
End Function

Function StrCmp(s1 As PCSTR, s2 As PCSTR) As Long
	Dim i = 0 As SIZE_T
	While s1[i] = s2[i]
		If s1[i] = 0 Then
			Exit While
		End If
		i++
	Wend
	Return s1[i] As Long - s2[i]
End Function



Function ChrCmp(s1 As PCWSTR, s2 As PCWSTR, size As SIZE_T) As Long
	Dim i = 0 As SIZE_T
	While i <> size 'Forではsize = 0のときにまずい
		ChrCmp = s1[i] As Long - s2[i]
		If ChrCmp <> 0 Then
			Exit Function
		End If
		i++
	Wend
End Function

Function ChrCmp(s1 As PCSTR, s2 As PCSTR, size As SIZE_T) As Long
	Dim i = 0 As SIZE_T
	While i <> size
		ChrCmp = s1[i] As Long - s2[i]
		If ChrCmp <> 0 Then
			Exit Function
		End If
		i++
	Wend
End Function

Function ChrCmp(s1 As PCWSTR, size1 As SIZE_T, s2 As PCWSTR, size2 As SIZE_T) As Long
	ChrCmp = ChrCmp(s1, s2, System.Math.Min(size1, size2))
	If ChrCmp = 0 Then
		ChrCmp = size1 - size2
	End If
End Function

Function ChrCmp(s1 As PCSTR, size1 As SIZE_T, s2 As PCSTR, size2 As SIZE_T) As Long
	ChrCmp = ChrCmp(s1, s2, System.Math.Min(size1, size2))
	If ChrCmp = 0 Then
		ChrCmp = size1 - size2
	End If
End Function

Function ChrPBrk(str As PCWSTR, cStr As SIZE_T, chars As PCWSTR, cChars As SIZE_T) As SIZE_T
	Dim i As SIZE_T
	For i = 0 To ELM(cStr)
		If ChrFind(chars, cChars, str[i]) <> -1 Then
			Return i
		End If
	Next
	Return -1 As SIZE_T
End Function

Function ChrPBrk(str As PCSTR, cStr As SIZE_T, Chars As PCSTR, cChars As SIZE_T) As SIZE_T
	Dim i As SIZE_T
	For i = 0 To ELM(cStr)
		If ChrFind(Chars, cChars, str[i]) <> -1 Then
			Return i
		End If
	Next
	Return -1 As SIZE_T
End Function

Function ChrFind(s As PCWSTR, size As SIZE_T, c As WCHAR) As SIZE_T
	Dim i As SIZE_T
	For i = 0 To ELM(size)
		If s[i] = c Then
			Return i
		End If
	Next
	Return -1 As SIZE_T
End Function

Function ChrFind(s As PCSTR, size As SIZE_T, c As CHAR) As SIZE_T
	Dim i As SIZE_T
	For i = 0 To ELM(size)
		If s[i] = c Then
			Return i
		End If
	Next
	Return -1 As SIZE_T
End Function

Function ChrFind(s1 As PCWSTR, len1 As SIZE_T, s2 As PCWSTR, len2 As SIZE_T) As SIZE_T
	If len2 = 0 Then
		'ChrFind = 0
		Exit Function
	End If
	Do
		Dim prev = ChrFind
		ChrFind = ChrFind(VarPtr(s1[prev]), (len1 - prev) As SIZE_T, s2[0])
		If ChrFind = -1 As SIZE_T Then
			Exit Function
		End If
		ChrFind += prev

		If ChrCmp(VarPtr(s1[ChrFind]), s2, len2) = 0 Then
			Exit Function
		End If
		ChrFind++
		If ChrFind = len1 Then
			ChrFind = -1
			Exit Function
		End If
	Loop
End Function

Function ChrFind(s1 As PCSTR, len1 As SIZE_T, s2 As PCSTR, len2 As SIZE_T) As SIZE_T
	If len2 = 0 Then
		'ChrFind = 0
		Exit Function
	End If
	Do
		Dim prev = ChrFind
		ChrFind = ChrFind(VarPtr(s1[prev]), (len1 - prev) As SIZE_T, s2[0])
		If ChrFind = -1 As SIZE_T Then
			Exit Function
		End If
		ChrFind += prev

		If ChrCmp(VarPtr(s1[ChrFind]), s2, len2) = 0 Then
			Exit Function
		End If
		ChrFind++
		If ChrFind = len1 Then
			ChrFind = -1
			Exit Function
		End If
	Loop
End Function

Namespace Detail
Function Split(s As String, c As StrChar) As System.Collections.ArrayList
	Split = New System.Collections.ArrayList

	Dim last = 0 As Long
	Do
		Dim i = s.IndexOf(c, last)
		If i < 0 Then
			Split.Add(s.Substring(last, s.Length - last))
			Exit Function
		End If
		Split.Add(s.Substring(last, i - last))
		last = i + 1
		If last > s.Length Then
			Split.Add(System.String.Empty)
		End If
	Loop
End Function
End Namespace 'Detail

End Namespace 'Strings
End Namespace 'ActiveBasic

#endif '__ACTIVEBASIC_STRINGS_STRINGS_AB__
