Copyright | (c) Robert Massaioli, 2014 |
---|---|
License | MIT |
Maintainer | robertmassaioli@gmail.com |
Stability | experimental |
Safe Haskell | Safe-Inferred |
Language | Haskell2010 |
This module was made as a convinience, it's purpose is to aid the manipulation of RIFF files such that you can both parse them and asseble them. If you wish to just parse or assemble Riff files then you may be better off just importing Data.Riff.Parse or Data.Riff.Assemble respectively.
- data RiffFile = RiffFile {}
- type RiffChunkSize = Word32
- data RiffFileType
- data RiffChunk
- = RiffChunkChild {
- riffChunkId :: RiffId
- riffData :: [RiffData]
- | RiffChunkParent { }
- = RiffChunkChild {
- type RiffId = String
- type RiffData = Word8
- type ParseError = (ByteOffset, String)
- withRiffFile :: FilePath -> (Either ParseError RiffFile -> IO ()) -> IO ()
- parseRiffData :: ByteString -> Either ParseError RiffFile
- assembleRiffFile :: FilePath -> RiffFile -> IO ()
- assembleRiffFileStream :: RiffFile -> ByteString
RIFF File Data Representaion
This is our representation of a RIFF file. These files all have a format type and are composed by one or more nestable data Chunks which we represent with a RiffChunk.
RiffFile | |
|
type RiffChunkSize = Word32 Source
A Riff file is made up exclusively of Riff Chunks and each chunk, as the second piece of data in the chunk, contains it's size. The size never includes the first 8 bytes of the chunk, which are the Chunk Id and the Chunk Size but, in the case of a nested chunk, it does include the four bytes of the Chunk FormType Id.
According to the specification a chunk size must be represented by four bytes of data. This means that the maximum number of bytes that can be present in a RIFF file is:
2 ^ 32 + 8 = 4294967304 bytes or ~4GB
If your raw data is larger than that then this file format cannot support it.
data RiffFileType Source
There are only two different types of RIFF file: RIFF and RIFX and the difference is in the way that data is encoded inside them.
A RiffFile is just an alias for a RiffChunk. A RiffFile is merely a nested collection of RiffChunks where the first element must be a list of chunks with the ID RIFF or RIFX.
A RiffId is just a four character string (FourCC). It is usually (but by no means always) chosen to be something that is human readable when converted to ASCII.
type ParseError = (ByteOffset, String) Source
Represents an error in the parsing of a Riff File. It contains the location in the file that we read up to and a message of what went wrong.
Reading (parsing) RIFF Files
:: FilePath | The file that will be read. |
-> (Either ParseError RiffFile -> IO ()) | An action to perform on the potentialy parsed file |
-> IO () | The resultant IO action. |
Given a FilePath you can provide a function that will be given either a ParseError or an actual RiffFile to process. It is important to note that you should do all of the processing of the RiffFile in the provided action because the file will be closed at the end of this function.
parseRiffData :: ByteString -> Either ParseError RiffFile Source
You can parse a raw ByteString and try and convert it into a RiffFile. This will give a best attempt at parsing the data and, if success is not possible, will give you a ParseError.
:: FilePath | The location on the filesystem to save the RiffFile. |
-> RiffFile | The in-memory representation of a RiffFile to be saved. |
-> IO () | Writing to disk is an IO operatin and we return no results. |
Given a file path and a RiffFile representation this will allow you to safely write out a RiffFile to disk. This allows you to save anything that you like in a RiffFile. Just remember that the maximum file size of a RiffFile is bounded by the maximum size of a 32bit integer. The behaviour of this function, should you give it too much data, is undefined.
:: RiffFile | The RIFF file to be written out. |
-> ByteString | The resultant stream of bytes representing the file. |
Assembles a RiffFile into it's representation in a Lazy ByteString.