Build [`FileReader`] with given reader.
(self, mut reader: R)
| 1220 | |
| 1221 | /// Build [`FileReader`] with given reader. |
| 1222 | pub fn build<R: Read + Seek>(self, mut reader: R) -> Result<FileReader<R>, ArrowError> { |
| 1223 | // Space for ARROW_MAGIC (6 bytes) and length (4 bytes) |
| 1224 | let mut buffer = [0; 10]; |
| 1225 | reader.seek(SeekFrom::End(-10))?; |
| 1226 | reader.read_exact(&mut buffer)?; |
| 1227 | |
| 1228 | let footer_len = read_footer_length(buffer)?; |
| 1229 | |
| 1230 | // read footer |
| 1231 | let mut footer_data = vec![0; footer_len]; |
| 1232 | reader.seek(SeekFrom::End(-10 - footer_len as i64))?; |
| 1233 | reader.read_exact(&mut footer_data)?; |
| 1234 | |
| 1235 | let verifier_options = VerifierOptions { |
| 1236 | max_tables: self.max_footer_fb_tables, |
| 1237 | max_depth: self.max_footer_fb_depth, |
| 1238 | ..Default::default() |
| 1239 | }; |
| 1240 | let footer = crate::root_as_footer_with_opts(&verifier_options, &footer_data[..]).map_err( |
| 1241 | |err| ArrowError::ParseError(format!("Unable to get root as footer: {err:?}")), |
| 1242 | )?; |
| 1243 | |
| 1244 | let blocks = footer.recordBatches().ok_or_else(|| { |
| 1245 | ArrowError::ParseError("Unable to get record batches from IPC Footer".to_string()) |
| 1246 | })?; |
| 1247 | |
| 1248 | let total_blocks = blocks.len(); |
| 1249 | |
| 1250 | let ipc_schema = footer.schema().unwrap(); |
| 1251 | if !ipc_schema.endianness().equals_to_target_endianness() { |
| 1252 | return Err(ArrowError::IpcError( |
| 1253 | "the endianness of the source system does not match the endianness of the target system.".to_owned() |
| 1254 | )); |
| 1255 | } |
| 1256 | |
| 1257 | let schema = crate::convert::fb_to_schema(ipc_schema); |
| 1258 | |
| 1259 | let mut custom_metadata = HashMap::new(); |
| 1260 | if let Some(fb_custom_metadata) = footer.custom_metadata() { |
| 1261 | for kv in fb_custom_metadata.into_iter() { |
| 1262 | custom_metadata.insert( |
| 1263 | kv.key().unwrap().to_string(), |
| 1264 | kv.value().unwrap().to_string(), |
| 1265 | ); |
| 1266 | } |
| 1267 | } |
| 1268 | |
| 1269 | let mut decoder = FileDecoder::new(Arc::new(schema), footer.version()); |
| 1270 | if let Some(projection) = self.projection { |
| 1271 | decoder = decoder.with_projection(projection) |
| 1272 | } |
| 1273 | |
| 1274 | // Create an array of optional dictionary value arrays, one per field. |
| 1275 | if let Some(dictionaries) = footer.dictionaries() { |
| 1276 | for block in dictionaries { |
| 1277 | let buf = read_block(&mut reader, block)?; |
| 1278 | decoder.read_dictionary(block, &buf)?; |
| 1279 | } |