Changeset 336


Ignore:
Timestamp:
Sep 20, 2007, 3:15:53 AM (17 years ago)
Author:
NoWest
Message:

非同期ファイル操作以外の実装はほぼ完了。
非同期は、インターフェイス、デリゲートの追加を待って実装予定。

File:
1 edited

Legend:

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

    r289 r336  
    2828    fileShare As DWord
    2929    fileOptions As DWord
    30 
    31     /* 現在は未使用 */
    32     /*Overlapped As OVERLAPPED*/
     30    fileReadOverlapped As OVERLAPPED
     31    fileWriteOverlapped As OVERLAPPED
    3332
    3433Public
     
    10099        'Throw System.IO.FileNotFoundException
    101100            This.handle=0
     101            Beep(220,500)
    102102            Exit Sub
    103103        End If
    104104
    105         filePath = path
    106         fileMode = mo
    107         fileAccess = ac
    108         fileShare = sh
    109         fileOptions = op
     105        This.filePath = path
     106        This.fileMode = mo
     107        This.fileAccess = ac
     108        This.fileShare = sh
     109        This.fileOptions = op
    110110    End Sub
    111111    Sub FileStream(path As String, mode As FileMode, access As FileAccess, share As FileShare)
    112         FileStream(path,mode,access,share,FileOptions.None)
     112        This.FileStream(path,mode,access,share,FileOptions.None)
    113113    End Sub
    114114    Sub FileStream(path As String, mode As FileMode, access As FileAccess)
    115         FileStream(path,mode,access,FileShare.None,FileOptions.None)
     115        This.FileStream(path,mode,access,FileShare.None,FileOptions.None)
    116116    End Sub
    117117    Sub FileStream(path As String, mode As FileMode)
     
    131131                access=FileAccess.Write
    132132        End Select
    133         FileStream(path,mode,access,FileShare.None,FileOptions.None)
     133        This.FileStream(path,mode,access,FileShare.None,FileOptions.None)
    134134    End Sub
    135135
     
    142142    Override Function CanRead() As Boolean
    143143        /* ファイルが読み込みに対応しているかを返す */
    144         If fileAccess=GENERIC_READ/*FileAccess.Read*/ or fileAccess=GENERIC_READ or GENERIC_WRITE/*FileAccess.ReadWrite*/ Then
     144        If This.fileAccess And GENERIC_READ Then
    145145            Return True
    146146        Else
     
    151151    Override Function CanSeek() As Boolean
    152152        /* ファイルがシークに対応しているかを返す */
    153         Return True
    154     End Function
    155 
    156     Override Function CanTimeout() As Boolean
    157         /* ファイルがタイムアウトに対応しているかを返す */
    158         Return False /*今のところ対応していないのでFalse*/
    159     End Function
     153        If GetFileType(This.handle)=FILE_TYPE_DISK Then
     154            Return True
     155        Else
     156            Return False
     157        End If
     158    End Function
     159
     160'   Override Function CanTimeout() As Boolean
     161'       /* ファイルがタイムアウトに対応しているかを返す */
     162'       Return False /*今のところ対応していないのでFalse*/
     163'   End Function*/
    160164
    161165    Override Function CanWrite() As Boolean
    162166        /* ファイルが書き込みに対応しているかを返す */
    163         If fileAccess=GENERIC_WRITE/*FileAccess.Write*/ or fileAccess=GENERIC_READ or GENERIC_WRITE/*FileAccess.ReadWrite*/ Then
     167        If This.fileAccess And GENERIC_WRITE Then
    164168            Return True
    165169        Else
     
    172176    Function IsAsync() As Boolean
    173177        /* ファイルが非同期操作に対応しているかを返す */
    174         If fileOptions=FILE_FLAG_OVERLAPPED/*FileOptions.Asynchronous*/ Then
     178        If This.fileOptions=FILE_FLAG_OVERLAPPED/*FileOptions.Asynchronous*/ Then
    175179            Return True
    176180        Else
     
    180184
    181185    Override Function Length() As Int64
    182         /* ファイルのサイズの取得 */
    183         Dim s As LARGE_INTEGER
    184         s.LowPart=GetFileSize(This.handle,VarPtr(s.HighPart) As *DWord)
    185         memcpy(VarPtr(Length),VarPtr(s),SizeOf(LARGE_INTEGER))
     186        If This.CanSeek() Then
     187            Dim length As LARGE_INTEGER
     188            length.LowPart=GetFileSize(This.handle,VarPtr(length.HighPart) As *DWord)
     189            Return MAKEQWORD(length.LowPart,length.HighPart)
     190        End If
    186191    End Function
    187192
    188193    Function Name() As String
    189         /* 多分文字列をコピーして返す方がいいのと思うが。。。*/
    190         Return filePath
     194        Return New String(This.filePath)
    191195    End Function
    192196   
    193197    Override Sub Position(value As Int64)
    194         /* ファイルポインタの位置の設定 */
    195         Dim o As LARGE_INTEGER
    196         memcpy(VarPtr(o),VarPtr(value),SizeOf(LARGE_INTEGER))
    197         If o.HighPart=0 And value<0 Then
    198             o.LowPart=-Abs(o.LowPart) As Long
    199         End If
    200         Dim ret As LARGE_INTEGER
    201         SetFilePointer(This.handle,o.LowPart,VarPtr(o.HighPart) As *DWord,FILE_CURRENT)
     198        If This.CanSeek() Then
     199            If This.IsAsync() Then
     200                fileReadOverlapped.Offset=LODWORD(value)
     201                fileReadOverlapped.OffsetHigh=HIDWORD(value)
     202                fileWriteOverlapped.OffsetHigh=LODWORD(value)
     203                fileWriteOverlapped.OffsetHigh=HIDWORD(value)
     204            Else
     205                Dim position As LARGE_INTEGER
     206                position.LowPart=LODWORD(value)
     207                position.HighPart=HIDWORD(value)
     208                SetFilePointer(This.handle,position.LowPart,VarPtr(position.HighPart) As *DWord,FILE_BEGIN)
     209            End If
     210        End If
    202211    End Sub
    203212    Override Function Position() As Int64
    204         /* ファイルポインタの位置の取得 */
    205         Dim o As LARGE_INTEGER
    206         o.HighPart=0
    207         o.LowPart=0
    208         o.LowPart=SetFilePointer(This.handle,0,VarPtr(o.HighPart) As *DWord,FILE_CURRENT)
    209         memcpy(VarPtr(Position),VarPtr(o),SizeOf(LARGE_INTEGER))
    210     End Function
    211 
    212     Override Sub ReadTimeout(value As Long)
     213        If This.CanSeek() Then
     214            If This.IsAsync() Then
     215                Return MAKEQWORD(fileReadOverlapped.Offset,fileReadOverlapped.OffsetHigh)
     216            Else
     217                Dim position As LARGE_INTEGER
     218                ZeroMemory(VarPtr(position),SizeOf(LARGE_INTEGER))
     219                position.LowPart=SetFilePointer(This.handle,position.LowPart,VarPtr(position.HighPart) As *DWord,FILE_CURRENT)
     220                Return MAKEQWORD(position.LowPart,position.HighPart)
     221            End If
     222        End If
     223    End Function
     224
     225/*  Override Sub ReadTimeout(value As Long)
    213226        'TODO
    214227    End Sub
    215228    Override Function ReadTimeout() As Long
    216229        'TODO
    217     End Function
     230    End Function*/
    218231
    219232    /* Safe~Handle系の実装は要相談!! */
     
    231244Public
    232245    Override Function BeginRead(ByRef buffer[] As Byte, offset As Long, count As Long, callback As AsyncCallback, state As Object) As System.IAsyncResult
    233         'TODO
     246        If This.IsAsync() Then
     247        Else
     248            Read(buffer,offset,count)
     249        End If
    234250    End Function
    235251
    236252    Override Function BeginWrite(ByRef buffer[] As Byte, offset As Long, count As Long, callback As AsyncCallback, state As Object) As System.IAsyncResult
    237         'TODO
     253        If This.IsAsync() Then
     254        Else
     255            Write(buffer,offset,count)
     256        End If
    238257    End Function
    239258
     
    276295
    277296    Sub Lock(position As Int64, length As Int64)
    278         Dim p As LARGE_INTEGER
    279         Dim l As LARGE_INTEGER
    280         memcpy(VarPtr(p),VarPtr(position),SizeOf(LARGE_INTEGER))
    281         memcpy(VarPtr(l),VarPtr(length),SizeOf(LARGE_INTEGER))
    282         LockFile(This.handle,p.LowPart,p.HighPart,l.LowPart,l.HighPart)
    283297    End Sub
    284298
    285299    Override Function Read(ByRef buffer[] As Byte, offset As Long, count As Long) As Long
    286         If offset Then
    287             SetFilePointer(This.handle,offset,NULL,FILE_CURRENT)
    288         End If
    289         ReadFile(This.handle,buffer,count,VarPtr(Read) As *DWord,ByVal NULL)
     300        If This.CanRead() Then
     301            Dim ret As DWord
     302            If This.IsAsync() Then
     303                ReadFile(This.handle,VarPtr(buffer[offset]),count,VarPtr(ret),This.fileReadOverlapped)
     304                While This.fileReadOverlapped.Internal=STATUS_PENDING
     305                Wend
     306                fileReadOverlapped.Offset+=LODWORD(ret)
     307                fileReadOverlapped.OffsetHigh+=HIDWORD(ret)
     308                fileWriteOverlapped.Offset+=LODWORD(ret)
     309                fileWriteOverlapped.OffsetHigh+=HIDWORD(ret)
     310                Return ret
     311            Else
     312                ReadFile(This.handle,VarPtr(buffer[offset]),count,VarPtr(ret),ByVal NULL)
     313                Return ret
     314            End If
     315        End If
    290316    End Function
    291317
     
    302328
    303329    Override Function Seek(offset As Int64, origin As SeekOrigin) As Long
    304         Dim o As LARGE_INTEGER
    305         memcpy(VarPtr(o),VarPtr(offset),SizeOf(LARGE_INTEGER))
    306         If o.HighPart=0 And offset<0 Then
    307             o.LowPart=-o.LowPart
    308         End If
    309         Select Case origin
    310             Case SeekOrigin.Begin
    311                 SetFilePointer(This.handle,o.LowPart,VarPtr(o.HighPart) As *DWord,FILE_BEGIN)
    312             Case SeekOrigin.Current
    313                 SetFilePointer(This.handle,o.LowPart,VarPtr(o.HighPart) As *DWord,FILE_CURRENT)
    314             Case SeekOrigin.End
    315                 SetFilePointer(This.handle,o.LowPart,VarPtr(o.HighPart) As *DWord,FILE_END)
    316         End Select
     330        If This.CanSeek() Then
     331            If This.IsAsync() Then
     332                Select Case origin
     333                    Case SeekOrigin.Begin
     334                        fileReadOverlapped.Offset=LODWORD(offset)
     335                        fileReadOverlapped.OffsetHigh=HIDWORD(offset)
     336                        fileWriteOverlapped.OffsetHigh=LODWORD(offset)
     337                        fileWriteOverlapped.OffsetHigh=HIDWORD(offset)
     338                    Case SeekOrigin.Current
     339                        fileReadOverlapped.Offset+=LODWORD(offset)
     340                        fileReadOverlapped.OffsetHigh+=HIDWORD(offset)
     341                        fileWriteOverlapped.Offset+=LODWORD(offset)
     342                        fileWriteOverlapped.OffsetHigh+=HIDWORD(offset)
     343                    Case SeekOrigin.End
     344                        fileReadOverlapped.Offset=LODWORD(This.Length()+offset)
     345                        fileReadOverlapped.OffsetHigh=HIDWORD(This.Length()+offset)
     346                        fileWriteOverlapped.Offset=LODWORD(This.Length()+offset)
     347                        fileWriteOverlapped.OffsetHigh=HIDWORD(This.Length()+offset)
     348                End Select
     349            Else
     350                Dim seek As LARGE_INTEGER
     351                seek.LowPart=LODWORD(offset)
     352                seek.HighPart=HIDWORD(offset)
     353                If seek.HighPart=0 And offset<0 Then seek.LowPart=-seek.LowPart
     354                Select Case origin
     355                    Case SeekOrigin.Begin
     356                        Return SetFilePointer(This.handle,seek.LowPart,VarPtr(seek.HighPart) As *DWord,FILE_BEGIN)
     357                    Case SeekOrigin.Current
     358                        Return SetFilePointer(This.handle,seek.LowPart,VarPtr(seek.HighPart) As *DWord,FILE_CURRENT)
     359                    Case SeekOrigin.End
     360                        Return SetFilePointer(This.handle,seek.LowPart,VarPtr(seek.HighPart) As *DWord,FILE_CURRENT)
     361                End Select
     362            End If
     363        End If
    317364    End Function
    318365
     
    322369
    323370    Override Sub SetLength(value As Int64)
    324         Dim o As LARGE_INTEGER
    325         memcpy(VarPtr(o),VarPtr(value),SizeOf(LARGE_INTEGER))
    326         If o.HighPart=0 And value<0 Then
    327             o.LowPart=-o.LowPart
    328         End If
    329         If Length()=>value Then
    330             SetFilePointer(This.handle,o.LowPart,VarPtr(o.HighPart) As *DWord,FILE_BEGIN)
    331             SetEndOfFile(This.handle)
     371        If This.CanWrite() and This.CanSeek() Then
     372            If This.IsAsync() Then
     373            Else
     374                Dim current = This.Position()
     375                This.Position(value)
     376                SetEndOfFile(This.handle)
     377            End If
    332378        End If
    333379    End Sub
     
    336382
    337383    Override Function ToString() As String
    338         Return Name()
     384        Return This.Name()
    339385    End Function
    340386
    341387    Sub Unlock(position As Int64, length As Int64)
    342         Dim p As LARGE_INTEGER
    343         Dim l As LARGE_INTEGER
    344         memcpy(VarPtr(p),VarPtr(position),SizeOf(LARGE_INTEGER))
    345         memcpy(VarPtr(l),VarPtr(length),SizeOf(LARGE_INTEGER))
    346         UnlockFile(This.handle,p.LowPart,p.HighPart,l.LowPart,l.HighPart)
    347388    End Sub
    348389
    349390    Override Sub Write(ByRef buffer[] As Byte, offset As Long, count As Long)
    350         If offset Then
    351             SetFilePointer(This.handle,offset,NULL,FILE_CURRENT)
    352         End If
    353         Dim ret As DWord
    354         WriteFile(This.handle,buffer,count,VarPtr(ret),ByVal NULL)
     391        If This.CanWrite() Then
     392            Dim ret As DWord
     393            If This.IsAsync() Then
     394                WriteFile(This.handle,VarPtr(buffer[offset]),count,VarPtr(ret),This.fileWriteOverlapped)
     395                While This.fileReadOverlapped.Internal=STATUS_PENDING
     396                Wend
     397                This.fileReadOverlapped.Offset+=LODWORD(ret)
     398                This.fileReadOverlapped.OffsetHigh+=HIDWORD(ret)
     399                This.fileWriteOverlapped.Offset+=LODWORD(ret)
     400                This.fileWriteOverlapped.OffsetHigh+=HIDWORD(ret)
     401            Else
     402                WriteFile(This.handle,VarPtr(buffer[offset]),count,VarPtr(ret),ByVal NULL)
     403            End If
     404        End If
    355405    End Sub
    356406
     
    360410
    361411Protected
    362     /*非同期ファイル操作に必須だがどうやって実装しようか検討中*/
    363412    Override Function CreateWaitHandle() As System.Threading.WaitHandle
    364 '       Return Nothing
     413        '調査した限りでは、System.Threading.EventWaitHandleクラスをNewする模様。
     414        '現状ではSystem.Threading.WaitHandleクラスをNewしてからHandleにて設定
     415        Dim wh As System.Threading.WaitHandle
     416        wh.Handle=CreateEvent(NULL,TRUE,FALSE,NULL)
     417        Return wh
    365418    End Function
    366419
     
    368421    Finalize
    369422    MemberwiseClone*/
     423Private
    370424End Class
    371425
Note: See TracChangeset for help on using the changeset viewer.