-- | This Module provides parsers for frames.moduleID3.Parser.Framewhere---- IMPORTSimportText.ParserCombinators.Poly.StateimportID3.Parser.GeneralimportID3.Parser.NativeFramesimportID3.Type.FrameimportID3.Type.Header(unsynchFlag)importData.AccessorimportData.Bits(testBit)importData.Either(rights)importData.Map(Map)importqualifiedData.MapasMapimportqualifiedData.ByteString.LazyasBSimportqualifiedData.ByteString.Lazy.Char8asC----parseFrames::TagParser([FrameID],MapFrameIDID3Frame)parseFrames=doframesAndErrs<-many1anyFrameletframes=rightsframesAndErrsletidList=map(\f->f^.frHeader^.frID)framesreturn(idList,Map.fromList(zipidListframes))-- | Parses any Frame HeaderanyFrameHeader::TagParser(EitherStringFrameHeader)anyFrameHeader=doi<-frameID`err`"frame id"s<-frameSize`err`"frame size"ifs>500000thenreturn$Left$"Frame of type "++(showi)++" is too big!"elsedof<-frameFlags`err`"frame flags"return$Right$initFrameHeader[frID^=i,frSize^=s,frFlags^=f]-- | Parses any FrameanyFrame::TagParser(EitherStringID3Frame)anyFrame=dohdr<-anyFrameHeader`err`"frame header"casehdrofLefte->return$LefteRighth->doi<-frameInfo(h^.frID)`err`"frame info"return$Right$initID3Frame[frHeader^=h,frInfo^=i]frameID::TagParserFrameIDframeID=doname<-count(4::Integer)$upper`onFail`digitposUpdate(+4)return$C.unpack$BS.packnameframeSize::TagParserFrameSizeframeSize=doversion<-tagVersionGetlet(majorVersion,_)=versionflags<-flagsGetletdoDecoding=(majorVersion>=4||unsynchFlagflags)size<-parseSize4doDecodingreturnsizeframeFlags::TagParserFrameFlagsframeFlags=dos<-frameStatusFlags`err`"status flags"f<-frameFormatFlags`err`"format flags"return$initFrameFlags[statusFlags^=s,formatFlags^=f]frameStatusFlags::ParserStTokenStatusFlagsframeStatusFlags=do(v,_)<-tagVersionGetifv<3thenreturn$StatusFlagsv(False,False,False)elsedoflags<-anyWord8sizeIncletbit=testBitflagscasevof3->return$StatusFlagsv(bit7,bit6,bit5)-- i.e., %abc000004->return$StatusFlagsv(bit6,bit5,bit4)-- i.e., %0abc0000_->error"internal error: status flag bits for unknown version"frameFormatFlags::ParserStTokenFormatFlagsframeFormatFlags=do(v,_)<-tagVersionGetifv<3thenreturn$FormatFlagsv(False,False,False,False,False)elsedoflags<-anyWord8sizeIncletbit=testBitflagscasevof3->return$FormatFlagsv(bit5,bit7,bit6,False,False)-- i.e., %ijk000004->return$FormatFlagsv(bit6,bit3,bit2,bit1,bit0)-- i.e., %0h00kmnp_->error"internal error: format flag bits for unknown version"-- {-- FRAME CONTENT{-
-If nothing else is said, strings, including numeric strings and URLs
- [URL], are represented as ISO-8859-1 [ISO-8859-1] characters in the
- range $20 - $FF. Such strings are represented in frame descriptions
- as <text string>, or <full text string> if newlines are allowed. If
- nothing else is said newline character is forbidden. In ISO-8859-1 a
- newline is represented, when allowed, with $0A only.
-
- Frames that allow different types of text encoding contains a text
- encoding description byte. Possible encodings:
-
- $00 ISO-8859-1 [ISO-8859-1]. Terminated with $00.
- $01 UTF-16 [UTF-16] encoded Unicode [UNICODE] with BOM. All
- strings in the same frame SHALL have the same byteorder.
- Terminated with $00 00.
- $02 UTF-16BE [UTF-16] encoded Unicode [UNICODE] without BOM.
- Terminated with $00 00.
- $03 UTF-8 [UTF-8] encoded Unicode [UNICODE]. Terminated with $00.
-
- Strings dependent on encoding are represented in frame descriptions
- as <text string according to encoding>, or <full text string
- according to encoding> if newlines are allowed. Any empty strings of
- type $01 which are NULL-terminated may have the Unicode BOM followed
- by a Unicode NULL ($FF FE 00 00 or $FE FF 00 00).
-
- The timestamp fields are based on a subset of ISO 8601. When being as
- precise as possible the format of a time string is
- yyyy-MM-ddTHH:mm:ss (year, "-", month, "-", day, "T", hour (out of
- 24), ":", minutes, ":", seconds), but the precision may be reduced by
- removing as many time indicators as wanted. Hence valid timestamps
- are
- yyyy, yyyy-MM, yyyy-MM-dd, yyyy-MM-ddTHH, yyyy-MM-ddTHH:mm and
- yyyy-MM-ddTHH:mm:ss. All time stamps are UTC. For durations, use
- the slash character as described in 8601, and for multiple non-
- contiguous dates, use multiple strings, if allowed by the frame
- definition.
-
- The three byte language field, present in several frames, is used to
- describe the language of the frame's content, according to ISO-639-2
- [ISO-639-2]. The language should be represented in lower case. If the
- language is not known the string "XXX" should be used.
-
- All URLs [URL] MAY be relative, e.g. "picture.png", "../doc.txt".
-
- If a frame is longer than it should be, e.g. having more fields than
- specified in this document, that indicates that additions to the
- frame have been made in a later version of the ID3v2 standard. This
- is reflected by the revision number in the header of the tag.
--}