msuikr: split up shims

This commit is contained in:
Alexander Capehart 2025-02-08 16:16:03 -07:00
parent cd102369a0
commit cf597cb98e
No known key found for this signature in database
GPG key ID: 37DBE3621FE9AD47
12 changed files with 201 additions and 152 deletions

View file

@ -109,6 +109,9 @@ fn main() {
// Build the shim and cxx bridge together
cxx_build::bridge("src/taglib/ffi.rs")
.file("shim/iostream_shim.cpp")
.file("shim/file_shim.cpp")
.file("shim/string_shim.cpp")
.file("shim/audioproperties_shim.cpp")
.include(format!("taglib/pkg/{}/include", arch))
.include("shim")
.include(".") // Add the current directory to include path
@ -119,5 +122,11 @@ fn main() {
// Rebuild if shim files change
println!("cargo:rerun-if-changed=shim/iostream_shim.hpp");
println!("cargo:rerun-if-changed=shim/iostream_shim.cpp");
println!("cargo:rerun-if-changed=shim/file_shim.hpp");
println!("cargo:rerun-if-changed=shim/file_shim.cpp");
println!("cargo:rerun-if-changed=shim/string_shim.hpp");
println!("cargo:rerun-if-changed=shim/string_shim.cpp");
println!("cargo:rerun-if-changed=shim/audioproperties_shim.hpp");
println!("cargo:rerun-if-changed=shim/audioproperties_shim.cpp");
println!("cargo:rerun-if-changed=src/taglib/ffi.rs");
}

View file

@ -0,0 +1,26 @@
#include "audioproperties_shim.hpp"
#include <taglib/tfile.h>
namespace taglib_shim {
const TagLib::AudioProperties* File_audioProperties(const TagLib::File& file) {
return file.audioProperties();
}
int AudioProperties_lengthInMilliseconds(const TagLib::AudioProperties* properties) {
return properties->lengthInMilliseconds();
}
int AudioProperties_bitrateInKilobitsPerSecond(const TagLib::AudioProperties* properties) {
return properties->bitrate();
}
int AudioProperties_sampleRateInHz(const TagLib::AudioProperties* properties) {
return properties->sampleRate();
}
int AudioProperties_numberOfChannels(const TagLib::AudioProperties* properties) {
return properties->channels();
}
} // namespace taglib_shim

View file

@ -0,0 +1,15 @@
#pragma once
#include <taglib/audioproperties.h>
#include <taglib/tfile.h>
namespace taglib_shim {
// Audio Properties methods
const TagLib::AudioProperties* File_audioProperties(const TagLib::File& file);
int AudioProperties_lengthInMilliseconds(const TagLib::AudioProperties* properties);
int AudioProperties_bitrateInKilobitsPerSecond(const TagLib::AudioProperties* properties);
int AudioProperties_sampleRateInHz(const TagLib::AudioProperties* properties);
int AudioProperties_numberOfChannels(const TagLib::AudioProperties* properties);
} // namespace taglib_shim

View file

@ -0,0 +1,66 @@
#include "file_shim.hpp"
namespace taglib_shim {
// FileRef helper functions
bool FileRef_isNull(const TagLib::FileRef& ref) {
return ref.isNull();
}
const TagLib::File& FileRef_file(const TagLib::FileRef& ref) {
return *ref.file();
}
// File tag methods
bool File_tag(const TagLib::File& file) {
return file.tag() != nullptr;
}
namespace {
// Keep the empty string as a static member to ensure it lives long enough
const TagLib::String empty_string;
}
const TagLib::String& File_tag_title(const TagLib::File& file) {
if (auto* tag = file.tag()) {
static TagLib::String title;
title = tag->title();
return title;
}
return empty_string;
}
// File type checking functions
bool File_isMPEG(const TagLib::File& file) {
return dynamic_cast<const TagLib::MPEG::File*>(&file) != nullptr;
}
bool File_isFLAC(const TagLib::File& file) {
return dynamic_cast<const TagLib::FLAC::File*>(&file) != nullptr;
}
bool File_isMP4(const TagLib::File& file) {
return dynamic_cast<const TagLib::MP4::File*>(&file) != nullptr;
}
bool File_isOgg(const TagLib::File& file) {
return dynamic_cast<const TagLib::Ogg::File*>(&file) != nullptr;
}
bool File_isOpus(const TagLib::File& file) {
return dynamic_cast<const TagLib::Ogg::Opus::File*>(&file) != nullptr;
}
bool File_isWAV(const TagLib::File& file) {
return dynamic_cast<const TagLib::RIFF::WAV::File*>(&file) != nullptr;
}
bool File_isWavPack(const TagLib::File& file) {
return dynamic_cast<const TagLib::WavPack::File*>(&file) != nullptr;
}
bool File_isAPE(const TagLib::File& file) {
return dynamic_cast<const TagLib::APE::File*>(&file) != nullptr;
}
} // namespace taglib_shim

View file

@ -0,0 +1,43 @@
#pragma once
#include <taglib/fileref.h>
#include <taglib/tag.h>
#include <taglib/tstring.h>
#include <taglib/audioproperties.h>
#include <taglib/mpegfile.h>
#include <taglib/flacfile.h>
#include <taglib/mp4file.h>
#include <taglib/oggfile.h>
#include <taglib/opusfile.h>
#include <taglib/wavfile.h>
#include <taglib/wavpackfile.h>
#include <taglib/apefile.h>
namespace taglib_shim {
// FileRef helper functions
bool FileRef_isNull(const TagLib::FileRef& ref);
const TagLib::File& FileRef_file(const TagLib::FileRef& ref);
// File tag methods
bool File_tag(const TagLib::File& file);
const TagLib::String& File_tag_title(const TagLib::File& file);
// File type checking functions
bool File_isMPEG(const TagLib::File& file);
bool File_isFLAC(const TagLib::File& file);
bool File_isMP4(const TagLib::File& file);
bool File_isOgg(const TagLib::File& file);
bool File_isOpus(const TagLib::File& file);
bool File_isWAV(const TagLib::File& file);
bool File_isWavPack(const TagLib::File& file);
bool File_isAPE(const TagLib::File& file);
// Audio Properties methods
const TagLib::AudioProperties* File_audioProperties(const TagLib::File& file);
int AudioProperties_length(const TagLib::AudioProperties* properties);
int AudioProperties_bitrate(const TagLib::AudioProperties* properties);
int AudioProperties_sampleRate(const TagLib::AudioProperties* properties);
int AudioProperties_channels(const TagLib::AudioProperties* properties);
} // namespace taglib_shim

View file

@ -1,6 +1,7 @@
#include "iostream_shim.hpp"
#include <stdexcept>
#include <rust/cxx.h>
#include <vector>
// These are the functions we'll define in Rust
extern "C" {
@ -26,64 +27,6 @@ std::unique_ptr<TagLib::FileRef> new_FileRef_from_stream(std::unique_ptr<RustIOS
return std::make_unique<TagLib::FileRef>(stream.release(), true);
}
// FileRef helper functions
bool FileRef_isNull(const TagLib::FileRef& ref) {
return ref.isNull();
}
const TagLib::File& FileRef_file(const TagLib::FileRef& ref) {
return *ref.file();
}
// File tag methods
bool File_tag(const TagLib::File& file) {
return file.tag() != nullptr;
}
namespace {
// Keep the empty string as a static member to ensure it lives long enough
const TagLib::String empty_string;
}
const TagLib::String& File_tag_title(const TagLib::File& file) {
if (auto* tag = file.tag()) {
static TagLib::String title;
title = tag->title();
return title;
}
return empty_string;
}
// Audio Properties methods
const TagLib::AudioProperties* File_audioProperties(const TagLib::File& file) {
return file.audioProperties();
}
int AudioProperties_length(const TagLib::AudioProperties* properties) {
return properties->length();
}
int AudioProperties_bitrate(const TagLib::AudioProperties* properties) {
return properties->bitrate();
}
int AudioProperties_sampleRate(const TagLib::AudioProperties* properties) {
return properties->sampleRate();
}
int AudioProperties_channels(const TagLib::AudioProperties* properties) {
return properties->channels();
}
// String utilities
const char* to_string(const TagLib::String& str) {
return str.toCString(true);
}
bool isEmpty(const TagLib::String& str) {
return str.isEmpty();
}
RustIOStream::RustIOStream(RustStream* stream) : rust_stream(stream) {}
RustIOStream::~RustIOStream() = default;

View file

@ -4,18 +4,6 @@
#include <string>
#include <taglib/tiostream.h>
#include <taglib/fileref.h>
#include <taglib/tag.h>
#include <taglib/tstring.h>
#include <taglib/audioproperties.h>
#include <cstdint>
#include <taglib/mpegfile.h>
#include <taglib/flacfile.h>
#include <taglib/mp4file.h>
#include <taglib/oggfile.h>
#include <taglib/opusfile.h>
#include <taglib/wavfile.h>
#include <taglib/wavpackfile.h>
#include <taglib/apefile.h>
namespace taglib_shim {
@ -50,56 +38,4 @@ private:
std::unique_ptr<RustIOStream> new_rust_iostream(RustStream* stream);
std::unique_ptr<TagLib::FileRef> new_FileRef_from_stream(std::unique_ptr<RustIOStream> stream);
// FileRef helper functions
bool FileRef_isNull(const TagLib::FileRef& ref);
const TagLib::File& FileRef_file(const TagLib::FileRef& ref);
// File tag methods
bool File_tag(const TagLib::File& file);
const TagLib::String& File_tag_title(const TagLib::File& file);
// File type checking functions
bool File_isMPEG(const TagLib::File& file) {
return dynamic_cast<const TagLib::MPEG::File*>(&file) != nullptr;
}
bool File_isFLAC(const TagLib::File& file) {
return dynamic_cast<const TagLib::FLAC::File*>(&file) != nullptr;
}
bool File_isMP4(const TagLib::File& file) {
return dynamic_cast<const TagLib::MP4::File*>(&file) != nullptr;
}
bool File_isOgg(const TagLib::File& file) {
return dynamic_cast<const TagLib::Ogg::File*>(&file) != nullptr;
}
bool File_isOpus(const TagLib::File& file) {
return dynamic_cast<const TagLib::Ogg::Opus::File*>(&file) != nullptr;
}
bool File_isWAV(const TagLib::File& file) {
return dynamic_cast<const TagLib::RIFF::WAV::File*>(&file) != nullptr;
}
bool File_isWavPack(const TagLib::File& file) {
return dynamic_cast<const TagLib::WavPack::File*>(&file) != nullptr;
}
bool File_isAPE(const TagLib::File& file) {
return dynamic_cast<const TagLib::APE::File*>(&file) != nullptr;
}
// Audio Properties methods
const TagLib::AudioProperties* File_audioProperties(const TagLib::File& file);
int AudioProperties_length(const TagLib::AudioProperties* properties);
int AudioProperties_bitrate(const TagLib::AudioProperties* properties);
int AudioProperties_sampleRate(const TagLib::AudioProperties* properties);
int AudioProperties_channels(const TagLib::AudioProperties* properties);
// String utilities
const char* to_string(const TagLib::String& str);
bool isEmpty(const TagLib::String& str);
}
} // namespace taglib_shim

View file

@ -0,0 +1,13 @@
#include "string_shim.hpp"
namespace taglib_shim {
const char* to_string(const TagLib::String& str) {
return str.toCString(true);
}
bool isEmpty(const TagLib::String& str) {
return str.isEmpty();
}
} // namespace taglib_shim

View file

@ -0,0 +1,11 @@
#pragma once
#include <taglib/tstring.h>
namespace taglib_shim {
// String utilities
const char* to_string(const TagLib::String& str);
bool isEmpty(const TagLib::String& str);
} // namespace taglib_shim

View file

@ -34,11 +34,7 @@ pub extern "C" fn Java_org_oxycblt_musikr_metadata_MetadataJNI_openFile<'local>(
}
};
// Get the file and read the title
let file = file_ref.file();
let title = file.title().unwrap_or("No title");
// Return the title
let output = env.new_string(title).expect("Couldn't create string!");
let output = env.new_string("title").expect("Couldn't create string!");
output.into_raw()
}

