'string.sbp
'文字列変数の操作用

/*!
@brief Stringが内部で保持しているポインタを返す。
@param[in] s 文字列。
@return sの内部バッファへのポインタ、ただしsがNothingならNULL。
*/
Function StrPtr(s As String) As *Char
	If Not ActiveBasic.IsNothing(s) Then
		StrPtr = s.StrPtr
	End If
End Function
'StringBuilder版はClasses/System/Text/StringBuilder.abに定義されている。

/*!
@brief 指定した長さの空文字(\0)を持つ文字列を作成する。
@param[in] length 長さ
@return Legnth = lengthとなっている文字列。
*/
Function ZeroString(length As Long) As String 
	ZeroString = New String(0 As Char, length) 
End Function 

Function MakeStr(psz As PSTR) As String
	Return New String(psz)
End Function

Function MakeStr(psz As PWSTR) As String
	Return New String(psz)
End Function

Dim _System_AllocForConvertedString As *Function(size As SIZE_T) As VoidPtr
_System_AllocForConvertedString = AddressOf (GC_malloc_atomic)

Namespace Detail
	Function GetWCStr(mbsSrc As PSTR, len As SIZE_T, ByRef wcsDst As PWSTR) As SIZE_T
		Dim lenWCS = MultiByteToWideChar(CP_ACP, 0, mbsSrc, (len As DWord) As Long, 0, 0)
		wcsDst = _System_AllocForConvertedString(SizeOf (WCHAR) * (lenWCS + 1)) As PWSTR
		GetWCStr = MultiByteToWideChar(CP_ACP, 0, mbsSrc, (len As DWord) As Long, wcsDst, lenWCS)
		wcsDst[lenWCS] = 0
	End Function

	Function GetWCStr(wcsSrc As PWSTR, len As SIZE_T, ByRef wcsDst As PWSTR) As SIZE_T
		wcsDst = wcsSrc
		GetWCStr = len
	End Function

	Function GetMBStr(wcsSrc As PWSTR, len As SIZE_T, ByRef mbsDst As PSTR) As SIZE_T
		Dim lenMBS = WideCharToMultiByte(CP_ACP, 0, wcsSrc, (len As DWord) As Long, 0, 0, 0, 0)
		mbsDst = _System_AllocForConvertedString(SizeOf (CHAR) * (lenMBS + 1)) As PSTR
		GetMBStr = WideCharToMultiByte(CP_ACP, 0, wcsSrc, (len As DWord) As Long, mbsDst, lenMBS, 0, 0) As SIZE_T
		mbsDst[lenMBS] = 0
	End Function

	Function GetMBStr(mbsSrc As PSTR, len As SIZE_T, ByRef mbsDst As PSTR) As SIZE_T
		mbsDst = mbsSrc
		GetMBStr = len
	End Function

	' ToTCStrの補助
	Sub GetStrNT(mbszSrc As PSTR, ByRef mbszDst As PSTR)
		mbszDst = mbszSrc
	End Sub

	Sub GetStrNT(mbszSrc As PSTR, ByRef wcszDst As PWSTR)
		GetStr(mbszSrc, wcszDst)
	End Sub

	Sub GetStrNT(wcszSrc As PWSTR, ByRef mbszDst As PSTR)
		GetStr(wcszSrc, mbszDst)
	End Sub

	Sub GetStrNT(wcszSrc As PWSTR, ByRef wcszDst As PWSTR)
		wcszDst = wcszSrc
	End Sub

End Namespace

/*
変換の組み合わせは、
入力引数: wcsz, wcs + len, mbsz, mbs + len, str
出力関数: wcs(z)出力GetStr, mbs(z)出力GetStr, ToWCStr, ToMBStr, ToTCStr,
で、5 * 5 = 25通り。
*/

Function GetStr(mbszSrc As PSTR, ByRef wcsDst As PWSTR) As SIZE_T
	If mbszSrc = 0 Then
		wcsDst = 0
		Return 0
	Else
		Return Detail.GetWCStr(mbszSrc, lstrlenA(mbszSrc) As SIZE_T, wcsDst)
	End If
End Function

Function GetStr(mbsSrc As PSTR, len As SIZE_T, ByRef wcsDst As PWSTR) As SIZE_T
	If mbsSrc = 0 Then
		wcsDst = 0
		Return 0
	Else
		Return Detail.GetWCStr(mbsSrc, len, wcsDst)
	End If
End Function

