13
13
//! ncurses-compatible compiled terminfo format parsing (term(5))
14
14
15
15
use std:: collections:: HashMap ;
16
- use std:: old_io;
16
+ use std:: io:: prelude:: * ;
17
+ use std:: io;
17
18
use super :: super :: TermInfo ;
18
19
19
20
// These are the orders ncurses uses in its compiled format (as of 5.9). Not sure if portable.
@@ -158,7 +159,7 @@ pub static stringnames: &'static[&'static str] = &[ "cbt", "_", "cr", "csr", "tb
158
159
"box1" ] ;
159
160
160
161
/// Parse a compiled terminfo entry, using long capability names if `longnames` is true
161
- pub fn parse ( file : & mut old_io :: Reader , longnames : bool )
162
+ pub fn parse ( file : & mut Read , longnames : bool )
162
163
-> Result < Box < TermInfo > , String > {
163
164
macro_rules! try { ( $e: expr) => (
164
165
match $e {
@@ -182,17 +183,17 @@ pub fn parse(file: &mut old_io::Reader, longnames: bool)
182
183
}
183
184
184
185
// Check magic number
185
- let magic = try!( file . read_le_u16 ( ) ) ;
186
+ let magic = try!( read_le_u16 ( file ) ) ;
186
187
if magic != 0x011A {
187
188
return Err ( format ! ( "invalid magic number: expected {:x}, found {:x}" ,
188
189
0x011A as usize , magic as usize ) ) ;
189
190
}
190
191
191
- let names_bytes = try!( file . read_le_i16 ( ) ) as int ;
192
- let bools_bytes = try!( file . read_le_i16 ( ) ) as int ;
193
- let numbers_count = try!( file . read_le_i16 ( ) ) as int ;
194
- let string_offsets_count = try!( file . read_le_i16 ( ) ) as int ;
195
- let string_table_bytes = try!( file . read_le_i16 ( ) ) as int ;
192
+ let names_bytes = try!( read_le_u16 ( file ) ) as int ;
193
+ let bools_bytes = try!( read_le_u16 ( file ) ) as int ;
194
+ let numbers_count = try!( read_le_u16 ( file ) ) as int ;
195
+ let string_offsets_count = try!( read_le_u16 ( file ) ) as int ;
196
+ let string_table_bytes = try!( read_le_u16 ( file ) ) as int ;
196
197
197
198
assert ! ( names_bytes > 0 ) ;
198
199
@@ -212,7 +213,7 @@ pub fn parse(file: &mut old_io::Reader, longnames: bool)
212
213
}
213
214
214
215
// don't read NUL
215
- let bytes = try!( file . read_exact ( names_bytes as uint - 1 ) ) ;
216
+ let bytes = try!( read_exact ( file , names_bytes as uint - 1 ) ) ;
216
217
let names_str = match String :: from_utf8 ( bytes) {
217
218
Ok ( s) => s,
218
219
Err ( _) => return Err ( "input not utf-8" . to_string ( ) ) ,
@@ -222,26 +223,26 @@ pub fn parse(file: &mut old_io::Reader, longnames: bool)
222
223
. map ( |s| s. to_string ( ) )
223
224
. collect ( ) ;
224
225
225
- try!( file . read_byte ( ) ) ; // consume NUL
226
+ try!( read_byte ( file ) ) ; // consume NUL
226
227
227
228
let mut bools_map = HashMap :: new ( ) ;
228
229
if bools_bytes != 0 {
229
230
for i in 0 ..bools_bytes {
230
- let b = try!( file . read_byte ( ) ) ;
231
+ let b = try!( read_byte ( file ) ) ;
231
232
if b == 1 {
232
233
bools_map. insert ( bnames[ i as uint ] . to_string ( ) , true ) ;
233
234
}
234
235
}
235
236
}
236
237
237
238
if ( bools_bytes + names_bytes) % 2 == 1 {
238
- try!( file . read_byte ( ) ) ; // compensate for padding
239
+ try!( read_byte ( file ) ) ; // compensate for padding
239
240
}
240
241
241
242
let mut numbers_map = HashMap :: new ( ) ;
242
243
if numbers_count != 0 {
243
244
for i in 0 ..numbers_count {
244
- let n = try!( file . read_le_u16 ( ) ) ;
245
+ let n = try!( read_le_u16 ( file ) ) ;
245
246
if n != 0xFFFF {
246
247
numbers_map. insert ( nnames[ i as uint ] . to_string ( ) , n) ;
247
248
}
@@ -253,10 +254,10 @@ pub fn parse(file: &mut old_io::Reader, longnames: bool)
253
254
if string_offsets_count != 0 {
254
255
let mut string_offsets = Vec :: with_capacity ( 10 ) ;
255
256
for _ in 0 ..string_offsets_count {
256
- string_offsets. push ( try!( file . read_le_u16 ( ) ) ) ;
257
+ string_offsets. push ( try!( read_le_u16 ( file ) ) ) ;
257
258
}
258
259
259
- let string_table = try!( file . read_exact ( string_table_bytes as uint ) ) ;
260
+ let string_table = try!( read_exact ( file , string_table_bytes as usize ) ) ;
260
261
261
262
if string_table. len ( ) != string_table_bytes as uint {
262
263
return Err ( "error: hit EOF before end of string \
@@ -309,6 +310,25 @@ pub fn parse(file: &mut old_io::Reader, longnames: bool)
309
310
} )
310
311
}
311
312
313
+ fn read_le_u16 < R : Read + ?Sized > ( r : & mut R ) -> io:: Result < u16 > {
314
+ let mut b = [ 0 ; 2 ] ;
315
+ assert_eq ! ( try!( r. read( & mut b) ) , 2 ) ;
316
+ Ok ( ( b[ 0 ] as u16 ) | ( ( b[ 1 ] as u16 ) << 8 ) )
317
+ }
318
+
319
+ fn read_byte < R : Read + ?Sized > ( r : & mut R ) -> io:: Result < u8 > {
320
+ let mut b = [ 0 ; 1 ] ;
321
+ assert_eq ! ( try!( r. read( & mut b) ) , 1 ) ;
322
+ Ok ( b[ 0 ] )
323
+ }
324
+
325
+ fn read_exact < R : Read + ?Sized > ( r : & mut R , sz : usize ) -> io:: Result < Vec < u8 > > {
326
+ let mut v = Vec :: with_capacity ( sz) ;
327
+ try!( r. take ( sz as u64 ) . read_to_end ( & mut v) ) ;
328
+ assert_eq ! ( v. len( ) , sz) ;
329
+ Ok ( v)
330
+ }
331
+
312
332
/// Create a dummy TermInfo struct for msys terminals
313
333
pub fn msys_terminfo ( ) -> Box < TermInfo > {
314
334
let mut strings = HashMap :: new ( ) ;
0 commit comments