=== modified file 'idiii.cabal' --- idiii.cabal 2012-08-26 06:13:08 +0000 +++ idiii.cabal 2012-08-26 12:31:41 +0000 @@ -1,6 +1,6 @@ Name: idiii Cabal-version: >= 1.2 -Version: 0.1.2.4 +Version: 0.1.2.5 Synopsis: ID3v2 (tagging standard for MP3 files) library Description: ID3v2 (tagging standard for MP3 files) library Category: Text, Sound === modified file 'src/ID3/Parser/Frame.hs' --- src/ID3/Parser/Frame.hs 2012-08-26 00:01:44 +0000 +++ src/ID3/Parser/Frame.hs 2012-08-26 13:56:10 +0000 @@ -71,17 +71,37 @@ frameStatusFlags :: Parser St Token StatusFlags frameStatusFlags = do - flags <- anyWord8 - sizeInc - let bit = testBit flags - return $ StatusFlags (bit 6, bit 5, bit 4) -- i.e., %0abc0000 + (v, _) <- tagVersionGet + if v < 3 + then return $ StatusFlags v (False, False, False) + else do + flags <- anyWord8 + sizeInc + let bit = testBit flags + case v of + 3 -> + return $ StatusFlags v (bit 7, bit 6, bit 5) -- i.e., %abc00000 + 4 -> + return $ StatusFlags v (bit 6, bit 5, bit 4) -- i.e., %0abc0000 + _ -> + error "internal error: status flag bits for unknown version" frameFormatFlags :: Parser St Token FormatFlags frameFormatFlags = do - flags <- anyWord8 - sizeInc - let bit = testBit flags - return $ FormatFlags (bit 6, bit 3, bit 2, bit 1, bit 0) -- i.e., %0h00kmnp + (v, _) <- tagVersionGet + if v < 3 + then return $ FormatFlags v (False, False, False, False, False) + else do + flags <- anyWord8 + sizeInc + let bit = testBit flags + case v of + 3 -> + return $ FormatFlags v (bit 5, bit 7, bit 6, False, False) -- i.e., %ijk00000 + 4 -> + return $ FormatFlags v (bit 6, bit 3, bit 2, bit 1, bit 0) -- i.e., %0h00kmnp + _ -> + error "internal error: format flag bits for unknown version" -- {-- FRAME CONTENT === modified file 'src/ID3/Type/Frame.hs' --- src/ID3/Type/Frame.hs 2012-08-26 00:01:44 +0000 +++ src/ID3/Type/Frame.hs 2012-08-26 13:58:03 +0000 @@ -5,6 +5,9 @@ import ID3.Type.Flags import ID3.Type.Unparse import ID3.Type.FrameInfo +import Numeric +import Data.Char +import Data.Word {-- | /ID3V2 FRAME OVERVIEW/ @@ -143,8 +146,8 @@ } deriving Eq emptyFrameFlags :: FrameFlags -emptyFrameFlags = FrameFlags (StatusFlags (False, False, False)) - (FormatFlags (False, False, False, False, False)) +emptyFrameFlags = FrameFlags (StatusFlags 4 (False, False, False)) + (FormatFlags 4 (False, False, False, False, False)) initFrameFlags :: [FrameFlags -> FrameFlags] -> FrameFlags initFrameFlags = flip compose emptyFrameFlags @@ -156,7 +159,8 @@ instance Show FrameFlags where show fs = if not ((anyStatusFlagsOn $ fs^.statusFlags) || (anyFormatFlagsOn $ fs^.formatFlags)) then "" else - "\tFlags:\n"++ + "\tFlags " ++ (showBinary $ unparse $ fs^.statusFlags) ++ + " " ++ (showBinary $ unparse $ fs^.formatFlags) ++ ":\n"++ (showStatusFlags $ fs^.statusFlags) ++ "\n" ++ (showFormatFlags $ fs^.formatFlags) @@ -199,25 +203,36 @@ without taking the proper means to compensate, e.g. recalculating the signature, the bit MUST be cleared. --} -data StatusFlags = StatusFlags (Bool, Bool, Bool) deriving Eq +data StatusFlags = StatusFlags Word8 (Bool, Bool, Bool) deriving Eq frameDiscardFlag :: StatusFlags -> Bool -frameDiscardFlag (StatusFlags (a, _, _)) = a +frameDiscardFlag (StatusFlags _ (a, _, _)) = a fileDiscardFlag :: StatusFlags -> Bool -fileDiscardFlag (StatusFlags (_, b, _)) = b +fileDiscardFlag (StatusFlags _ (_, b, _)) = b readOnlyFlag :: StatusFlags -> Bool -readOnlyFlag (StatusFlags (_, _, c)) = c +readOnlyFlag (StatusFlags _ (_, _, c)) = c anyStatusFlagsOn :: StatusFlags -> Bool -anyStatusFlagsOn (StatusFlags (a, b, c)) = a || b || c +anyStatusFlagsOn (StatusFlags _ (a, b, c)) = a || b || c + +showBinary :: [Word8] -> String +showBinary [n] = + pad $ showIntAtBase 2 intToDigit n "" + where + pad s = replicate (8 - length s) '0' ++ s +showBinary _ = error "internal error: flags unparsed incorrectly" showStatusFlags :: StatusFlags -> String showStatusFlags stat = if not (anyStatusFlagsOn stat) then "" else "\t\tStatus Flags:\n" ++ finfo - where finfo = (if frameDiscardFlag stat then "\t\t\t- Frame should be discarded\n" else "") ++ - (if fileDiscardFlag stat then "\t\t\t- Frame should be discarded\n" else "") ++ - (if readOnlyFlag stat then "\t\t\t- Read only!\n" else "") + where finfo = (if frameDiscardFlag stat then "\t\t\t- Frame should be discarded when tag is altered\n" else "") ++ + (if fileDiscardFlag stat then "\t\t\t- Frame should be discarded when file contents are altered\n" else "") ++ + (if readOnlyFlag stat then "\t\t\t- Frame is read only!\n" else "") instance Parsed StatusFlags where - unparse (StatusFlags (a, b, c)) = [flagsToWord8 (False, a, b, c, False, False, False, False)] + unparse (StatusFlags v (a, b, c)) = + case v of + 3 -> [flagsToWord8 (a, b, c, False, False, False, False, False)] + 4 -> [flagsToWord8 (False, a, b, c, False, False, False, False)] + _ -> [0] {-- | /Frame format flags/ @@ -287,20 +302,20 @@ 1 A data length Indicator has been added to the frame. @ --} -data FormatFlags = FormatFlags (Bool, Bool, Bool, Bool, Bool) deriving Eq +data FormatFlags = FormatFlags Word8 (Bool, Bool, Bool, Bool, Bool) deriving Eq groupPartFlag :: FormatFlags -> Bool -groupPartFlag (FormatFlags (h, _, _, _, _)) = h -- Grouping identity +groupPartFlag (FormatFlags _ (h, _, _, _, _)) = h -- Grouping identity compressedFlag :: FormatFlags -> Bool -compressedFlag (FormatFlags (_, k, _, _, _)) = k -- Compression +compressedFlag (FormatFlags _ (_, k, _, _, _)) = k -- Compression encryptedFlag :: FormatFlags -> Bool -encryptedFlag (FormatFlags (_, _, m, _, _)) = m -- Encryption +encryptedFlag (FormatFlags _ (_, _, m, _, _)) = m -- Encryption unsychronisedFlag :: FormatFlags -> Bool -unsychronisedFlag (FormatFlags (_, _, _, n, _)) = n -- Unsynchronisation +unsychronisedFlag (FormatFlags _ (_, _, _, n, _)) = n -- Unsynchronisation dataLengthIdFlag :: FormatFlags -> Bool -dataLengthIdFlag (FormatFlags (_, _, _, _, p)) = p -- Data length indicator +dataLengthIdFlag (FormatFlags _ (_, _, _, _, p)) = p -- Data length indicator anyFormatFlagsOn :: FormatFlags -> Bool -anyFormatFlagsOn (FormatFlags (h, k, m, n, p)) = h || k || m || n || p +anyFormatFlagsOn (FormatFlags _ (h, k, m, n, p)) = h || k || m || n || p showFormatFlags :: FormatFlags -> String showFormatFlags fs = if not (anyFormatFlagsOn fs) then "" else finfo @@ -313,7 +328,11 @@ (if dataLengthIdFlag fs then ["frame has data length indicator"] else []) instance Parsed FormatFlags where - unparse (FormatFlags (h, k, m, n, p)) = [flagsToWord8 (False, h, False, False, k, m, n, p)] + unparse (FormatFlags v (h, k, m, n, p)) = + case v of + 3 -> [flagsToWord8 (k, m, h, False, False, False, False, False)] + 4 -> [flagsToWord8 (False, h, False, False, k, m, n, p)] + _ -> [0] --------------------------------------------------------------------------------------------