source: trunk/Include/Classes/System/IO/StreamReader.ab@ 426

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

StreamReaderの実装開始。
Stringの+演算子で右辺がNullのときに起こるアクセス違反を回避。

File size: 2.8 KB
Line 
1Namespace System
2Namespace IO
3
4Class StreamReader
5 Inherits TextReader
6Public
7 Sub StreamReader(path As String)
8 init(New FileStream(path, FileMode.Open, FileAccess.Read, FileShare.Read))
9 End Sub
10
11 Sub StreamReader(stream As Stream)
12 init(stream)
13 End Sub
14
15 Override Sub Dispose(disposing As Boolean)
16 s.Dispose(disposing)
17 size = 0
18 cur = 0
19 last = 0
20 End Sub
21
22 Override Function Peek() As Long
23 If cur = last Then
24 last = s.Read(buf, 0, size)
25 cur = 0
26 If last = 0 Then
27 Peek = -1
28 Exit Function
29 End If
30 End If
31 Peek = buf[cur]
32 End Function
33
34 Override Function Read() As Long
35 Read = Peek()
36 cur++
37 End Function
38
39 Override Function Read(buffer As *StrChar, index As Long, count As Long) As Long
40 If buffer = 0 Then
41 ElseIf index < 0 Then
42 ElseIf count < 0 Then
43 End If
44
45 Dim n = last - cur
46 If count <= n Then
47 Read = ReadFromBuffer(buffer, index, count)
48 Exit Function
49 End If
50 Dim p = VarPtr(buffer[index])
51 Read = ReadFromBuffer(p, 0, n)
52 If Read = count Then 'バッファの中身で足りた場合
53 Exit Function
54 End If
55 p = VarPtr(p[n])
56 count -= n
57 If count > size Then
58 n = (count \ size) * size 'sizeの倍数分だけは直接bufferへ読み込ませる
59 Dim read = s.Read(p, 0, n)
60 If read = 0 Then 'EOF
61 Exit Function
62 End If
63 p = VarPtr(p[n])
64 Read += n
65 count -= n
66 End If
67 last = s.Read(buffer, 0, size)
68 cur = 0
69 If last = 0 Then 'EOF
70 Exit Function
71 End If
72 Read += ReadFromBuffer(p, 0, Math.Min(last, count))
73 End Function
74
75 Override Function ReadLine() As String
76 Dim sb = New Text.StringBuilder(256)
77 Do
78 Dim ch = Read()
79 If ch = &h0D Then
80 If Peek() = &h0A Then
81 Read() 'CR LFの場合
82 End If
83 Exit Do
84 End If
85 Select Case ch
86 Case -1 'EOF
87 Exit Do
88 Case &h0A 'LF
89 Exit Do
90 Case &h0B 'VT
91 Exit Do
92 Case &h0C 'FF
93 Exit Do
94 Case &h0D 'CR
95 Exit Do
96' Case &h85 'NEL
97' Exit Do
98' Case &h2028 'LS
99' Exit Do
100' Case &h2029 'PS
101' Exit Do
102 End Select
103 sb.Append(ch As StrChar) 'ToDo キャスト不要にすべきというチケットを書くこと
104 Loop
105 ReadLine = sb.ToString
106 End Function
107
108 Override Function ReadToEnd() As String
109 End Function
110
111Private
112 Sub init(str As Stream)
113 s = str
114 size = 4096
115 last = 0
116 cur = 0
117 buf = GC_malloc(size)
118 End Sub
119
120 /**
121 @brief バッファの中身から読み取る。
122 文字数が足りなくても、元のストリームまで読みには行かない。
123 */
124 Function ReadFromBuffer(p As *StrChar, index As Long, count As Long) As Long
125 memcpy(VarPtr(p[index]), VarPtr(buf[cur]), count * SizeOf (StrChar))
126 cur += count
127 ReadFromBuffer = count
128 End Function
129
130 s As Stream
131 size As Long
132 cur As Long
133 last As Long '中身の終わり
134 buf As *Byte '暫定
135End Class
136
137End Namespace
138End Namespace
Note: See TracBrowser for help on using the repository browser.