pub fn read_file_metadata<R: Read + Seek>(reader: &mut R) -> Result<FileMetadata> {
    // check if header and footer contain correct magic bytes
    let mut magic_buffer: [u8; 6] = [0; 6];
    reader.read_exact(&mut magic_buffer)?;
    if magic_buffer != ARROW_MAGIC {
        return Err(ArrowError::Ipc(
            "Arrow file does not contain correct header".to_string(),
        ));
    }
    reader.seek(SeekFrom::End(-6))?;
    reader.read_exact(&mut magic_buffer)?;
    if magic_buffer != ARROW_MAGIC {
        return Err(ArrowError::Ipc(
            "Arrow file does not contain correct footer".to_string(),
        ));
    }
    // read footer length
    let mut footer_size: [u8; 4] = [0; 4];
    reader.seek(SeekFrom::End(-10))?;
    reader.read_exact(&mut footer_size)?;
    let footer_len = i32::from_le_bytes(footer_size);

    // read footer
    let mut footer_data = vec![0; footer_len as usize];
    reader.seek(SeekFrom::End(-10 - footer_len as i64))?;
    reader.read_exact(&mut footer_data)?;

    let footer = gen::File::root_as_footer(&footer_data[..])
        .map_err(|err| ArrowError::Ipc(format!("Unable to get root as footer: {:?}", err)))?;

    let blocks = footer.recordBatches().ok_or_else(|| {
        ArrowError::Ipc("Unable to get record batches from IPC Footer".to_string())
    })?;

    let total_blocks = blocks.len();

    let ipc_schema = footer.schema().unwrap();
    let (schema, is_little_endian) = convert::fb_to_schema(ipc_schema);
    let schema = Arc::new(schema);

    // Create an array of optional dictionary value arrays, one per field.
    let mut dictionaries_by_field = vec![None; schema.fields().len()];
    for block in footer.dictionaries().unwrap() {
        // read length from end of offset
        let mut message_size: [u8; 4] = [0; 4];
        reader.seek(SeekFrom::Start(block.offset() as u64))?;
        reader.read_exact(&mut message_size)?;
        let footer_len = if message_size == CONTINUATION_MARKER {
            reader.read_exact(&mut message_size)?;
            i32::from_le_bytes(message_size)
        } else {
            i32::from_le_bytes(message_size)
        };

        let mut block_data = vec![0; footer_len as usize];

        reader.read_exact(&mut block_data)?;

        let message = gen::Message::root_as_message(&block_data[..])
            .map_err(|err| ArrowError::Ipc(format!("Unable to get root as message: {:?}", err)))?;

        match message.header_type() {
            gen::Message::MessageHeader::DictionaryBatch => {
                let block_offset = block.offset() as u64 + block.metaDataLength() as u64;
                let batch = message.header_as_dictionary_batch().unwrap();
                read_dictionary(
                    batch,
                    &schema,
                    is_little_endian,
                    &mut dictionaries_by_field,
                    reader,
                    block_offset,
                )?;
            }
            t => {
                return Err(ArrowError::Ipc(format!(
                    "Expecting DictionaryBatch in dictionary blocks, found {:?}.",
                    t
                )));
            }
        };
    }
    Ok(FileMetadata {
        schema,
        is_little_endian,
        blocks: blocks.to_vec(),
        total_blocks,
        dictionaries_by_field,
        version: footer.version(),
    })
}
/// Read the IPC file's metadata
Read the IPC file's metadata
Read the IPC file ' s metadata
pub fn read_file_metadata<R: Read + Seek>(reader: &mut R) -> Result<FileMetadata> {
    // check if header and footer contain correct magic bytes
    let mut magic_buffer: [u8; 6] = [0; 6];
    reader.read_exact(&mut magic_buffer)?;
    if magic_buffer != ARROW_MAGIC {
        return Err(ArrowError::Ipc(
            "Arrow file does not contain correct header".to_string(),
        ));
    }
    reader.seek(SeekFrom::End(-6))?;
    reader.read_exact(&mut magic_buffer)?;
    if magic_buffer != ARROW_MAGIC {
        return Err(ArrowError::Ipc(
            "Arrow file does not contain correct footer".to_string(),
        ));
    }
    // read footer length
    let mut footer_size: [u8; 4] = [0; 4];
    reader.seek(SeekFrom::End(-10))?;
    reader.read_exact(&mut footer_size)?;
    let footer_len = i32::from_le_bytes(footer_size);
    // read footer
    let mut footer_data = vec![0; footer_len as usize];
    reader.seek(SeekFrom::End(-10 - footer_len as i64))?;
    reader.read_exact(&mut footer_data)?;
    let footer = gen::File::root_as_footer(&footer_data[..])
        .map_err(|err| ArrowError::Ipc(format!("Unable to get root as footer: {:?}", err)))?;
    let blocks = footer.recordBatches().ok_or_else(|| {
        ArrowError::Ipc("Unable to get record batches from IPC Footer".to_string())
    })?;
    let total_blocks = blocks.len();
    let ipc_schema = footer.schema().unwrap();
    let (schema, is_little_endian) = convert::fb_to_schema(ipc_schema);
    let schema = Arc::new(schema);
    // Create an array of optional dictionary value arrays, one per field.
    let mut dictionaries_by_field = vec![None; schema.fields().len()];
    for block in footer.dictionaries().unwrap() {
        // read length from end of offset
        let mut message_size: [u8; 4] = [0; 4];
        reader.seek(SeekFrom::Start(block.offset() as u64))?;
        reader.read_exact(&mut message_size)?;
        let footer_len = if message_size == CONTINUATION_MARKER {
            reader.read_exact(&mut message_size)?;
            i32::from_le_bytes(message_size)
        } else {
            i32::from_le_bytes(message_size)
        };
        let mut block_data = vec![0; footer_len as usize];
        reader.read_exact(&mut block_data)?;
        let message = gen::Message::root_as_message(&block_data[..])
            .map_err(|err| ArrowError::Ipc(format!("Unable to get root as message: {:?}", err)))?;
        match message.header_type() {
            gen::Message::MessageHeader::DictionaryBatch => {
                let block_offset = block.offset() as u64 + block.metaDataLength() as u64;
                let batch = message.header_as_dictionary_batch().unwrap();
                read_dictionary(
                    batch,
                    &schema,
                    is_little_endian,
                    &mut dictionaries_by_field,
                    reader,
                    block_offset,
                )?;
            }
            t => {
                return Err(ArrowError::Ipc(format!(
                    "Expecting DictionaryBatch in dictionary blocks, found {:?}.",
                    t
                )));
            }
        };
    }
    Ok(FileMetadata {
        schema,
        is_little_endian,
        blocks: blocks.to_vec(),
        total_blocks,
        dictionaries_by_field,
        version: footer.version(),
    })
}
pub fn read_file_metadata < R : Read + Seek > ( reader : & mut R ) -> Result < FileMetadata > { // check if header and footer contain correct magic bytes let mut magic_buffer : [ u8 ; 6 ] = [ 0 ; 6 ] ; reader . read_exact ( & mut magic_buffer ) ? ; if magic_buffer != ARROW_MAGIC { return Err ( ArrowError :: Ipc ( " " . to_string ( ) , ) ) ; } reader . seek ( SeekFrom :: End ( - 6 ) ) ? ; reader . read_exact ( & mut magic_buffer ) ? ; if magic_buffer != ARROW_MAGIC { return Err ( ArrowError :: Ipc ( " " . to_string ( ) , ) ) ; } // read footer length let mut footer_size : [ u8 ; 4 ] = [ 0 ; 4 ] ; reader . seek ( SeekFrom :: End ( - 10 ) ) ? ; reader . read_exact ( & mut footer_size ) ? ; let footer_len = i32 :: from_le_bytes ( footer_size ) ; // read footer let mut footer_data = vec ! [ 0 footer_len as usize ] ; reader . seek ( SeekFrom :: End ( - 10 - footer_len as i64 ) ) ? ; reader . read_exact ( & mut footer_data ) ? ; let footer = gen :: File :: root_as_footer ( & footer_data [ .. ] ) . map_err ( | err | ArrowError :: Ipc ( format ! ( " " err ) ) ) ? ; let blocks = footer . recordBatches ( ) . ok_or_else ( | | { ArrowError :: Ipc ( " " . to_string ( ) ) } ) ? ; let total_blocks = blocks . len ( ) ; let ipc_schema = footer . schema ( ) . unwrap ( ) ; let ( schema , is_little_endian ) = convert :: fb_to_schema ( ipc_schema ) ; let schema = Arc :: new ( schema ) ; // Create an array of optional dictionary value arrays, one per field. let mut dictionaries_by_field = vec ! [ None schema fields ( ) len ( ) ] ; for block in footer . dictionaries ( ) . unwrap ( ) { // read length from end of offset let mut message_size : [ u8 ; 4 ] = [ 0 ; 4 ] ; reader . seek ( SeekFrom :: Start ( block . offset ( ) as u64 ) ) ? ; reader . read_exact ( & mut message_size ) ? ; let footer_len = if message_size == CONTINUATION_MARKER { reader . read_exact ( & mut message_size ) ? ; i32 :: from_le_bytes ( message_size ) } else { i32 :: from_le_bytes ( message_size ) } ; let mut block_data = vec ! [ 0 footer_len as usize ] ; reader . read_exact ( & mut block_data ) ? ; let message = gen :: Message :: root_as_message ( & block_data [ .. ] ) . map_err ( | err | ArrowError :: Ipc ( format ! ( " " err ) ) ) ? ; match message . header_type ( ) { gen :: Message :: MessageHeader :: DictionaryBatch => { let block_offset = block . offset ( ) as u64 + block . metaDataLength ( ) as u64 ; let batch = message . header_as_dictionary_batch ( ) . unwrap ( ) ; read_dictionary ( batch , & schema , is_little_endian , & mut dictionaries_by_field , reader , block_offset , ) ? ; } t => { return Err ( ArrowError :: Ipc ( format ! ( " " t ) ) ) ; } } ; } Ok ( FileMetadata { schema , is_little_endian , blocks : blocks . to_vec ( ) , total_blocks , dictionaries_by_field , version : footer . version ( ) , } ) }
Read the IPC file's metadata
Read the IPC file ' s metadata
reader
&mut R