Changeset 429


Ignore:
Timestamp:
Feb 26, 2008, 6:10:51 PM (16 years ago)
Author:
OverTaker
Message:

System/IO/Path.ab再実装。

File:
1 edited

Legend:

Unmodified
Added
Removed
  • trunk/Include/Classes/System/IO/Path.ab

    r407 r429  
    55*/
    66
    7 #require <Classes/System/Environment.ab>
    8 
    97Namespace System
    108Namespace IO
     
    1210Class Path
    1311Public
    14     Static AltDirectorySeparatorChar = &H2F As StrChar '/
    15     Static DirectorySeparatorChar    = &H5C As StrChar '\
    16     Static PathSeparator             = &H3B As StrChar ';
    17     Static VolumeSeparatorChar       = &H3A As StrChar ':
     12    Static Const AltDirectorySeparatorChar = &H2F As StrChar '/
     13    Static Const DirectorySeparatorChar    = &H5C As StrChar '\
     14    Static Const PathSeparator             = &H3B As StrChar ';
     15    Static Const VolumeSeparatorChar       = &H3A As StrChar ':
     16
     17    '----------------------------------------------------------------
     18    ' パブリック メソッド
     19    '----------------------------------------------------------------
     20
     21    /*
     22    @brief  拡張子を変更する
     23    @param  パス
     24    @param  変更する拡張子(.を含む)
     25    @return 拡張子変更後のパス
     26    */
     27    Static Function ChangeExtension(path As String, extension As String) As String
     28        path = CheckPath(path)
     29        If HasExtension(path) Then
     30            Return path.Remove(GetExtensionIndex(path)) + extension
     31        Else
     32            Return path + extension
     33        End If
     34    End Function
     35
     36    /*
     37    @brief  二つのパスを結合する
     38    @param  結合されるパス
     39    @param  結合するパス
     40    @return パス
     41    */
     42    Static Function Combine(path1 As String, path2 As String) As String
     43        path1 = CheckPath(path1)
     44        path2 = CheckPath(path2)
     45        If IsPathRooted(path2) Then
     46            Return path2
     47        Else
     48            If Not path1.EndsWith(DirectorySeparatorChar) Then
     49                path1 += Chr$(DirectorySeparatorChar)
     50            End If
     51            Return path1 + path2
     52        End If
     53    End Function
     54
     55    /*
     56    @brief  パス文字列からファイル名を取得する
     57    @param  パス
     58    @return ファイル名
     59    */
     60    Static Function GetFileName(path As String) As String
     61        path = CheckPath(path)
     62        Dim lastSeparatorIndex = GetLastSeparatorIndex(path) As Long
     63        If lastSeparatorIndex <> -1 Then
     64            Return path.Substring(lastSeparatorIndex + 1)
     65        Else
     66            Return path
     67        End If
     68    End Function
     69
     70    /*
     71    @brief  パス文字列からファイル名を拡張子を除いて取得する
     72    @param  パス
     73    @return 拡張子を除いたファイル名
     74    */
     75    Static Function GetFileNameWithoutExtension(path As String) As String
     76        path = GetFileName(path)
     77        If HasExtension(path) Then
     78            Return path.Remove(GetExtensionIndex(path))
     79        Else
     80            Return path
     81        End If
     82    End Function
     83
     84    /*
     85    @brief  絶対パスを取得する
     86    @param  相対パス
     87    @return 絶対パス
     88    */
     89    Static Function GetFullPath(path As String) As String
     90        Return Combine(System.Environment.CurrentDirectory, path)
     91    End Function
     92
     93    /*
     94    @brief  パス文字列から拡張子を取得する
     95    @param  パス
     96    @return .を含む拡張子
     97    */
     98    Static Function GetExtension(path As String) As String
     99        path = CheckPath(path)
     100        Dim extensionIndex = GetExtensionIndex(path)
     101        If extensionIndex <> -1 Then
     102            Return path.Substring(extensionIndex)
     103        Else
     104            Return New String()
     105        End If
     106    End Function
     107
     108    /*
     109    @brief  ひとつ上のディレクトリを取得する
     110    @param  パス
     111    @return ディレクトリパス
     112    */
     113    Static Function GetDirectoryName(path As String) As String
     114        path = CheckPath(path)
     115        Dim lastSeparatorIndex = GetLastSeparatorIndex(path)
     116        If lastSeparatorIndex = -1 Then
     117            Return New String()
     118        Else
     119            Return path.Substring(0, lastSeparatorIndex)
     120        End If
     121    End Function
     122
     123    /*
     124    @brief  ルートディレクトリを取得する
     125    @param  パス
     126    @return ルートディレクトリ
     127    */
     128    Static Function GetPathRoot(path As String) As String
     129        path = CheckPath(path)
     130        If IsPathRooted(path) Then
     131            If path.Contains(UniformNamingConventionString) Then
     132                Return path.Remove(path.IndexOf(DirectorySeparatorChar,
     133                                                      UniformNamingConventionString.Length) + 1)
     134            Else
     135                Return path.Remove(3)
     136            End If
     137        Else
     138            Return New String()
     139        End If
     140    End Function
    18141
    19142    /*!
    20     @brief  ファイル名を取得する
    21     @author OverTaker
    22     @date   
     143    @brief  ランダムなファイル名を取得する
    23144    @param  ファイルパス
    24145    @return ファイル名
    25     */
    26     Static Function GetFileName(path As String) As String
    27         CheckPath(path)
    28         Return path.Remove(0, GetLastSeparatorIndex(path) + 1)
    29     End Function
    30 
    31     /*!
    32     @brief  拡張子を除いたファイル名を取得する
    33     @author OverTaker
    34     @date   
    35     @param  ファイルパス
    36     @return ファイル名
    37     */
    38     Static Function GetFileNameWithoutExtension(path As String) As String
    39         CheckPath(path)
    40         Dim fileName = GetFileName(path) As String
    41         Dim extPos = GetExtensionIndex(fileName) As Long
    42         If extPos = -1 Then Return ""
    43 
    44         Return fileName.Remove(extPos)
    45     End Function
    46 
    47     /*!
    48     @brief  ランダムなファイル名を取得する
    49     @author OverTaker
    50     @date   
    51     @param  ファイルパス
    52     @return ファイル名
     146    手抜き実装
    53147    */
    54148    Static Function GetRandomFileName() As String
    55149        Randomize
    56         Dim temp As Long
    57         temp = ((Rnd() * 900000000) As Long) + 10000000
    58         Return Str$(temp)
    59     End Function
    60 
    61     /*!
    62     @brief  ファイルの拡張子を取得する
    63     @author OverTaker
    64     @date   
    65     @param  ファイルパス
    66     @return 拡張子(.を含む)
    67     */
    68     Static Function GetExtension(path As String) As String
    69         CheckPath(path)
    70         Dim extPos = GetExtensionIndex(path) As Long
    71         If extPos = -1 Then Return ""
    72 
    73         Return path.Remove(0, extPos)
    74     End Function
    75 
    76     /*!
    77     @brief  ファイル拡張子を変更する
    78     @author OverTaker
    79     @date   
    80     @param  拡張子(.を含む)
    81     @return 拡張子を変更したファイルパス
    82     */
    83     Static Function ChangeExtension(path As String, extension As String) As String
    84         Dim extPos = GetExtensionIndex(path) As Long
    85         If extPos => 0 Then
    86             path = path.Remove(extPos)
    87         End If
    88 
    89         CheckPath(path)
    90         Return path + extension
    91     End Function
    92 
    93     /*!
    94     @brief  ファイルパスの拡張子が含まれるかどうか
    95     @author OverTaker
    96     @date   
    97     @param  ファイルパス
    98     @return 拡張子があればTure,なければFalse
    99     */
    100     Static Function HasExtension(path As String) As Boolean
    101         CheckPath(path)
    102         If GetExtension(path) <> "" Then
    103             Return True
    104         Else
    105             Return False
    106         End If
     150        Return Str$(((Rnd() * 900000000) As Long) + 10000000)
    107151    End Function
    108152
    109153    /*!
    110154    @brief  一時ファイルを作成し、ファイルパスを取得する
    111     @author OverTaker
    112     @date   
    113     @return 一時ファイルを示すファイルパス
     155    @return パス
    114156    */
    115157    Static Function GetTempFileName() As String
    116         Dim tempPathSize = __GetTempPath(0, 0)
    117         Dim tempPath = _System_malloc(SizeOf (TCHAR) * tempPathSize) As PTSTR
    118         If tempPath = 0 Then
    119             ' Throw OutOfMemoryException
    120             Debug
    121         End If
    122         If __GetTempPath(tempPathSize, tempPath) > tempPathSize Then
    123             ' Throw IOException?
    124             Debug
    125         End If
    126 
    127158        Dim tempFileName[ELM(MAX_PATH)] As TCHAR
    128         Dim len = __GetTempFileName(tempPath, "ABT", 0, tempFileName)
    129         _System_free(tempPath)
    130         Return New String(tempFileName, len As Long)
    131     End Function
    132    
    133     /*!
    134     @brief  システムの一時フォルダを取得する
    135     @author OverTaker
    136     @date   
    137     @return ファイルパス
     159        Dim len = WIN32API_GetTempFileName(GetTempPath(), "ABT", 0, tempFileName)
     160        If len <> 0 Then
     161            Return New String(tempFileName, len As Long)
     162        Else
     163            Throw New IOException("Path.GetTempFileName: Failed to GetTempFileName.")
     164        End If
     165    End Function
     166
     167
     168    /*
     169    @brief  システムの一時フォルダのパス取得する
     170    @return パス
    138171    */
    139172    Static Function GetTempPath() As String
    140         Dim size = __GetTempPath(0, 0)
    141         Dim tempPath = _System_malloc(size) As PTSTR
    142         __GetTempPath(size, tempPath)
    143         GetTempPath = New String(tempPath)
    144         _System_free(tempPath)
    145     End Function
    146 
    147     /*!
    148     @brief  フルパスを取得する
    149     @author OverTaker
    150     @date   
    151     @param  ファイルパス
    152     @return ファイルパス
    153     */
    154     Static Function GetFullPath(path As String) As String
    155         CheckPath(path)
    156         If IsPathRooted(path) Then
    157             Return path
    158         Else
    159             Return Environment.CurrentDirectory + Chr$(DirectorySeparatorChar) + path
    160         End If
    161     End Function
    162 
    163     /*!
    164     @brief  ひとつ上のディレクトリを取得する
    165     @author OverTaker
    166     @date   
    167     @param  ファイルパス
    168     @return ひとつ上のディレクトリを示すファイルパス
    169     */
    170     Static Function GetDirectoryName(path As String) As String
    171         CheckPath(path)
    172         Dim lastSepPos = GetLastSeparatorIndex(path) As Long
    173         If lastSepPos = -1 Then Return ""
    174 
    175         path = path.Remove(lastSepPos)
    176         If path.Length <= 3 Then
    177             If IsPathRooted(path) Then Return ""
    178         End If
    179         Return path
    180     End Function
    181 
    182     /*!
    183     @brief  ルートディレクトリを取得する
    184     @author OverTaker
    185     @date   
    186     @param  ファイルパス
    187     @return ルートディレクトリを示すパス
    188     */
    189     Static Function GetPathRoot(path As String) As String
    190         CheckPath(path)
    191         If IsPathRooted(path) Then
    192             Return path.Remove(3)
    193         Else
    194             Return ""
    195         End If
    196     End Function
    197 
    198     /*!
    199     @brief  パスにルートディレクトリが含まれるかどうか
    200     @author OverTaker
    201     @date   
    202     @param  ファイルパス
    203     @return 含まれる場合True,そうでない場合False
     173        Dim size = WIN32API_GetTempPath(0, 0)
     174        Dim p = GC_malloc_atomic(SizeOf (TCHAR) * size) As PCTSTR
     175        Dim len = WIN32API_GetTempPath(size, p)
     176        If (len > size) or len = 0 Then
     177            Throw New IOException("Path.GetTempPath: Failed to GetTempPath.")
     178        Else
     179            Return New String(p, len As Long)
     180        End If
     181    End Function
     182
     183
     184    /*
     185    @brief  パスに拡張子が含まれるかどうか
     186    @param  パス
     187    @retval True  含まれる
     188    @retval False 含まれない
     189    */
     190    Static Function HasExtension(path As String) As Boolean
     191        path = CheckPath(path)
     192        Return GetExtensionIndex(path) <> -1
     193    End Function
     194
     195    /*
     196    @brief  パスが絶対パスか取得する
     197    @param  パス
     198    @retval True  絶対パス
     199    @retval False 相対パス
    204200    */
    205201    Static Function IsPathRooted(path As String) As Boolean
    206         CheckPath(path)
    207         If path.IndexOf(Chr$(VolumeSeparatorChar), 1, 1) = 1 Then
    208             Return True
    209         Else
    210             Return False
    211         End If
    212     End Function
    213 
    214     /*!
    215     @brief  二つのパスを結合します
    216     @author OverTaker
    217     @date   
    218     @param  結合されるファイルパス
    219     @param  結合するファイルパス
    220     @return 結合されたファイルパス
    221     */
    222     Static Function Combine(path1 As String, path2 As String) As String
    223         CheckPath(path1)
    224         CheckPath(path2)
    225         If path1.LastIndexOf(VolumeSeparatorChar) And path1.Length = 2 Then
    226             Return path1 + path2
    227         End If
    228 
    229         If path1.LastIndexOf(DirectorySeparatorChar, ELM(path1.Length), 1) = -1 Then
    230             Return path1 + Chr$(DirectorySeparatorChar) + path2
    231         Else
    232             Return path1 + path2
    233         End If
     202        path = CheckPath(path)
     203        Return path.Contains(UniformNamingConventionString) _
     204            or path.Contains(VolumeSeparatorChar) _
     205            or path.StartsWith(DirectorySeparatorChar)
    234206    End Function
    235207
    236208Private
     209    Static Const ExtensionSeparatorChar = &H2E As StrChar
    237210    Static Const InvalidPathChars = Ex"\q<>|\0\t" As String
    238 
    239     /*!
    240     @brief  無効なパス文字列がないか調べる
    241     @author OverTaker
    242     @date   
    243     @param  ファイルパス
    244     */
    245     Static Sub CheckPath(path As String)
     211    Static Const UniformNamingConventionString = Ex"\\\\" As String
     212
     213    '----------------------------------------------------------------
     214    ' プライベート メソッド
     215    '----------------------------------------------------------------
     216
     217    /*
     218    @brief  パスに不正な文字が含まれていないか調べる。
     219    @param  パス
     220    @return 正しく直されたパス
     221    パス末端にディレクトリ区切り記号があった場合除去する
     222    ..\などが含まれるパスについては未実装
     223    */
     224    Static Function CheckPath(path As String) As String
     225        path = path.Replace(AltDirectorySeparatorChar, DirectorySeparatorChar)
     226
    246227        Dim i As Long
    247228        For i = 0 To ELM(InvalidPathChars.Length)
    248229            If path.Contains(InvalidPathChars.Substring(i, 1)) Then
    249                 Throw New ArgumentException("Path.CheckPath: The path contains invalidChars.")
     230                Throw New IOException("Path.CheckPath: The path contains invalidPathChars.")
    250231            End If
    251232        Next
    252     End Sub
    253 
    254     /*!
    255     @brief  ファイルの拡張子の位置を取得する
    256     @author OverTaker
    257     @date   
    258     @param  ファイルパス
    259     @return 0から始まるインデックス値。みつからない場合-1
     233
     234        If path.LastIndexOf(UniformNamingConventionString) > 0 Then
     235            Throw New IOException("Path.CheckPath: The path is invalid value.")
     236        End If
     237
     238        If path.EndsWith(DirectorySeparatorChar) Then
     239            Return path.Remove(path.Length - 1)
     240        Else
     241            Return path
     242        End If
     243    End Function
     244
     245    /*
     246    @brief  パスの最も後ろにあるディレクトリ区切り記号の位置を取得する
     247    @param  パス
     248    @return インデックス
     249    */
     250    Static Function GetLastSeparatorIndex(path As String) As Long
     251        Return System.Math.Max(path.LastIndexOf(DirectorySeparatorChar),
     252                               path.LastIndexOf(AltDirectorySeparatorChar)) As Long
     253    End Function
     254
     255    /*
     256    @brief  拡張子の位置を取得する。
     257    @param  パス
     258    @return インデックス
    260259    */
    261260    Static Function GetExtensionIndex(path As String) As Long
    262         Dim lastSepIndex = GetLastSeparatorIndex(path) As Long
    263         If lastSepIndex = -1 Then lastSepIndex = 0
    264         Return path.LastIndexOf(Asc("."), ELM(path.Length), path.Length - lastSepIndex)
    265     End Function
    266 
    267     /*!
    268     @brief  最も後ろにあるディレクトリ区切り文字の位置を取得する
    269     @author OverTaker
    270     @date   
    271     @param  ファイルパス
    272     @return 0から始まるインデックス値。みつからない場合-1
    273     */
    274     Static Function GetLastSeparatorIndex(path As String) As Long
    275         Return System.Math.Max( path.LastIndexOf(DirectorySeparatorChar),
    276                                 path.LastIndexOf(VolumeSeparatorChar) )
     261        Dim extensionIndex = path.LastIndexOf(ExtensionSeparatorChar) As Long
     262        If extensionIndex > GetLastSeparatorIndex(path) Then
     263            Return extensionIndex
     264        Else
     265            Return -1
     266        End If
    277267    End Function
    278268End Class
    279269
    280 '今はメソッド内で使えないので、実装されるまで回避
    281 Function __GetTempPath(nBufferLength As DWord, lpBuffer As LPSTR) As DWord
     270'メソッドと名前が被るAPI
     271Function WIN32API_GetTempPath(nBufferLength As DWord, lpBuffer As PTSTR) As DWord
    282272    Return GetTempPath(nBufferLength, lpBuffer)
    283273End Function
    284274
    285 Function __GetTempFileName(pPathName As PCSTR, pPrefixString As PCSTR, uUnique As DWord, pTempFileName As PSTR) As DWord
     275Function WIN32API_GetTempFileName (pPathName As PCTSTR, pPrefixString As PCTSTR, uUnique As DWord, pTempFileName As PTSTR) As DWord
    286276    Return GetTempFileName(pPathName, pPrefixString, uUnique, pTempFileName)
    287277End Function
Note: See TracChangeset for help on using the changeset viewer.