Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 2 additions & 2 deletions lofty/src/file/file_type.rs
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
use crate::config::global_options;
use crate::resolve::custom_resolvers;
use crate::resolve::CUSTOM_RESOLVERS;
use crate::tag::{TagSupport, TagType};

use std::ffi::OsStr;
Expand Down Expand Up @@ -189,7 +189,7 @@ impl FileType {

// Give custom resolvers priority
if unsafe { global_options().use_custom_resolvers } {
if let Some((ty, _)) = custom_resolvers()
if let Some((ty, _)) = CUSTOM_RESOLVERS
.lock()
.ok()?
.iter()
Expand Down
40 changes: 17 additions & 23 deletions lofty/src/id3/v2/util/upgrade.rs
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,7 @@ use std::collections::HashMap;
/// assert_eq!(new_title, Some("TIT2"));
/// ```
pub fn upgrade_v2(key: &str) -> Option<&'static str> {
v2keys().get(key).copied()
V2_KEYS.get(key).copied()
}

/// Upgrade an ID3v2.3 key to an ID3v2.4 key
Expand All @@ -31,38 +31,32 @@ pub fn upgrade_v2(key: &str) -> Option<&'static str> {
/// assert_eq!(new_involved_people_list, Some("TIPL"));
/// ```
pub fn upgrade_v3(key: &str) -> Option<&'static str> {
v3keys().get(key).copied()
V3_KEYS.get(key).copied()
}

macro_rules! gen_upgrades {
(V2 => [$($($v2_key:literal)|* => $id3v24_from_v2:literal),+]; V3 => [$($($v3_key:literal)|* => $id3v24_from_v3:literal),+]) => {
use std::sync::OnceLock;
use std::sync::LazyLock;

fn v2keys() -> &'static HashMap<&'static str, &'static str> {
static INSTANCE: OnceLock<HashMap<&'static str, &'static str>> = OnceLock::new();
INSTANCE.get_or_init(|| {
let mut map = HashMap::new();
static V2_KEYS: LazyLock<HashMap<&'static str, &'static str>> = LazyLock::new(|| {
let mut map = HashMap::new();
$(
$(
$(
map.insert($v2_key, $id3v24_from_v2);
)+
map.insert($v2_key, $id3v24_from_v2);
)+
map
})
}
)+
map
});

fn v3keys() -> &'static HashMap<&'static str, &'static str> {
static INSTANCE: OnceLock<HashMap<&'static str, &'static str>> = OnceLock::new();
INSTANCE.get_or_init(|| {
let mut map = HashMap::new();
static V3_KEYS: LazyLock<HashMap<&'static str, &'static str>> = LazyLock::new(|| {
let mut map = HashMap::new();
$(
$(
$(
map.insert($v3_key, $id3v24_from_v3);
)+
map.insert($v3_key, $id3v24_from_v3);
)+
map
})
}
)+
map
});
};
}

Expand Down
29 changes: 13 additions & 16 deletions lofty/src/id3/v2/write/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -15,26 +15,23 @@ use crate::util::io::{FileLike, Length, Truncate};

use std::io::{Cursor, Read, Seek, SeekFrom, Write};
use std::ops::Not;
use std::sync::OnceLock;
use std::sync::LazyLock;

use byteorder::{BigEndian, LittleEndian, WriteBytesExt};

// In the very rare chance someone wants to write a CRC in their extended header
fn crc_32_table() -> &'static [u32; 256] {
static INSTANCE: OnceLock<[u32; 256]> = OnceLock::new();
INSTANCE.get_or_init(|| {
let mut crc32_table = [0; 256];

for n in 0..256 {
crc32_table[n as usize] = (0..8).fold(n as u32, |acc, _| match acc & 1 {
1 => 0xEDB8_8320 ^ (acc >> 1),
_ => acc >> 1,
});
}
static CRC32_TABLE: LazyLock<[u32; 256]> = LazyLock::new(|| {
let mut crc32_table = [0; 256];

for n in 0..256 {
crc32_table[n as usize] = (0..8).fold(n as u32, |acc, _| match acc & 1 {
1 => 0xEDB8_8320 ^ (acc >> 1),
_ => acc >> 1,
});
}

crc32_table
})
}
crc32_table
});

