IpatchRiffParser

IpatchRiffParser — RIFF file parser.

Synopsis




                    IpatchRiffChunk;
enum                IpatchRiffStatus;
enum                IpatchRiffMode;
                    IpatchRiffParser;
                    IpatchRiffParserClass;
#define             IPATCH_RIFF_NEED_SWAP               (parser)
#define             IPATCH_RIFF_BIG_ENDIAN              (parser)
enum                IpatchRiffChunkType;
#define             IPATCH_RIFF_PARSER_ERROR
enum                IpatchRiffParserError;
#define             IPATCH_FOURCC                       (c1, c2, c3, c4)
#define             IPATCH_FOURCC_RIFF
#define             IPATCH_FOURCC_RIFX
#define             IPATCH_FOURCC_LIST
#define             IPATCH_RIFF_WAVE_FMT_PCM
#define             IPATCH_RIFF_WAVE_FMT_FLOAT
#define             IPATCH_RIFF_HEADER_SIZE
#define             IPATCH_RIFF_FOURCC_SIZE
#define             IPATCH_RIFF_LIST_HEADER_SIZE
GQuark              ipatch_riff_parser_error_quark      (void);
IpatchRiffParser*   ipatch_riff_parser_new              (IpatchFile *file);
void                ipatch_riff_set_file                (IpatchRiffParser *parser,
                                                         IpatchFile *file);
IpatchFile*         ipatch_riff_get_file                (IpatchRiffParser *parser);
int                 ipatch_riff_get_chunk_level         (IpatchRiffParser *parser);
IpatchRiffChunk*    ipatch_riff_get_chunk_array         (IpatchRiffParser *parser,
                                                         int *count);
IpatchRiffChunk*    ipatch_riff_get_chunk               (IpatchRiffParser *parser,
                                                         int level);
guint32             ipatch_riff_get_total_size          (IpatchRiffParser *parser);
guint32             ipatch_riff_get_position            (IpatchRiffParser *parser);
void                ipatch_riff_push_state              (IpatchRiffParser *parser);
gboolean            ipatch_riff_pop_state               (IpatchRiffParser *parser,
                                                         GError **err);
IpatchRiffChunk*    ipatch_riff_start_read              (IpatchRiffParser *parser,
                                                         GError **err);
IpatchRiffChunk*    ipatch_riff_start_read_chunk        (IpatchRiffParser *parser,
                                                         GError **err);
IpatchRiffChunk*    ipatch_riff_read_chunk_verify       (IpatchRiffParser *parser,
                                                         IpatchRiffChunkType type,
                                                         guint32 id,
                                                         GError **err);
IpatchRiffChunk*    ipatch_riff_read_chunk              (IpatchRiffParser *parser,
                                                         GError **err);
#define             ipatch_riff_write_list_chunk        (parser, id, err)
#define             ipatch_riff_write_sub_chunk         (parser, id, err)
gboolean            ipatch_riff_write_chunk             (IpatchRiffParser *parser,
                                                         IpatchRiffChunkType type,
                                                         guint32 id,
                                                         GError **err);
#define             ipatch_riff_end_chunk               (parser, err)
gboolean            ipatch_riff_close_chunk             (IpatchRiffParser *parser,
                                                         int level,
                                                         GError **err);
#define             ipatch_riff_skip_chunk              (parser, err)
gboolean            ipatch_riff_skip_chunks             (IpatchRiffParser *parser,
                                                         guint count,
                                                         GError **err);
gboolean            ipatch_riff_get_error               (IpatchRiffParser *parser,
                                                         GError **err);
char*               ipatch_riff_message_detail          (IpatchRiffParser *parser,
                                                         int level,
                                                         const char *format,
                                                         ...);

Object Hierarchy


  GObject
   +----IpatchRiffParser
         +----IpatchDLSReader
         +----IpatchDLSWriter
         +----IpatchSF2Reader
         +----IpatchSF2Writer

Description

Defines a RIFF file parser object that can be used to load or save RIFF format files.

Details

IpatchRiffChunk

typedef struct {
  IpatchRiffChunkType type;	/* type of chunk */
  guint32 id;	  /* chunk ID in integer format for easy comparison */
  char idstr[4];		/* four character chunk ID string */
  gint32 position; /* current position in chunk (read or write mode) */
  guint32 size;			/* size of chunk (read mode only) */
} IpatchRiffChunk;


enum IpatchRiffStatus

