Index: trunk/Include/Classes/System/IO/MemoryStream.ab
===================================================================
--- trunk/Include/Classes/System/IO/MemoryStream.ab	(revision 445)
+++ trunk/Include/Classes/System/IO/MemoryStream.ab	(revision 445)
@@ -0,0 +1,268 @@
+
+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<Byte>
+		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<Byte>
+		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
