module Codec.Audio.FLAC.Metadata.Internal.Level2Interface
(
withChain
, chainStatus
, chainRead
, chainWrite
, chainSortPadding
, withIterator
, iteratorGetBlockType
, iteratorGetBlock
, iteratorSetBlock
, iteratorDeleteBlock
, iteratorInsertBlockAfter )
where
import Codec.Audio.FLAC.Metadata.Internal.Types
import Codec.Audio.FLAC.Util
import Control.Monad.Catch
import Control.Monad.IO.Class (MonadIO (..))
import Foreign.C.String
import Foreign.C.Types
import Prelude hiding (iterate)
withChain :: (MetaChain -> IO a) -> IO a
withChain f = bracket chainNew (mapM_ chainDelete) $ \mchain ->
case mchain of
Nothing -> throwM
(MetaGeneralProblem MetaChainStatusMemoryAllocationError)
Just x -> f x
chainNew :: IO (Maybe MetaChain)
chainNew = maybePtr <$> c_chain_new
foreign import ccall unsafe "FLAC__metadata_chain_new"
c_chain_new :: IO MetaChain
chainDelete :: MetaChain -> IO ()
chainDelete = c_chain_delete
foreign import ccall unsafe "FLAC__metadata_chain_delete"
c_chain_delete :: MetaChain -> IO ()
chainStatus :: MetaChain -> IO MetaChainStatus
chainStatus = fmap toEnum' . c_chain_status
foreign import ccall unsafe "FLAC__metadata_chain_status"
c_chain_status :: MetaChain -> IO CUInt
chainRead :: MetaChain -> FilePath -> IO Bool
chainRead chain path = withCString path (c_chain_read chain)
foreign import ccall unsafe "FLAC__metadata_chain_read"
c_chain_read :: MetaChain -> CString -> IO Bool
chainWrite
:: MetaChain
-> Bool
-> Bool
-> IO Bool
chainWrite chain usePadding preserveStats =
c_chain_write chain (fromEnum' usePadding) (fromEnum' preserveStats)
foreign import ccall unsafe "FLAC__metadata_chain_write"
c_chain_write :: MetaChain -> CInt -> CInt -> IO Bool
chainSortPadding :: MetaChain -> IO ()
chainSortPadding = c_chain_sort_padding
foreign import ccall unsafe "FLAC__metadata_chain_sort_padding"
c_chain_sort_padding :: MetaChain -> IO ()
withIterator :: (MonadMask m, MonadIO m)
=> MetaChain
-> (MetaIterator -> m (Maybe a))
-> m [a]
withIterator chain f = bracket acquire release action
where
acquire = liftIO iteratorNew
release = mapM_ (liftIO . iteratorDelete)
action mi =
case mi of
Nothing -> throwM
(MetaGeneralProblem MetaChainStatusMemoryAllocationError)
Just i -> do
liftIO (iteratorInit i chain)
let go thisNext =
if thisNext
then do
res <- f i
let next = liftIO (iteratorNext i) >>= go
case res of
Nothing -> next
Just x -> (x :) <$> next
else return []
go True
iteratorNew :: IO (Maybe MetaIterator)
iteratorNew = maybePtr <$> c_iterator_new
foreign import ccall unsafe "FLAC__metadata_iterator_new"
c_iterator_new :: IO MetaIterator
iteratorDelete :: MetaIterator -> IO ()
iteratorDelete = c_iterator_delete
foreign import ccall unsafe "FLAC__metadata_iterator_delete"
c_iterator_delete :: MetaIterator -> IO ()
iteratorInit
:: MetaIterator
-> MetaChain
-> IO ()
iteratorInit = c_iterator_init
foreign import ccall unsafe "FLAC__metadata_iterator_init"
c_iterator_init :: MetaIterator -> MetaChain -> IO ()
iteratorNext :: MetaIterator -> IO Bool
iteratorNext = c_iterator_next
foreign import ccall unsafe "FLAC__metadata_iterator_next"
c_iterator_next :: MetaIterator -> IO Bool
iteratorGetBlockType :: MetaIterator -> IO MetadataType
iteratorGetBlockType = fmap toEnum' . c_iterator_get_block_type
foreign import ccall unsafe "FLAC__metadata_iterator_get_block_type"
c_iterator_get_block_type :: MetaIterator -> IO CUInt
iteratorGetBlock :: MetaIterator -> IO Metadata
iteratorGetBlock = c_iterator_get_block
foreign import ccall unsafe "FLAC__metadata_iterator_get_block"
c_iterator_get_block :: MetaIterator -> IO Metadata
iteratorSetBlock :: MetaIterator -> Metadata -> IO Bool
iteratorSetBlock = c_iterator_set_block
foreign import ccall unsafe "FLAC__metadata_iterator_set_block"
c_iterator_set_block :: MetaIterator -> Metadata -> IO Bool
iteratorDeleteBlock
:: MetaIterator
-> IO Bool
iteratorDeleteBlock block = c_iterator_delete_block block False
foreign import ccall unsafe "FLAC__metadata_iterator_delete_block"
c_iterator_delete_block :: MetaIterator -> Bool -> IO Bool
iteratorInsertBlockAfter :: MetaIterator -> Metadata -> IO Bool
iteratorInsertBlockAfter = c_iterator_insert_block_after
foreign import ccall unsafe "FLAC__metadata_iterator_insert_block_after"
c_iterator_insert_block_after :: MetaIterator -> Metadata -> IO Bool