Legend:
Page
Library
Module
Module type
Parameter
Class
Class type
Source
Page
Library
Module
Module type
Parameter
Class
Class type
Source
metadataRIFF.ml1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62open MetadataBase module R = Reader (* Tag normalization. *) let tagn = [ ("IART", "artist"); ("ICMT", "comment"); ("ICOP", "copyright"); ("ICRD", "date"); ("ICRD", "date"); ("IGNR", "genre"); ("INAM", "title"); ("IPRD", "album"); ("IPRT", "track"); ("ISFT", "encoder"); ("ITRK", "track"); ] let parse ?format f : metadata = if R.read f 4 <> "RIFF" then raise Invalid; let _ (* file size *) = R.int32_le f in if format <> None && Some (R.read f 4) <> format then raise Invalid; let ans = ref [] in let chunk () = let tag = R.read f 4 in let size = R.int32_le f in if tag <> "LIST" then R.drop f size else ( let subtag = R.read f 4 in match subtag with | "INFO" -> let remaining = ref (size - 4) in while !remaining > 0 do let tag = R.read f 4 in let size = R.int32_le f in match R.read_tag ~length:(size - 1) ~label:tag f with | None -> () | Some s -> R.drop f 1; (* null-terminated *) let padding = size mod 2 in R.drop f padding; remaining := !remaining - (8 + size + padding); let tag = match List.assoc_opt tag tagn with | Some tag -> tag | None -> tag in ans := (tag, s) :: !ans done | "movi" -> raise Exit (* stop parsing there *) | _ -> R.drop f (size - 4)) in try while true do chunk () done; assert false with _ -> List.rev !ans let parse_file ?format ?custom_parser file = R.with_file ?custom_parser (parse ?format) file