source: trunk/ab5.0/ablib/src/Classes/System/IO/StreamReader.ab@ 662

Last change on this file since 662 was 662, checked in by イグトランス (egtra), 15 years ago

StreamReaderとStringReaderでEOF絡みの判定漏れを修正。

File size: 3.8 KB
RevLine 
[432]1'Classes/System/IO/StreamReader.ab
2
[271]3Namespace System
4Namespace IO
5
[432]6/*
7@brief ストリームから読み取りを行うTextReaderの実装。
8@date 2008/02/25
9@auther Egtra
10*/
[426]11Class StreamReader
12 Inherits TextReader
13Public
[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]30Public
[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]66Protected
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
98Private
[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]174End Class
175
176End Namespace
177End Namespace
Note: See TracBrowser for help on using the repository browser.