Add utils for ptr->&str conversion

This commit is contained in:
FreezyLemon 2024-10-23 12:09:46 +02:00 committed by Josh Holmer
parent 814f8b9464
commit 251c09e732
24 changed files with 93 additions and 152 deletions

View File

@ -1,9 +1,6 @@
use std::ffi::CStr;
use std::str::from_utf8_unchecked;
use super::{Audio, Capabilities, Id, Profile, Video};
use crate::ffi::*;
use crate::{media, Error};
use crate::{media, utils, Error};
#[derive(PartialEq, Eq, Copy, Clone)]
pub struct Codec {
@ -37,18 +34,11 @@ impl Codec {
}
pub fn name(&self) -> &str {
unsafe { from_utf8_unchecked(CStr::from_ptr((*self.as_ptr()).name).to_bytes()) }
unsafe { utils::str_from_c_ptr((*self.as_ptr()).name) }
}
pub fn description(&self) -> &str {
unsafe {
let long_name = (*self.as_ptr()).long_name;
if long_name.is_null() {
""
} else {
from_utf8_unchecked(CStr::from_ptr(long_name).to_bytes())
}
}
unsafe { utils::optional_str_from_c_ptr((*self.as_ptr()).long_name).unwrap_or("") }
}
pub fn medium(&self) -> media::Type {

View File

@ -1,9 +1,7 @@
use std::ffi::CStr;
use std::str::from_utf8_unchecked;
use crate::ffi::AVCodecID::*;
use crate::ffi::*;
use crate::util::media;
use crate::utils;
#[cfg(feature = "serialize")]
use serde::{Deserialize, Serialize};
@ -661,7 +659,7 @@ impl Id {
}
pub fn name(&self) -> &'static str {
unsafe { from_utf8_unchecked(CStr::from_ptr(avcodec_get_name((*self).into())).to_bytes()) }
unsafe { utils::str_from_c_ptr(avcodec_get_name((*self).into())) }
}
}

View File

@ -48,19 +48,17 @@ pub mod decoder;
pub mod encoder;
pub mod traits;
use std::ffi::CStr;
use std::str::from_utf8_unchecked;
use crate::ffi::*;
use crate::utils;
pub fn version() -> u32 {
unsafe { avcodec_version() }
}
pub fn configuration() -> &'static str {
unsafe { from_utf8_unchecked(CStr::from_ptr(avcodec_configuration()).to_bytes()) }
unsafe { utils::str_from_c_ptr(avcodec_configuration()) }
}
pub fn license() -> &'static str {
unsafe { from_utf8_unchecked(CStr::from_ptr(avcodec_license()).to_bytes()) }
unsafe { utils::str_from_c_ptr(avcodec_license()) }
}

View File

