@@ -11,8 +11,25 @@ native "rust" mod rustrt {
11
11
12
12
tag seek_style { seek_set; seek_end; seek_cur; }
13
13
14
+ // The raw underlying reader class. All readers must implement this.
15
+ type buf_reader =
16
+ state obj {
17
+ impure fn read( uint len) -> vec[ u8] ;
18
+ impure fn unread_byte ( int byte ) ;
19
+ impure fn eof ( ) -> bool ;
20
+
21
+ // FIXME: Seekable really should be orthogonal. We will need
22
+ // inheritance.
23
+ impure fn seek ( int offset , seek_style whence) ;
24
+ impure fn tell ( ) -> uint ;
25
+ } ;
26
+
27
+ // Convenience methods for reading.
14
28
type reader =
15
29
state obj {
30
+ // FIXME: This should inherit from buf_reader.
31
+ impure fn get_buf_reader( ) -> buf_reader;
32
+
16
33
impure fn read_byte ( ) -> int ;
17
34
impure fn unread_byte ( int byte ) ;
18
35
impure fn read_bytes ( uint len) -> vec[ u8 ] ;
@@ -35,21 +52,58 @@ fn convert_whence(seek_style whence) -> int {
35
52
}
36
53
}
37
54
38
- state obj FILE_reader ( os. libc . FILE f, bool must_close) {
39
- impure fn read_byte ( ) -> int {
40
- ret os. libc . fgetc ( f) ;
55
+ state obj FILE_buf_reader ( os. libc . FILE f, bool must_close) {
56
+ impure fn read ( uint len) -> vec[ u8] {
57
+ auto buf = _vec. alloc [ u8] ( len) ;
58
+ auto read = os. libc . fread ( _vec. buf [ u8] ( buf) , 1 u, len, f) ;
59
+ _vec. len_set [ u8] ( buf, read) ;
60
+ ret buf;
41
61
}
42
62
impure fn unread_byte ( int byte ) {
43
63
os. libc . ungetc ( byte, f) ;
44
64
}
65
+ impure fn eof ( ) -> bool {
66
+ ret os. libc . feof ( f) != 0 ;
67
+ }
68
+ impure fn seek ( int offset , seek_style whence) {
69
+ check ( os. libc . fseek ( f, offset, convert_whence ( whence) ) == 0 ) ;
70
+ }
71
+ impure fn tell ( ) -> uint {
72
+ ret os. libc . ftell ( f) as uint ;
73
+ }
74
+ drop {
75
+ if ( must_close) { os. libc . fclose ( f) ; }
76
+ }
77
+ }
78
+
79
+ // FIXME: When we have a "self" keyword, move this into read_byte(). This is
80
+ // only here so that multiple method implementations below can use it.
81
+ //
82
+ // FIXME: Return value should be option[u8], not int.
83
+ impure fn read_byte_from_buf_reader( buf_reader rdr) -> int {
84
+ auto buf = rdr. read ( 1 u) ;
85
+ if ( _vec. len [ u8] ( buf) == 0 u) {
86
+ ret -1 ;
87
+ }
88
+ ret buf. ( 0 ) as int ;
89
+ }
90
+
91
+ // FIXME: Convert this into pseudomethods on buf_reader.
92
+ state obj new_reader ( buf_reader rdr) {
93
+ impure fn get_buf_reader ( ) -> buf_reader {
94
+ ret rdr;
95
+ }
96
+ impure fn read_byte ( ) -> int {
97
+ ret read_byte_from_buf_reader ( rdr) ;
98
+ }
99
+ impure fn unread_byte ( int byte ) {
100
+ ret rdr. unread_byte ( byte) ;
101
+ }
45
102
impure fn read_bytes ( uint len) -> vec[ u8 ] {
46
- auto buf = _vec. alloc [ u8] ( len) ;
47
- auto read = os. libc . fread ( _vec. buf [ u8] ( buf) , 1 u, len, f) ;
48
- _vec. len_set [ u8] ( buf, read) ;
49
- ret buf;
103
+ ret rdr. read ( len) ;
50
104
}
51
105
impure fn read_char ( ) -> char {
52
- auto c0 = os . libc . fgetc ( f ) ;
106
+ auto c0 = read_byte_from_buf_reader ( rdr ) ;
53
107
if ( c0 == -1 ) { ret -1 as char ; } // FIXME will this stay valid?
54
108
auto b0 = c0 as u8 ;
55
109
auto w = _str. utf8_char_width ( b0) ;
@@ -58,7 +112,7 @@ state obj FILE_reader(os.libc.FILE f, bool must_close) {
58
112
auto val = 0 u;
59
113
while ( w > 1 u) {
60
114
w -= 1 u;
61
- auto next = os . libc . fgetc ( f ) ;
115
+ auto next = read_byte_from_buf_reader ( rdr ) ;
62
116
check ( next > -1 ) ;
63
117
check ( next & 0xc0 == 0x80 ) ;
64
118
val <<= 6 u;
@@ -69,17 +123,14 @@ state obj FILE_reader(os.libc.FILE f, bool must_close) {
69
123
ret val as char ;
70
124
}
71
125
impure fn eof ( ) -> bool {
72
- auto ch = os. libc . fgetc ( f) ;
73
- if ( ch == -1 ) { ret true ; }
74
- os. libc . ungetc ( ch, f) ;
75
- ret false;
126
+ ret rdr. eof ( ) ;
76
127
}
77
128
impure fn read_line ( ) -> str {
78
129
let vec[ u8] buf = vec ( ) ;
79
130
// No break yet in rustc
80
131
auto go_on = true ;
81
132
while ( go_on) {
82
- auto ch = os . libc . fgetc ( f ) ;
133
+ auto ch = read_byte_from_buf_reader ( rdr ) ;
83
134
if ( ch == -1 || ch == 10 ) { go_on = false ; }
84
135
else { _vec. push [ u8] ( buf, ch as u8 ) ; }
85
136
}
@@ -89,7 +140,7 @@ state obj FILE_reader(os.libc.FILE f, bool must_close) {
89
140
let vec[ u8] buf = vec ( ) ;
90
141
auto go_on = true ;
91
142
while ( go_on) {
92
- auto ch = os . libc . fgetc ( f ) ;
143
+ auto ch = read_byte_from_buf_reader ( rdr ) ;
93
144
if ( ch < 1 ) { go_on = false ; }
94
145
else { _vec. push [ u8] ( buf, ch as u8 ) ; }
95
146
}
@@ -100,7 +151,7 @@ state obj FILE_reader(os.libc.FILE f, bool must_close) {
100
151
auto val = 0 u;
101
152
auto pos = 0 u;
102
153
while ( size > 0 u) {
103
- val += ( os . libc . fgetc ( f ) as uint ) << pos;
154
+ val += ( read_byte_from_buf_reader ( rdr ) as uint ) << pos;
104
155
pos += 8 u;
105
156
size -= 1 u;
106
157
}
@@ -110,25 +161,22 @@ state obj FILE_reader(os.libc.FILE f, bool must_close) {
110
161
auto val = 0 u;
111
162
auto pos = 0 u;
112
163
while ( size > 0 u) {
113
- val += ( os . libc . fgetc ( f ) as uint ) << pos;
164
+ val += ( read_byte_from_buf_reader ( rdr ) as uint ) << pos;
114
165
pos += 8 u;
115
166
size -= 1 u;
116
167
}
117
168
ret val as int ;
118
169
}
119
170
impure fn seek ( int offset , seek_style whence) {
120
- check ( os . libc . fseek ( f , offset, convert_whence ( whence) ) == 0 ) ;
171
+ ret rdr . seek ( offset, whence) ;
121
172
}
122
173
impure fn tell ( ) -> uint {
123
- ret os. libc . ftell ( f) as uint ;
124
- }
125
- drop {
126
- if ( must_close) { os. libc . fclose ( f) ; }
174
+ ret rdr. tell ( ) ;
127
175
}
128
176
}
129
177
130
178
fn stdin ( ) -> reader {
131
- ret FILE_reader ( rustrt. rust_get_stdin ( ) , false) ;
179
+ ret new_reader ( FILE_buf_reader ( rustrt. rust_get_stdin ( ) , false ) ) ;
132
180
}
133
181
134
182
fn file_reader ( str path ) -> reader {
@@ -137,9 +185,17 @@ fn file_reader(str path) -> reader {
137
185
log "error opening " + path;
138
186
fail;
139
187
}
140
- ret FILE_reader ( f, true ) ;
188
+ ret new_reader ( FILE_buf_reader ( f, true ) ) ;
141
189
}
142
190
191
+
192
+ // Byte buffer readers
193
+
194
+ //state obj byte_buf_reader(vec[mutable? u8] buf) {
195
+ // fn read(
196
+ //}
197
+
198
+
143
199
// Writing
144
200
145
201
tag fileflag {
@@ -152,6 +208,7 @@ tag fileflag {
152
208
type buf_writer = state obj {
153
209
fn write( vec[ u8] v) ;
154
210
211
+ // FIXME: Seekable really should be orthogonal. We will need inheritance.
155
212
fn seek ( int offset , seek_style whence) ;
156
213
fn tell ( ) -> uint ; // FIXME: eventually u64
157
214
} ;
0 commit comments