typedef enum
{
  IPATCH_RIFF_STATUS_FAIL = 0,	/* error occured */
  IPATCH_RIFF_STATUS_BEGIN,	/* parsing has not yet began */
  IPATCH_RIFF_STATUS_FINISHED,	/* no more parsing to be done */
  IPATCH_RIFF_STATUS_NORMAL,	/* normal status */
  IPATCH_RIFF_STATUS_CHUNK_END	/* end of a chunk */
} IpatchRiffStatus;


enum IpatchRiffMode

typedef enum
{
  IPATCH_RIFF_READ,
  IPATCH_RIFF_WRITE
} IpatchRiffMode;


IpatchRiffParser

typedef struct _IpatchRiffParser IpatchRiffParser;


IpatchRiffParserClass

typedef struct {
  GObjectClass parent_class;
} IpatchRiffParserClass;


IPATCH_RIFF_NEED_SWAP()

#define IPATCH_RIFF_NEED_SWAP(parser)  IPATCH_FILE_NEED_SWAP (parser->file)

parser :

IPATCH_RIFF_BIG_ENDIAN()

#define IPATCH_RIFF_BIG_ENDIAN(parser) IPATCH_FILE_BIG_ENDIAN (parser->file)

parser :

enum IpatchRiffChunkType

typedef enum
{
  IPATCH_RIFF_CHUNK_RIFF,	/* toplevel "RIFF" (or "RIFX") list chunk */
  IPATCH_RIFF_CHUNK_LIST,	/* a "LIST" chunk */
  IPATCH_RIFF_CHUNK_SUB		/* a sub chunk */
} IpatchRiffChunkType;


IPATCH_RIFF_PARSER_ERROR

#define IPATCH_RIFF_PARSER_ERROR  ipatch_riff_parser_error_quark()


enum IpatchRiffParserError

typedef enum
{
  IPATCH_RIFF_ERROR_NOT_RIFF,	/* not a RIFF file */
  IPATCH_RIFF_ERROR_UNEXPECTED_ID, /* unexpected chunk ID */
  IPATCH_RIFF_ERROR_INVALID_ID, /* invalid chunk FOURCC ID */
  IPATCH_RIFF_ERROR_ODD_SIZE,	/* chunk size is ODD */
  IPATCH_RIFF_ERROR_SIZE_EXCEEDED, /* chunk size exceeded */

  /* convenience errors - not used by the parser itself */
  IPATCH_RIFF_ERROR_SIZE_MISMATCH, /* chunk size mismatch */
  IPATCH_RIFF_ERROR_INVALID_DATA /* generic invalid data error */
} IpatchRiffParserError;


IPATCH_FOURCC()

#define             IPATCH_FOURCC(c1, c2, c3, c4)

c1 :
c2 :
c3 :
c4 :

IPATCH_FOURCC_RIFF

#define IPATCH_FOURCC_RIFF IPATCH_FOURCC ('R','I','F','F')


IPATCH_FOURCC_RIFX

#define IPATCH_FOURCC_RIFX IPATCH_FOURCC ('R','I','F','X') /* big endian */


IPATCH_FOURCC_LIST

#define IPATCH_FOURCC_LIST IPATCH_FOURCC ('L','I','S','T')


IPATCH_RIFF_WAVE_FMT_PCM

#define IPATCH_RIFF_WAVE_FMT_PCM   0x1


IPATCH_RIFF_WAVE_FMT_FLOAT

#define IPATCH_RIFF_WAVE_FMT_FLOAT 0x3


IPATCH_RIFF_HEADER_SIZE

#define IPATCH_RIFF_HEADER_SIZE 8 /* size of RIFF chunk headers (ID + size) */


IPATCH_RIFF_FOURCC_SIZE

#define IPATCH_RIFF_FOURCC_SIZE 4 /* RIFF FOURCC ID size */


IPATCH_RIFF_LIST_HEADER_SIZE

#define             IPATCH_RIFF_LIST_HEADER_SIZE


ipatch_riff_parser_error_quark ()

GQuark              ipatch_riff_parser_error_quark      (void);

Returns :

ipatch_riff_parser_new ()

IpatchRiffParser*   ipatch_riff_parser_new              (IpatchFile *file);

Create a new RIFF file parser context

file : File object to parse or NULL to set later
Returns : The RIFF file context

ipatch_riff_set_file ()

void                ipatch_riff_set_file                (IpatchRiffParser *parser,
                                                         IpatchFile *file);

Set the file object of a RIFF file parser

parser : RIFF file parser
file : File object to assign to the parser

ipatch_riff_get_file ()

IpatchFile*         ipatch_riff_get_file                (IpatchRiffParser *parser);

