source: trunk/ab5.0/ablib/src/Classes/System/IO/TextReader.ab@ 676

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

#231に関連して、エンコーディング周りを見直し、Encoder/Decoderをストリーム用に特化。
UTF8Encodingをコンパイル可能にし、ビルドに含めるようにした。ただし、実装が不完全なためテストは不可。
(#231)

File size: 4.7 KB
Line 
1Namespace System
2Namespace IO
3
4Class TextReader
5 Implements System.IDisposable
6Public
7 Virtual Sub ~TextReader()
8 Dispose(False)
9 End Sub
10
11' Static Null = StreamReader.Null As TextReader
12
13Public
14 Sub Close()
15 Dispose(True)
16 End Sub
17
18 Sub Dispose()
19 Dispose(True)
20 End Sub
21
22 Virtual Function Peek() As Long
23 If pos >= buf.Length Then
24 buf.Length = 0
25 pos = 0
26 If Not Underflow() Then
27 Peek = -1
28 Exit Function
29 End If
30 End If
31 Peek = buf[pos]
32 End Function
33
34 Virtual Function Read() As Long
35 Read = Peek()
36 pos++
37 End Function
38 /*
39 @date 2008/02/26
40 @auther Egtra
41 */
42 Virtual Function Read(buffer As *Char, index As Long, count As Long) As Long
43 If buffer = 0 Then
44 Throw New ArgumentNullException("buffer")
45 ElseIf index < 0 Then
46 Throw New ArgumentOutOfRangeException("index")
47 ElseIf count < 0 Then
48 Throw New ArgumentOutOfRangeException("count")
49 End If
50 Read = ReadImpl(VarPtr(buffer[index]), count)
51 End Function
52
53 Static Function Synchronized(reader As TextReader) As TextReader
54 Synchronized = New Detail.SynchronizedTextReader(reader)
55 End Function
56
57 /*
58 @date 2008/02/26
59 @auther Egtra
60 @retval Nothing EOFに達しているとき
61 @retval 有効なStringインスタンス 読み取った1行
62 */
63 Virtual Function ReadLine() As String
64 If Peek() = -1 Then
65 Exit Function
66 End If
67 Dim sb = New Text.StringBuilder
68 Dim isLead = FALSE
69 Do
70 Dim ch = Read()
71 If ch = -1 Then Exit Do
72 If isLead = FALSE Then
73 If ch = &h0D Then
74 If Peek() = &h0A Then
75 Read() 'CR LFの場合
76 End If
77 Exit Do
78 End If
79 Select Case ch
80 Case -1 'EOF
81 Exit Do
82 Case &h0A 'LF
83 Exit Do
84 Case &h0B 'VT
85 Exit Do
86 Case &h0C 'FF
87 Exit Do
88 Case &h0D 'CR
89 Exit Do
90#ifdef UNICODE
91 Case &h85 'NEL
92 Exit Do
93 Case &h2028 'LS
94 Exit Do
95 Case &h2029 'PS
96 Exit Do
97#endif
98 End Select
99 End If
100 sb.Append(ch As Char)
101#ifndef UNICODE
102 isLead = IsDBCSLeadByte(ch As Byte)
103#endif
104 Loop
105 ReadLine = sb.ToString()
106 End Function
107
108 /*!
109 @brief 現在位置からストリームの終わりまで読み込む。
110 @date 2008/02/26
111 @auther Egtra
112 */
113 Virtual Function ReadToEnd() As String
114 buf.Remove(0, pos)
115 While Underflow()
116 Wend
117 ReadToEnd = buf.ToString()
118 buf.Length = 0
119 pos = 0
120 End Function
121
122Protected
123 Sub TextReader()
124 buf = New Text.StringBuilder
125 pos = 0
126 End Sub
127
128 Virtual Sub Dispose(disposing As Boolean)
129 End Sub
130
131 /*!
132 @brief バッファが足りなくなったときに呼ばれる。
133 @date 2008/12/27
134 @auther Egtra
135 @retval True まだEOFに達していない場合
136 @retval False EOFに達した場合
137 */
138 Virtual Function Underflow() As Boolean
139 Underflow = False
140 End Function
141
142 /*!
143 @brief 内部バッファを返す
144 @date 2008/12/27
145 @auther Egtra
146 @return 内部バッファ
147 内部バッファの既存の要素は、一切の変更をしないこと。また、空であるという仮定を置かないこと。
148 */
149 Function Buffer() As Text.StringBuilder
150 Buffer = buf
151 End Function
152
153 /*!
154 @date 2008/02/26
155 @auther Egtra
156 */
157 Function ReadImpl(buffer As *Char, count As Long) As Long
158 'ToDo 適当なところでバッファの読み取り済みの部分を除去する処理を入れる(現在Peekのみ)。
159 Dim p = StrPtr(buf)
160 While buf.Length - pos < count
161 If Underflow() = False Then Exit While
162 Wend
163 ReadImpl = Math.Min(buf.Length - pos, count)
164 ActiveBasic.Strings.ChrCopy(buffer, VarPtr(p[pos]) As *Char, ReadImpl As SIZE_T)
165 pos += ReadImpl
166 End Function
167
168Private
169 buf As Text.StringBuilder
170 pos As Long
171End Class
172
173Namespace Detail
174
175Class SynchronizedTextReader
176 Inherits TextReader
177Public
178 Sub SynchronizedTextReader(reader As TextReader)
179 cs = New ActiveBasic.Windows.CriticalSection
180 base = reader
181 End Sub
182
183 Override Function Peek() As Long
184' Using lock = cs.Lock()
185 Peek = base.Peek()
186' End Using
187 End Function
188
189 Override Function Read() As Long
190' Using lock = cs.Lock()
191 Read = base.Read()
192' End Using
193 End Function
194
195 Override Function Read(buffer As *Char, index As Long, count As Long) As Long
196' Using lock = cs.Lock()
197 Read = base.Read(buffer, index, count)
198' End Using
199 End Function
200
201 Override Function ReadToEnd() As String
202' Using lock = cs.Lock
203 ReadToEnd = base.ReadToEnd
204' End Using
205 End Function
206
207Protected
208 Override Sub Dispose(disposing As Boolean)
209 Dim s = Nothing As Stream
210 SetPointer(VarPtr(s) As *VoidPtr, InterlockedExchangePointer(ByVal VarPtr(base) As *VoidPtr, 0))
211 If disposing Then
212 If Not ActiveBasic.IsNothing(s) Then
213 s.Dispose()
214 End If
215 cs.Dispose()
216 End If
217 End Sub
218
219Private
220 cs As ActiveBasic.Windows.CriticalSection
221 base As TextReader
222End Class
223
224End Namespace
225
226End Namespace
227End Namespace
Note: See TracBrowser for help on using the repository browser.