@ -1,9 +1,8 @@
use std::ffi::CStr;
use std::marker::PhantomData;
use std::str::from_utf8_unchecked;
use super::{Flags, Type};
use crate::ffi::*;
use crate::utils;
#[cfg(not(feature = "ffmpeg_5_0"))]
use crate::{format, Picture};
@ -122,7 +121,7 @@ impl<'a> Text<'a> {
impl<'a> Text<'a> {
pub fn get(&self) -> &str {
unsafe { from_utf8_unchecked(CStr::from_ptr((*self.as_ptr()).text).to_bytes()) }
unsafe { utils::str_from_c_ptr((*self.as_ptr()).text) }
}
}
@ -147,6 +146,6 @@ impl<'a> Ass<'a> {
impl<'a> Ass<'a> {
pub fn get(&self) -> &str {
unsafe { from_utf8_unchecked(CStr::from_ptr((*self.as_ptr()).ass).to_bytes()) }
unsafe { utils::str_from_c_ptr((*self.as_ptr()).ass) }
}
}

View File

@ -2,11 +2,10 @@ pub mod extensions;
pub mod input;
pub mod output;
use std::ffi::CStr;
use std::marker::PhantomData;
use std::str::from_utf8_unchecked;
use crate::ffi::*;
use crate::utils;
pub struct Info<'a> {
ptr: *mut AVDeviceInfo,
@ -33,13 +32,11 @@ impl<'a> Info<'a> {
impl<'a> Info<'a> {
pub fn name(&self) -> &str {
unsafe { from_utf8_unchecked(CStr::from_ptr((*self.as_ptr()).device_name).to_bytes()) }
unsafe { utils::str_from_c_ptr((*self.as_ptr()).device_name) }
}
pub fn description(&self) -> &str {
unsafe {
from_utf8_unchecked(CStr::from_ptr((*self.as_ptr()).device_description).to_bytes())
}
unsafe { utils::str_from_c_ptr((*self.as_ptr()).device_description) }
}
}
@ -54,9 +51,9 @@ pub fn version() -> u32 {
}
pub fn configuration() -> &'static str {
unsafe { from_utf8_unchecked(CStr::from_ptr(avdevice_configuration()).to_bytes()) }
unsafe { utils::str_from_c_ptr(avdevice_configuration()) }
}
pub fn license() -> &'static str {
unsafe { from_utf8_unchecked(CStr::from_ptr(avdevice_license()).to_bytes()) }
unsafe { utils::str_from_c_ptr(avdevice_license()) }
}

View File

@ -1,9 +1,8 @@
use std::ffi::CStr;
use std::marker::PhantomData;
use std::str::from_utf8_unchecked;
use super::{Flags, Pad};
use crate::ffi::*;
use crate::utils;
pub struct Filter {
ptr: *mut AVFilter,
@ -25,19 +24,11 @@ impl Filter {
impl Filter {
pub fn name(&self) -> &str {
unsafe { from_utf8_unchecked(CStr::from_ptr((*self.as_ptr()).name).to_bytes()) }
unsafe { utils::str_from_c_ptr((*self.as_ptr()).name) }
}
pub fn description(&self) -> Option<&str> {
unsafe {
let ptr = (*self.as_ptr()).description;
if ptr.is_null() {
None
} else {
Some(from_utf8_unchecked(CStr::from_ptr(ptr).to_bytes()))
}
}
unsafe { utils::optional_str_from_c_ptr((*self.as_ptr()).description) }
}
pub fn inputs(&self) -> Option<PadIter> {

View File

@ -13,10 +13,10 @@ pub use self::context::{Context, Sink, Source};
pub mod graph;
pub use self::graph::Graph;
use std::ffi::{CStr, CString};
use std::str::from_utf8_unchecked;
use std::ffi::CString;
use crate::ffi::*;
use crate::utils;
#[cfg(not(feature = "ffmpeg_5_0"))]
use crate::Error;
@ -42,11 +42,11 @@ pub fn version() -> u32 {
}
pub fn configuration() -> &'static str {
unsafe { from_utf8_unchecked(CStr::from_ptr(avfilter_configuration()).to_bytes()) }
unsafe { utils::str_from_c_ptr(avfilter_configuration()) }
}
pub fn license() -> &'static str {
unsafe { from_utf8_unchecked(CStr::from_ptr(avfilter_license()).to_bytes()) }
unsafe { utils::str_from_c_ptr(avfilter_license()) }
}
pub fn find(name: &str) -> Option<Filter> {

View File

@ -1,9 +1,8 @@
use std::ffi::CStr;
use std::marker::PhantomData;
use std::str::from_utf8_unchecked;
use crate::ffi::*;
use crate::media;
use crate::utils;
pub struct Pad<'a> {
ptr: *const AVFilterPad,
@ -34,12 +33,7 @@ impl<'a> Pad<'a> {
pub fn name(&self) -> Option<&str> {
unsafe {
let ptr = avfilter_pad_get_name(self.ptr, self.idx as i32);
if ptr.is_null() {
None
} else {
Some(from_utf8_unchecked(CStr::from_ptr(ptr).to_bytes()))
}
utils::optional_str_from_c_ptr(ptr)
}
}

View File

@ -1,7 +1,5 @@
use std::ffi::CStr;
use std::str::from_utf8_unchecked;
use crate::ffi::*;
use crate::utils;
pub struct Input {
ptr: *mut AVInputFormat,
@ -23,19 +21,11 @@ impl Input {
impl Input {
pub fn name(&self) -> &str {
unsafe { from_utf8_unchecked(CStr::from_ptr((*self.as_ptr()).name).to_bytes()) }
unsafe { utils::str_from_c_ptr((*self.as_ptr()).name) }
}
pub fn description(&self) -> &str {
unsafe {
let long_name = (*self.as_ptr()).long_name;
if long_name.is_null() {
""
} else {
from_utf8_unchecked(CStr::from_ptr(long_name).to_bytes())
}
}
unsafe { utils::optional_str_from_c_ptr((*self.as_ptr()).long_name).unwrap_or("") }
}
pub fn extensions(&self) -> Vec<&str> {
@ -45,9 +35,7 @@ impl Input {
if ptr.is_null() {
Vec::new()
} else {
from_utf8_unchecked(CStr::from_ptr(ptr).to_bytes())
.split(',')
.collect()
utils::str_from_c_ptr(ptr).split(',').collect()
}
}
}
@ -59,9 +47,7 @@ impl Input {
if ptr.is_null() {
Vec::new()
} else {
from_utf8_unchecked(CStr::from_ptr(ptr).to_bytes())
.split(',')
.collect()
utils::str_from_c_ptr(ptr).split(',').collect()
}
}
}

View File

@ -1,12 +1,11 @@
use std::path::Path;
use std::ffi::{CStr, CString};
use std::ffi::CString;
use std::ptr;
use std::str::from_utf8_unchecked;
use super::Flags;
use crate::ffi::*;
use crate::{codec, media};
use crate::{codec, media, utils};
pub struct Output {
ptr: *mut AVOutputFormat,
@ -28,19 +27,11 @@ impl Output {
impl Output {
pub fn name(&self) -> &str {
unsafe { from_utf8_unchecked(CStr::from_ptr((*self.as_ptr()).name).to_bytes()) }
unsafe { utils::str_from_c_ptr((*self.as_ptr()).name) }
}
pub fn description(&self) -> &str {
unsafe {
let long_name = (*self.as_ptr()).long_name;
if long_name.is_null() {
""
} else {
from_utf8_unchecked(CStr::from_ptr(long_name).to_bytes())
}
}
unsafe { utils::optional_str_from_c_ptr((*self.as_ptr()).long_name).unwrap_or("") }
}
pub fn extensions(&self) -> Vec<&str> {
@ -50,9 +41,7 @@ impl Output {
if ptr.is_null() {
Vec::new()
} else {
from_utf8_unchecked(CStr::from_ptr(ptr).to_bytes())
.split(',')
.collect()
utils::str_from_c_ptr(ptr).split(',').collect()
}
}
}
@ -64,9 +53,7 @@ impl Output {
if ptr.is_null() {
Vec::new()
} else {
from_utf8_unchecked(CStr::from_ptr(ptr).to_bytes())
.split(',')
.collect()
utils::str_from_c_ptr(ptr).split(',').collect()
}
}
}

View File

@ -15,12 +15,12 @@ pub use self::format::{Input, Output};
pub mod network;
use std::ffi::{CStr, CString};
use std::ffi::CString;
use std::path::Path;
use std::ptr;
use std::str::from_utf8_unchecked;
use crate::ffi::*;
use crate::utils;
use crate::{Dictionary, Error};
#[cfg(not(feature = "ffmpeg_5_0"))]
@ -49,11 +49,11 @@ pub fn version() -> u32 {
}
pub fn configuration() -> &'static str {
unsafe { from_utf8_unchecked(CStr::from_ptr(avformat_configuration()).to_bytes()) }
unsafe { utils::str_from_c_ptr(avformat_configuration()) }
}
pub fn license() -> &'static str {
unsafe { from_utf8_unchecked(CStr::from_ptr(avformat_license()).to_bytes()) }
unsafe { utils::str_from_c_ptr(avformat_license()) }
}
// XXX: use to_cstring when stable

View File

@ -77,6 +77,8 @@ pub use crate::filter::Filter;
pub mod software;
pub(crate) mod utils;
fn init_error() {
util::error::register_all();
}

View File

@ -18,19 +18,17 @@ pub use self::context::Context;
mod extensions;
use std::ffi::CStr;
use std::str::from_utf8_unchecked;
use crate::ffi::*;
use crate::utils;
pub fn version() -> u32 {
unsafe { swresample_version() }
}
pub fn configuration() -> &'static str {
unsafe { from_utf8_unchecked(CStr::from_ptr(swresample_configuration()).to_bytes()) }
unsafe { utils::str_from_c_ptr(swresample_configuration()) }
}
pub fn license() -> &'static str {
unsafe { from_utf8_unchecked(CStr::from_ptr(swresample_license()).to_bytes()) }
unsafe { utils::str_from_c_ptr(swresample_license()) }
}

View File

@ -17,19 +17,17 @@ pub use self::context::Context;
mod extensions;
use std::ffi::CStr;
use std::str::from_utf8_unchecked;
use crate::ffi::*;
use crate::utils;
pub fn version() -> u32 {
unsafe { swscale_version() }
}
pub fn configuration() -> &'static str {
unsafe { from_utf8_unchecked(CStr::from_ptr(swscale_configuration()).to_bytes()) }
unsafe { utils::str_from_c_ptr(swscale_configuration()) }
}
pub fn license() -> &'static str {
unsafe { from_utf8_unchecked(CStr::from_ptr(swscale_license()).to_bytes()) }
unsafe { utils::str_from_c_ptr(swscale_license()) }
}

View File

@ -1,8 +1,6 @@
use std::ffi::CStr;
use std::str::from_utf8_unchecked;
use crate::ffi::AVColorPrimaries::*;
use crate::ffi::*;
use crate::utils;
#[cfg(feature = "serialize")]
use serde::{Deserialize, Serialize};
@ -40,8 +38,7 @@ impl Primaries {
}
unsafe {
let ptr = av_color_primaries_name((*self).into());
ptr.as_ref()
.map(|ptr| from_utf8_unchecked(CStr::from_ptr(ptr).to_bytes()))
utils::optional_str_from_c_ptr(ptr)
}
}
}

View File

@ -1,8 +1,6 @@
use std::ffi::CStr;
use std::str::from_utf8_unchecked;
use crate::ffi::AVColorRange::*;
use crate::ffi::*;
use crate::utils;
#[cfg(feature = "serialize")]
use serde::{Deserialize, Serialize};
@ -21,8 +19,7 @@ impl Range {
}
unsafe {
let ptr = av_color_range_name((*self).into());
ptr.as_ref()
.map(|ptr| from_utf8_unchecked(CStr::from_ptr(ptr).to_bytes()))
utils::optional_str_from_c_ptr(ptr)
}
}
}

