📄 streamreader.cls
字号:
' so just return the contents.
ReadLine = mLineBuilder.ToString
End If
' We terminate a line with either a Return, LineFeed, or Return-LineFeed.
' So check if we had a Return, and if so, determine if the next character
' is a LineFeed. Remove them both if possible.
If TermChar = vbReturn Then
' We still have characters in the buffer, so check if
' the next character is a linefeed and remove it if so.
If mCharIndex < mCharLength Then
If mCharBuffer(mCharIndex) = vbLineFeed Then mCharIndex = mCharIndex + 1
Else
' The return was the last character in the buffer,
' so fill the buffer with the next set of character.
' If atleast 1 character was read, then check for
' a linefeed and remove it, if so.
If ReadBuffer > 0 Then
If mCharBuffer(0) = vbLineFeed Then mCharIndex = mCharIndex + 1
End If
End If
End If
End Function
''
' Returns a string of all remaining characters in the stream.
'
' @return A string containing the remaining characters.
'
Public Function ReadToEnd() As String
Call VerifyIsOpen
If Not HaveChars Then Exit Function
' The byte buffer wasn't completey full, meaning there is no more to
' be read from the stream. So the last of the characters have been
' read, so just take them and make a string.
If mByteLength < mBufferSize Then
ReadToEnd = cString.FromCharArray(mCharBuffer, mCharIndex, mCharLength)
Else
' Keep reading from the stream and placing the characters into the
' builder. Keep refilling the buffer until the end of the stream is reached.
mLineBuilder.Length = 0
Do
Call mLineBuilder.AppendChars(mCharBuffer, mCharIndex, mCharLength - mCharIndex)
Loop While ReadBuffer > 0
ReadToEnd = mLineBuilder.ToString
End If
mCharIndex = mCharLength
End Function
''
' Returns a string representation of this object instance.
'
' @return String representing this instance.
Public Function ToString() As String
ToString = Object.ToString(Me, App)
End Function
''
' Returns a boolean indicating if the value and this object
' instance are the same instance.
'
' @param value The value to compare equality to.
' @return Boolean indicating equality.
Public Function Equals(ByRef Value As Variant) As Boolean
Equals = Object.Equals(Me, Value)
End Function
''
' Returns a pseudo-unique number identifying this instance.
'
' @return Pseudo-unique number identifying this instance.
Public Function GetHashCode() As Long
GetHashCode = ObjPtr(CUnk(Me))
End Function
'''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''
' Friend Interface
'''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''
Friend Sub Init(ByRef Source As Variant, ByVal oEncoding As Encoding, ByVal determineEncodingFromByteOrderMarks As Boolean, ByVal BufferSize As Long)
If BufferSize < 0 Then _
Throw Cor.NewArgumentOutOfRangeException(Environment.GetResourceString(ArgumentOutOfRange_NeedNonNegNum), "BufferSize", BufferSize)
' Get the source from the correct place.
Select Case VarType(Source)
Case vbObject
' We expect an open Stream object here.
If Source Is Nothing Then _
Throw Cor.NewArgumentNullException(Environment.GetResourceString(ArgumentNull_Stream))
If Not TypeOf Source Is Stream Then _
Throw Cor.NewArgumentException(Environment.GetResourceString(Argument_StreamRequired), "Source")
Set mStream = Source
Case vbString
' We expect a filename here.
Set mStream = Cor.NewFileStream(Source, FileMode.OpenExisting, FileAccess.ReadAccess, FileShare.ReadShare)
Case Else
Throw Cor.NewArgumentException("A file path or Stream object is required.", "Source")
End Select
' Set up the encoding scheme.
mDetermineEncoding = determineEncodingFromByteOrderMarks
If Not oEncoding Is Nothing Then
Set mEncoding = oEncoding
Set mDecoder = mEncoding.GetDecoder
End If
' Set up the read buffer.
If BufferSize < MIN_BUFFERSIZE Then BufferSize = MIN_BUFFERSIZE
mBufferSize = BufferSize
ReDim mByteBuffer(0 To mBufferSize - 1)
mIsOpen = True
End Sub
'''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''
' Private Helpers
'''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''
Private Function HaveChars() As Boolean
' This will be true when:
' - The buffer is empty
' - All the characters in the buffer have been read
If mCharIndex = mCharLength Then
' The buffer needs filling.
HaveChars = (ReadBuffer > 0)
Else
' The buffer already has characters
HaveChars = True
End If
End Function
Private Function ReadBuffer() As Long
' Fill our local byte buffer from the stream.
mByteLength = mStream.ReadBlock(mByteBuffer, 0, mBufferSize)
' If bytes have been read in then fill the character buffer.
If mByteLength > 0 Then
' We may still need to determine encoding from the stream.
If mDetermineEncoding Then DetermineEncoding
' We couldn't ReDim the character buffer earlier because we
' had no idea the type of encoding we'd end up with, causing
' a different number of characters to be generated.
If SAPtr(mCharBuffer) = vbNullPtr Then ReDim mCharBuffer(0 To mEncoding.GetMaxCharCount(mBufferSize) - 1)
' Fill the character buffer using a Decoder to maintain
' state between buffer readings for multi-byte characters.
mCharLength = mDecoder.GetChars(mByteBuffer, mByteIndex, mByteLength, mCharBuffer, 0)
Else
' We didn't read anything from the Stream, so we
' can't have any characters in the character buffer.
mCharLength = 0
End If
mByteIndex = 0
mCharIndex = 0
ReadBuffer = mCharLength
End Function
Private Sub DetermineEncoding()
If mByteLength < 2 Then Exit Sub ' don't have enough bytes to determine anything.
Select Case AsWord(mByteBuffer(0))
Case &HFEFF ' Little-Endian UnicodeEncoding
Set mEncoding = Cor.NewUnicodeEncoding(False, False)
mByteIndex = 2
mByteLength = mByteLength - 2
Case &HFFFE ' Big-Endian UnicodeEncoding
Set mEncoding = Cor.NewUnicodeEncoding(True, False)
mByteIndex = 2
mByteLength = mByteLength - 2
Case &HBBEF ' possible UTF-8 encoding
If mByteLength < 3 Then Exit Sub ' not quite enough bytes to determine if UTF-8 encoding.
If mByteBuffer(2) = &HBF Then Set mEncoding = Cor.NewUTF8Encoding(False, False)
mByteIndex = 3
mByteLength = mByteLength - 3
End Select
' We have either determined the encoding from the BOM, or
' we are going to use the default encoding for the reader.
' Get the Decoder from the encoding now.
If Not mEncoding Is Nothing Then Set mDecoder = mEncoding.GetDecoder
mDetermineEncoding = False
End Sub
Private Sub VerifyIsOpen()
If Not mIsOpen Then Throw Cor.NewObjectDisposedException("StreamReader", "Cannot read from a closed StreamReader.")
End Sub
'''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''
' Class Events
'''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''
Private Sub Class_Initialize()
Set mEncoding = Encoding.UTF8
Set mDecoder = mEncoding.GetDecoder
End Sub
'''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''
' IObject Interface
'''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''
Private Function IObject_Equals(Value As Variant) As Boolean
IObject_Equals = Equals(Value)
End Function
Private Function IObject_GetHashcode() As Long
IObject_GetHashcode = GetHashCode
End Function
Private Function IObject_ToString() As String
IObject_ToString = ToString
End Function
'''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''
' TextReader Interface
'''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''
Private Sub TextReader_CloseReader()
Call CloseReader
End Sub
Private Function TextReader_Equals(Value As Variant) As Boolean
TextReader_Equals = Equals(Value)
End Function
Private Function TextReader_GetHashCode() As Long
TextReader_GetHashCode = GetHashCode
End Function
Private Function TextReader_Peek() As Long
TextReader_Peek = Peek
End Function
Private Function TextReader_Read() As Long
TextReader_Read = Read
End Function
Private Function TextReader_ReadBlock(Chars() As Integer, ByVal Index As Long, ByVal Count As Long) As Long
TextReader_ReadBlock = ReadBlock(Chars, Index, Count)
End Function
Private Function TextReader_ReadLine() As String
TextReader_ReadLine = ReadLine
End Function
Private Function TextReader_ReadToEnd() As String
TextReader_ReadToEnd = ReadToEnd
End Function
Private Function TextReader_ToString() As String
TextReader_ToString = ToString
End Function
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -