1 |
|
---|
2 | NameSpace System
|
---|
3 | NameSpace IO
|
---|
4 |
|
---|
5 | Class MemoryStream
|
---|
6 | Inherits Stream
|
---|
7 |
|
---|
8 | Public
|
---|
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 |
|
---|
128 | Public
|
---|
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 |
|
---|
352 | Protected
|
---|
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 |
|
---|
363 | Private
|
---|
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
|
---|
415 | End Class
|
---|
416 |
|
---|
417 | End NameSpace 'IO
|
---|
418 | End NameSpace 'System
|
---|