@@ -24,6 +24,8 @@ use std::sync::atomic::Ordering;
2424
2525use std:: fs;
2626use std:: io;
27+ use std:: io:: BorrowedBuf ;
28+ use std:: io:: Read ;
2729
2830#[ cfg( test) ]
2931mod tests;
@@ -101,10 +103,13 @@ pub trait FileLoader {
101103 fn file_exists ( & self , path : & Path ) -> bool ;
102104
103105 /// Read the contents of a UTF-8 file into memory.
106+ /// This function must return a String because we normalize
107+ /// source files, which may require resizing.
104108 fn read_file ( & self , path : & Path ) -> io:: Result < String > ;
105109
106110 /// Read the contents of a potentially non-UTF-8 file into memory.
107- fn read_binary_file ( & self , path : & Path ) -> io:: Result < Vec < u8 > > ;
111+ /// We don't normalize binary files, so we can start in an Lrc.
112+ fn read_binary_file ( & self , path : & Path ) -> io:: Result < Lrc < [ u8 ] > > ;
108113}
109114
110115/// A FileLoader that uses std::fs to load real files.
@@ -119,8 +124,16 @@ impl FileLoader for RealFileLoader {
119124 fs:: read_to_string ( path)
120125 }
121126
122- fn read_binary_file ( & self , path : & Path ) -> io:: Result < Vec < u8 > > {
123- fs:: read ( path)
127+ fn read_binary_file ( & self , path : & Path ) -> io:: Result < Lrc < [ u8 ] > > {
128+ let mut file = fs:: File :: open ( path) ?;
129+ let len = file. metadata ( ) ?. len ( ) ;
130+
131+ let mut bytes = Lrc :: new_uninit_slice ( len as usize ) ;
132+ let mut buf = BorrowedBuf :: from ( Lrc :: get_mut ( & mut bytes) . unwrap ( ) ) ;
133+ file. read_buf_exact ( buf. unfilled ( ) ) ?;
134+ // SAFETY: If the read_buf_exact call returns Ok(()), then we have
135+ // read len bytes and initialized the buffer.
136+ Ok ( unsafe { bytes. assume_init ( ) } )
124137 }
125138}
126139
@@ -228,7 +241,7 @@ impl SourceMap {
228241 ///
229242 /// Unlike `load_file`, guarantees that no normalization like BOM-removal
230243 /// takes place.
231- pub fn load_binary_file ( & self , path : & Path ) -> io:: Result < Vec < u8 > > {
244+ pub fn load_binary_file ( & self , path : & Path ) -> io:: Result < Lrc < [ u8 ] > > {
232245 let bytes = self . file_loader . read_binary_file ( path) ?;
233246
234247 // We need to add file to the `SourceMap`, so that it is present
0 commit comments