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

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

非同期入出力(Begin/End-Read/Writeメソッド)を実装。

File size: 3.0 KB
Line 
1'Classes/System/IO/StreamReader.ab
2
3Namespace System
4Namespace IO
5
6/*
7@brief ストリームから読み取りを行うTextReaderの実装。
8@date 2008/02/25
9@auther Egtra
10*/
11Class StreamReader
12 Inherits TextReader
13Public
14 /*
15 @date 2008/02/25
16 @auther Egtra
17 */
18 Sub StreamReader(path As String)
19 init(New FileStream(path, FileMode.Open, FileAccess.Read, FileShare.Read))
20 End Sub
21
22 /*
23 @date 2008/02/25
24 @auther Egtra
25 */
26 Sub StreamReader(stream As Stream)
27 init(stream)
28 End Sub
29
30 /*
31 @date 2008/02/25
32 @auther Egtra
33 */
34 Override Function Peek() As Long
35 If cur = last Then
36 last = s.Read(buf As *Byte, 0, size)
37 cur = 0
38 If last = 0 Then
39 Peek = -1
40 Exit Function
41 End If
42 End If
43 Peek = buf[cur]
44 End Function
45
46 /*
47 @date 2008/02/25
48 @auther Egtra
49 */
50 Override Function Read() As Long
51 Read = Peek()
52 If Read <> -1 Then
53 cur++
54 End If
55 End Function
56
57 /*
58 @date 2008/02/26
59 @auther Egtra
60 */
61 Override Function ReadToEnd() As String
62 Dim sb = New Text.StringBuilder(65536)
63 sb.Append(buf, cur, last - cur)
64 Do
65 Dim read = Read(buf, 0, size)
66 sb.Append(buf, 0, read)
67 If read < size Then
68 ReadToEnd = sb.ToString
69 Exit Function
70 End If
71 Loop
72 End Function
73
74Protected
75 /*
76 @date 2008/02/25
77 @auther Egtra
78 */
79 Override Sub Dispose(disposing As Boolean)
80 If disposing Then
81 If Not ActiveBasic.IsNothing(s) Then
82 s.Dispose(True)
83 End If
84 End If
85 s = Nothing
86 size = 0
87 cur = 0
88 last = 0
89 End Sub
90
91 /*
92 @date 2008/02/25
93 @auther Egtra
94 */
95 Override Function ReadImpl(buffer As *Char, index As Long, count As Long) As Long
96 Dim n = last - cur
97 If count <= n Then
98 ReadImpl = ReadFromBuffer(buffer, index, count)
99 Exit Function
100 End If
101 Dim p = VarPtr(buffer[index])
102 ReadImpl = ReadFromBuffer(p, 0, n)
103 If ReadImpl = count Then 'バッファの中身で足りた場合
104 Exit Function
105 End If
106 p = VarPtr(p[n])
107 count -= n
108 If count > size Then
109 n = (count \ size) * size 'sizeの倍数分だけは直接bufferへ読み込ませる
110 Dim read = s.Read(p As *Byte, 0, n)
111 If read = 0 Then 'EOF
112 Exit Function
113 End If
114 p = VarPtr(p[n])
115 ReadImpl += n
116 count -= n
117 End If
118 last = s.Read(buffer As *Byte, 0, size)
119 cur = 0
120 If last = 0 Then 'EOF
121 Exit Function
122 End If
123 ReadImpl += ReadFromBuffer(p, 0, Math.Min(last, count))
124 End Function
125
126Private
127 /*
128 @date 2008/02/25
129 @auther Egtra
130 */
131 Sub init(str As Stream)
132 s = str
133 size = 4096
134 last = 0
135 cur = 0
136 buf = GC_malloc(size)
137 End Sub
138
139 /**
140 @brief バッファの中身から読み取る。
141 @date 2008/02/25
142 @auther Egtra
143 文字数が足りなくても、元のストリームまで読みには行かない。
144 */
145 Function ReadFromBuffer(p As *Char, index As Long, count As Long) As Long
146 memcpy(VarPtr(p[index]), VarPtr(buf[cur]), count * SizeOf (Char))
147 cur += count
148 ReadFromBuffer = count
149 End Function
150
151 s As Stream
152 size As Long
153 cur As Long
154 last As Long '中身の終わり
155 buf As *SByte '暫定
156End Class
157
158End Namespace
159End Namespace
Note: See TracBrowser for help on using the repository browser.