use crate::translate::StringVariantHashMap;
use crate::{SectorType, ffi};
use glib::translate::*;
use std::collections::HashMap;
#[doc(alias = "mirage_helper_ascii2isrc")]
pub fn ascii2isrc(c: glib::Char) -> u8 {
assert_initialized_main_thread!();
unsafe { ffi::mirage_helper_ascii2isrc(c.into_glib()) }
}
#[doc(alias = "mirage_helper_bcd2hex")]
pub fn bcd2hex(bcd: i32) -> i32 {
assert_initialized_main_thread!();
unsafe { ffi::mirage_helper_bcd2hex(bcd) }
}
#[doc(alias = "mirage_helper_calculate_crc16")]
pub fn calculate_crc16(data: &[u8], crctab: &[u16; 256], reflected: bool, invert: bool) -> u16 {
unsafe {
ffi::mirage_helper_calculate_crc16(
data.as_ptr(),
data.len() as glib::ffi::guint,
&raw const *crctab,
reflected.into_glib(),
invert.into_glib(),
)
}
}
#[doc(alias = "mirage_helper_calculate_crc32_fast")]
pub fn calculate_crc32_fast(
data: &[u8],
crctab: &[u32; 2048],
reflected: bool,
invert: bool,
) -> u32 {
unsafe {
ffi::mirage_helper_calculate_crc32_fast(
data.as_ptr(),
data.len() as glib::ffi::guint,
&raw const *crctab,
reflected.into_glib(),
invert.into_glib(),
)
}
}
#[doc(alias = "mirage_helper_calculate_crc32_standard")]
pub fn calculate_crc32_standard(
data: &[u8],
crctab: &[u32; 256],
reflected: bool,
invert: bool,
) -> u32 {
unsafe {
ffi::mirage_helper_calculate_crc32_standard(
data.as_ptr(),
data.len() as glib::ffi::guint,
&raw const *crctab,
reflected.into_glib(),
invert.into_glib(),
)
}
}
#[doc(alias = "mirage_helper_determine_sector_type")]
pub fn determine_sector_type(buf: &[u8]) -> SectorType {
assert_initialized_main_thread!();
unsafe { from_glib(ffi::mirage_helper_determine_sector_type(buf.as_ptr())) }
}
#[cfg(feature = "v3_3_2")]
#[cfg_attr(docsrs, doc(cfg(feature = "v3_3_2")))]
#[doc(alias = "mirage_helper_dump_buffer_to_hex")]
pub fn dump_buffer_to_hex(data: &[u8], add_spaces: bool, wrap: i32) -> Option<glib::GString> {
assert_initialized_main_thread!();
let data_size = data.len() as _;
unsafe {
from_glib_full(ffi::mirage_helper_dump_buffer_to_hex(
data.to_glib_none().0,
data_size,
add_spaces.into_glib(),
wrap,
))
}
}
#[doc(alias = "mirage_helper_encoding_from_bom")]
pub fn encoding_from_bom(buffer: &[u8; 4]) -> Option<glib::GString> {
unsafe { from_glib_none(ffi::mirage_helper_encoding_from_bom(&raw const *buffer)) }
}
#[doc(alias = "mirage_helper_find_data_file")]
pub fn find_data_file(filename: &str, path: Option<&str>) -> Option<glib::GString> {
assert_initialized_main_thread!();
unsafe {
from_glib_full(ffi::mirage_helper_find_data_file(
filename.to_glib_none().0,
path.to_glib_none().0,
))
}
}
#[macro_export]
#[doc(hidden)]
#[doc(alias = "mirage_helper_format_string")]
macro_rules! helper_format_string {
($format:expr $(, $($token:expr => $value:expr),* $(,)?)?) => {{
#[allow(unused_mut)]
let mut map = ::std::collections::HashMap::<::std::string::String, $crate::glib::Variant>::default();
$(
$(
map.insert($token.into(), $value.into());
)*
)?
$crate::helper::format_stringd($format, &map)
}};
}
#[doc(inline)]
pub use helper_format_string as format_string;
use std::ffi::c_char;
use std::os::raw::c_void;
use std::{ops, slice};
#[doc(alias = "mirage_helper_format_stringd")]
pub fn format_stringd(
format: &str,
dictionary: &HashMap<String, glib::Variant>,
) -> Option<glib::GString> {
unsafe {
from_glib_full(ffi::mirage_helper_format_stringd(
format.to_glib_none().0,
StringVariantHashMap(dictionary).to_glib_none().0,
))
}
}
#[doc(alias = "mirage_helper_get_suffix")]
pub fn get_suffix(filename: &str) -> Option<glib::GString> {
assert_initialized_main_thread!();
unsafe { from_glib_none(ffi::mirage_helper_get_suffix(filename.to_glib_none().0)) }
}
#[doc(alias = "mirage_helper_has_suffix")]
pub fn has_suffix(filename: &str, suffix: &str) -> bool {
assert_initialized_main_thread!();
unsafe {
from_glib(ffi::mirage_helper_has_suffix(
filename.to_glib_none().0,
suffix.to_glib_none().0,
))
}
}
#[doc(alias = "mirage_helper_hex2bcd")]
pub fn hex2bcd(hex: i32) -> i32 {
assert_initialized_main_thread!();
unsafe { ffi::mirage_helper_hex2bcd(hex) }
}
#[doc(alias = "mirage_helper_init_crc16_lut")]
pub fn init_crc16_lut(genpoly: u16) -> Option<LookupTable<u16>> {
assert_initialized_main_thread!();
unsafe {
let ret = ffi::mirage_helper_init_crc16_lut(genpoly);
if ret.is_null() {
None
} else {
Some(LookupTable(ret, 256))
}
}
}
#[doc(alias = "mirage_helper_init_crc32_lut")]
pub fn init_crc32_lut(genpoly: u32, slices: u32) -> Option<LookupTable<u32>> {
assert_initialized_main_thread!();
unsafe {
let ret = ffi::mirage_helper_init_crc32_lut(genpoly, slices);
if ret.is_null() {
None
} else {
Some(LookupTable(ret, slices as usize * 256))
}
}
}
#[doc(alias = "mirage_helper_init_ecma_130b_scrambler_lut")]
pub fn init_ecma_130b_scrambler_lut() -> Option<LookupTable<u8>> {
assert_initialized_main_thread!();
unsafe {
let ret = ffi::mirage_helper_init_ecma_130b_scrambler_lut();
if ret.is_null() {
None
} else {
Some(LookupTable(ret, 2340))
}
}
}
#[derive(Debug)]
pub struct LookupTable<T>(*mut T, usize);
impl<T> Drop for LookupTable<T> {
fn drop(&mut self) {
unsafe { glib::ffi::g_free(self.0 as *mut c_void) };
}
}
impl<T> ops::Deref for LookupTable<T> {
type Target = [T];
fn deref(&self) -> &Self::Target {
unsafe { slice::from_raw_parts(self.0, self.1) }
}
}
impl<T> ops::DerefMut for LookupTable<T> {
fn deref_mut(&mut self) -> &mut Self::Target {
unsafe { slice::from_raw_parts_mut(self.0, self.1) }
}
}
#[doc(alias = "mirage_helper_isrc2ascii")]
pub fn isrc2ascii(c: u8) -> glib::Char {
assert_initialized_main_thread!();
unsafe { from_glib(ffi::mirage_helper_isrc2ascii(c)) }
}
#[doc(alias = "mirage_helper_lba2msf")]
pub fn lba2msf(lba: i32, diff: bool) -> (u8, u8, u8) {
assert_initialized_main_thread!();
unsafe {
let mut m = std::mem::MaybeUninit::uninit();
let mut s = std::mem::MaybeUninit::uninit();
let mut f = std::mem::MaybeUninit::uninit();
ffi::mirage_helper_lba2msf(
lba,
diff.into_glib(),
m.as_mut_ptr(),
s.as_mut_ptr(),
f.as_mut_ptr(),
);
(m.assume_init(), s.assume_init(), f.assume_init())
}
}
#[doc(alias = "mirage_helper_lba2msf_str")]
pub fn lba2msf_str(lba: i32, diff: bool) -> Option<glib::GString> {
assert_initialized_main_thread!();
unsafe { from_glib_full(ffi::mirage_helper_lba2msf_str(lba, diff.into_glib())) }
}
#[doc(alias = "mirage_helper_msf2lba")]
pub fn msf2lba(m: u8, s: u8, f: u8, diff: bool) -> i32 {
assert_initialized_main_thread!();
unsafe { ffi::mirage_helper_msf2lba(m, s, f, diff.into_glib()) }
}
#[doc(alias = "mirage_helper_msf2lba_str")]
pub fn msf2lba_str(msf: &str, diff: bool) -> i32 {
assert_initialized_main_thread!();
unsafe { ffi::mirage_helper_msf2lba_str(msf.to_glib_none().0, diff.into_glib()) }
}
#[doc(alias = "mirage_helper_sector_edc_ecc_compute_edc_block")]
pub fn sector_edc_ecc_compute_edc_block(src: &[u8], dest: &mut [u8; 4]) {
let size = u16::try_from(src.len()).expect("size should fit into a u16");
unsafe { ffi::mirage_helper_sector_edc_ecc_compute_edc_block(src.as_ptr(), size, dest) }
}
#[doc(alias = "mirage_helper_strcasecmp")]
pub fn strcasecmp(str1: &str, str2: &str) -> i32 {
assert_initialized_main_thread!();
unsafe { ffi::mirage_helper_strcasecmp(str1.to_glib_none().0, str2.to_glib_none().0) }
}
#[doc(alias = "mirage_helper_strncasecmp")]
pub fn strncasecmp(str1: &str, str2: &str) -> i32 {
assert_initialized_main_thread!();
let len = str2.len() as _;
unsafe { ffi::mirage_helper_strncasecmp(str1.to_glib_none().0, str2.to_glib_none().0, len) }
}
#[doc(alias = "mirage_helper_subchannel_deinterleave")]
pub fn subchannel_deinterleave(subchan: i32, channel96: &[u8; 96], channel12: &mut [u8; 12]) {
unsafe { ffi::mirage_helper_subchannel_deinterleave(subchan, channel96, channel12) }
}
#[doc(alias = "mirage_helper_subchannel_interleave")]
pub fn subchannel_interleave(subchan: i32, channel12: &[u8; 12], channel96: &mut [u8; 96]) {
unsafe { ffi::mirage_helper_subchannel_interleave(subchan, channel12, channel96) }
}
#[doc(alias = "mirage_helper_subchannel_q_calculate_crc")]
pub fn subchannel_q_calculate_crc(data: &[u8; 10]) -> u16 {
unsafe { ffi::mirage_helper_subchannel_q_calculate_crc(data) }
}
#[doc(alias = "mirage_helper_subchannel_q_decode_isrc")]
pub fn subchannel_q_decode_isrc(buf: &[u8; 8], isrc: &mut [c_char; 12]) {
unsafe { ffi::mirage_helper_subchannel_q_decode_isrc(buf, isrc) }
}
#[doc(alias = "mirage_helper_subchannel_q_decode_mcn")]
pub fn subchannel_q_decode_mcn(buf: &[u8; 7], mcn: &mut [c_char; 13]) {
unsafe { ffi::mirage_helper_subchannel_q_decode_mcn(buf, mcn) }
}
#[doc(alias = "mirage_helper_subchannel_q_encode_isrc")]
pub fn subchannel_q_encode_isrc(buf: &mut [u8; 8], isrc: &[c_char; 12]) {
unsafe { ffi::mirage_helper_subchannel_q_encode_isrc(buf, isrc) }
}
#[doc(alias = "mirage_helper_subchannel_q_encode_mcn")]
pub fn subchannel_q_encode_mcn(buf: &mut [u8; 7], mcn: &[c_char; 13]) {
unsafe { ffi::mirage_helper_subchannel_q_encode_mcn(buf, mcn) }
}
#[doc(alias = "mirage_helper_validate_isrc")]
pub fn validate_isrc(isrc: &[c_char; 12]) -> bool {
unsafe { from_glib(ffi::mirage_helper_validate_isrc(isrc)) }
}
#[cfg(test)]
mod tests {
use super::*;
#[test]
fn format_string_works() {
let result = format_string!(
"%b-%02s-track%t.%e",
"b" => "some_image",
"s" => 1i16,
"t" => 3i16,
"e" => "iso",
);
assert_eq!("some_image-01-track3.iso", result.unwrap());
}
}