#[allow(clippy::shadow_unrelated)]
pub(crate) fn write_id3v2<'a, F, I>(
Expand Down Expand Up @@ -270,7 +267,7 @@ fn calculate_crc(content: &[u8]) -> [u8; 5] {
let crc: u32 = content
.iter()
.fold(!0, |crc, octet| {
(crc >> 8) ^ crc_32_table()[(((crc & 0xFF) ^ u32::from(*octet)) & 0xFF) as usize]
(crc >> 8) ^ CRC32_TABLE[(((crc & 0xFF) ^ u32::from(*octet)) & 0xFF) as usize]
})
.not();

Expand Down
4 changes: 2 additions & 2 deletions lofty/src/probe.rs
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,7 @@ use crate::musepack::MpcFile;
use crate::ogg::opus::OpusFile;
use crate::ogg::speex::SpeexFile;
use crate::ogg::vorbis::VorbisFile;
use crate::resolve::custom_resolvers;
use crate::resolve::CUSTOM_RESOLVERS;
use crate::wavpack::WavPackFile;

use crate::io::FileLike;
Expand Down Expand Up @@ -336,7 +336,7 @@ impl<R: Read + Seek> Probe<R> {

// Give custom resolvers priority
if unsafe { global_options().use_custom_resolvers } {
if let Ok(lock) = custom_resolvers().lock() {
if let Ok(lock) = CUSTOM_RESOLVERS.lock() {
#[allow(clippy::significant_drop_in_scrutinee)]
for (_, resolve) in lock.iter() {
if let ret @ Some(_) = resolve.guess(&buf[..buf_len]) {
Expand Down
12 changes: 5 additions & 7 deletions lofty/src/resolve.rs
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@ use crate::tag::{TagSupport, TagType};
use std::collections::HashMap;
use std::io::{Read, Seek};
use std::marker::PhantomData;
use std::sync::{Arc, Mutex, OnceLock};
use std::sync::{Arc, LazyLock, Mutex};

/// A custom file resolver
///
Expand All @@ -35,13 +35,11 @@ pub trait FileResolver: Send + Sync + AudioFile {
// Just broken out to its own type to make `CUSTOM_RESOLVER`'s type shorter :)
type ResolverMap = HashMap<&'static str, &'static dyn ObjectSafeFileResolver>;

pub(crate) fn custom_resolvers() -> &'static Arc<Mutex<ResolverMap>> {
static INSTANCE: OnceLock<Arc<Mutex<ResolverMap>>> = OnceLock::new();
INSTANCE.get_or_init(Default::default)
}
pub(crate) static CUSTOM_RESOLVERS: LazyLock<Arc<Mutex<ResolverMap>>> =
LazyLock::new(Default::default);

pub(crate) fn lookup_resolver(name: &'static str) -> &'static dyn ObjectSafeFileResolver {
let res = custom_resolvers().lock().unwrap();
let res = CUSTOM_RESOLVERS.lock().unwrap();

if let Some(resolver) = res.get(name).copied() {
return resolver;
Expand Down Expand Up @@ -114,7 +112,7 @@ impl<T: FileResolver> ObjectSafeFileResolver for GhostlyResolver<T> {
/// * Attempting to register an existing name or type
/// * See [`Mutex::lock`]
pub fn register_custom_resolver<T: FileResolver + 'static>(name: &'static str) {
let mut res = custom_resolvers().lock().unwrap();
let mut res = CUSTOM_RESOLVERS.lock().unwrap();
assert!(
res.iter().all(|(n, _)| *n != name),
"Resolver `{}` already exists!",
Expand Down
6 changes: 3 additions & 3 deletions lofty/src/tag/item.rs
Original file line number Diff line number Diff line change
Expand Up @@ -52,8 +52,7 @@ macro_rules! gen_map {
$(#[$meta])?
impl $NAME {
pub(crate) fn get_item_key(&self, key: &str) -> Option<ItemKey> {
static INSTANCE: std::sync::OnceLock<HashMap<&'static str, &'static [ItemKey]>> = std::sync::OnceLock::new();
INSTANCE.get_or_init(|| {
static INSTANCE: std::sync::LazyLock<HashMap<&'static str, &'static [ItemKey]>> = std::sync::LazyLock::new(|| {
let mut map = HashMap::new();
$(
let values: &'static [ItemKey] = &[$(ItemKey::$variant,)+];
Expand All @@ -62,7 +61,8 @@ macro_rules! gen_map {
)+
)+
map
}).iter().find(|(k, _)| k.eq_ignore_ascii_case(key)).map(|(_, v)| v[0])
});
INSTANCE.iter().find(|(k, _)| k.eq_ignore_ascii_case(key)).map(|(_, v)| v[0])
}

pub(crate) fn get_key(&self, item_key: ItemKey) -> Option<&'static str> {
Expand Down