diff --git a/musicxml/src/parser/mod.rs b/musicxml/src/parser/mod.rs index df6e75a..b494739 100644 --- a/musicxml/src/parser/mod.rs +++ b/musicxml/src/parser/mod.rs @@ -1,6 +1,6 @@ use crate::elements::{ScorePartwise, ScoreTimewise}; use alloc::{collections::BTreeMap, string::String, vec::Vec}; -use musicxml_internal::{ElementDeserializer, ElementSerializer, XmlElement}; +use musicxml_internal::{bytes_to_string, ElementDeserializer, ElementSerializer, XmlElement}; #[cfg(feature = "std")] extern crate std; @@ -45,7 +45,7 @@ fn get_musicxml_contents(data: Vec) -> Result { Err(String::from("Cannot find MusicXML file in compressed archive"))?; } } else { - contents = String::from_utf8(data).or_else(|_| Err(String::from("Invalid UTF-8 data in MusicXML content")))?; + contents = bytes_to_string(&data)?; } Ok(contents) } diff --git a/musicxml/src/parser/zip_parser.rs b/musicxml/src/parser/zip_parser.rs index d8dee86..d44f909 100644 --- a/musicxml/src/parser/zip_parser.rs +++ b/musicxml/src/parser/zip_parser.rs @@ -4,6 +4,7 @@ use alloc::{collections::BTreeMap, vec::Vec}; use crc32fast; use miniz_oxide::deflate::compress_to_vec; use miniz_oxide::inflate::decompress_to_vec; +use musicxml_internal::bytes_to_string; #[cfg(feature = "std")] use std::time::{SystemTime, UNIX_EPOCH}; @@ -247,7 +248,7 @@ impl<'a> ZipArchive<'a> { let decoded_data = decompress_to_vec(&self.zip_data.content[file.relative_offset..(file.relative_offset + file.compressed_size)]) .map_err(|e| e.to_string())?; - String::from_utf8(decoded_data).map_err(|e| e.to_string()) + bytes_to_string(&decoded_data).map_err(|e| e.to_string()) } pub fn iter(&self) -> impl Iterator { diff --git a/musicxml/tests/MozaChloSample.musicxml b/musicxml/tests/MozaChloSample.musicxml new file mode 100755 index 0000000..1c7f18a Binary files /dev/null and b/musicxml/tests/MozaChloSample.musicxml differ diff --git a/musicxml_internal/src/lib.rs b/musicxml_internal/src/lib.rs index 6a114b2..2c52e78 100644 --- a/musicxml_internal/src/lib.rs +++ b/musicxml_internal/src/lib.rs @@ -2,9 +2,25 @@ extern crate alloc; +use alloc::borrow::ToOwned; use alloc::string::{String, ToString}; use alloc::vec::Vec; +pub fn bytes_to_string(bytes: &[u8]) -> Result { + String::from_utf8(bytes.to_owned()).or_else(|_| { + let convert = if bytes[0] == 0xFF && bytes[1] == 0xFE { + u16::from_le_bytes + } else { + u16::from_be_bytes + }; + let u16_bytes: Vec = bytes + .chunks_exact(2) + .map(|bytes| convert([bytes[0], bytes[1]])) + .collect(); + String::from_utf16(&u16_bytes).map_err(|_| String::from("Invalid UTF-8 or UTF-16 data in MusicXML content")) + }) +} + #[derive(Debug, Default, PartialEq, Eq)] pub struct XmlElement { pub name: String,