Index: trunk/Include/Classes/System/IO/Path.ab
===================================================================
--- trunk/Include/Classes/System/IO/Path.ab	(revision 407)
+++ trunk/Include/Classes/System/IO/Path.ab	(revision 429)
@@ -5,6 +5,4 @@
 */
 
-#require <Classes/System/Environment.ab>
-
 Namespace System
 Namespace IO
@@ -12,276 +10,268 @@
 Class Path
 Public
-	Static AltDirectorySeparatorChar = &H2F As StrChar '/
-	Static DirectorySeparatorChar    = &H5C As StrChar '\
-	Static PathSeparator             = &H3B As StrChar ';
-	Static VolumeSeparatorChar       = &H3A As StrChar ':
+	Static Const AltDirectorySeparatorChar = &H2F As StrChar '/
+	Static Const DirectorySeparatorChar    = &H5C As StrChar '\
+	Static Const PathSeparator             = &H3B As StrChar ';
+	Static Const VolumeSeparatorChar       = &H3A As StrChar ':
+
+	'----------------------------------------------------------------
+	' パブリック メソッド
+	'----------------------------------------------------------------
+
+	/*
+	@brief  拡張子を変更する
+	@param  パス
+	@param  変更する拡張子(.を含む)
+	@return 拡張子変更後のパス
+	*/
+	Static Function ChangeExtension(path As String, extension As String) As String
+		path = CheckPath(path)
+		If HasExtension(path) Then
+			Return path.Remove(GetExtensionIndex(path)) + extension
+		Else
+			Return path + extension
+		End If
+	End Function
+
+	/*
+	@brief  二つのパスを結合する
+	@param  結合されるパス
+	@param  結合するパス
+	@return パス
+	*/
+	Static Function Combine(path1 As String, path2 As String) As String
+		path1 = CheckPath(path1)
+		path2 = CheckPath(path2)
+		If IsPathRooted(path2) Then
+			Return path2
+		Else
+			If Not path1.EndsWith(DirectorySeparatorChar) Then
+				path1 += Chr$(DirectorySeparatorChar)
+			End If
+			Return path1 + path2
+		End If
+	End Function
+
+	/*
+	@brief  パス文字列からファイル名を取得する
+	@param  パス
+	@return ファイル名
+	*/
+	Static Function GetFileName(path As String) As String
+		path = CheckPath(path)
+		Dim lastSeparatorIndex = GetLastSeparatorIndex(path) As Long
+		If lastSeparatorIndex <> -1 Then
+			Return path.Substring(lastSeparatorIndex + 1)
+		Else
+			Return path
+		End If
+	End Function
+
+	/*
+	@brief  パス文字列からファイル名を拡張子を除いて取得する
+	@param  パス
+	@return 拡張子を除いたファイル名
+	*/
+	Static Function GetFileNameWithoutExtension(path As String) As String
+		path = GetFileName(path)
+		If HasExtension(path) Then
+			Return path.Remove(GetExtensionIndex(path))
+		Else
+			Return path
+		End If
+	End Function
+
+	/*
+	@brief  絶対パスを取得する
+	@param  相対パス
+	@return 絶対パス
+	*/
+	Static Function GetFullPath(path As String) As String
+		Return Combine(System.Environment.CurrentDirectory, path)
+	End Function
+
+	/*
+	@brief  パス文字列から拡張子を取得する
+	@param  パス
+	@return .を含む拡張子
+	*/
+	Static Function GetExtension(path As String) As String
+		path = CheckPath(path)
+		Dim extensionIndex = GetExtensionIndex(path)
+		If extensionIndex <> -1 Then
+			Return path.Substring(extensionIndex)
+		Else
+			Return New String()
+		End If
+	End Function
+
+	/*
+	@brief  ひとつ上のディレクトリを取得する
+	@param  パス
+	@return ディレクトリパス
+	*/
+	Static Function GetDirectoryName(path As String) As String
+		path = CheckPath(path)
+		Dim lastSeparatorIndex = GetLastSeparatorIndex(path)
+		If lastSeparatorIndex = -1 Then
+			Return New String()
+		Else
+			Return path.Substring(0, lastSeparatorIndex)
+		End If
+	End Function
+
+	/*
+	@brief  ルートディレクトリを取得する
+	@param  パス
+	@return ルートディレクトリ
+	*/
+	Static Function GetPathRoot(path As String) As String
+		path = CheckPath(path)
+		If IsPathRooted(path) Then
+			If path.Contains(UniformNamingConventionString) Then
+				Return path.Remove(path.IndexOf(DirectorySeparatorChar, 
+													  UniformNamingConventionString.Length) + 1)
+			Else
+				Return path.Remove(3)
+			End If
+		Else
+			Return New String()
+		End If
+	End Function
 
 	/*!
-	@brief	ファイル名を取得する
-	@author	OverTaker
-	@date	
+	@brief	ランダムなファイル名を取得する
 	@param	ファイルパス
 	@return ファイル名
-	*/
-	Static Function GetFileName(path As String) As String
-		CheckPath(path)
-		Return path.Remove(0, GetLastSeparatorIndex(path) + 1)
-	End Function
-
-	/*!
-	@brief	拡張子を除いたファイル名を取得する
-	@author	OverTaker
-	@date	
-	@param	ファイルパス
-	@return ファイル名
-	*/
-	Static Function GetFileNameWithoutExtension(path As String) As String
-		CheckPath(path)
-		Dim fileName = GetFileName(path) As String
-		Dim extPos = GetExtensionIndex(fileName) As Long
-		If extPos = -1 Then Return ""
-
-		Return fileName.Remove(extPos)
-	End Function
-
-	/*!
-	@brief	ランダムなファイル名を取得する
-	@author	OverTaker
-	@date	
-	@param	ファイルパス
-	@return ファイル名
+	手抜き実装
 	*/
 	Static Function GetRandomFileName() As String
 		Randomize