Function GetStr(wcszSrc As PWSTR, ByRef wcsDst As PWSTR) As SIZE_T
	If wcszSrc = 0 Then
		wcsDst = 0
		Return 0
	Else
		wcsDst = wcszSrc
		Return lstrlenW(wcszSrc) As SIZE_T + 1
	End If
End Function

Function GetStr(wcsSrc As PWSTR, len As SIZE_T, ByRef wcsDst As PWSTR) As SIZE_T
	If wcsSrc = 0 Then
		wcsDst = 0
		Return 0
	Else
		wcsDst = wcsSrc
		Return len
	End If
End Function

Function GetStr(wcszSrc As PWSTR, ByRef mbsDst As PSTR) As SIZE_T
	If wcszSrc = 0 Then
		mbsDst = 0
		Return 0
	Else
		Return Detail.GetMBStr(wcszSrc, lstrlenW(wcszSrc) As SIZE_T, mbsDst)
	End If
End Function

Function GetStr(wcsSrc As PWSTR, len As SIZE_T, ByRef mbsDst As PSTR) As SIZE_T
	If wcsSrc = 0 Then
		mbsDst = 0
		Return 0
	Else
		Return Detail.GetMBStr(wcsSrc, len As SIZE_T, mbsDst)
	End If
End Function

Function GetStr(mbszSrc As PSTR, ByRef mbsDst As PSTR) As SIZE_T
	If mbszSrc = 0 Then
		mbsDst = 0
		Return 0
	Else
		mbsDst = mbszSrc
		Return lstrlenA(mbszSrc) As SIZE_T + 1
	End If
End Function

Function GetStr(mbsSrc As PSTR, len As SIZE_T, ByRef mbsDst As PSTR) As SIZE_T
	If mbsSrc = 0 Then
		mbsDst = 0
		Return len
	Else
		mbsDst = mbsSrc
		Return 0
	End If
End Function

Function GetStr(strSrc As String, ByRef wcsDst As PWSTR) As SIZE_T
	If ActiveBasic.IsNothing(strSrc) Then
		wcsDst = 0
		Return 0
	Else
		Return Detail.GetWCStr(strSrc.StrPtr, strSrc.Length As SIZE_T, wcsDst)
	End If
End Function

Function GetStr(strSrc As String, ByRef mbsDst As PSTR) As SIZE_T
	If ActiveBasic.IsNothing(strSrc) Then
		mbsDst = 0
		Return 0
	Else
		Return Detail.GetMBStr(strSrc.StrPtr, strSrc.Length As SIZE_T, mbsDst)
	End If
End Function

Function ToWCStr(mbsz As PSTR) As PWSTR
	Detail.GetStrNT(mbsz, ToWCStr)
End Function

Function ToWCStr(mbs As PSTR, len As SIZE_T) As PWSTR
	GetStr(mbs, len, ToWCStr)
End Function

Function ToWCStr(wcsz As PWSTR) As PWSTR
	ToWCStr = wcsz
End Function

Function ToWCStr(wcs As PWSTR, len As SIZE_T) As PWSTR
	ToWCStr = wcs
End Function

Function ToWCStr(s As String) As PWSTR
	GetStr(s, ToWCStr)
End Function

Function ToMBStr(mbsz As PSTR) As PSTR
	ToMBStr = mbsz
End Function

Function ToMBStr(mbs As PSTR, len As SIZE_T) As PSTR
	ToMBStr = mbs
End Function

Function ToMBStr(wcsz As PWSTR) As PSTR
	Detail.GetStrNT(wcsz, ToMBStr)
End Function

Function ToMBStr(wcs As PWSTR, len As SIZE_T) As PSTR
	GetStr(wcs, len, ToMBStr)
End Function

Function ToMBStr(s As String) As PSTR
	GetStr(s, ToMBStr)
End Function

Function ToTCStr(mbsz As PSTR) As PCTSTR
	Detail.GetStrNT(mbsz, ToTCStr)
End Function

Function ToTCStr(mbs As PSTR, len As SIZE_T) As PCTSTR
	GetStr(mbs, len, ToTCStr)
End Function

Function ToTCStr(wcsz As PWSTR) As PCTSTR
	Detail.GetStrNT(wcsz, ToTCStr)
End Function

Function ToTCStr(wcs As PWSTR, len As SIZE_T) As PCTSTR
	GetStr(wcs, len, ToTCStr)
End Function

Function ToTCStr(s As String) As PCTSTR
	Return StrPtr(s)
End Function

#ifndef UNICODE
TypeDef BoxedStrChar = System.SByte
#else
TypeDef BoxedStrChar = System.UInt16
#endif
