index
[cleanm.git] / flac.icl
1 implementation module flac
2
3 import StdEnv
4
5 import Data.Error
6 import Data.Func
7 import Control.Monad => qualified join
8 import System.FilePath
9 import System._Pointer
10 import System._Posix
11 import Text
12
13 import StdDebug
14
15 NUM_COMMENT_OFFSET :== 32
16 COMMENTS_OFFSET :== 40
17 COMMENT_SIZE :== 16
18
19 getTags :: FilePath !*World -> *(MaybeErrorString [(String, String)], !*World)
20 getTags fp w
21 #! (mdp, w) = mallocSt 8 w
22 #! (ok, w) = FLAC__metadata_get_tags (packString fp) mdp w
23 | not ok
24 #! w = freeSt mdp w
25 = (Error "Error getting tags", w)
26 #! md = derefInt mdp
27 #! num_comments = readInt md NUM_COMMENT_OFFSET
28 #! comments = readInt md COMMENTS_OFFSET
29 #! comments = mapM (makeComment o derefString)
30 [readInt comments (COMMENT_SIZE*i+8)\\i<-[0..num_comments-1]]
31 #! w = FLAC__metadata_object_delete md w
32 #! w = freeSt mdp w
33 = (comments, w)
34 where
35 makeComment :: !String -> MaybeErrorString (String, String)
36 makeComment s = case indexOf "=" s of
37 -1 = Error "No = in the tag"
38 i = Ok (s % (0, i-1), s % (i+1, size s))
39
40 FLAC__metadata_get_tags :: !String !Pointer !*env -> (!Bool, !*env)
41 FLAC__metadata_get_tags _ _ _ = code {
42 ccall FLAC__metadata_get_tags "sp:I:A"
43 }
44
45 FLAC__metadata_object_delete :: !Pointer !*env -> *env
46 FLAC__metadata_object_delete _ _ = code {
47 ccall FLAC__metadata_object_delete "p:V:A"
48 }
49
50 Start w = getTags
51 "/mnt/data/music/Ahab/The Divinity of Oceans/01 Yet Another Raft of the Medusa (Pollard's Weakness).flac"
52 w