📄 memorystream.cls
字号:
' will determine if the stream is allowed to be written to. Otherwise, the stream
' is always writable while it is open.
'
Public Property Get CanWrite() As Boolean
CanWrite = mCanWrite And (Not mIsClosed)
End Property
''
' Determines if the current MemoryStream can seek positions within the stream.
'
' @return The status of the ability to seek a position within the stream.
' @remarks If the MemoryStream is open, then it is seekable, otherwise it is not.
'
Public Property Get CanSeek() As Boolean
CanSeek = Not mIsClosed
End Property
''
' Returns the current capacity of the internal stream buffer.
'
' @return The number of bytes the internal array contains.
' @remarks If the the capacity is reached while writing, then the capacity
' will be expanded, unless the underlying byte array is user-supplied. In
' this case, an exception will be thrown if the capacity is changed.
'
Public Property Get Capacity() As Long
Capacity = mCapacity
End Property
''
' Sets the current capacity for the internal stream buffer.
'
' @param RHS The number of bytes to allocate for the internal array.
' @remarks The capacity cannot be set less than the current length of
' the stream. If the underlying byte array is user-supplied, then an
' exception will be thrown if the capacity is modified.
'
Public Property Let Capacity(ByVal RHS As Long)
Call VerifyOpen
If mIsUserArray Then _
Throw Cor.NewNotSupportedException("The capacity cannot be modified when using a user supplied byte array.")
If RHS < mLength Then _
Throw Cor.NewArgumentOutOfRangeException("Capacity cannot be set less than then length of the stream.", "Capacity", RHS)
If RHS = mLength Then Exit Property
mCapacity = RHS - 1
If mBufferSet Then
ReDim Preserve mBuffer(0 To mCapacity - 1)
Else
Call VerifyBuffer
End If
End Property
''
' Returns the current length of the stream.
'
' @return The number of bytes the current stream is.
' @remarks The length of the stream differs from the capacity in that the
' capacity is the amount of allocated memory used to store the stream, and the
' length is the number of bytes used from within the allocated memory.
'
Public Property Get Length() As Currency
Length = mLength
End Property
''
' Returns the current position within the stream.
'
' @return The byte index within the stream.
' @remarks The position is the index at which the next read or write
' will occur. Position is alway zero based, even if a user-supplied
' array is not.
'
Public Property Get Position() As Currency
Position = mPosition
End Property
''
' Sets the current position within the stream.
'
' @param RHS The absolution position within the stream.
' @remarks The position is the index at which the next read or write
' will occur. Position is always zero based, even if a user-supplied
' array is not.
'
Public Property Let Position(ByVal RHS As Currency)
Call VerifyOpen
If RHS < 0@ Then _
Throw Cor.NewArgumentOutOfRangeException(Environment.GetResourceString(ArgumentOutOfRange_NeedNonNegNum), "Position", RHS)
mPosition = Int(RHS)
End Property
''
' Closes the MemoryStream and releases any resources allocated.
'
' @remarks If a user-supplied array is being used, it will be released
' at this point. The user then may modify the array as normal.
'
Public Sub CloseStream()
If mIsClosed Then Exit Sub
If mIsUserArray Then
Call UnlockArray
SAPtr(mBuffer) = 0
End If
mIsClosed = True
End Sub
''
' Writes an array of bytes to the underlying stream.
'
' @param Bytes The bytes to be written to the stream.
' @param Offset The startind index in <i>Buffer</i> to begin writing from.
' @param Count The number of bytes to be written to the stream.
' @remarks <p>If the position in the stream is closer to the end than Count bytes, then
' the stream will expand if possible. If the underlying stream is a user-supplied
' byte array, then an exception will occur if the capacity is reached.</p>
' <p>The stream must be open to write to it, otherwise an exception will be thrown.</p>
'
Public Sub WriteBlock(ByRef Bytes() As Byte, ByVal Offset As Long, ByVal Count As Long)
Call VerifyWritable
Call VerifyOpen
Call VerifyBuffer
Dim Result As Long
Result = VerifyArrayRange(SAPtr(Bytes), Offset, Count)
If Result <> NO_ERROR Then Call ThrowArrayRangeException(Result, "Bytes", Offset, "Offset", Count, "Count")
If Count = 0 Then Exit Sub
Call EnsureCapacity(mPosition + Count)
Call CopyMemory(mBuffer(mIndex + mPosition), Bytes(Offset), Count)
mPosition = mPosition + Count
If mPosition > mLength Then mLength = mPosition
End Sub
''
' Writes a single byte to the underlying stream.
'
' @param value The byte to be written to the stream.
' @remarks <p>If the position to be written exceeds the current capacity, then
' the stream will be expanded if possible. If the underlying stream is a
' user-supply byte array, then the capacity cannot be modified and an
' exception will be thrown.</p>
' <p>The stream must be open to write to it, otherwise an exception will be thrown.</p>
'
Public Sub WriteByte(ByVal Value As Byte)
Call VerifyWritable
Call VerifyOpen
Call VerifyBuffer
mBuffer(mPosition + mIndex) = Value
mPosition = mPosition + 1
If mPosition > mLength Then mLength = mPosition
End Sub
''
' Reads a specifiec number of bytes from the stream.
'
' @param Bytes The destination for the bytes to be read from the stream.
' @param Offset The startind index in <i>buffer</i> to begin storing the bytes read from the stream.
' @param Count The maximum number of bytes to be read from the stream.
' @return The total number of bytes read from the stream.
' @remarks <p>If Offset plus Count exceeds the end of <i>Buffer</i> then an exception will be thrown.
' If the current position in the stream is closer to the end than Count bytes, then only the
' remaining bytes will be read.</p>
' <p>The stream must be open to read from it, otherwise an exception will be thrown.</p>
' <p>After reading from the stream, the current position will advance the number of byte as returend.</p>
'
Public Function ReadBlock(ByRef Bytes() As Byte, ByVal Offset As Long, ByVal Count As Long) As Long
Call VerifyOpen
Call VerifyBuffer
Dim Result As Long
Result = VerifyArrayRange(SAPtr(Bytes), Offset, Count)
If Result <> NO_ERROR Then Call ThrowArrayRangeException(Result, "Bytes", Offset, "Offset", Count, "Count")
If mPosition >= mLength Then Exit Function
If mPosition + Count > mLength Then Count = mLength - mPosition
Call CopyMemory(Bytes(Offset), mBuffer(mPosition + mIndex), Count)
mPosition = mPosition + Count
ReadBlock = Count
End Function
''
' Reads a single byte from the stream.
'
' @return The byte value from the current position in the stream.
' @remarks <p>The stream must be open for read from it, otherwise an exception will be thrown.</p>
' <p>If the end of the stream is reached during a read, then a value of
' -1 is returned.</p>
' <p>Each read from the stream will advance the position one byte.</p>
'
Public Function ReadByte() As Long
If mPosition >= mLength Then
ReadByte = -1
Exit Function
End If
ReadByte = mBuffer(mPosition + mIndex)
mPosition = mPosition + 1
End Function
''
' Changes the position within the stream.
'
' @param Offset The number of bytes to move.
' @param Loc The starting position in the stream to move from.
' @return The actual position moved to.
' @param <p>The offset is applied to a starting position refered to by <i>Loc</i>.
' the <i>Offset</i> can be negative to move the position backwards.</p>
' <p>If the position ends up being before the start of the stream an exception will be thrown.
' The position can be set passed the end of the stream. This will cause the stream to be
' expanded on the next access. If the stream expansion is not supported an exception
' will be thrown. This may be the case when using a user-supplied byte array.</p>
'
Public Function SeekPosition(ByVal Offset As Currency, ByVal Loc As SeekOrigin) As Currency
Offset = Int(Offset)
Select Case Loc
Case FromBeginning
Position = Offset
Case FromCurrent
Position = mPosition + Offset
Case FromEnd
Position = (mLength - 1) + Offset
End Select
SeekPosition = mPosition
End Function
''
' Sets the current length of the stream.
'
' @param value The size of the stream in bytes.
' @remarks <p>The shortening the length of the stream will truncate the excess data. If
' increasing the length, then the new exposed data will be set to zero.</p>
' <p>If a user-supplied byte array is being used, this function has limited capabilites.
' The size of the stream can be changed to withing the origin size of the user-supplied
' byte array. If a length greater than the original array size is set, then an exception
' is thrown.</p>
'
Public Sub SetLength(ByVal Value As Currency)
Call VerifyWritable
Value = Int(Value)
Select Case Value
Case mLength + 1 To mCapacity
Dim i As Long
For i = mLength To Value - 1
mBuffer(mIndex + i) = 0
Next i
Case Is > mCapacity
Capacity = Value
Case Is < 0@
Throw Cor.NewArgumentOutOfRangeException(Environment.GetResourceString(ArgumentOutOfRange_NeedNonNegNum), "Value", Value)
End Select
mLength = Value
End Sub
''
' Returns a byte array copy of the underlying byte stream.
'
' @return The byte array copy of the underlying stream.
' @remarks If the underlying stream is a user-supplied byte array, then only
' that portion determined by Count when the stream was created is returned, not
' the entire array.
'
Public Function ToArray() As Byte()
Call VerifyBuffer
Dim Ret() As Byte
ReDim Ret(0 To mLength - 1)
Call CopyMemory(Ret(0), mBuffer(mIndex), mLength)
ToArray = Ret
End Function
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -