NameSpace System NameSpace IO Class MemoryStream Inherits Stream Public /* 0に初期化される拡張可能な容量を使用して初期化 */ Sub MemoryStream() This.writable = True This.Resizable = True This.visible = False This.handle = HeapCreate(0,0,0) This.p = HeapAlloc(This.handle,HEAP_ZERO_MEMORY,0) This.StreamLength = 0 This.CurrentPosition = 0 End Sub Sub MemoryStream(capacity As Long) This.writable = True This.Resizable = True This.visible = False This.handle = HeapCreate(0,0,0) This.p = HeapAlloc(This.handle,HEAP_ZERO_MEMORY,capacity) This.StreamLength = capacity This.CurrentPosition = 0 End Sub Sub MemoryStream(buffer As *Byte, length As Long) This.writable = True This.Resizable = False This.visible = False This.handle = HeapCreate(0,0,0) This.p = HeapAlloc(This.handle,HEAP_ZERO_MEMORY,length) MoveMemory(This.p,buffer,length) This.StreamLength = length This.CurrentPosition = 0 End Sub Sub MemoryStream(buffer As *Byte, length As Long, writable As Boolean) This.writable = writable This.Resizable = False This.visible = False This.handle = HeapCreate(0,0,0) This.p = HeapAlloc(This.handle,HEAP_ZERO_MEMORY,length) MoveMemory(This.p,buffer,length) This.StreamLength = length This.CurrentPosition = 0 End Sub Sub MemoryStream(buffer As *Byte, index As Long, count As Long) This.writable = True This.Resizable = False This.visible = False This.handle = HeapCreate(0,0,0) This.p = HeapAlloc(This.handle,HEAP_ZERO_MEMORY,count) MoveMemory(This.p,VarPtr(buffer[index]),count) This.StreamLength = count This.CurrentPosition = 0 End Sub Sub MemoryStream(buffer As *Byte, index As Long, count As Long, writable As Boolean) This.writable = writable This.Resizable = False This.visible = False This.handle = HeapCreate(0,0,0) This.p = HeapAlloc(This.handle,HEAP_ZERO_MEMORY,count) MoveMemory(This.p,VarPtr(buffer[index]),count) This.StreamLength = count This.CurrentPosition = 0 End Sub Sub MemoryStream(buffer As *Byte, index As Long, count As Long, writable As Boolean, visible As Boolean) This.writable = writable This.Resizable = False This.visible = visible This.handle = HeapCreate(0,0,0) This.p = HeapAlloc(This.handle,HEAP_ZERO_MEMORY,count) MoveMemory(This.p,VarPtr(buffer[index]),count) This.StreamLength = count This.CurrentPosition = 0 End Sub Sub ~MemoryStream() This.Close() End Sub Public Override Function CanRead() As Boolean If This.p Then Return True Else Return False End If End Function Override Function CanSeek() As Boolean If This.p Then Return True Else Return False End If End Function Override Function CanWrite() As Boolean If This.p Then Return This.writable Else Return False End If End Function /* メモリの容量であってストリームの長さではない メモリはヒープからブロック単位で確保されるので 指定したストリーム長より大きくなることがある また、配列として扱う場合の配列長となる */ Virtual Function Capacity() As Long If This.p = 0 Then Debug'Throw New ObjectDisposedException Return HeapSize(This.handle,0,This.p) End Function Virtual Sub Capacity(value As Long) If This.p = 0 Then Debug'Throw New ObjectDisposedException If value < 0 Then Debug'Throw New ArgumentOutOfRangeException If value < This.StreamLength Then Debug'Throw New ArgumentOutOfRangeException This.p = HeapReAlloc(This.handle,HEAP_ZERO_MEMORY,This.p,value) End Sub /* こちらは容量とは別のストリーム長 実際のデータの長さはこちら */ Override Function Length() As Int64 If This.p = 0 Then Debug'Throw New ObjectDisposedException Return This.StreamLength End Function /* ストリームの現在位置を取得または設定 */ Override Sub Position(value As Int64) If This.p = 0 Then Debug'Throw New ObjectDisposedException If value < 0 Then Debug'Throw New ArgumentOutOfRangeException If value > Int32.MaxValue() Then Debug'Throw New ArgumentOutOfRangeException This.CurrentPosition = value As Long End Sub Override Function Position() As Int64 If This.p = 0 Then Debug'Throw New ObjectDisposedException Return This.CurrentPosition As Int64 End Function Override Sub Flush() End Sub /* Virtual Function GetBuffer() As Array If visible = False Then Return NULL Return p End Function*/ Override Function Read(buffer As *Byte, offset As Long, count As Long) As Long If This.p = 0 Then Debug'Throw New ObjectDisposedException If buffer = 0 Then Debug 'Throw New ArgumentNullException If offset < 0 Then Debug'Throw New ArgumentOutOfRangeException If count < 0 Then Debug'Throw New ArgumentOutOfRangeException If (This.StreamLength - (This.CurrentPosition + count)) < 0 Then count + = (This.StreamLength - (This.CurrentPosition + count)) ElseIf count < 1 Then Return 0 End If MoveMemory(VarPtr(buffer[offset]),VarPtr(This.p[This.CurrentPosition]),count) This.CurrentPosition + = count Return count End Function Override Function ReadByte() As Long Dim b As Byte Dim ret = Read(VarPtr(b), 0, 1) If ret <> 0 Then Return b Else Return -1 End If End Function Override Function Seek(offset As Int64, origin As SeekOrigin) As Int64 If This.p = 0 Then Debug'Throw New ObjectDisposedException If offset > Int32.MaxValue() Then Debug'Throw New ArgumentOutOfRangeException Select Case origin Case SeekOrigin.Begin If offset < 0 Then Debug 'Throw New IOException This.CurrentPosition = offset As Long Case SeekOrigin.Current Beep(440,10) If (This.CurrentPosition + offset) < 0 Then Debug 'Throw New IOException This.CurrentPosition += offset As Long Case SeekOrigin.End If (This.StreamLength + offset) < 0 Then Debug 'Throw New IOException This.CurrentPosition = (This.StreamLength + offset) As Long Case Else Debug 'Throw New ArgumentException End Select Return This.CurrentPosition As Int64 End Function Override Sub SetLength(value As Int64) If This.p = 0 Then Debug'Throw New ObjectDisposedException If This.writable = False Then Debug 'Throw New NotSupportedException If This.Resizable = False Then Debug 'Throw New NotSupportedException If value < 0 Then Debug'Throw New ArgumentOutOfRangeException If value > Int32.MaxValue() Then Debug'Throw New ArgumentOutOfRangeException This.p = HeapReAlloc(This.handle,HEAP_ZERO_MEMORY,This.p,value As Long) This.StreamLength = value As Long End Sub Override Sub Write(buffer As *Byte, offset As Long, count As Long) If This.p = 0 Then Debug'Throw New ObjectDisposedException If This.writable = False Then Debug'Throw New NotSupportedException If buffer = 0 Then Debug 'Throw New ArgumentNullException If offset < 0 Then Debug'Throw New ArgumentOutOfRangeException If count < 0 Then Debug'Throw New ArgumentOutOfRangeException If count > (This.StreamLength - This.CurrentPosition) Then If This.Resizable = False Then Debug 'Throw New NotSupportedException Else If count > (This.Capacity() - This.CurrentPosition) Then This.p = HeapReAlloc(This.handle,HEAP_ZERO_MEMORY,This.p,This.CurrentPosition+count) End If This.StreamLength = This.CurrentPosition+count End If End If MoveMemory(VarPtr(This.p[This.CurrentPosition]),VarPtr(buffer[offset]),count) This.CurrentPosition + = count End Sub Override Sub WriteByte(b As Byte) Write(VarPtr(b), 0, 1) End Sub /* Virtual Function ToArray() As List TODO: End Function*/ Virtual Sub WriteTo(stream As Stream) If This.p = 0 Then Debug'Throw New ObjectDisposedException If ActiveBasic.IsNothing(stream) Then Debug 'Throw New ArgumentNullException("path") stream.Write(This.p,0,This.Capacity()) End Sub Protected Override Sub Dispose(disposing As Boolean) HeapFree(This.handle,0,InterlockedExchangePointer(ByVal VarPtr(This.p) As VoidPtr,NULL) As VoidPtr) HeapDestroy(InterlockedExchangePointer(ByVal VarPtr(This.handle) As VoidPtr,NULL) As HANDLE) End Sub /* status */ writable As Boolean Resizable As Boolean visible As Boolean StreamLength As Long CurrentPosition As Long Private handle As HANDLE p As *Byte End Class End NameSpace 'IO End NameSpace 'System