-		Dim temp As Long
-		temp = ((Rnd() * 900000000) As Long) + 10000000
-		Return Str$(temp)
-	End Function
-
-	/*!
-	@brief	ファイルの拡張子を取得する
-	@author	OverTaker
-	@date	
-	@param  ファイルパス
-	@return 拡張子(.を含む)
-	*/
-	Static Function GetExtension(path As String) As String
-		CheckPath(path)
-		Dim extPos = GetExtensionIndex(path) As Long
-		If extPos = -1 Then Return ""
-
-		Return path.Remove(0, extPos)
-	End Function
-
-	/*!
-	@brief	ファイル拡張子を変更する
-	@author	OverTaker
-	@date	
-	@param  拡張子(.を含む)
-	@return 拡張子を変更したファイルパス
-	*/
-	Static Function ChangeExtension(path As String, extension As String) As String
-		Dim extPos = GetExtensionIndex(path) As Long
-		If extPos => 0 Then
-			path = path.Remove(extPos)
-		End If
-
-		CheckPath(path)
-		Return path + extension
-	End Function
-
-	/*!
-	@brief	ファイルパスの拡張子が含まれるかどうか
-	@author	OverTaker
-	@date	
-	@param  ファイルパス
-	@return 拡張子があればTure,なければFalse
-	*/
-	Static Function HasExtension(path As String) As Boolean
-		CheckPath(path)
-		If GetExtension(path) <> "" Then
-			Return True
-		Else
-			Return False
-		End If
+		Return Str$(((Rnd() * 900000000) As Long) + 10000000)
 	End Function
 
 	/*!
 	@brief	一時ファイルを作成し、ファイルパスを取得する
-	@author	OverTaker
-	@date	
-	@return 一時ファイルを示すファイルパス
+	@return パス
 	*/
 	Static Function GetTempFileName() As String
-		Dim tempPathSize = __GetTempPath(0, 0)
-		Dim tempPath = _System_malloc(SizeOf (TCHAR) * tempPathSize) As PTSTR
-		If tempPath = 0 Then
-			' Throw OutOfMemoryException
-			Debug
-		End If
-		If __GetTempPath(tempPathSize, tempPath) > tempPathSize Then
-			' Throw IOException?
-			Debug
-		End If
-
 		Dim tempFileName[ELM(MAX_PATH)] As TCHAR
-		Dim len = __GetTempFileName(tempPath, "ABT", 0, tempFileName)
-		_System_free(tempPath)
-		Return New String(tempFileName, len As Long)
-	End Function
-	
-	/*!
-	@brief	システムの一時フォルダを取得する
-	@author	OverTaker
-	@date	
-	@return ファイルパス
+		Dim len = WIN32API_GetTempFileName(GetTempPath(), "ABT", 0, tempFileName)
+		If len <> 0 Then
+			Return New String(tempFileName, len As Long)
+		Else
+			Throw New IOException("Path.GetTempFileName: Failed to GetTempFileName.")
+		End If
+	End Function
+
+
+	/*
+	@brief  システムの一時フォルダのパス取得する
+	@return パス
 	*/
 	Static Function GetTempPath() As String