View file

@ -4,6 +4,9 @@ pub(crate) mod bindings {
include!("taglib/taglib.h");
include!("taglib/tstring.h");
include!("shim/iostream_shim.hpp");
include!("shim/file_shim.hpp");
include!("shim/string_shim.hpp");
include!("shim/audioproperties_shim.hpp");
#[namespace = "TagLib"]
type FileRef;
@ -58,13 +61,13 @@ pub(crate) mod bindings {
#[namespace = "taglib_shim"]
unsafe fn File_audioProperties(file: &File) -> *const AudioProperties;
#[namespace = "taglib_shim"]
unsafe fn AudioProperties_length(properties: *const AudioProperties) -> i32;
unsafe fn AudioProperties_lengthInMilliseconds(properties: *const AudioProperties) -> i32;
#[namespace = "taglib_shim"]
unsafe fn AudioProperties_bitrate(properties: *const AudioProperties) -> i32;
unsafe fn AudioProperties_bitrateInKilobitsPerSecond(properties: *const AudioProperties) -> i32;
#[namespace = "taglib_shim"]
unsafe fn AudioProperties_sampleRate(properties: *const AudioProperties) -> i32;
unsafe fn AudioProperties_sampleRateInHz(properties: *const AudioProperties) -> i32;
#[namespace = "taglib_shim"]
unsafe fn AudioProperties_channels(properties: *const AudioProperties) -> i32;
unsafe fn AudioProperties_numberOfChannels(properties: *const AudioProperties) -> i32;
// String conversion utilities
#[namespace = "taglib_shim"]
@ -73,15 +76,3 @@ pub(crate) mod bindings {
fn isEmpty(s: &TagString) -> bool;
}
}
extern "C" {
// File type checking functions
pub fn File_isMPEG(file: *const bindings::File) -> bool;
pub fn File_isFLAC(file: *const bindings::File) -> bool;
pub fn File_isMP4(file: *const bindings::File) -> bool;
pub fn File_isOgg(file: *const bindings::File) -> bool;
pub fn File_isOpus(file: *const bindings::File) -> bool;
pub fn File_isWAV(file: *const bindings::File) -> bool;
pub fn File_isWavPack(file: *const bindings::File) -> bool;
pub fn File_isAPE(file: *const bindings::File) -> bool;
}

View file

@ -7,10 +7,10 @@ use ffi::bindings;
/// Audio properties of a media file
#[derive(Default)]
pub struct AudioProperties {
pub length: i32,
pub bitrate: i32,
pub sample_rate: i32,
pub channels: i32,
pub length_in_milliseconds: i32,
pub bitrate_in_kilobits_per_second: i32,
pub sample_rate_in_hz: i32,
pub number_of_channels: i32,
}
pub enum File {
@ -139,10 +139,10 @@ impl FileRef {
let props_ptr = ffi::bindings::File_audioProperties(file_ptr);
if !props_ptr.is_null() {
Some(AudioProperties {
length: ffi::bindings::AudioProperties_length(props_ptr),
bitrate: ffi::bindings::AudioProperties_bitrate(props_ptr),
sample_rate: ffi::bindings::AudioProperties_sampleRate(props_ptr),
channels: ffi::bindings::AudioProperties_channels(props_ptr),
length_in_milliseconds: ffi::bindings::AudioProperties_lengthInMilliseconds(props_ptr),
bitrate_in_kilobits_per_second: ffi::bindings::AudioProperties_bitrateInKilobitsPerSecond(props_ptr),
sample_rate_in_hz: ffi::bindings::AudioProperties_sampleRateInHz(props_ptr),
number_of_channels: ffi::bindings::AudioProperties_numberOfChannels(props_ptr),
})
} else {
None