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
RevLine 
[655]1Namespace System
2Namespace IO
[420]3
4Class TextReader
5 Implements System.IDisposable
6Public
[426]7 Virtual Sub ~TextReader()
8 Dispose(False)
9 End Sub
[420]10
[426]11' Static Null = StreamReader.Null As TextReader
[420]12
13Public
[426]14 Sub Close()
15 Dispose(True)
[420]16 End Sub
[426]17
18 Sub Dispose()
19 Dispose(True)
20 End Sub
21
[665]22 Virtual Function Peek() As Long
23 If pos >= buf.Length Then
[676]24 buf.Length = 0
25 pos = 0
[665]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
[432]38 /*
39 @date 2008/02/26
40 @auther Egtra
41 */
[665]42 Virtual Function Read(buffer As *Char, index As Long, count As Long) As Long
[432]43 If buffer = 0 Then
[655]44 Throw New ArgumentNullException("buffer")
[432]45 ElseIf index < 0 Then
[655]46 Throw New ArgumentOutOfRangeException("index")
[432]47 ElseIf count < 0 Then
[655]48 Throw New ArgumentOutOfRangeException("count")
[432]49 End If
[655]50 Read = ReadImpl(VarPtr(buffer[index]), count)
[426]51 End Function
[432]52
[655]53 Static Function Synchronized(reader As TextReader) As TextReader
54 Synchronized = New Detail.SynchronizedTextReader(reader)
55 End Function
56
[432]57 /*
58 @date 2008/02/26
59 @auther Egtra
60 @retval Nothing EOFに達しているとき
61 @retval 有効なStringインスタンス 読み取った1行
62 */
[665]63 Virtual Function ReadLine() As String
[432]64 If Peek() = -1 Then
65 Exit Function
66 End If
[665]67 Dim sb = New Text.StringBuilder
68 Dim isLead = FALSE
[432]69 Do
70 Dim ch = Read()
[665]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
[432]78 End If
[665]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
[432]99 End If
[665]100 sb.Append(ch As Char)
101#ifndef UNICODE
102 isLead = IsDBCSLeadByte(ch As Byte)
103#endif
[432]104 Loop
[665]105 ReadLine = sb.ToString()
[432]106 End Function
[665]107
108 /*!
[457]109 @brief 現在位置からストリームの終わりまで読み込む。
[432]110 @date 2008/02/26
111 @auther Egtra
112 */
113 Virtual Function ReadToEnd() As String
[665]114 buf.Remove(0, pos)
115 While Underflow()
116 Wend
117 ReadToEnd = buf.ToString()
[676]118 buf.Length = 0
119 pos = 0
[432]120 End Function
121
[655]122Protected
123 Sub TextReader()
[665]124 buf = New Text.StringBuilder
125 pos = 0
[655]126 End Sub
[457]127
[468]128 Virtual Sub Dispose(disposing As Boolean)
129 End Sub
[432]130
[665]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 内部バッファ
[676]147 内部バッファの既存の要素は、一切の変更をしないこと。また、空であるという仮定を置かないこと。
[665]148 */
149 Function Buffer() As Text.StringBuilder
150 Buffer = buf
151 End Function
152
153 /*!
[432]154 @date 2008/02/26
155 @auther Egtra
156 */
[665]157 Function ReadImpl(buffer As *Char, count As Long) As Long
[676]158 'ToDo 適当なところでバッファの読み取り済みの部分を除去する処理を入れる(現在Peekのみ)。
[665]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)
[676]164 ActiveBasic.Strings.ChrCopy(buffer, VarPtr(p[pos]) As *Char, ReadImpl As SIZE_T)
[665]165 pos += ReadImpl
[432]166 End Function
[665]167
168Private
169 buf As Text.StringBuilder
170 pos As Long
[420]171End Class
172
[457]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
[665]184' Using lock = cs.Lock()
185 Peek = base.Peek()
[457]186' End Using
187 End Function
188
189 Override Function Read() As Long
[665]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
[457]202' Using lock = cs.Lock
[665]203 ReadToEnd = base.ReadToEnd
[457]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
[655]226End Namespace
227End Namespace
Note: See TracBrowser for help on using the repository browser.