implementation module flac import StdEnv import Data.Error import Data.Func import Control.Monad => qualified join import System.FilePath import System._Pointer import System._Posix import Text import StdDebug NUM_COMMENT_OFFSET :== 32 COMMENTS_OFFSET :== 40 COMMENT_SIZE :== 16 getTags :: FilePath !*World -> *(MaybeErrorString [(String, String)], !*World) getTags fp w #! (mdp, w) = mallocSt 8 w #! (ok, w) = FLAC__metadata_get_tags (packString fp) mdp w | not ok #! w = freeSt mdp w = (Error "Error getting tags", w) #! md = derefInt mdp #! num_comments = readInt md NUM_COMMENT_OFFSET #! comments = readInt md COMMENTS_OFFSET #! comments = mapM (makeComment o derefString) [readInt comments (COMMENT_SIZE*i+8)\\i<-[0..num_comments-1]] #! w = FLAC__metadata_object_delete md w #! w = freeSt mdp w = (comments, w) where makeComment :: !String -> MaybeErrorString (String, String) makeComment s = case indexOf "=" s of -1 = Error "No = in the tag" i = Ok (s % (0, i-1), s % (i+1, size s)) FLAC__metadata_get_tags :: !String !Pointer !*env -> (!Bool, !*env) FLAC__metadata_get_tags _ _ _ = code { ccall FLAC__metadata_get_tags "sp:I:A" } FLAC__metadata_object_delete :: !Pointer !*env -> *env FLAC__metadata_object_delete _ _ = code { ccall FLAC__metadata_object_delete "p:V:A" } Start w = getTags "/mnt/data/music/Ahab/The Divinity of Oceans/01 Yet Another Raft of the Medusa (Pollard's Weakness).flac" w