use writeln! macro; replace unsafe with expect

This commit is contained in:
Hantao Hui 2022-02-25 17:59:50 +01:00
parent 9e0dfd14de
commit 0cae584262
1 changed files with 55 additions and 41 deletions

View File

@ -508,9 +508,9 @@ mod internal {
/// When matrix is a Hermitian matrix, it will convert itself to its conjugate. /// When matrix is a Hermitian matrix, it will convert itself to its conjugate.
fn conjugate(self) -> Result<Self, MatrixMarketError>; fn conjugate(self) -> Result<Self, MatrixMarketError>;
/// Returns the name of SupportedMatrixMarketScalar, used when write the matrix /// Returns the name of SupportedMatrixMarketScalar, used when write the matrix
fn typename() -> &'static [u8]; fn typename() -> &'static str;
/// Convert the data to bytes /// Write the data self to w
fn to_matrixmarket_bytes(&self) -> Vec<u8>; fn write_matrix_market<W: std::fmt::Write>(&self, w: W) -> Result<(), std::fmt::Error>;
} }
pub trait SupportedMatrixMarketExport<T: SupportedMatrixMarketScalar> { pub trait SupportedMatrixMarketExport<T: SupportedMatrixMarketScalar> {
@ -574,12 +574,15 @@ macro_rules! mm_int_impl {
Ok(-self) Ok(-self)
} }
#[inline] #[inline]
fn typename() -> &'static [u8] { fn typename() -> &'static str {
b"integer" "integer"
} }
#[inline] #[inline]
fn to_matrixmarket_bytes(&self) -> Vec<u8> { fn write_matrix_market<W: std::fmt::Write>(
self.to_string().into_bytes() &self,
mut w: W,
) -> Result<(), std::fmt::Error> {
write!(w, "{}", self)
} }
} }
}; };
@ -627,12 +630,15 @@ macro_rules! mm_real_impl {
Ok(-self) Ok(-self)
} }
#[inline] #[inline]
fn typename() -> &'static [u8] { fn typename() -> &'static str {
b"real" "real"
} }
#[inline] #[inline]
fn to_matrixmarket_bytes(&self) -> Vec<u8> { fn write_matrix_market<W: std::fmt::Write>(
self.to_string().into_bytes() &self,
mut w: W,
) -> Result<(), std::fmt::Error> {
write!(w, "{}", self)
} }
} }
}; };
@ -681,12 +687,15 @@ macro_rules! mm_complex_impl {
Ok(-self) Ok(-self)
} }
#[inline] #[inline]
fn typename() -> &'static [u8] { fn typename() -> &'static str {
b"complex" "complex"
} }
#[inline] #[inline]
fn to_matrixmarket_bytes(&self) -> Vec<u8> { fn write_matrix_market<W: std::fmt::Write>(
(self.re.to_string() + " " + &self.im.to_string()).into_bytes() &self,
mut w: W,
) -> Result<(), std::fmt::Error> {
write!(w, "{} {}", self.re, self.im)
} }
} }
}; };
@ -738,12 +747,15 @@ macro_rules! mm_pattern_impl {
)) ))
} }
#[inline] #[inline]
fn typename() -> &'static [u8] { fn typename() -> &'static str {
b"pattern" "pattern"
} }
#[inline] #[inline]
fn to_matrixmarket_bytes(&self) -> Vec<u8> { fn write_matrix_market<W: std::fmt::Write>(
Vec::<u8>::new() &self,
mut _w: W,
) -> Result<(), std::fmt::Error> {
Ok(())
} }
} }
}; };
@ -1448,9 +1460,9 @@ pub fn write_to_matrix_market_str<T: MatrixMarketScalar, S: MatrixMarketExport<T
// The vector will grow as needed. // The vector will grow as needed.
// So, unwrap here won't cause any issue. // So, unwrap here won't cause any issue.
write_to_matrix_market(&mut bytes, sparse_matrix).unwrap(); write_to_matrix_market(&mut bytes, sparse_matrix).unwrap();
// safety issue is because 'from_utf8_unchecked' does not check that the bytes passed to it are valid UTF-8.
// Since 'bytes' created here is valid UTF-8 data, so it will not cause any problem. String::from_utf8(bytes)
unsafe { String::from_utf8_unchecked(bytes) } .expect("Unexpected non UTF-8 data was generated when export to matrix market string")
} }
/// Write a sparse matrix into Matrix Market format file. /// Write a sparse matrix into Matrix Market format file.
@ -1486,7 +1498,7 @@ pub fn write_to_matrix_market_file<
>( >(
sparse_matrix: &S, sparse_matrix: &S,
path: P, path: P,
) -> Result<(), MatrixMarketError> { ) -> Result<(), std::io::Error> {
let mut file = File::create(path)?; let mut file = File::create(path)?;
write_to_matrix_market(&mut file, sparse_matrix)?; write_to_matrix_market(&mut file, sparse_matrix)?;
Ok(()) Ok(())
@ -1494,33 +1506,35 @@ pub fn write_to_matrix_market_file<
/// low level implementation of writing sparse matrix into any [std::io::Write] object /// low level implementation of writing sparse matrix into any [std::io::Write] object
fn write_to_matrix_market<T: MatrixMarketScalar, S: MatrixMarketExport<T>, W: Write>( fn write_to_matrix_market<T: MatrixMarketScalar, S: MatrixMarketExport<T>, W: Write>(
w: &mut W, mut w: W,
sparse_matrix: &S, sparse_matrix: &S,
) -> Result<(), MatrixMarketError> { ) -> Result<(), std::io::Error> {
// write header // write header
w.write_all(b"%%matrixmarket matrix coordinate ")?; writeln!(
w.write_all(T::typename())?; w,
w.write_all(b" general\n")?; "%%matrixmarket matrix coordinate {} general",
T::typename()
)?;
//write comment //write comment
w.write_all(b"% matrixmarket file generated by nalgebra-sparse.\n")?; writeln!(w, "% matrixmarket file generated by nalgebra-sparse.")?;
// write shape information // write shape information
w.write_all(sparse_matrix.nrows().to_string().as_bytes())?; writeln!(
w.write_all(b" ")?; w,
w.write_all(sparse_matrix.ncols().to_string().as_bytes())?; "{} {} {}",
w.write_all(b" ")?; sparse_matrix.nrows(),
w.write_all(sparse_matrix.nnz().to_string().as_bytes())?; sparse_matrix.ncols(),
w.write_all(b"\n")?; sparse_matrix.nnz()
)?;
//write triplets //write triplets
let mut buffer = String::new();
for (r, c, d) in sparse_matrix.triplet_iter() { for (r, c, d) in sparse_matrix.triplet_iter() {
w.write_all((r + 1).to_string().as_bytes())?; buffer.clear();
w.write_all(b" ")?; d.write_matrix_market(&mut buffer)
w.write_all((c + 1).to_string().as_bytes())?; .expect("Unexpected format error was generated when write to String");
w.write_all(b" ")?; writeln!(w, "{} {} {} ", r + 1, c + 1, buffer)?;
w.write_all(&d.to_matrixmarket_bytes())?;
w.write_all(b"\n")?;
} }
Ok(()) Ok(())
} }