[432] | 1 | 'Classes/System/IO/StreamReader.ab
|
---|
| 2 |
|
---|
[271] | 3 | Namespace System
|
---|
| 4 | Namespace IO
|
---|
| 5 |
|
---|
[432] | 6 | /*
|
---|
| 7 | @brief ストリームから読み取りを行うTextReaderの実装。
|
---|
| 8 | @date 2008/02/25
|
---|
| 9 | @auther Egtra
|
---|
| 10 | */
|
---|
[426] | 11 | Class StreamReader
|
---|
| 12 | Inherits TextReader
|
---|
| 13 | Public
|
---|
[432] | 14 | /*
|
---|
| 15 | @date 2008/02/25
|
---|
| 16 | @auther Egtra
|
---|
| 17 | */
|
---|
[426] | 18 | Sub StreamReader(path As String)
|
---|
| 19 | init(New FileStream(path, FileMode.Open, FileAccess.Read, FileShare.Read))
|
---|
| 20 | End Sub
|
---|
[271] | 21 |
|
---|
[432] | 22 | /*
|
---|
| 23 | @date 2008/02/25
|
---|
| 24 | @auther Egtra
|
---|
| 25 | */
|
---|
[426] | 26 | Sub StreamReader(stream As Stream)
|
---|
| 27 | init(stream)
|
---|
| 28 | End Sub
|
---|
| 29 |
|
---|
[627] | 30 | Public
|
---|
[432] | 31 | /*
|
---|
[627] | 32 | @brief 基になるストリームを取得する
|
---|
| 33 | @date 2008/09/02
|
---|
| 34 | @auther NoWest
|
---|
| 35 | */
|
---|
| 36 | Function BaseStream () As Stream
|
---|
| 37 | Return s
|
---|
| 38 | End Function
|
---|
| 39 |
|
---|
| 40 | /*
|
---|
[432] | 41 | @date 2008/02/25
|
---|
| 42 | @auther Egtra
|
---|
| 43 | */
|
---|
[426] | 44 | Override Function Peek() As Long
|
---|
[655] | 45 | If charSize = charCur Then
|
---|
| 46 | fillCharBuf()
|
---|
| 47 | If charSize = charCur Then
|
---|
[426] | 48 | Peek = -1
|
---|
| 49 | Exit Function
|
---|
| 50 | End If
|
---|
| 51 | End If
|
---|
[655] | 52 | Peek = charBuf[charCur]
|
---|
[426] | 53 | End Function
|
---|
| 54 |
|
---|
[432] | 55 | /*
|
---|
| 56 | @date 2008/02/25
|
---|
| 57 | @auther Egtra
|
---|
| 58 | */
|
---|
[426] | 59 | Override Function Read() As Long
|
---|
| 60 | Read = Peek()
|
---|
[435] | 61 | If Read <> -1 Then
|
---|
[655] | 62 | charCur++
|
---|
[435] | 63 | End If
|
---|
[426] | 64 | End Function
|
---|
| 65 |
|
---|
[432] | 66 | Protected
|
---|
| 67 | /*
|
---|
| 68 | @date 2008/02/25
|
---|
| 69 | @auther Egtra
|
---|
| 70 | */
|
---|
| 71 | Override Sub Dispose(disposing As Boolean)
|
---|
| 72 | If disposing Then
|
---|
| 73 | If Not ActiveBasic.IsNothing(s) Then
|
---|
| 74 | s.Dispose(True)
|
---|
| 75 | End If
|
---|
[426] | 76 | End If
|
---|
[432] | 77 | s = Nothing
|
---|
| 78 | End Sub
|
---|
[426] | 79 |
|
---|
[432] | 80 | /*
|
---|
| 81 | @date 2008/02/25
|
---|
| 82 | @auther Egtra
|
---|
| 83 | */
|
---|
[655] | 84 | Override Function ReadImpl(buffer As *WCHAR, count As Long) As Long
|
---|
| 85 | Dim n = charSize - charCur '現在のバッファに溜まっている文字数
|
---|
| 86 | If count <= n And charEof <> False Then
|
---|
| 87 | ReadImpl = readFromBuffer(buffer, count)
|
---|
[426] | 88 | Exit Function
|
---|
| 89 | End If
|
---|
[655] | 90 | ReadImpl = readFromBuffer(buffer, n)
|
---|
[432] | 91 | If ReadImpl = count Then 'バッファの中身で足りた場合
|
---|
[426] | 92 | Exit Function
|
---|
| 93 | End If
|
---|
[655] | 94 | fillCharBuf()
|
---|
| 95 | ReadImpl += ReadImpl(VarPtr(buffer[n]), count - n)
|
---|
[426] | 96 | End Function
|
---|
| 97 |
|
---|
| 98 | Private
|
---|
[432] | 99 | /*
|
---|
| 100 | @date 2008/02/25
|
---|
| 101 | @auther Egtra
|
---|
| 102 | */
|
---|
[426] | 103 | Sub init(str As Stream)
|
---|
| 104 | s = str
|
---|
[655] | 105 | '暫定。正式版ではUTF-8を標準とする。
|
---|
| 106 | encoding = New Text.Detail.WindowsCodePageEncoding(CP_ACP)
|
---|
| 107 | decoder = encoding.GetDecoder()
|
---|
| 108 | charCapacity = 4096
|
---|
| 109 | byteCapacity = 4096
|
---|
| 110 | charBuf = GC_malloc(charCapacity * SizeOf(WCHAR))
|
---|
| 111 | byteBuf = GC_malloc(byteCapacity)
|
---|
| 112 | charCur = 0
|
---|
| 113 | byteCur = 0
|
---|
| 114 | charSize = 0
|
---|
| 115 | byteSize = 0
|
---|
| 116 | charEof = False
|
---|
| 117 | byteEof = False
|
---|
[426] | 118 | End Sub
|
---|
| 119 |
|
---|
| 120 | /**
|
---|
| 121 | @brief バッファの中身から読み取る。
|
---|
[432] | 122 | @date 2008/02/25
|
---|
| 123 | @auther Egtra
|
---|
[426] | 124 | 文字数が足りなくても、元のストリームまで読みには行かない。
|
---|
| 125 | */
|
---|
[655] | 126 | Function readFromBuffer(p As *WCHAR, count As Long) As Long
|
---|
| 127 | memcpy(p, VarPtr(charBuf[charCur]), count * SizeOf (WCHAR))
|
---|
| 128 | charCur += count
|
---|
| 129 | readFromBuffer = count
|
---|
[426] | 130 | End Function
|
---|
| 131 |
|
---|
[655] | 132 | /*!
|
---|
| 133 | @brief byteBufを基にcharBufを埋める。charBufが空になったときに用いる。
|
---|
| 134 | @date 2008/11/08
|
---|
| 135 | @auther Egtra
|
---|
| 136 | */
|
---|
| 137 | Sub fillCharBuf()
|
---|
| 138 | charCur = 0
|
---|
| 139 | charSize = 0
|
---|
| 140 | If charEof = False Then
|
---|
| 141 | If byteCur = byteSize Then
|
---|
| 142 | byteSize = s.Read(byteBuf, 0, byteCapacity)
|
---|
| 143 | byteCur = 0
|
---|
| 144 | If byteSize = 0 Then
|
---|
| 145 | byteEof = True
|
---|
| 146 | End If
|
---|
| 147 | End If
|
---|
| 148 | Dim charUsed As Long
|
---|
| 149 | Dim byteUsed As Long
|
---|
[660] | 150 | Dim completed As Boolean
|
---|
[655] | 151 | decoder.Convert(VarPtr(byteBuf[byteCur]), byteSize - byteCur,
|
---|
| 152 | VarPtr(charBuf[charSize]), charCapacity - charSize,
|
---|
[660] | 153 | byteEof, charUsed, byteUsed, completed)
|
---|
[662] | 154 | charEof = byteEof And completed And byteCur = byteSize
|
---|
[655] | 155 | byteCur += byteUsed
|
---|
| 156 | charSize += charUsed
|
---|
| 157 | End If
|
---|
| 158 | End Sub
|
---|
| 159 |
|
---|
[426] | 160 | s As Stream
|
---|
[655] | 161 | encoding As Text.Encoding
|
---|
| 162 | decoder As Text.Decoder
|
---|
| 163 | charBuf As *WCHAR
|
---|
| 164 | byteBuf As *Byte
|
---|
| 165 | charCur As Long '読み取っていないデータの開始位置
|
---|
| 166 | byteCur As Long
|
---|
| 167 | charSize As Long 'Bufの内、有効なデータの数
|
---|
| 168 | byteSize As Long
|
---|
| 169 | charCapacity As Long '確保済み容量 = GC_mallocしたときの引数の値
|
---|
| 170 | byteCapacity As Long
|
---|
| 171 | charEof As Boolean 'Trueのとき、次にcur = sizeになるまでしかデータがことを示す
|
---|
| 172 | byteEof As Boolean
|
---|
| 173 | '常に0 <= cur <= size <= capacity
|
---|
[271] | 174 | End Class
|
---|
| 175 |
|
---|
| 176 | End Namespace
|
---|
| 177 | End Namespace
|
---|