use std::io::{Read, Seek, SeekFrom, Write};
use crate::error::{Error, Result};
use super::endianess::is_native_little_endian;
use super::read::{self, FileMetadata};
use super::write::common::DictionaryTracker;
use super::write::writer::*;
use super::write::*;
impl<R: Read + Seek + Write> FileWriter<R> {
pub fn try_from_file(
mut writer: R,
metadata: FileMetadata,
options: WriteOptions,
) -> Result<FileWriter<R>> {
if metadata.ipc_schema.is_little_endian != is_native_little_endian() {
return Err(Error::nyi(
"Appending to a file of a non-native endianess is still not supported",
));
}
let dictionaries =
read::read_file_dictionaries(&mut writer, &metadata, &mut Default::default())?;
let last_block = metadata.blocks.last().ok_or_else(|| {
Error::oos("An Arrow IPC file must have at least 1 message (the schema message)")
})?;
let offset: u64 = last_block
.offset
.try_into()
.map_err(|_| Error::oos("The block's offset must be a positive number"))?;
let meta_data_length: u64 = last_block
.meta_data_length
.try_into()
.map_err(|_| Error::oos("The block's meta length must be a positive number"))?;
let body_length: u64 = last_block
.body_length
.try_into()
.map_err(|_| Error::oos("The block's body length must be a positive number"))?;
let offset: u64 = offset + meta_data_length + body_length;
writer.seek(SeekFrom::Start(offset))?;
Ok(FileWriter {
writer,
options,
schema: metadata.schema,
ipc_fields: metadata.ipc_schema.fields,
block_offsets: offset as usize,
dictionary_blocks: metadata.dictionaries.unwrap_or_default(),
record_blocks: metadata.blocks,
state: State::Started, dictionary_tracker: DictionaryTracker {
dictionaries,
cannot_replace: true,
},
encoded_message: Default::default(),
})
}
}