1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100
use std::{
fs::{File, OpenOptions},
io::Read,
path::Path,
};
use crate::{
error::Error,
file::{Compression, Limits},
validate::Problems,
};
use super::reader::Omf1Reader;
/// Returns true if the file looks more like OMF1 than OMF2.
///
/// Does not guarantee that the file will load. Returns an error in file read fails.
pub fn detect(read: &mut impl Read) -> Result<bool, Error> {
const PREFIX: [u8; 8] = [0x84, 0x83, 0x82, 0x81, b'O', b'M', b'F', b'-'];
let mut prefix = [0; PREFIX.len()];
read.read_exact(&mut prefix)?;
Ok(prefix == PREFIX)
}
/// Returns true if the path looks more like OMF1 than OMF2.
///
/// Does not guarantee that the file will load. Returns an error in file open or read fails.
pub fn detect_open(path: &Path) -> Result<bool, Error> {
detect(&mut File::open(path)?)
}
/// Converts a OMF1 files to OMF2.
///
/// This object allows you to set up the desired parameters then convert one or more files.
#[derive(Debug, Default)]
pub struct Converter {
limits: Limits,
compression: Compression,
}
impl Converter {
/// Creates a new default converter.
pub fn new() -> Self {
Self::default()
}
/// Returns the current limits.
pub fn limits(&self) -> Limits {
self.limits
}
/// Set the limits to use during conversion.
pub fn set_limits(&mut self, limits: Limits) {
self.limits = limits;
}
/// Returns the current compression level.
pub fn compression(&self) -> Compression {
self.compression
}
/// Set the compression level to use when writing.
pub fn set_compression(&mut self, compression: Compression) {
self.compression = compression;
}
/// Runs a conversion from one open file to another file.
///
/// `input` must support read and seek, while `output` must support write.
/// On success the validation warnings are returned.
///
/// May be called more than once to convert multiple files with the same parameters.
pub fn convert(&self, input: File, output: File) -> Result<Problems, Error> {
let reader = Omf1Reader::new(input, self.limits.json_bytes)?;
let mut writer = crate::file::Writer::new(output)?;
writer.set_compression(self.compression);
let project = reader.project()?.convert(&reader, &mut writer)?;
writer.finish(project).map(|(_, p)| p)
}
/// Runs a conversion from one filename to another.
///
/// The output file will be created if it does not exist, and truncated if it does.
/// On success the validation warnings are returned.
///
/// May be called more than once to convert multiple files with the same parameters.
pub fn convert_open(
&self,
input_path: impl AsRef<Path>,
output_path: impl AsRef<Path>,
) -> Result<Problems, Error> {
let input = File::open(input_path)?;
let output = OpenOptions::new()
.write(true)
.create(true)
.truncate(true)
.open(output_path)?;
self.convert(input, output)
}
}