Get the file object from a RIFF file parser. Returned file object is not reffed, but should be, if used beyond the life of the parser and its current file object setting.

parser : RIFF file parser
Returns : The file object or NULL if not assigned.

ipatch_riff_get_chunk_level ()

int                 ipatch_riff_get_chunk_level         (IpatchRiffParser *parser);

Gets the current chunk level count (number of embedded chunks) currently being processed in a RIFF file.

parser : RIFF file parser
Returns : Chunk level count (0 = no open chunks)

ipatch_riff_get_chunk_array ()

IpatchRiffChunk*    ipatch_riff_get_chunk_array         (IpatchRiffParser *parser,
                                                         int *count);

Gets the array of open chunk info structures. The returned value is only valid while the chunk state is unchanged, therefore this function should be called again following other RIFF parser calls.

parser : RIFF file parser
count : Location to store the number of elements in the returned array
Returns : Array of IpatchRiffChunk structures or NULL if no chunks being processed (processing hasn't started). The returned array is internal and should not be modified or freed. Also note that the array is valid only while the chunk state is unchanged. The number of elements in the array is stored in count.

ipatch_riff_get_chunk ()

IpatchRiffChunk*    ipatch_riff_get_chunk               (IpatchRiffParser *parser,
                                                         int level);

Get the chunk at the specified level from a RIFF parser chunk state array.

parser : RIFF file parser
level : Level of chunk to get (-1 for current chunk)
Returns : Pointer to the chunk or NULL if invalid level. The returned chunk is internal and should not be modified or freed.

ipatch_riff_get_total_size ()

guint32             ipatch_riff_get_total_size          (IpatchRiffParser *parser);

Get total size of toplevel chunk. This is a convenience function that just adds the size of the toplevel chunk and its header, the actual file object size is not checked.

parser : RIFF file parser
Returns : Size of toplevel chunk + header size, in bytes. Actual file size is not checked.

ipatch_riff_get_position ()

guint32             ipatch_riff_get_position            (IpatchRiffParser *parser);

Get current position in the toplevel RIFF chunk (including header, i.e., the file position). Does not check actual position in file object, but uses the toplevel RIFF chunk position instead.

parser : RIFF file parser
Returns : The current offset, in bytes, into the toplevel RIFF chunk (including header). Does not check actual file position.

ipatch_riff_push_state ()

void                ipatch_riff_push_state              (IpatchRiffParser *parser);

Pushes the current file position and chunk state onto the state stack. This state can be later restored to return to the same position in a RIFF file.

parser : RIFF parser object

ipatch_riff_pop_state ()

gboolean            ipatch_riff_pop_state               (IpatchRiffParser *parser,
                                                         GError **err);

Pops the most recent state pushed onto the state stack. This causes the position in the RIFF file stored by the state to be restored.

parser : RIFF parser object
err : Location to store error info or NULL
Returns : TRUE on success, FALSE otherwise which is fatal

ipatch_riff_start_read ()

IpatchRiffChunk*    ipatch_riff_start_read              (IpatchRiffParser *parser,
                                                         GError **err);

Start parsing the parser file object as if it were at the beginning of a RIFF file. Clears any current parser chunk state, loads a chunk and ensures that it has the "RIFF" or "RIFX" ID. If this call is sucessful there will be one chunk on the chunk stack with the secondary ID of the RIFF chunk. If it is desirable to process a chunk that is not the beginning of a RIFF file, ipatch_riff_start_read_chunk() can be used. This function will also automatically enable byte order swapping if needed.

parser : RIFF file parser
err : Location to store error info or NULL
Returns : Pointer to the opened RIFF chunk or NULL on error. The returned chunk is internal and should not be modified or freed.

ipatch_riff_start_read_chunk ()

IpatchRiffChunk*    ipatch_riff_start_read_chunk        (IpatchRiffParser *parser,
                                                         GError **err);

Start parsing the parser file object at an arbitrary chunk. Clears any current parser chunk state and loads a chunk. If this call is sucessful there will be one chunk on the chunk stack. If it is desirable to start processing from the beginning of a RIFF file ipatch_riff_start_read() should be used instead. An end of file condition is considered an error. Note that it is up to the caller to ensure byte order swapping is enabled, if needed.

parser : RIFF file parser
err : Location to store error info or NULL
Returns : Pointer to the opened RIFF chunk or NULL on error. The returned chunk is internal and should not be modified or freed.

ipatch_riff_read_chunk_verify ()

IpatchRiffChunk*    ipatch_riff_read_chunk_verify       (IpatchRiffParser *parser,
                                                         IpatchRiffChunkType type,
                                                         guint32 id,
                                                         GError **err);

Read a RIFF chunk and ensure that it has a specific type and ID. If the chunk is not the expected chunk, it is concidered an error.

parser : RIFF parser object
type : Expected chunk type
id : Expected chunk ID
err : Location to store error info or NULL
Returns : New opened chunk or NULL on error.

ipatch_riff_read_chunk ()

IpatchRiffChunk*    ipatch_riff_read_chunk              (IpatchRiffParser *parser,
                                                         GError **err);

Parse next RIFF chunk header. The ipatch_riff_close_chunk() function should be called at the end of a chunk, otherwise this function will return FALSE if the current chunk has ended. When the first RIFF chunk is read the IPATCH_RIFF_FLAG_BIG_ENDIAN flag is cleared or set depending on if its RIFF or RIFX respectively, endian swapping is also enabled if the file uses non-native endian format to the host.

parser : RIFF file parser
err : Location to store error info or NULL
Returns : Pointer to new opened chunk or NULL if current chunk has ended or on error. Returned chunk pointer is internal and should not be modified or freed.

ipatch_riff_write_list_chunk()

#define             ipatch_riff_write_list_chunk(parser, id, err)

parser :
id :
err :

ipatch_riff_write_sub_chunk()

#define             ipatch_riff_write_sub_chunk(parser, id, err)

parser :
id :
err :

ipatch_riff_write_chunk ()

gboolean            ipatch_riff_write_chunk             (IpatchRiffParser *parser,
                                                         IpatchRiffChunkType type,
                                                         guint32 id,
                                                         GError **err);

Opens a new chunk and writes a chunk header to the file object in parser. The size field of the chunk is set to 0 and will be filled in when the chunk is closed (see ipatch_riff_close_chunk()).

parser : RIFF parser
type : Chunk type (RIFF, LIST, or SUB)
id : Chunk ID (secondary ID for RIFF and LIST chunks)
err : Location to store error info or NULL
Returns : TRUE on success, FALSE otherwise.

ipatch_riff_end_chunk()

#define             ipatch_riff_end_chunk(parser, err)

parser :
err :

ipatch_riff_close_chunk ()

gboolean            ipatch_riff_close_chunk             (IpatchRiffParser *parser,
                                                         int level,
                                                         GError **err);

Closes the chunk specified by level and all its children (if any).

In write mode the chunk size is filled in for chunks that get closed and therefore the file object of parser must be seekable (anyone need non-seekable RIFF writing?). The chunk size is padded to an even number if necessary (by writing a NULL byte).

Apon successful completion the file position will be where it was prior to the call (write mode) or at the beginning of the next chunk (read mode). There will be level open chunks (or previous chunk count - 1 if level == -1). In read mode the parser status will be IPATCH_RIFF_STATUS_NORMAL if open chunks remain or IPATCH_RIFF_STATUS_FINISHED if toplevel chunk was closed. The status is not modified in write mode.

parser : RIFF parser
level : Level of chunk to close (-1 for current chunk)
err : Location to store error info or NULL
Returns : TRUE on success, FALSE otherwise.

ipatch_riff_skip_chunk()

#define             ipatch_riff_skip_chunk(parser, err)

parser :
err :

ipatch_riff_skip_chunks ()

gboolean            ipatch_riff_skip_chunks             (IpatchRiffParser *parser,
                                                         guint count,
                                                         GError **err);

Skips RIFF chunks at the current chunk level (children of the current chunk).

parser : RIFF parser object
count : Number of chunks to skip
err : Location to store error info or NULL
Returns : TRUE on success, FALSE otherwise

ipatch_riff_get_error ()

gboolean            ipatch_riff_get_error               (IpatchRiffParser *parser,
                                                         GError **err);

Gets error information from a RIFF parser object.

parser : RIFF parser object
err : Location to store error info
Returns : FALSE if parser is in IPATCH_RIFF_STATUS_FAIL condition and info can be found in err, TRUE if no error has occured.

ipatch_riff_message_detail ()

char*               ipatch_riff_message_detail          (IpatchRiffParser *parser,
                                                         int level,
                                                         const char *format,
                                                         ...);

Generates a detailed message, including current position in RIFF file and a chunk trace back. Useful for debugging purposes.

parser : RIFF parser object
level : Chunk level to generate detail for (-1 for current chunk)
format : Printf style format string of message to display at beginning of riff detail
... : Arguments for msg string
Returns : Detailed message string which is internal to parser and should not be modified or freed. Also note that this string is only valid until the next call to this function.

See Also

IpatchDLSLoader