From 687885b88d6a58fa2f2769ce30f7b445e62d374d Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E9=B2=81=E6=A0=91=E4=BA=BA?= Date: Wed, 18 Sep 2024 23:01:01 +0100 Subject: [PATCH] [wasm/xmly] feat: add wasm glue --- Cargo.lock | 1 + um_wasm/Cargo.toml | 1 + um_wasm/src/exports/mod.rs | 1 + um_wasm/src/exports/xmly.rs | 70 +++++++++++++++++++++++++++++++++++++ 4 files changed, 73 insertions(+) create mode 100644 um_wasm/src/exports/xmly.rs diff --git a/Cargo.lock b/Cargo.lock index df15492..1302607 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -544,6 +544,7 @@ dependencies = [ "umc_kuwo", "umc_ncm", "umc_qmc", + "umc_xmly", "wasm-bindgen", "wasm-bindgen-test", ] diff --git a/um_wasm/Cargo.toml b/um_wasm/Cargo.toml index 516a116..08def2b 100644 --- a/um_wasm/Cargo.toml +++ b/um_wasm/Cargo.toml @@ -28,6 +28,7 @@ umc_kgm = { path = "../um_crypto/kgm" } umc_kuwo = { path = "../um_crypto/kuwo" } umc_ncm = { path = "../um_crypto/ncm" } umc_qmc = { path = "../um_crypto/qmc" } +umc_xmly = { path = "../um_crypto/xmly" } um_audio = { path = "../um_audio" } [dev-dependencies] diff --git a/um_wasm/src/exports/mod.rs b/um_wasm/src/exports/mod.rs index 5b63cdd..e29a581 100644 --- a/um_wasm/src/exports/mod.rs +++ b/um_wasm/src/exports/mod.rs @@ -4,3 +4,4 @@ pub mod kgm; pub mod kuwo; pub mod ncm; pub mod qmc; +pub mod xmly; diff --git a/um_wasm/src/exports/xmly.rs b/um_wasm/src/exports/xmly.rs new file mode 100644 index 0000000..cd7b418 --- /dev/null +++ b/um_wasm/src/exports/xmly.rs @@ -0,0 +1,70 @@ +use std::convert::TryInto; +use umc_xmly::android::{decrypt_android, FileType}; +use umc_xmly::pc::Header as PCHeader; +use umc_xmly::XmlyError; +use wasm_bindgen::prelude::wasm_bindgen; +use wasm_bindgen::JsError; + +/// Decrypt X2M Header +#[wasm_bindgen(js_name=decryptX2MHeader)] +pub fn js_decrypt_x2m_header(buffer: &mut [u8]) -> Result<(), JsError> { + decrypt_android(FileType::X2M, buffer.try_into().map_err(JsError::from)?); + Ok(()) +} + +/// Decrypt X3M Header +#[wasm_bindgen(js_name=decryptX3MHeader)] +pub fn js_decrypt_x3m_header(buffer: &mut [u8]) -> Result<(), JsError> { + decrypt_android(FileType::X3M, buffer.try_into().map_err(JsError::from)?); + Ok(()) +} + +/// Ximalaya PC Decipher. +#[wasm_bindgen(js_name=XmlyPC)] +pub struct JsXmlyPC(PCHeader); + +#[wasm_bindgen(js_class=XmlyPC)] +impl JsXmlyPC { + /// Get required bytes for the header, or throw error if not valid XM file. + #[wasm_bindgen(js_name = "getHeaderSize")] + pub fn get_header_size(buffer: &[u8]) -> Result { + let required_len = match PCHeader::from_buffer(buffer) { + Ok(hdr) => hdr.data_start_offset, + Err(XmlyError::MetadataTooSmall(n)) => n, + Err(err) => Err(JsError::from(err))?, + }; + + Ok(required_len) + } + + /// Create a new XmlyPC decipher + #[wasm_bindgen(constructor)] + pub fn new(header: &[u8]) -> Result { + let hdr = PCHeader::from_buffer(header)?; + Ok(Self(hdr)) + } + + /// Get the first few bytes of the header. + #[wasm_bindgen(getter, js_name=audioHeader)] + pub fn get_audio_header(&self) -> Vec { + self.0.copy_m4a_header() + } + + /// Get the offset where the encrypted header is + #[wasm_bindgen(getter, js_name=encryptedHeaderOffset)] + pub fn get_encrypted_header_offset(&self) -> usize { + self.0.data_start_offset + } + + /// Get the size of encrypted header + #[wasm_bindgen(getter, js_name=encryptedHeaderSize)] + pub fn get_encrypted_header_len(&self) -> usize { + self.0.encrypted_header_size + } + + /// Decrypt encrypted header + pub fn decrypt(&self, buffer: &mut [u8]) -> Result { + let size = self.0.decrypt(buffer)?.len(); + Ok(size) + } +}