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
Line 
1
2NameSpace System
3NameSpace IO
4
5Class MemoryStream
6 Inherits Stream
7
8Public
9 /*!
10 @brief MemoryStreamクラスの新しいインスタンスを初期化します。
11 @author NoWest
12 @date 2008/3/12
13 */
14 Sub MemoryStream()
15 This.writable = True
16 This.resizable = True
17 This.visible = False
18 This.create()
19 This.pointer = This.allocate(0)
20 This.streamLength = 0
21 This.currentPosition = 0
22 End Sub
23
24 /*!
25 @brief MemoryStreamクラスの新しいインスタンスを初期容量を指定して初期化します。
26 @author NoWest
27 @date 2008/3/12
28 */
29 Sub MemoryStream(capacity As Long)
30 This.writable = True
31 This.resizable = True
32 This.visible = False
33 This.create()
34 This.pointer = This.allocate(capacity)
35 This.streamLength = capacity
36 This.currentPosition = 0
37 End Sub
38
39 /*!
40 @brief MemoryStreamクラスの新しいインスタンスを指定したバッファに基づいて初期化します。容量を変更することはできません。
41 @author NoWest
42 @date 2008/3/12
43 */
44 Sub MemoryStream(buffer As *Byte, length As Long)
45 This.writable = True
46 This.resizable = False
47 This.visible = False
48 This.create()
49 This.pointer = This.allocate(length)
50 MoveMemory(This.pointer,buffer,length)
51 This.streamLength = length
52 This.currentPosition = 0
53 End Sub
54
55 /*!
56 @brief MemoryStreamクラスの新しいインスタンスを指定したバッファに基づいて初期化します。容量を変更することはできません。また、書き込みをサポートするかどうかも指定できます。
57 @author NoWest
58 @date 2008/3/12
59 */
60 Sub MemoryStream(buffer As *Byte, length As Long, writable As Boolean)
61 This.writable = writable
62 This.resizable = False
63 This.visible = False
64 This.create()
65 This.pointer = This.allocate(length)
66 MoveMemory(This.pointer,buffer,length)
67 This.streamLength = length
68 This.currentPosition = 0
69 End Sub
70
71 /*!
72 @brief MemoryStreamクラスの新しいインスタンスを指定したバッファの指定された領域に基づいて初期化します。容量を変更することはできません。
73 @author NoWest
74 @date 2008/3/12
75 */
76 Sub MemoryStream(buffer As *Byte, index As Long, count As Long)
77 This.writable = True
78 This.resizable = False
79 This.visible = False
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
85 End Sub
86
87 /*!
88 @brief MemoryStreamクラスの新しいインスタンスを指定したバッファの指定された領域に基づいて初期化します。容量を変更することはできません。また、書き込みをサポートするかどうかを指定できます。
89 @author NoWest
90 @date 2008/3/12
91 */
92 Sub MemoryStream(buffer As *Byte, index As Long, count As Long, writable As Boolean)
93 This.writable = writable
94 This.resizable = False
95 This.visible = False
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
101 End Sub
102
103 /*!
104 @brief MemoryStreamクラスの新しいインスタンスを指定したバッファの指定された領域に基づいて初期化します。容量を変更することはできません。また、書き込みをサポートするかどうかを指定できます。GetBufferメソッドをサポートするかどうかを指定できます。
105 @author NoWest
106 @date 2008/3/12
107 */
108 Sub MemoryStream(buffer As *Byte, index As Long, count As Long, writable As Boolean, visible As Boolean)
109 This.writable = writable
110 This.resizable = False
111 This.visible = visible
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
117 End Sub
118
119 /*!
120 @brief MemoryStreamクラスのデストラクタです。
121 @author NoWest
122 @date 2008/3/12
123 */
124 Sub ~MemoryStream()
125 This.Close()
126 End Sub
127
128Public
129 /*!
130 @brief ストリームが読み取りをサポートしているかどうかを示す値を取得します。
131 @author NoWest
132 @date 2008/3/12
133 */
134 Override Function CanRead() As Boolean
135 If This.pointer Then
136 Return True
137 Else
138 Return False
139 End If
140 End Function
141
142 /*!
143 @brief ストリームがシークをサポートしているかどうかを示す値を取得します。
144 @author NoWest
145 @date 2008/3/12
146 */
147 Override Function CanSeek() As Boolean
148 If This.pointer Then
149 Return True
150 Else
151 Return False
152 End If
153 End Function
154
155 /*!
156 @brief ストリームが書き込みをサポートしているかどうかを示す値を取得します。
157 @author NoWest
158 @date 2008/3/12
159 */
160 Override Function CanWrite() As Boolean
161 If This.pointer Then
162 Return This.writable
163 Else
164 Return False
165 End If
166 End Function
167
168 /*!
169 @brief ストリームに割り当てるメモリ容量をバイト単位で設定します。
170 @author NoWest
171 @date 2008/3/12
172 */
173 Virtual Sub Capacity(value As Long)
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)
178 End Sub
179
180 /*!
181 @brief ストリームに割り当てられたメモリ容量をバイト単位で取得します。
182 @author NoWest
183 @date 2008/3/12
184 */
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 */
195 Override Function Length() As Int64
196 If This.pointer = 0 Then Throw New ObjectDisposedException("MemoryStream: This stream has closed.")
197 Return This.streamLength
198 End Function
199
200 /*!
201 @brief ストリームの現在位置を設定します。
202 @author NoWest
203 @date 2008/3/12
204 */
205 Override Sub Position(value As Int64)
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
210 End Sub
211
212 /*!
213 @brief ストリームの現在位置を取得します。
214 @author NoWest
215 @date 2008/3/12
216 */
217 Override Function Position() As Int64
218 If This.pointer = 0 Then Throw New ObjectDisposedException("MemoryStream: This stream has closed.")
219 Return This.currentPosition As Int64
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
230 /*!
231 @brief ストリームから指定されたバイト数を読み取り、bufferに書き込みます。
232 @author NoWest
233 @date 2008/3/12
234 */
235 Override Function Read(buffer As *Byte, offset As Long, count As Long) As Long
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))
242 ElseIf count < 1 Then
243 Return 0
244 End If
245 MoveMemory(VarPtr(buffer[offset]),VarPtr(This.pointer[This.currentPosition]),count)
246 This.currentPosition + = count
247 Return count
248 End Function
249
250 /*!
251 @brief ストリームから指定された1バイト読み取ります。
252 @author NoWest
253 @date 2008/3/12
254 */
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
265 /*!
266 @brief ストリーム内の位置を指定した値に設定します。
267 @author NoWest
268 @date 2008/3/12
269 */
270 Override Function Seek(offset As Int64, origin As SeekOrigin) As Int64
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")
273 Select Case origin
274 Case SeekOrigin.Begin
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
277 Case SeekOrigin.Current
278 Beep(440,10)
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
281 Case SeekOrigin.End
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
284 Case Else
285 Throw New ArgumentException("MemoryStream.Seek: An argument is an invalid SeekOrigin","origin")
286 End Select
287 Return This.currentPosition As Int64
288 End Function
289
290 /*!
291 @brief ストリームの長さを設定します。メモリ容量を超えては設定できません。
292 @author NoWest
293 @date 2008/3/12
294 */
295 Override Sub SetLength(value As Int64)
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
304 End Sub
305
306 /*!
307 @brief ストリームにbufferの内容を指定したバイト数書き込みます。
308 @author NoWest
309 @date 2008/3/12
310 */
311 Override Sub Write(buffer As *Byte, offset As Long, count As Long)
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)
321 End If
322 This.streamLength = This.currentPosition+count
323 End If
324 MoveMemory(VarPtr(This.pointer[This.currentPosition]),VarPtr(buffer[offset]),count)
325 This.currentPosition + = count
326 End Sub
327
328 /*!
329 @brief ストリームに1バイト書き込みます。
330 @author NoWest
331 @date 2008/3/12
332 */
333 Override Sub WriteByte(b As Byte)
334 Write(VarPtr(b), 0, 1)
335 End Sub
336
337/* Virtual Function ToArray() As Array<Byte>
338 TODO:
339 End Function*/
340
341 /*!
342 @brief ストリームの内容全体をまるごと別のストリームに書き込みます。
343 @author NoWest
344 @date 2008/3/12
345 */
346 Virtual Sub WriteTo(stream As Stream)
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())
350 End Sub
351
352Protected
353
354 /*!
355 @brief Streamクラスから継承
356 @author NoWest
357 @date 2008/3/12
358 */
359 Override Sub Dispose(disposing As Boolean)
360 This.destroy()
361 End Sub
362
363Private
364 /* Heap memory address */
365 pointer As *Byte
366 /* MemoryStream status */
367 writable As Boolean
368 resizable As Boolean
369 visible As Boolean
370 streamLength As Long
371 currentPosition As Long
372
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
383
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
415End Class
416
417End NameSpace 'IO
418End NameSpace 'System
Note: See TracBrowser for help on using the repository browser.