-		Dim size = __GetTempPath(0, 0)
-		Dim tempPath = _System_malloc(size) As PTSTR
-		__GetTempPath(size, tempPath)
-		GetTempPath = New String(tempPath)
-		_System_free(tempPath)
-	End Function
-
-	/*!
-	@brief	フルパスを取得する
-	@author	OverTaker
-	@date	
-	@param  ファイルパス
-	@return ファイルパス
-	*/
-	Static Function GetFullPath(path As String) As String
-		CheckPath(path)
-		If IsPathRooted(path) Then
-			Return path
-		Else
-			Return Environment.CurrentDirectory + Chr$(DirectorySeparatorChar) + path
-		End If
-	End Function
-
-	/*!
-	@brief	ひとつ上のディレクトリを取得する
-	@author	OverTaker
-	@date	
-	@param  ファイルパス
-	@return ひとつ上のディレクトリを示すファイルパス
-	*/
-	Static Function GetDirectoryName(path As String) As String
-		CheckPath(path)
-		Dim lastSepPos = GetLastSeparatorIndex(path) As Long
-		If lastSepPos = -1 Then Return ""
-
-		path = path.Remove(lastSepPos)
-		If path.Length <= 3 Then
-			If IsPathRooted(path) Then Return ""
-		End If
-		Return path
-	End Function
-
-	/*!
-	@brief	ルートディレクトリを取得する
-	@author	OverTaker
-	@date	
-	@param  ファイルパス
-	@return ルートディレクトリを示すパス
-	*/
-	Static Function GetPathRoot(path As String) As String
-		CheckPath(path)
-		If IsPathRooted(path) Then
-			Return path.Remove(3)
-		Else
-			Return ""
-		End If
-	End Function
-
-	/*!
-	@brief	パスにルートディレクトリが含まれるかどうか
-	@author	OverTaker
-	@date	
-	@param  ファイルパス
-	@return 含まれる場合True,そうでない場合False
+		Dim size = WIN32API_GetTempPath(0, 0)
+		Dim p = GC_malloc_atomic(SizeOf (TCHAR) * size) As PCTSTR
+		Dim len = WIN32API_GetTempPath(size, p)
+		If (len > size) or len = 0 Then
+			Throw New IOException("Path.GetTempPath: Failed to GetTempPath.")
+		Else
+			Return New String(p, len As Long)
+		End If
+	End Function
+
+
+	/*
+	@brief  パスに拡張子が含まれるかどうか
+	@param  パス
+	@retval True  含まれる
+	@retval False 含まれない
+	*/
+	Static Function HasExtension(path As String) As Boolean
+		path = CheckPath(path)
+		Return GetExtensionIndex(path) <> -1
+	End Function
+
+	/*
+	@brief  パスが絶対パスか取得する
+	@param  パス
+	@retval True  絶対パス
+	@retval False 相対パス
 	*/
 	Static Function IsPathRooted(path As String) As Boolean
-		CheckPath(path)
-		If path.IndexOf(Chr$(VolumeSeparatorChar), 1, 1) = 1 Then
-			Return True
-		Else
-			Return False
-		End If
-	End Function
-
-	/*!
-	@brief	二つのパスを結合します
-	@author	OverTaker
-	@date	
-	@param  結合されるファイルパス
-	@param  結合するファイルパス
-	@return 結合されたファイルパス
-	*/
-	Static Function Combine(path1 As String, path2 As String) As String
-		CheckPath(path1)
-		CheckPath(path2)
-		If path1.LastIndexOf(VolumeSeparatorChar) And path1.Length = 2 Then
-			Return path1 + path2
-		End If
-
-		If path1.LastIndexOf(DirectorySeparatorChar, ELM(path1.Length), 1) = -1 Then
-			Return path1 + Chr$(DirectorySeparatorChar) + path2
-		Else
-			Return path1 + path2
-		End If
+		path = CheckPath(path)
+		Return path.Contains(UniformNamingConventionString) _
+			or path.Contains(VolumeSeparatorChar) _
+			or path.StartsWith(DirectorySeparatorChar)
 	End Function
 
 Private
