source: trunk/Include/Classes/System/IO/MemoryStream.ab@ 472

Last change on this file since 472 was 472, checked in by NoWest, 16 years ago

MemoryStreamの実装は一通り完了。TestCaseの方を作成します。

File size: 13.8 KB
RevLine 
[445]1
2NameSpace System
3NameSpace IO
4
5Class MemoryStream
6 Inherits Stream
7
8Public
[472]9 /*!
10 @brief MemoryStreamクラスの新しいインスタンスを初期化します。
11 @author NoWest
12 @date 2008/3/12
[445]13 */
14 Sub MemoryStream()
15 This.writable = True
[472]16 This.resizable = True
[445]17 This.visible = False
[472]18 This.create()
19 This.pointer = This.allocate(0)
20 This.streamLength = 0
21 This.currentPosition = 0
[445]22 End Sub
[472]23
24 /*!
25 @brief MemoryStreamクラスの新しいインスタンスを初期容量を指定して初期化します。
26 @author NoWest
27 @date 2008/3/12
28 */
[445]29 Sub MemoryStream(capacity As Long)
30 This.writable = True
[472]31 This.resizable = True
[445]32 This.visible = False
[472]33 This.create()
34 This.pointer = This.allocate(capacity)
35 This.streamLength = capacity
36 This.currentPosition = 0
[445]37 End Sub
[472]38
39 /*!
40 @brief MemoryStreamクラスの新しいインスタンスを指定したバッファに基づいて初期化します。容量を変更することはできません。
41 @author NoWest
42 @date 2008/3/12
43 */
[445]44 Sub MemoryStream(buffer As *Byte, length As Long)
45 This.writable = True
[472]46 This.resizable = False
[445]47 This.visible = False
[472]48 This.create()
49 This.pointer = This.allocate(length)
50 MoveMemory(This.pointer,buffer,length)
51 This.streamLength = length
52 This.currentPosition = 0
[445]53 End Sub
[472]54
55 /*!
56 @brief MemoryStreamクラスの新しいインスタンスを指定したバッファに基づいて初期化します。容量を変更することはできません。また、書き込みをサポートするかどうかも指定できます。
57 @author NoWest
58 @date 2008/3/12
59 */
[445]60 Sub MemoryStream(buffer As *Byte, length As Long, writable As Boolean)
61 This.writable = writable
[472]62 This.resizable = False
[445]63 This.visible = False
[472]64 This.create()
65 This.pointer = This.allocate(length)
66 MoveMemory(This.pointer,buffer,length)
67 This.streamLength = length
68 This.currentPosition = 0
[445]69 End Sub
[472]70
71 /*!
72 @brief MemoryStreamクラスの新しいインスタンスを指定したバッファの指定された領域に基づいて初期化します。容量を変更することはできません。
73 @author NoWest
74 @date 2008/3/12
75 */
[445]76 Sub MemoryStream(buffer As *Byte, index As Long, count As Long)
77 This.writable = True
[472]78 This.resizable = False
[445]79 This.visible = False
[472]80 This.create()
81 This.pointer = This.allocate(count)
82 MoveMemory(This.pointer,VarPtr(buffer[index]),count)
83 This.streamLength = count
84 This.currentPosition = 0
[445]85 End Sub
[472]86
87 /*!
88 @brief MemoryStreamクラスの新しいインスタンスを指定したバッファの指定された領域に基づいて初期化します。容量を変更することはできません。また、書き込みをサポートするかどうかを指定できます。
89 @author NoWest
90 @date 2008/3/12
91 */
[445]92 Sub MemoryStream(buffer As *Byte, index As Long, count As Long, writable As Boolean)
93 This.writable = writable
[472]94 This.resizable = False
[445]95 This.visible = False
[472]96 This.create()
97 This.pointer = This.allocate(count)
98 MoveMemory(This.pointer,VarPtr(buffer[index]),count)
99 This.streamLength = count
100 This.currentPosition = 0
[445]101 End Sub
[472]102
103 /*!
104 @brief MemoryStreamクラスの新しいインスタンスを指定したバッファの指定された領域に基づいて初期化します。容量を変更することはできません。また、書き込みをサポートするかどうかを指定できます。GetBufferメソッドをサポートするかどうかを指定できます。
105 @author NoWest
106 @date 2008/3/12
107 */
[445]108 Sub MemoryStream(buffer As *Byte, index As Long, count As Long, writable As Boolean, visible As Boolean)
109 This.writable = writable
[472]110 This.resizable = False
[445]111 This.visible = visible
[472]112 This.create()
113 This.pointer = This.allocate(count)
114 MoveMemory(This.pointer,VarPtr(buffer[index]),count)
115 This.streamLength = count
116 This.currentPosition = 0
[445]117 End Sub
[472]118
119 /*!
120 @brief MemoryStreamクラスのデストラクタです。
121 @author NoWest
122 @date 2008/3/12
123 */
[445]124 Sub ~MemoryStream()
125 This.Close()
126 End Sub
127
128Public
[472]129 /*!
130 @brief ストリームが読み取りをサポートしているかどうかを示す値を取得します。
131 @author NoWest
132 @date 2008/3/12
133 */
[445]134 Override Function CanRead() As Boolean
[472]135 If This.pointer Then
[445]136 Return True
137 Else
138 Return False
139 End If
140 End Function
141
[472]142 /*!
143 @brief ストリームがシークをサポートしているかどうかを示す値を取得します。
144 @author NoWest
145 @date 2008/3/12
146 */
[445]147 Override Function CanSeek() As Boolean
[472]148 If This.pointer Then
[445]149 Return True
150 Else
151 Return False
152 End If
153 End Function
154
[472]155 /*!
156 @brief ストリームが書き込みをサポートしているかどうかを示す値を取得します。
157 @author NoWest
158 @date 2008/3/12
159 */
[445]160 Override Function CanWrite() As Boolean
[472]161 If This.pointer Then
[445]162 Return This.writable
163 Else
164 Return False
165 End If
166 End Function
167
[472]168 /*!
169 @brief ストリームに割り当てるメモリ容量をバイト単位で設定します。
170 @author NoWest
171 @date 2008/3/12
[445]172 */
173 Virtual Sub Capacity(value As Long)
[472]174 If This.pointer = 0 Then Throw New ObjectDisposedException("MemoryStream: This stream has closed.")
175 If value < 0 Then Throw New ArgumentOutOfRangeException("MemoryStream.Capacity: A capacity is set to negative value.", New System.Int64(value),"Capacity")
176 If value < This.streamLength Then Throw New ArgumentOutOfRangeException("MemoryStream.Capacity: A capacity is less than the current length of the stream.",New System.Int64(value),"Capacity")
177 This.pointer = This.reallocate(This.pointer,value)
[445]178 End Sub
179
[472]180 /*!
181 @brief ストリームに割り当てられたメモリ容量をバイト単位で取得します。
182 @author NoWest
183 @date 2008/3/12
[445]184 */
[472]185 Virtual Function Capacity() As Long
186 If This.pointer = 0 Then Throw New ObjectDisposedException("MemoryStream: This stream has closed.")
187 Return This.size(This.pointer)
188 End Function
189
190 /*!
191 @brief ストリームの長さをバイト単位で取得します。Capacityプロパティの値より小さい場合があります。
192 @author NoWest
193 @date 2008/3/12
194 */
[445]195 Override Function Length() As Int64
[472]196 If This.pointer = 0 Then Throw New ObjectDisposedException("MemoryStream: This stream has closed.")
197 Return This.streamLength
[445]198 End Function
199
[472]200 /*!
201 @brief ストリームの現在位置を設定します。
202 @author NoWest
203 @date 2008/3/12
[445]204 */
205 Override Sub Position(value As Int64)
[472]206 If This.pointer = 0 Then Throw New ObjectDisposedException("MemoryStream: This stream has closed.")
207 If value < 0 Then Throw New ArgumentOutOfRangeException("MemoryStream.Position: The position is set to a negative value.", New System.Int64(value), "Position")
208 If value > Int32.MaxValue() Then Throw New ArgumentOutOfRangeException("MemoryStream.Position: The position is a value greater than MaxValue.", New System.Int64(value), "Position")
209 This.currentPosition = value As Long
[445]210 End Sub
211
[472]212 /*!
213 @brief ストリームの現在位置を取得します。
214 @author NoWest
215 @date 2008/3/12
216 */
[445]217 Override Function Position() As Int64
[472]218 If This.pointer = 0 Then Throw New ObjectDisposedException("MemoryStream: This stream has closed.")
219 Return This.currentPosition As Int64
[445]220 End Function
221
222 Override Sub Flush()
223 End Sub
224
225/* Virtual Function GetBuffer() As Array<Byte>
226 If visible = False Then Return NULL
227 Return p
228 End Function*/
229
[472]230 /*!
231 @brief ストリームから指定されたバイト数を読み取り、bufferに書き込みます。
232 @author NoWest
233 @date 2008/3/12
234 */
[445]235 Override Function Read(buffer As *Byte, offset As Long, count As Long) As Long
[472]236 If This.pointer = 0 Then Throw New ObjectDisposedException("MemoryStream: This stream has closed.")
237 If buffer = 0 Then Throw New ArgumentNullException("FileStream.Read: An argument is a null value.", "buffer")
238 If offset < 0 Then Throw New ArgumentOutOfRangeException("MemoryStream.Read: An argument is a negative value.", New System.Int64(offset), "offset")
239 If count < 0 Then Throw New ArgumentOutOfRangeException("MemoryStream.Read: An argument is a negative value.", New System.Int64(count), "count")
240 If (This.streamLength - (This.currentPosition + count)) < 0 Then
241 count + = (This.streamLength - (This.currentPosition + count))
[445]242 ElseIf count < 1 Then
243 Return 0
244 End If
[472]245 MoveMemory(VarPtr(buffer[offset]),VarPtr(This.pointer[This.currentPosition]),count)
246 This.currentPosition + = count
[445]247 Return count
248 End Function
249
[472]250 /*!
251 @brief ストリームから指定された1バイト読み取ります。
252 @author NoWest
253 @date 2008/3/12
254 */
[445]255 Override Function ReadByte() As Long
256 Dim b As Byte
257 Dim ret = Read(VarPtr(b), 0, 1)
258 If ret <> 0 Then
259 Return b
260 Else
261 Return -1
262 End If
263 End Function
264
[472]265 /*!
266 @brief ストリーム内の位置を指定した値に設定します。
267 @author NoWest
268 @date 2008/3/12
269 */
[445]270 Override Function Seek(offset As Int64, origin As SeekOrigin) As Int64
[472]271 If This.pointer = 0 Then Throw New ObjectDisposedException("MemoryStream: This stream has closed.")
272 If offset > Int32.MaxValue() Then Throw New ArgumentOutOfRangeException("MemoryStream.Seek: The offset is a value greater than MaxValue.", New System.Int64(offset), "offset")
[445]273 Select Case origin
274 Case SeekOrigin.Begin
[472]275 If offset < 0 Then Throw New IOException("MemoryStream.Seek: Seeking is attempted before the beginning of the stream.")
276 This.currentPosition = offset As Long
[445]277 Case SeekOrigin.Current
278 Beep(440,10)
[472]279 If (This.currentPosition + offset) < 0 Then Throw New IOException("MemoryStream.Seek: Seeking is attempted before the beginning of the stream.")
280 This.currentPosition += offset As Long
[445]281 Case SeekOrigin.End
[472]282 If (This.streamLength + offset) < 0 Then Throw New IOException("MemoryStream.Seek: Seeking is attempted before the beginning of the stream.")
283 This.currentPosition = (This.streamLength + offset) As Long
[445]284 Case Else
[472]285 Throw New ArgumentException("MemoryStream.Seek: An argument is an invalid SeekOrigin","origin")
[445]286 End Select
[472]287 Return This.currentPosition As Int64
[445]288 End Function
289
[472]290 /*!
291 @brief ストリームの長さを設定します。メモリ容量を超えては設定できません。
292 @author NoWest
293 @date 2008/3/12
294 */
[445]295 Override Sub SetLength(value As Int64)
[472]296 If This.pointer = 0 Then Throw New ObjectDisposedException("MemoryStream: This stream has closed.")
297 If This.writable = False Then Throw New NotSupportedException("MemoryStream: The current stream is not writable")
298 If This.resizable = False Then Throw New NotSupportedException("MemoryStream: The current stream is not resizable")
299 If value > This.Capacity() Then Throw New NotSupportedException("MemoryStream.SetLength: This stream length is larger than the current capacity.")
300 If value < 0 Then Throw New ArgumentOutOfRangeException("MemoryStream.Read: An argument is a negative value.", New System.Int64(value), "value")
301 If value > Int32.MaxValue() Then Throw New ArgumentOutOfRangeException("MemoryStream.SetLength: The length is a value greater than MaxValue.", New System.Int64(value), "value")
302 This.pointer = This.reallocate(This.pointer,value As Long)
303 This.streamLength = value As Long
[445]304 End Sub
305
[472]306 /*!
307 @brief ストリームにbufferの内容を指定したバイト数書き込みます。
308 @author NoWest
309 @date 2008/3/12
310 */
[445]311 Override Sub Write(buffer As *Byte, offset As Long, count As Long)
[472]312 If This.pointer = 0 Then Throw New ObjectDisposedException("MemoryStream: This stream has closed.")
313 If This.writable = False Then Throw New NotSupportedException("MemoryStream: The current stream is not writable")
314 If buffer = 0 Then Throw New ArgumentNullException("MemoryStream.Write: An argument is a null value.", "buffer")
315 If offset < 0 Then Throw New ArgumentOutOfRangeException("MemoryStream.Write: An argument is a negative value.", New System.Int64(offset), "offset")
316 If count < 0 Then Throw New ArgumentOutOfRangeException("MemoryStream.Write: An argument is a negative value.", New System.Int64(count), "count")
317 If count > (This.streamLength - This.currentPosition) Then
318 If This.resizable = False Then Throw New NotSupportedException("MemoryStream: The current stream is not resizable")
319 If (This.Capacity() - This.currentPosition) < count Then
320 This.pointer = This.reallocate(This.pointer,This.currentPosition+count)
[445]321 End If
[472]322 This.streamLength = This.currentPosition+count
[445]323 End If
[472]324 MoveMemory(VarPtr(This.pointer[This.currentPosition]),VarPtr(buffer[offset]),count)
325 This.currentPosition + = count
[445]326 End Sub
327
[472]328 /*!
329 @brief ストリームに1バイト書き込みます。
330 @author NoWest
331 @date 2008/3/12
332 */
[445]333 Override Sub WriteByte(b As Byte)
334 Write(VarPtr(b), 0, 1)
335 End Sub
336
[472]337/* Virtual Function ToArray() As Array<Byte>
[445]338 TODO:
339 End Function*/
340
[472]341 /*!
342 @brief ストリームの内容全体をまるごと別のストリームに書き込みます。
343 @author NoWest
344 @date 2008/3/12
345 */
[445]346 Virtual Sub WriteTo(stream As Stream)
[472]347 If This.pointer = 0 Then Throw New ObjectDisposedException("MemoryStream: This stream has closed.")
348 If ActiveBasic.IsNothing(stream) Then Throw New ArgumentNullException("MemoryStream.WriteTo: An argument is a null value.", "stream")
349 stream.Write(This.pointer,0,This.Capacity())
[445]350 End Sub
351
352Protected
[472]353
354 /*!
355 @brief Streamクラスから継承
356 @author NoWest
357 @date 2008/3/12
358 */
[445]359 Override Sub Dispose(disposing As Boolean)
[472]360 This.destroy()
[445]361 End Sub
362
[472]363Private
364 /* Heap memory address */
365 pointer As *Byte
366 /* MemoryStream status */
[445]367 writable As Boolean
[472]368 resizable As Boolean
[445]369 visible As Boolean
[472]370 streamLength As Long
371 currentPosition As Long
[445]372
[472]373 /*
374 バッファ管理用のPrivate関数類
375 一応初期設定ではGC_mallocでメモリを確保しています。
376 */
377 handle As HANDLE
378 Sub create()
379#ifdef NOT_USE_GC
380 This.handle = HeapCreate(0,0,0)
381#endif
382 End Sub
[445]383
[472]384 Sub destroy()
385#ifdef NOT_USE_GC
386 HeapFree(This.handle,0,InterlockedExchangePointer(ByVal VarPtr(This.pointer) As VoidPtr,NULL) As VoidPtr)
387 HeapDestroy(InterlockedExchangePointer(ByVal VarPtr(This.handle) As VoidPtr,NULL) As HANDLE)
388#endif
389 End Sub
390
391 Function allocate(length As SIZE_T) As VoidPtr
392#ifdef NOT_USE_GC
393 Return HeapAlloc(This.handle,HEAP_ZERO_MEMORY,length)
394#else
395 Return GC_malloc_atomic(length)
396#endif
397 End Function
398
399 Function reallocate(p As VoidPtr, length As SIZE_T) As VoidPtr
400#ifdef NOT_USE_GC
401 Return HeapReAlloc(This.handle,HEAP_ZERO_MEMORY,p,This.currentPosition+count)
402#else
403 Return _System_pGC->__realloc(p,length)
404#endif
405 End Function
406
407 Function size(p As VoidPtr) As Long
408#ifdef NOT_USE_GC
409 Return HeapSize(This.handle,0,p)
410#else
411 Dim pmemobj = _System_pGC->GetMemoryObjectPtr(p)
412 Return pmemobj->size
413#endif
414 End Function
[445]415End Class
416
417End NameSpace 'IO
418End NameSpace 'System
Note: See TracBrowser for help on using the repository browser.