8
8
// option. This file may not be copied, modified, or distributed
9
9
// except according to those terms.
10
10
11
- // ignore-test reading from os::args()[1] - bogus!
12
-
13
- use std:: cast:: transmute;
14
- use std:: from_str:: FromStr ;
15
- use std:: libc:: { FILE , STDOUT_FILENO , c_int, fdopen, fputc, fputs, fwrite, size_t} ;
11
+ use std:: cmp:: min;
12
+ use std:: io:: { stdout, BufferedWriter , IoResult } ;
16
13
use std:: os;
17
- use std:: uint:: min;
18
14
use std:: vec:: bytes:: copy_memory;
19
15
use std:: vec;
20
16
@@ -37,10 +33,6 @@ static ALU: &'static str = "GGCCGGGCGCGGTGGCTCACGCCTGTAATCCCAGCACTTTG\
37
33
38
34
static NULL_AMINO_ACID : AminoAcid = AminoAcid { c : ' ' as u8 , p : 0.0 } ;
39
35
40
- static MESSAGE_1 : & ' static str = ">ONE Homo sapiens alu\n " ;
41
- static MESSAGE_2 : & ' static str = ">TWO IUB ambiguity codes\n " ;
42
- static MESSAGE_3 : & ' static str = ">THREE Homo sapiens frequency\n " ;
43
-
44
36
static IUB : [ AminoAcid , ..15 ] = [
45
37
AminoAcid { c : 'a' as u8 , p : 0.27 } ,
46
38
AminoAcid { c : 'c' as u8 , p : 0.12 } ,
@@ -85,73 +77,68 @@ struct AminoAcid {
85
77
p : f32 ,
86
78
}
87
79
88
- struct RepeatFasta {
80
+ struct RepeatFasta < ' a , W > {
89
81
alu : & ' static str ,
90
- stdout : * FILE ,
82
+ out : & ' a mut W
91
83
}
92
84
93
- impl RepeatFasta {
94
- fn new ( stdout : * FILE , alu : & ' static str ) -> RepeatFasta {
95
- RepeatFasta {
96
- alu : alu,
97
- stdout : stdout,
98
- }
85
+ impl < ' a , W : Writer > RepeatFasta < ' a , W > {
86
+ fn new ( alu : & ' static str , w : & ' a mut W ) -> RepeatFasta < ' a , W > {
87
+ RepeatFasta { alu : alu, out : w }
99
88
}
100
89
101
- fn make ( & mut self , n : uint ) {
102
- unsafe {
103
- let stdout = self . stdout ;
104
- let alu_len = self . alu . len ( ) ;
105
- let mut buf = vec:: from_elem ( alu_len + LINE_LEN , 0u8 ) ;
106
- let alu: & [ u8 ] = self . alu . as_bytes ( ) ;
107
-
108
- copy_memory ( buf, alu) ;
109
- let buf_len = buf. len ( ) ;
110
- copy_memory ( buf. mut_slice ( alu_len, buf_len) ,
111
- alu. slice_to ( LINE_LEN ) ) ;
112
-
113
- let mut pos = 0 ;
114
- let mut bytes;
115
- let mut n = n;
116
- while n > 0 {
117
- bytes = min ( LINE_LEN , n) ;
118
- fwrite ( transmute ( & buf[ pos] ) , bytes as size_t , 1 , stdout) ;
119
- fputc ( '\n' as c_int , stdout) ;
120
- pos += bytes;
121
- if pos > alu_len {
122
- pos -= alu_len;
123
- }
124
- n -= bytes;
90
+ fn make ( & mut self , n : uint ) -> IoResult < ( ) > {
91
+ let alu_len = self . alu . len ( ) ;
92
+ let mut buf = vec:: from_elem ( alu_len + LINE_LEN , 0u8 ) ;
93
+ let alu: & [ u8 ] = self . alu . as_bytes ( ) ;
94
+
95
+ copy_memory ( buf, alu) ;
96
+ let buf_len = buf. len ( ) ;
97
+ copy_memory ( buf. mut_slice ( alu_len, buf_len) ,
98
+ alu. slice_to ( LINE_LEN ) ) ;
99
+
100
+ let mut pos = 0 ;
101
+ let mut bytes;
102
+ let mut n = n;
103
+ while n > 0 {
104
+ bytes = min ( LINE_LEN , n) ;
105
+ try!( self . out . write ( buf. slice ( pos, pos + bytes) ) ) ;
106
+ try!( self . out . write_u8 ( '\n' as u8 ) ) ;
107
+ pos += bytes;
108
+ if pos > alu_len {
109
+ pos -= alu_len;
125
110
}
111
+ n -= bytes;
126
112
}
113
+ Ok ( ( ) )
127
114
}
128
115
}
129
116
130
- struct RandomFasta {
117
+ fn make_lookup ( a : & [ AminoAcid ] ) -> [ AminoAcid , ..LOOKUP_SIZE ] {
118
+ let mut lookup = [ NULL_AMINO_ACID , ..LOOKUP_SIZE ] ;
119
+ let mut j = 0 ;
120
+ for ( i, slot) in lookup. mut_iter ( ) . enumerate ( ) {
121
+ while a[ j] . p < ( i as f32 ) {
122
+ j += 1 ;
123
+ }
124
+ * slot = a[ j] ;
125
+ }
126
+ lookup
127
+ }
128
+
129
+ struct RandomFasta < ' a , W > {
131
130
seed : u32 ,
132
- stdout : * FILE ,
133
131
lookup : [ AminoAcid , ..LOOKUP_SIZE ] ,
132
+ out : & ' a mut W ,
134
133
}
135
134
136
- impl RandomFasta {
137
- fn new ( stdout : * FILE , a : & [ AminoAcid ] ) -> RandomFasta {
135
+ impl < ' a , W : Writer > RandomFasta < ' a , W > {
136
+ fn new ( w : & ' a mut W , a : & [ AminoAcid ] ) -> RandomFasta < ' a , W > {
138
137
RandomFasta {
139
138
seed : 42 ,
140
- stdout : stdout,
141
- lookup : RandomFasta :: make_lookup ( a) ,
142
- }
143
- }
144
-
145
- fn make_lookup ( a : & [ AminoAcid ] ) -> [ AminoAcid , ..LOOKUP_SIZE ] {
146
- let mut lookup = [ NULL_AMINO_ACID , ..LOOKUP_SIZE ] ;
147
- let mut j = 0 ;
148
- for ( i, slot) in lookup. mut_iter ( ) . enumerate ( ) {
149
- while a[ j] . p < ( i as f32 ) {
150
- j += 1 ;
151
- }
152
- * slot = a[ j] ;
139
+ out : w,
140
+ lookup : make_lookup ( a) ,
153
141
}
154
- lookup
155
142
}
156
143
157
144
fn rng ( & mut self , max : f32 ) -> f32 {
@@ -169,51 +156,50 @@ impl RandomFasta {
169
156
0
170
157
}
171
158
172
- fn make ( & mut self , n : uint ) {
173
- unsafe {
174
- let lines = n / LINE_LEN ;
175
- let chars_left = n % LINE_LEN ;
176
- let mut buf = [ 0 , ..LINE_LEN + 1 ] ;
177
-
178
- for _ in range ( 0 , lines) {
179
- for i in range ( 0 u, LINE_LEN ) {
180
- buf[ i] = self . nextc ( ) ;
181
- }
182
- buf[ LINE_LEN ] = '\n' as u8 ;
183
- fwrite ( transmute ( & buf[ 0 ] ) ,
184
- LINE_LEN as size_t + 1 ,
185
- 1 ,
186
- self . stdout ) ;
187
- }
188
- for i in range ( 0 u, chars_left) {
159
+ fn make ( & mut self , n : uint ) -> IoResult < ( ) > {
160
+ let lines = n / LINE_LEN ;
161
+ let chars_left = n % LINE_LEN ;
162
+ let mut buf = [ 0 , ..LINE_LEN + 1 ] ;
163
+
164
+ for _ in range ( 0 , lines) {
165
+ for i in range ( 0 u, LINE_LEN ) {
189
166
buf[ i] = self . nextc ( ) ;
190
167
}
191
- fwrite ( transmute ( & buf[ 0 ] ) , chars_left as size_t , 1 , self . stdout ) ;
168
+ buf[ LINE_LEN ] = '\n' as u8 ;
169
+ try!( self . out . write ( buf) ) ;
170
+ }
171
+ for i in range ( 0 u, chars_left) {
172
+ buf[ i] = self . nextc ( ) ;
192
173
}
174
+ self . out . write ( buf. slice_to ( chars_left) )
193
175
}
194
176
}
195
177
196
178
fn main ( ) {
197
- let n: uint = FromStr :: from_str ( os:: args ( ) [ 1 ] ) . unwrap ( ) ;
198
-
199
- unsafe {
200
- let mode = "w" ;
201
- let stdout = fdopen ( STDOUT_FILENO as c_int , transmute ( & mode[ 0 ] ) ) ;
202
-
203
- fputs ( transmute ( & MESSAGE_1 [ 0 ] ) , stdout) ;
204
- let mut repeat = RepeatFasta :: new ( stdout, ALU ) ;
205
- repeat. make ( n * 2 ) ;
179
+ let args = os:: args ( ) ;
180
+ let n = if args. len ( ) > 1 {
181
+ from_str :: < uint > ( args[ 1 ] ) . unwrap ( )
182
+ } else {
183
+ 5
184
+ } ;
185
+
186
+ let mut out = BufferedWriter :: new ( stdout ( ) ) ;
187
+
188
+ out. write_line ( ">ONE Homo sapiens alu" ) . unwrap ( ) ;
189
+ {
190
+ let mut repeat = RepeatFasta :: new ( ALU , & mut out) ;
191
+ repeat. make ( n * 2 ) . unwrap ( ) ;
192
+ }
206
193
207
- fputs ( transmute ( & MESSAGE_2 [ 0 ] ) , stdout ) ;
208
- let iub = sum_and_scale ( IUB ) ;
209
- let mut random = RandomFasta :: new ( stdout , iub) ;
210
- random. make ( n * 3 ) ;
194
+ out . write_line ( ">TWO IUB ambiguity codes" ) . unwrap ( ) ;
195
+ let iub = sum_and_scale ( IUB ) ;
196
+ let mut random = RandomFasta :: new ( & mut out , iub) ;
197
+ random. make ( n * 3 ) . unwrap ( ) ;
211
198
212
- fputs ( transmute ( & MESSAGE_3 [ 0 ] ) , stdout ) ;
213
- let homo_sapiens = sum_and_scale ( HOMO_SAPIENS ) ;
214
- random. lookup = RandomFasta :: make_lookup ( homo_sapiens) ;
215
- random. make ( n * 5 ) ;
199
+ random . out . write_line ( ">THREE Homo sapiens frequency" ) . unwrap ( ) ;
200
+ let homo_sapiens = sum_and_scale ( HOMO_SAPIENS ) ;
201
+ random. lookup = make_lookup ( homo_sapiens) ;
202
+ random. make ( n * 5 ) . unwrap ( ) ;
216
203
217
- fputc ( '\n' as c_int , stdout) ;
218
- }
204
+ random. out . write_str ( "\n " ) . unwrap ( ) ;
219
205
}
0 commit comments