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

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

TextWriter同様TextReaderでバッファリングし、StreamReaderはMultiByteToWideChar固定で仮実装。これで、マルチバイトモードでもStringReaderが使えるようにした。
(#235)

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