View File

@ -1,8 +1,6 @@
use std::ffi::CStr;
use std::str::from_utf8_unchecked;
use crate::ffi::AVColorSpace::*;
use crate::ffi::*;
use crate::utils;
#[cfg(feature = "serialize")]
use serde::{Deserialize, Serialize};
@ -43,8 +41,7 @@ impl Space {
}
unsafe {
let ptr = av_color_space_name((*self).into());
ptr.as_ref()
.map(|ptr| from_utf8_unchecked(CStr::from_ptr(ptr).to_bytes()))
utils::optional_str_from_c_ptr(ptr)
}
}
}

View File

@ -1,8 +1,6 @@
use std::ffi::CStr;
use std::str::from_utf8_unchecked;
use crate::ffi::AVColorTransferCharacteristic::*;
use crate::ffi::*;
use crate::utils;
#[cfg(feature = "serialize")]
use serde::{Deserialize, Serialize};
@ -37,8 +35,7 @@ impl TransferCharacteristic {
}
unsafe {
let ptr = av_color_transfer_name((*self).into());
ptr.as_ref()
.map(|ptr| from_utf8_unchecked(CStr::from_ptr(ptr).to_bytes()))
utils::optional_str_from_c_ptr(ptr)
}
}
}

View File

@ -1,9 +1,9 @@
use std::ffi::{CStr, CString};
use std::ffi::CString;
use std::marker::PhantomData;
use std::ptr;
use std::str::from_utf8_unchecked;
use crate::ffi::*;
use crate::utils;
pub struct Iter<'a> {
ptr: *const AVDictionary,
@ -32,8 +32,8 @@ impl<'a> Iterator for Iter<'a> {
let entry = av_dict_get(self.ptr, empty.as_ptr(), self.cur, AV_DICT_IGNORE_SUFFIX);
if !entry.is_null() {
let key = from_utf8_unchecked(CStr::from_ptr((*entry).key).to_bytes());
let val = from_utf8_unchecked(CStr::from_ptr((*entry).value).to_bytes());
let key = utils::str_from_c_ptr((*entry).key);
let val = utils::str_from_c_ptr((*entry).value);
self.cur = entry;

View File

@ -1,10 +1,11 @@
use std::error;
use std::ffi::{CStr, CString, NulError};
use std::ffi::{CString, NulError};
use std::fmt;
use std::str::{from_utf8_unchecked, FromStr};
use std::str::FromStr;
use crate::ffi::AVPixelFormat::*;
use crate::ffi::*;
use crate::utils;
#[cfg(feature = "serialize")]
use serde::{Deserialize, Serialize};
@ -448,7 +449,7 @@ impl Descriptor {
}
pub fn name(self) -> &'static str {
unsafe { from_utf8_unchecked(CStr::from_ptr((*self.as_ptr()).name).to_bytes()) }
unsafe { utils::str_from_c_ptr((*self.as_ptr()).name) }
}
pub fn nb_components(self) -> u8 {

View File

@ -1,11 +1,11 @@
use std::ffi::{CStr, CString};
use std::ffi::CString;
use std::ops::Index;
use std::ptr;
use std::slice;
use std::str::from_utf8_unchecked;
use crate::ffi::AVSampleFormat::*;
use crate::ffi::*;
use crate::utils;
use libc::{c_int, c_void};
#[cfg(feature = "serialize")]
use serde::{Deserialize, Serialize};
@ -33,9 +33,7 @@ pub enum Type {
impl Sample {
#[inline]
pub fn name(&self) -> &'static str {
unsafe {
from_utf8_unchecked(CStr::from_ptr(av_get_sample_fmt_name((*self).into())).to_bytes())
}
unsafe { utils::str_from_c_ptr(av_get_sample_fmt_name((*self).into())) }
}
#[inline]

View File

@ -1,11 +1,10 @@
use std::ffi::CStr;
use std::marker::PhantomData;
use std::slice;
use std::str::from_utf8_unchecked;
use super::Frame;
use crate::ffi::AVFrameSideDataType::*;
use crate::ffi::*;
use crate::utils;
use crate::DictionaryRef;
#[cfg(feature = "serialize")]
use serde::{Deserialize, Serialize};
@ -74,9 +73,7 @@ pub enum Type {
impl Type {
#[inline]
pub fn name(&self) -> &'static str {
unsafe {
from_utf8_unchecked(CStr::from_ptr(av_frame_side_data_name((*self).into())).to_bytes())
}
unsafe { utils::str_from_c_ptr(av_frame_side_data_name((*self).into())) }
}
}

View File

@ -16,10 +16,8 @@ pub mod range;
pub mod rational;
pub mod time;
use std::ffi::CStr;
use std::str::from_utf8_unchecked;
use crate::ffi::*;
use crate::utils;
#[inline(always)]
pub fn version() -> u32 {
@ -28,10 +26,10 @@ pub fn version() -> u32 {
#[inline(always)]
pub fn configuration() -> &'static str {
unsafe { from_utf8_unchecked(CStr::from_ptr(avutil_configuration()).to_bytes()) }
unsafe { utils::str_from_c_ptr(avutil_configuration()) }
}
#[inline(always)]
pub fn license() -> &'static str {
unsafe { from_utf8_unchecked(CStr::from_ptr(avutil_license()).to_bytes()) }
unsafe { utils::str_from_c_ptr(avutil_license()) }
}

21
src/utils.rs Normal file
View File

@ -0,0 +1,21 @@
//! Internal utils, not related to `avutil`
use std::ffi::CStr;
/// `ptr` must be non-null and valid.
/// Ensure that the returned lifetime is correctly bounded.
#[inline]
pub unsafe fn str_from_c_ptr<'s>(ptr: *const libc::c_char) -> &'s str {
unsafe { std::str::from_utf8_unchecked(CStr::from_ptr(ptr).to_bytes()) }
}
/// `ptr` must be null or valid.
/// Ensure that the returned lifetime is correctly bounded.
#[inline]
pub unsafe fn optional_str_from_c_ptr<'s>(ptr: *const libc::c_char) -> Option<&'s str> {
if ptr.is_null() {
None
} else {
Some(str_from_c_ptr(ptr))
}
}