+	Static Const ExtensionSeparatorChar = &H2E As StrChar
 	Static Const InvalidPathChars = Ex"\q<>|\0\t" As String
-
-	/*!
-	@brief	無効なパス文字列がないか調べる
-	@author	OverTaker
-	@date	
-	@param  ファイルパス
-	*/
-	Static Sub CheckPath(path As String)
+	Static Const UniformNamingConventionString = Ex"\\\\" As String
+
+	'----------------------------------------------------------------
+	' プライベート　メソッド
+	'----------------------------------------------------------------
+
+	/*
+	@brief  パスに不正な文字が含まれていないか調べる。
+	@param  パス
+	@return 正しく直されたパス
+	パス末端にディレクトリ区切り記号があった場合除去する
+	..\などが含まれるパスについては未実装
+	*/
+	Static Function CheckPath(path As String) As String
+		path = path.Replace(AltDirectorySeparatorChar, DirectorySeparatorChar)
+
 		Dim i As Long
 		For i = 0 To ELM(InvalidPathChars.Length)
 			If path.Contains(InvalidPathChars.Substring(i, 1)) Then
-				Throw New ArgumentException("Path.CheckPath: The path contains invalidChars.")
+				Throw New IOException("Path.CheckPath: The path contains invalidPathChars.")
 			End If
 		Next
-	End Sub
-
-	/*!
-	@brief	ファイルの拡張子の位置を取得する
-	@author	OverTaker
-	@date	
-	@param  ファイルパス
-	@return 0から始まるインデックス値。みつからない場合-1
+
+		If path.LastIndexOf(UniformNamingConventionString) > 0 Then
+			Throw New IOException("Path.CheckPath: The path is invalid value.")
+		End If
+
+		If path.EndsWith(DirectorySeparatorChar) Then
+			Return path.Remove(path.Length - 1)
+		Else
+			Return path
+		End If
+	End Function
+
+	/*
+	@brief  パスの最も後ろにあるディレクトリ区切り記号の位置を取得する
+	@param  パス
+	@return インデックス
+	*/
+	Static Function GetLastSeparatorIndex(path As String) As Long
+		Return System.Math.Max(path.LastIndexOf(DirectorySeparatorChar), 
+							   path.LastIndexOf(AltDirectorySeparatorChar)) As Long
+	End Function
+
+	/*
+	@brief  拡張子の位置を取得する。
+	@param  パス
+	@return インデックス
 	*/
 	Static Function GetExtensionIndex(path As String) As Long
-		Dim lastSepIndex = GetLastSeparatorIndex(path) As Long
-		If lastSepIndex = -1 Then lastSepIndex = 0
-		Return path.LastIndexOf(Asc("."), ELM(path.Length), path.Length - lastSepIndex)
-	End Function
-
-	/*!
-	@brief	最も後ろにあるディレクトリ区切り文字の位置を取得する
-	@author	OverTaker
-	@date	
-	@param  ファイルパス
-	@return 0から始まるインデックス値。みつからない場合-1
-	*/
-	Static Function GetLastSeparatorIndex(path As String) As Long
-		Return System.Math.Max( path.LastIndexOf(DirectorySeparatorChar),
-								path.LastIndexOf(VolumeSeparatorChar) )
+		Dim extensionIndex = path.LastIndexOf(ExtensionSeparatorChar) As Long
+		If extensionIndex > GetLastSeparatorIndex(path) Then
+			Return extensionIndex
+		Else
+			Return -1
+		End If
 	End Function
 End Class
 
-'今はメソッド内で使えないので、実装されるまで回避
-Function __GetTempPath(nBufferLength As DWord, lpBuffer As LPSTR) As DWord
+'メソッドと名前が被るAPI
+Function WIN32API_GetTempPath(nBufferLength As DWord, lpBuffer As PTSTR) As DWord
 	Return GetTempPath(nBufferLength, lpBuffer)
 End Function
 
-Function __GetTempFileName(pPathName As PCSTR, pPrefixString As PCSTR, uUnique As DWord, pTempFileName As PSTR) As DWord
+Function WIN32API_GetTempFileName (pPathName As PCTSTR, pPrefixString As PCTSTR, uUnique As DWord, pTempFileName As PTSTR) As DWord
 	Return GetTempFileName(pPathName, pPrefixString, uUnique, pTempFileName)
 End Function
