{-# LANGUAGE ForeignFunctionInterface #-}
module Foreign.Libcdio.CdText
(
Cdio
, Field ( .. )
, Genre ( .. )
, Language ( .. )
, fieldString
, languageString
, parseLanguage
, genreString
, cdTextDataInit
, listLanguages
, listAllLanguages
, selectLanguage
, selectLanguageIndex
, cdTextGet
, genre
, language
, firstTrack
, lastTrack
) where
import qualified Data.List as L
import qualified Data.Maybe as Y
import qualified Foreign.C.String as C
import qualified Foreign.C.Types as C
import qualified Foreign.Ptr as C
import qualified Foreign.Marshal.Array as M
import qualified Foreign.Marshal.Utils as M
import qualified System.IO.Unsafe as IO.Unsafe
import Foreign.Libcdio.Device
import Foreign.Libcdio.Marshal
import Foreign.Libcdio.Track
import Foreign.Libcdio.Types.Enums
import Foreign.Libcdio.Types.Internal
import Foreign.Libcdio.Version
import Sound.Libcdio.Common
genreString :: Genre -> String
genreString :: Genre -> String
genreString = IO String -> String
forall a. IO a -> a
IO.Unsafe.unsafePerformIO (IO String -> String) -> (Genre -> IO String) -> Genre -> String
forall b c a. (b -> c) -> (a -> b) -> a -> c
.
CString -> IO String
C.peekCString (CString -> IO String) -> (Genre -> CString) -> Genre -> IO String
forall b c a. (b -> c) -> (a -> b) -> a -> c
. CGenre -> CString
genreString' (CGenre -> CString) -> (Genre -> CGenre) -> Genre -> CString
forall b c a. (b -> c) -> (a -> b) -> a -> c
. Int -> CGenre
forall a b. (Integral a, Num b) => a -> b
fromIntegral (Int -> CGenre) -> (Genre -> Int) -> Genre -> CGenre
forall b c a. (b -> c) -> (a -> b) -> a -> c
. Genre -> Int
forall a. Enum a => a -> Int
fromEnum
foreign import ccall safe "cdio/compat/cdtext.h cdtext_genre2str"
genreString' :: CGenre -> C.CString
languageString :: Language -> String
languageString :: Language -> String
languageString = IO String -> String
forall a. IO a -> a
IO.Unsafe.unsafePerformIO (IO String -> String)
-> (Language -> IO String) -> Language -> String
forall b c a. (b -> c) -> (a -> b) -> a -> c
.
CString -> IO String
C.peekCString (CString -> IO String)
-> (Language -> CString) -> Language -> IO String
forall b c a. (b -> c) -> (a -> b) -> a -> c
. CGenre -> CString
languageString' (CGenre -> CString) -> (Language -> CGenre) -> Language -> CString
forall b c a. (b -> c) -> (a -> b) -> a -> c
. Int -> CGenre
forall a b. (Integral a, Num b) => a -> b
fromIntegral (Int -> CGenre) -> (Language -> Int) -> Language -> CGenre
forall b c a. (b -> c) -> (a -> b) -> a -> c
. Language -> Int
forall a. Enum a => a -> Int
fromEnum
foreign import ccall safe "cdio/compat/cdtext.h cdtext_lang2str"
languageString' :: CLanguage -> C.CString
parseLanguage :: String -> Maybe Language
parseLanguage :: String -> Maybe Language
parseLanguage String
s
| Version
libcdioVersionNum Version -> Version -> Bool
forall a. Ord a => a -> a -> Bool
>= [Int] -> Version
makeVersion [Int
2,Int
1] = IO (Maybe Language) -> Maybe Language
forall a. IO a -> a
IO.Unsafe.unsafePerformIO (IO (Maybe Language) -> Maybe Language)
-> IO (Maybe Language) -> Maybe Language
forall a b. (a -> b) -> a -> b
$ do
CGenre
i <- String -> (CString -> IO CGenre) -> IO CGenre
forall a. String -> (CString -> IO a) -> IO a
C.withCString String
s CString -> IO CGenre
parseLanguage'
Maybe Language -> IO (Maybe Language)
forall (m :: * -> *) a. Monad m => a -> m a
return (Maybe Language -> IO (Maybe Language))
-> (Maybe CGenre -> Maybe Language)
-> Maybe CGenre
-> IO (Maybe Language)
forall b c a. (b -> c) -> (a -> b) -> a -> c
. (CGenre -> Language) -> Maybe CGenre -> Maybe Language
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
fmap (Int -> Language
forall a. Enum a => Int -> a
toEnum (Int -> Language) -> (CGenre -> Int) -> CGenre -> Language
forall b c a. (b -> c) -> (a -> b) -> a -> c
. CGenre -> Int
forall a b. (Integral a, Num b) => a -> b
fromIntegral) (Maybe CGenre -> IO (Maybe Language))
-> Maybe CGenre -> IO (Maybe Language)
forall a b. (a -> b) -> a -> b
$ [CGenre] -> CGenre -> Maybe CGenre
forall a. Eq a => [a] -> a -> Maybe a
maybeError [CGenre
languageInvalid, CGenre
languageUnused] CGenre
i
| Bool
otherwise = Maybe Language
forall a. Maybe a
Nothing
foreign import ccall safe "cdio/compat/cdtext.h cdtext_str2lang_safe"
parseLanguage' :: C.CString -> IO CLanguage
foreign import ccall safe "cdio/compat/cdtext.h language_unknown"
languageUnknown :: CLanguage
foreign import ccall safe "cdio/compat/cdtext.h language_invalid"
languageInvalid :: CLanguage
foreign import ccall safe "cdio/compat/cdtext.h language_unused"
languageUnused :: CLanguage
fieldString :: Field -> String
fieldString :: Field -> String
fieldString = IO String -> String
forall a. IO a -> a
IO.Unsafe.unsafePerformIO (IO String -> String) -> (Field -> IO String) -> Field -> String
forall b c a. (b -> c) -> (a -> b) -> a -> c
.
CString -> IO String
C.peekCString (CString -> IO String) -> (Field -> CString) -> Field -> IO String
forall b c a. (b -> c) -> (a -> b) -> a -> c
. CGenre -> CString
fieldString' (CGenre -> CString) -> (Field -> CGenre) -> Field -> CString
forall b c a. (b -> c) -> (a -> b) -> a -> c
. Int -> CGenre
forall a b. (Integral a, Num b) => a -> b
fromIntegral (Int -> CGenre) -> (Field -> Int) -> Field -> CGenre
forall b c a. (b -> c) -> (a -> b) -> a -> c
. Field -> Int
forall a. Enum a => a -> Int
fromEnum
foreign import ccall safe "cdio/compat/cdtext.h cdtext_field2str"
fieldString' :: CField -> C.CString
cdTextGet :: Cdio -> Field -> Maybe Track -> IO (Maybe String)
cdTextGet :: Cdio -> Field -> Maybe Track -> IO (Maybe String)
cdTextGet Cdio
_ Field
_ (Just Track
DiscPregap) = Maybe String -> IO (Maybe String)
forall (m :: * -> *) a. Monad m => a -> m a
return Maybe String
forall a. Maybe a
Nothing
cdTextGet Cdio
_ Field
_ (Just Track
DiscLeadout) = Maybe String -> IO (Maybe String)
forall (m :: * -> *) a. Monad m => a -> m a
return Maybe String
forall a. Maybe a
Nothing
cdTextGet Cdio
c Field
GenreName Maybe Track
_ = Cdio -> Field -> Track -> IO (Maybe String)
cdTextGet_ Cdio
c Field
GenreName Track
0
cdTextGet Cdio
c Field
DiscId Maybe Track
_ = Cdio -> Field -> Track -> IO (Maybe String)
cdTextGet_ Cdio
c Field
DiscId Track
0
cdTextGet Cdio
c Field
f Maybe Track
Nothing = Cdio -> Field -> Track -> IO (Maybe String)
cdTextGet_ Cdio
c Field
f Track
0
cdTextGet Cdio
c Field
f (Just Track
t) = Cdio -> Field -> Track -> IO (Maybe String)
cdTextGet_ Cdio
c Field
f Track
t
cdTextGet_ :: Cdio -> Field -> Track -> IO (Maybe String)
cdTextGet_ :: Cdio -> Field -> Track -> IO (Maybe String)
cdTextGet_ Cdio
c Field
f Track
t = Maybe String
-> Cdio -> (Ptr CdText -> IO (Maybe String)) -> IO (Maybe String)
forall b. b -> Cdio -> (Ptr CdText -> IO b) -> IO b
withCdText' Maybe String
forall a. Maybe a
Nothing Cdio
c ((Ptr CdText -> IO (Maybe String)) -> IO (Maybe String))
-> (Ptr CdText -> IO (Maybe String)) -> IO (Maybe String)
forall a b. (a -> b) -> a -> b
$ \Ptr CdText
x ->
Ptr CdText -> CGenre -> CTrack -> IO CString
cdTextGet' Ptr CdText
x (Int -> CGenre
forall a b. (Integral a, Num b) => a -> b
fromIntegral (Int -> CGenre) -> Int -> CGenre
forall a b. (a -> b) -> a -> b
$ Field -> Int
forall a. Enum a => a -> Int
fromEnum Field
f) (Int -> CTrack
forall a b. (Integral a, Num b) => a -> b
fromIntegral (Int -> CTrack) -> Int -> CTrack
forall a b. (a -> b) -> a -> b
$ Track -> Int
forall a. Enum a => a -> Int
fromEnum Track
t) IO CString -> (CString -> IO (Maybe String)) -> IO (Maybe String)
forall (m :: * -> *) a b. Monad m => m a -> (a -> m b) -> m b
>>= (CString -> IO String) -> CString -> IO (Maybe String)
forall a b. (Ptr a -> IO b) -> Ptr a -> IO (Maybe b)
M.maybePeek CString -> IO String
C.peekCString
foreign import ccall safe "cdio/compat/cdtext.h cdtext_get_const"
cdTextGet' :: C.Ptr CdText -> CField -> CTrack -> IO C.CString
genre :: Cdio -> IO (Maybe Genre)
genre :: Cdio -> IO (Maybe Genre)
genre Cdio
c = do
Maybe CGenre
g <- Cdio -> (Ptr CdText -> IO CGenre) -> IO (Maybe CGenre)
forall b. Cdio -> (Ptr CdText -> IO b) -> IO (Maybe b)
withCdText Cdio
c Ptr CdText -> IO CGenre
genre'
Maybe Genre -> IO (Maybe Genre)
forall (m :: * -> *) a. Monad m => a -> m a
return (Maybe Genre -> IO (Maybe Genre))
-> Maybe Genre -> IO (Maybe Genre)
forall a b. (a -> b) -> a -> b
$ if Maybe CGenre
g Maybe CGenre -> Maybe CGenre -> Bool
forall a. Eq a => a -> a -> Bool
== CGenre -> Maybe CGenre
forall a. a -> Maybe a
Just CGenre
0 then Maybe Genre
forall a. Maybe a
Nothing else Int -> Genre
forall a. Enum a => Int -> a
toEnum (Int -> Genre) -> (CGenre -> Int) -> CGenre -> Genre
forall b c a. (b -> c) -> (a -> b) -> a -> c
. CGenre -> Int
forall a b. (Integral a, Num b) => a -> b
fromIntegral (CGenre -> Genre) -> Maybe CGenre -> Maybe Genre
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> Maybe CGenre
g
foreign import ccall safe "cdio/compat/cdtext.h cdtext_get_genre"
genre' :: C.Ptr CdText -> IO CGenre
language :: Cdio -> IO (Maybe Language)
language :: Cdio -> IO (Maybe Language)
language Cdio
c = (CGenre -> Language) -> Maybe CGenre -> Maybe Language
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
fmap (Int -> Language
forall a. Enum a => Int -> a
toEnum (Int -> Language) -> (CGenre -> Int) -> CGenre -> Language
forall b c a. (b -> c) -> (a -> b) -> a -> c
. CGenre -> Int
forall a b. (Integral a, Num b) => a -> b
fromIntegral) (Maybe CGenre -> Maybe Language)
-> IO (Maybe CGenre) -> IO (Maybe Language)
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> Cdio -> (Ptr CdText -> IO CGenre) -> IO (Maybe CGenre)
forall b. Cdio -> (Ptr CdText -> IO b) -> IO (Maybe b)
withCdText Cdio
c Ptr CdText -> IO CGenre
language'
foreign import ccall safe "cdio/compat/cdtext.h cdtext_get_language"
language' :: C.Ptr CdText -> IO CLanguage
firstTrack :: Cdio -> IO (Maybe Track)
firstTrack :: Cdio -> IO (Maybe Track)
firstTrack Cdio
c = (CTrack -> Track) -> Maybe CTrack -> Maybe Track
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
fmap (Int -> Track
forall a. Enum a => Int -> a
toEnum (Int -> Track) -> (CTrack -> Int) -> CTrack -> Track
forall b c a. (b -> c) -> (a -> b) -> a -> c
. CTrack -> Int
forall a b. (Integral a, Num b) => a -> b
fromIntegral) (Maybe CTrack -> Maybe Track)
-> (CTrack -> Maybe CTrack) -> CTrack -> Maybe Track
forall b c a. (b -> c) -> (a -> b) -> a -> c
. [CTrack] -> CTrack -> Maybe CTrack
forall a. Eq a => [a] -> a -> Maybe a
maybeError [CTrack
0] (CTrack -> Maybe Track) -> IO CTrack -> IO (Maybe Track)
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> CTrack -> Cdio -> (Ptr CdText -> IO CTrack) -> IO CTrack
forall b. b -> Cdio -> (Ptr CdText -> IO b) -> IO b
withCdText' CTrack
0 Cdio
c Ptr CdText -> IO CTrack
firstTrack'
foreign import ccall safe "cdio/compat/cdtext.h cdtext_get_first_track"
firstTrack' :: C.Ptr CdText -> IO CTrack
lastTrack :: Cdio -> IO (Maybe Track)
lastTrack :: Cdio -> IO (Maybe Track)
lastTrack Cdio
c = (CTrack -> Track) -> Maybe CTrack -> Maybe Track
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
fmap (Int -> Track
forall a. Enum a => Int -> a
toEnum (Int -> Track) -> (CTrack -> Int) -> CTrack -> Track
forall b c a. (b -> c) -> (a -> b) -> a -> c
. CTrack -> Int
forall a b. (Integral a, Num b) => a -> b
fromIntegral) (Maybe CTrack -> Maybe Track)
-> (CTrack -> Maybe CTrack) -> CTrack -> Maybe Track
forall b c a. (b -> c) -> (a -> b) -> a -> c
. [CTrack] -> CTrack -> Maybe CTrack
forall a. Eq a => [a] -> a -> Maybe a
maybeError [CTrack
0] (CTrack -> Maybe Track) -> IO CTrack -> IO (Maybe Track)
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> CTrack -> Cdio -> (Ptr CdText -> IO CTrack) -> IO CTrack
forall b. b -> Cdio -> (Ptr CdText -> IO b) -> IO b
withCdText' CTrack
0 Cdio
c Ptr CdText -> IO CTrack
lastTrack'
foreign import ccall safe "cdio/compat/cdtext.h cdtext_get_last_track"
lastTrack' :: C.Ptr CdText -> IO CTrack
selectLanguage :: Cdio -> Language -> IO Bool
selectLanguage :: Cdio -> Language -> IO Bool
selectLanguage Cdio
c Language
l = (CBool -> Bool) -> IO CBool -> IO Bool
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
fmap CBool -> Bool
forall a. (Eq a, Num a) => a -> Bool
M.toBool (IO CBool -> IO Bool)
-> ((Ptr CdText -> IO CBool) -> IO CBool)
-> (Ptr CdText -> IO CBool)
-> IO Bool
forall b c a. (b -> c) -> (a -> b) -> a -> c
. CBool -> Cdio -> (Ptr CdText -> IO CBool) -> IO CBool
forall b. b -> Cdio -> (Ptr CdText -> IO b) -> IO b
withCdText' CBool
0 Cdio
c ((Ptr CdText -> IO CBool) -> IO Bool)
-> (Ptr CdText -> IO CBool) -> IO Bool
forall a b. (a -> b) -> a -> b
$ \Ptr CdText
x ->
Ptr CdText -> CGenre -> IO CBool
selectLanguage' Ptr CdText
x (CGenre -> IO CBool) -> (Int -> CGenre) -> Int -> IO CBool
forall b c a. (b -> c) -> (a -> b) -> a -> c
. Int -> CGenre
forall a b. (Integral a, Num b) => a -> b
fromIntegral (Int -> IO CBool) -> Int -> IO CBool
forall a b. (a -> b) -> a -> b
$ Language -> Int
forall a. Enum a => a -> Int
fromEnum Language
l
foreign import ccall safe "cdio/compat/cdtext.h cdtext_select_language"
selectLanguage' :: C.Ptr CdText -> CLanguage -> IO CBool
listLanguages :: Cdio -> IO [Language]
listLanguages :: Cdio -> IO [Language]
listLanguages Cdio
c = [Language]
-> Cdio -> (Ptr CdText -> IO [Language]) -> IO [Language]
forall b. b -> Cdio -> (Ptr CdText -> IO b) -> IO b
withCdText' [] Cdio
c ((Ptr CdText -> IO [Language]) -> IO [Language])
-> (Ptr CdText -> IO [Language]) -> IO [Language]
forall a b. (a -> b) -> a -> b
$ \Ptr CdText
x -> do
Ptr CGenre
l' <- Ptr CdText -> IO (Ptr CGenre)
listLanguages' Ptr CdText
x
[Maybe Language]
ls <- Ptr CGenre -> [CGenre] -> IO [Maybe Language]
peekLanguages Ptr CGenre
l' [CGenre
languageUnknown, CGenre
languageInvalid, CGenre
languageUnused]
[Language] -> IO [Language]
forall (m :: * -> *) a. Monad m => a -> m a
return ([Language] -> IO [Language])
-> ([Language] -> [Language]) -> [Language] -> IO [Language]
forall b c a. (b -> c) -> (a -> b) -> a -> c
. [Language] -> [Language]
forall a. Eq a => [a] -> [a]
L.nub ([Language] -> IO [Language]) -> [Language] -> IO [Language]
forall a b. (a -> b) -> a -> b
$ [Maybe Language] -> [Language]
forall a. [Maybe a] -> [a]
Y.catMaybes [Maybe Language]
ls
foreign import ccall safe "cdio/compat/cdtext.h cdtext_list_languages"
listLanguages' :: C.Ptr CdText -> IO (C.Ptr CLanguage)
listAllLanguages :: Cdio -> IO [Maybe Language]
listAllLanguages :: Cdio -> IO [Maybe Language]
listAllLanguages Cdio
c = [Maybe Language]
-> Cdio
-> (Ptr CdText -> IO [Maybe Language])
-> IO [Maybe Language]
forall b. b -> Cdio -> (Ptr CdText -> IO b) -> IO b
withCdText' [] Cdio
c ((Ptr CdText -> IO [Maybe Language]) -> IO [Maybe Language])
-> (Ptr CdText -> IO [Maybe Language]) -> IO [Maybe Language]
forall a b. (a -> b) -> a -> b
$ \Ptr CdText
x -> do
Ptr CGenre
l' <- Ptr CdText -> IO (Ptr CGenre)
listAllLanguages' Ptr CdText
x
[Maybe Language]
ls <- Ptr CGenre -> [CGenre] -> IO [Maybe Language]
peekLanguages Ptr CGenre
l' [CGenre
languageInvalid, CGenre
languageUnused]
[Maybe Language] -> IO [Maybe Language]
forall (m :: * -> *) a. Monad m => a -> m a
return ([Maybe Language] -> IO [Maybe Language])
-> [Maybe Language] -> IO [Maybe Language]
forall a b. (a -> b) -> a -> b
$ case (Maybe Language -> Bool) -> [Maybe Language] -> [Maybe Language]
forall a. (a -> Bool) -> [a] -> [a]
L.dropWhileEnd Maybe Language -> Bool
forall a. Maybe a -> Bool
Y.isNothing [Maybe Language]
ls of
[] -> [Language -> Maybe Language
forall a. a -> Maybe a
Just Language
UnknownLanguage]
[Maybe Language]
ls' -> [Maybe Language]
ls'
foreign import ccall safe "cdio/compat/cdtext.h cdtext_list_languages_v2_safe"
listAllLanguages' :: C.Ptr CdText -> IO (C.Ptr CLanguage)
peekLanguages :: C.Ptr CLanguage -> [CLanguage] -> IO [Maybe Language]
peekLanguages :: Ptr CGenre -> [CGenre] -> IO [Maybe Language]
peekLanguages Ptr CGenre
p [CGenre]
es
| Ptr CGenre
p Ptr CGenre -> Ptr CGenre -> Bool
forall a. Eq a => a -> a -> Bool
== Ptr CGenre
forall a. Ptr a
C.nullPtr = [Maybe Language] -> IO [Maybe Language]
forall (m :: * -> *) a. Monad m => a -> m a
return []
| Bool
otherwise = (CGenre -> Maybe Language) -> [CGenre] -> [Maybe Language]
forall a b. (a -> b) -> [a] -> [b]
map ((CGenre -> Language) -> Maybe CGenre -> Maybe Language
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
fmap (Int -> Language
forall a. Enum a => Int -> a
toEnum (Int -> Language) -> (CGenre -> Int) -> CGenre -> Language
forall b c a. (b -> c) -> (a -> b) -> a -> c
. CGenre -> Int
forall a b. (Integral a, Num b) => a -> b
fromIntegral) (Maybe CGenre -> Maybe Language)
-> (CGenre -> Maybe CGenre) -> CGenre -> Maybe Language
forall b c a. (b -> c) -> (a -> b) -> a -> c
. [CGenre] -> CGenre -> Maybe CGenre
forall a. Eq a => [a] -> a -> Maybe a
maybeError [CGenre]
es) ([CGenre] -> [Maybe Language])
-> IO [CGenre] -> IO [Maybe Language]
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> Int -> Ptr CGenre -> IO [CGenre]
forall a. Storable a => Int -> Ptr a -> IO [a]
M.peekArray Int
8 Ptr CGenre
p
selectLanguageIndex :: Cdio -> Word -> IO Bool
selectLanguageIndex :: Cdio -> Word -> IO Bool
selectLanguageIndex Cdio
c Word
i = CBool -> Bool
forall a. (Eq a, Num a) => a -> Bool
M.toBool (CBool -> Bool) -> IO CBool -> IO Bool
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> CBool -> Cdio -> (Ptr CdText -> IO CBool) -> IO CBool
forall b. b -> Cdio -> (Ptr CdText -> IO b) -> IO b
withCdText' CBool
0 Cdio
c ((Ptr CdText -> CGenre -> IO CBool)
-> CGenre -> Ptr CdText -> IO CBool
forall a b c. (a -> b -> c) -> b -> a -> c
flip Ptr CdText -> CGenre -> IO CBool
selectLanguageIndex' (CGenre -> Ptr CdText -> IO CBool)
-> CGenre -> Ptr CdText -> IO CBool
forall a b. (a -> b) -> a -> b
$ Word -> CGenre
forall a b. (Integral a, Num b) => a -> b
fromIntegral Word
i)
foreign import ccall safe "cdio/compat/cdtext.h cdtext_set_language_index_safe"
selectLanguageIndex' :: C.Ptr CdText -> C.CInt -> IO CBool