@@ -41,6 +41,7 @@ enum fieldtype {
41
41
42
42
iface rowiter {
43
43
fn readrow( & row: [ str] ) -> bool;
44
+ fn iter ( f : fn ( & row: [ str ] ) -> bool ) ;
44
45
}
45
46
46
47
fn new_reader ( +f : io:: reader , +delim : char , +quote : char ) -> rowreader {
@@ -80,16 +81,16 @@ fn statestr(state: state) -> str {
80
81
}
81
82
}
82
83
83
- fn unescape ( escaped : [ char ] ) -> [ char ] {
84
+ fn unescape ( escaped : [ char ] , quote : char ) -> [ char ] {
84
85
let mut r : [ char ] = [ ] ;
85
86
vec:: reserve ( r, vec:: len ( escaped) ) ;
86
87
let mut in_q = false ;
87
88
for c in escaped {
88
89
if in_q {
89
- assert ( c == '"' ) ;
90
+ assert ( c == quote ) ;
90
91
in_q = false ;
91
92
} else {
92
- in_q = c == '"' ;
93
+ in_q = c == quote ;
93
94
r += [ c] ;
94
95
}
95
96
}
@@ -100,7 +101,7 @@ impl of rowiter for rowreader {
100
101
#[ inline]
101
102
fn readrow ( & row: [ str ] ) -> bool {
102
103
fn row_from_buf ( self : rowreader , & fields: [ str ] ) -> bool {
103
- fn decode ( buffers : [ [ char ] ] , field : fieldtype ) -> str {
104
+ fn decode ( buffers : [ [ char ] ] , field : fieldtype , quote : char ) -> str {
104
105
alt field {
105
106
emptyfield( ) { "" }
106
107
bufferfield ( desc) {
@@ -120,7 +121,7 @@ impl of rowiter for rowreader {
120
121
i = i + 1 u;
121
122
}
122
123
if desc. escaped {
123
- buf = unescape ( buf) ;
124
+ buf = unescape ( buf, quote ) ;
124
125
}
125
126
str:: from_chars ( buf)
126
127
}
@@ -159,24 +160,24 @@ impl of rowiter for rowreader {
159
160
self . state = inquotedfield ( cbuffer, coffset) ;
160
161
} else if c == '\n' {
161
162
if after_delim {
162
- fields += [ decode ( self . buffers , emptyfield) ] ;
163
+ fields += [ decode ( self . buffers , emptyfield, self . quote ) ] ;
163
164
}
164
165
ret true;
165
166
} else if c == self . delim {
166
167
self . state = fieldstart ( true ) ;
167
- fields += [ decode ( self . buffers , emptyfield) ] ;
168
+ fields += [ decode ( self . buffers , emptyfield, self . quote ) ] ;
168
169
} else {
169
170
self . state = infield ( cbuffer, coffset) ;
170
171
}
171
172
}
172
173
infield ( b, o) {
173
174
#debug ( "field : %u %u" , b, o) ;
174
175
if c == '\n' {
175
- fields += [ decode ( self . buffers , new_bufferfield ( self , false , b, o, coffset) ) ] ;
176
+ fields += [ decode ( self . buffers , new_bufferfield ( self , false , b, o, coffset) , self . quote ) ] ;
176
177
ret true;
177
178
} else if c == self . delim {
178
179
self . state = fieldstart ( true ) ;
179
- fields += [ decode ( self . buffers , new_bufferfield ( self , false , b, o, coffset) ) ] ;
180
+ fields += [ decode ( self . buffers , new_bufferfield ( self , false , b, o, coffset) , self . quote ) ] ;
180
181
}
181
182
}
182
183
inquotedfield ( b, o) {
@@ -188,13 +189,13 @@ impl of rowiter for rowreader {
188
189
inquote ( b, o) {
189
190
#debug ( "inquote : %u %u" , b, o) ;
190
191
if c == '\n' {
191
- fields += [ decode ( self . buffers , new_bufferfield ( self , true , b, o, coffset) ) ] ;
192
+ fields += [ decode ( self . buffers , new_bufferfield ( self , true , b, o, coffset) , self . quote ) ] ;
192
193
ret true;
193
194
} else if c == self . quote {
194
195
self . state = inquotedfield ( b, o) ;
195
196
} else if c == self . delim {
196
197
self . state = fieldstart ( true ) ;
197
- fields += [ decode ( self . buffers , new_bufferfield ( self , true , b, o, coffset) ) ] ;
198
+ fields += [ decode ( self . buffers , new_bufferfield ( self , true , b, o, coffset) , self . quote ) ] ;
198
199
}
199
200
// swallow odd chars, eg. space between field and "
200
201
}
@@ -240,6 +241,15 @@ impl of rowiter for rowreader {
240
241
}
241
242
ret false;
242
243
}
244
+
245
+ fn iter ( f : fn ( & row: [ str ] ) -> bool ) {
246
+ let mut row = [ ] ;
247
+ while self . readrow ( row) {
248
+ if !f ( row) {
249
+ break ;
250
+ }
251
+ }
252
+ }
243
253
}
244
254
245
255
#[ cfg( test) ]
@@ -340,5 +350,15 @@ mod test {
340
350
fn blank_line ( ) {
341
351
rowmatch ( "\n \n " , [ [ ] , [ ] ] ) ;
342
352
}
353
+
354
+ #[ test]
355
+ fn iter_test ( ) {
356
+ let f = io:: str_reader ( "a brown,cat" ) ;
357
+ let r : rowreader = new_reader ( f, ',' , '"' ) ;
358
+ for r. iter( ) { |row|
359
+ assert( row[ 0 ] == "a brown" ) ;
360
+ assert( row[ 1 ] == "cat" ) ;
361
+ }
362
+ }
343
363
}
344
364
0 commit comments