RIFFFile Class Reference

Nice class for reading RIFF files, takes a CCFile in the Init() routine to get it's data from. This doesn't view a RIFF file quite how they're actually stored on the disc. It's viewed as a series of Objects. These objects can be Chunks Start of lists End of lists End of file An object inside a list has a higher level than the list and chunks just before the list. You ask for the next object with NextObject(). This reads in the details about the next object in the file, which you can then read with the Get functions. You can get at the data with GetChunkData - this will error if the last object is not a chunk. This function reads the data into a block you give it. Alternatively, use AquireChunkData which will read it into a block maintained by this class. Data is not read unless it has to be. RepeatCurrent() will repeat the current object, giving one level of rewind. Useful for reading files with naff structures. SkipToListEnd() will skip to the end of the list of the level given. More...

#include <rifffile.h>

List of all members.

Public Member Functions

 RIFFFile ()
 Constructor for the RIFFFile class.
 ~RIFFFile ()
 Destructor for the RIFFFile class.
FOURCC Init (CCLexFile *File, BOOL NoHeader=FALSE)
 Initialises the class for reading in a RIFF file. If NoHeader is TRUE then the file has no header and a RIFF chunk is expected to start immediately.
BOOL NextObject (void)
 Initialises the class for reading in a RIFF file.
BOOL GetChunkData (ADDR Block, INT32 Size)
 Gets the all data from a RIFF chunk.
BOOL GetChunkData (ADDR Block, INT32 Size, INT32 Offset)
 Gets a certain amount of the data from a RIFF chunk. ATM it's a bit inefficient.
BOOL AquireChunkData (void)
 Gets the data from a RIFF chunk and puts it into a buffer maintained by the class. Any previous data is lost.
BOOL SkipToListEnd (UINT32 Level)
 Skips to the end of a given level. ListEnd objects are not returned for the lists you skip.
BOOL RepeatCurrent (void)
 Makes the next NextObject return the current object.
BOOL GetListContents (ADDR *Block, INT32 *Size)
 gets the contents from a list. This is in the raw form from the RIFF file
BOOL AquireListContents (INT32 *ListSize)
 Aquires the data of an entire list. Fills in ListSize to be the size of the data.
RIFFObjectType GetObjType (void)
FOURCC GetObjChunkType (void)
INT32 GetObjSize (void)
UINT32 GetObjLevel (void)
ADDR GetAquiredData (void)
INT32 ProgressLimit (void)
INT32 ProgressNow (void)

Static Public Member Functions

static FOURCC CheckRIFFHeader (ADDR Header, DWORD FileSize)
 Checks to see if the header supplied is that of a valid RIFF form. Useful for HowCompatable functions in filter code.
static BOOL FindChunkWithinListContents (ADDR ListContents, INT32 ListSize, FOURCC Type, INT32 Entry, ADDR *Chunk, INT32 *ChunkSize)
 Finds a chunk within a list.

Private Member Functions

 CC_DECLARE_MEMDUMP (RIFFFile)
BOOL EnsureAquiredSizeIsAtLeast (INT32 Size)
 Ensures that the aquired block is at least a certain size.

Private Attributes

CCLexFileFile
RIFFObjectType ObjType
FOURCC ObjChunkType
INT32 ObjSize
UINT32 ObjLevel
INT32 ObjLocation
UINT32 CurrentLevel
INT32 Location
INT32 Size
BOOL GotData
INT32 AlignedObjectSize
List Levels
BOOL RepeatObject
BOOL Error
BYTE * AquiredData
INT32 AquiredDataSize


Detailed Description

Nice class for reading RIFF files, takes a CCFile in the Init() routine to get it's data from. This doesn't view a RIFF file quite how they're actually stored on the disc. It's viewed as a series of Objects. These objects can be Chunks Start of lists End of lists End of file An object inside a list has a higher level than the list and chunks just before the list. You ask for the next object with NextObject(). This reads in the details about the next object in the file, which you can then read with the Get functions. You can get at the data with GetChunkData - this will error if the last object is not a chunk. This function reads the data into a block you give it. Alternatively, use AquireChunkData which will read it into a block maintained by this class. Data is not read unless it has to be. RepeatCurrent() will repeat the current object, giving one level of rewind. Useful for reading files with naff structures. SkipToListEnd() will skip to the end of the list of the level given.

Author:
Ben_Summers (Xara Group Ltd) <camelotdev@xara.com>
Date:
21 03 95
It's recommended that you have a quite shufty at the documentation in the MSDN about RIFF files.

Definition at line 159 of file rifffile.h.


Constructor & Destructor Documentation

RIFFFile::RIFFFile void   ) 
 

Constructor for the RIFFFile class.

Author:
Ben_Summers (Xara Group Ltd) <camelotdev@xara.com>
Date:
21 03 95
Parameters:
[INPUTS] 
Returns:
See also:

Definition at line 133 of file rifffile.cpp.

00134 {
00135     File = NULL;
00136     Error = FALSE;
00137     AquiredData = NULL;
00138 }

RIFFFile::~RIFFFile void   ) 
 

Destructor for the RIFFFile class.

Author:
Ben_Summers (Xara Group Ltd) <camelotdev@xara.com>
Date:
21 03 95
Parameters:
[INPUTS] 
Returns:
See also:

Definition at line 154 of file rifffile.cpp.

00155 {
00156     // get rid of all the list entries in the file
00157     Levels.DeleteAll();
00158 
00159     // Get rid of the aquired object, if there is one
00160     if(AquiredData != 0)
00161         CCFree(AquiredData);
00162 }


Member Function Documentation

BOOL RIFFFile::AquireChunkData void   ) 
 

Gets the data from a RIFF chunk and puts it into a buffer maintained by the class. Any previous data is lost.

Author:
Ben_Summers (Xara Group Ltd) <camelotdev@xara.com>
Date:
21 03 95
Parameters:
none [INPUTS]
Returns:
whether an error occured
See also:

Definition at line 653 of file rifffile.cpp.

00654 {
00655     // check to see if the current object is a chunk
00656     ERROR2IF(ObjType != RIFFOBJECTTYPE_CHUNK, FALSE, "Tried an AquiredChunkData on a non-chunk RIFF object\n");
00657     
00658     // ensure that AquiredData points at enough space for this to be hoopy
00659     if(!EnsureAquiredSizeIsAtLeast(ObjSize))
00660         return FALSE;
00661 
00662     // there is at enough space in AquiredData to store the current object
00663     // use GetChunkData on it
00664 
00665     return GetChunkData(AquiredData, AquiredDataSize);
00666 }

BOOL RIFFFile::AquireListContents INT32 *  ListSize  ) 
 

Aquires the data of an entire list. Fills in ListSize to be the size of the data.

Author:
Ben_Summers (Xara Group Ltd) <camelotdev@xara.com>
Date:
06/06/95
Parameters:
none [INPUTS]
Returns:
whether an error occured
See also:

Definition at line 683 of file rifffile.cpp.

00684 {
00685     ERROR2IF(ObjType != RIFFOBJECTTYPE_LISTSTART, FALSE, "Tried an GetListContents on a non-list start RIFF object\n");
00686 
00687     // OK, first thing we need to do is to get the list's header... where is it?
00688     INT32 StartLocation = Location - sizeof(RIFFck) - sizeof(RIFFFile_List);
00689 
00690     // seek there
00691     if(File->seek(StartLocation).bad())
00692     {
00693         RIFFFILE_RETURNERR;
00694     }
00695 
00696     // OK, get the chunk header (not the list header which gives it's type
00697     RIFFck ChunkHeader;
00698 
00699     if(File->read(&ChunkHeader, sizeof(ChunkHeader)).bad())
00700     {
00701         RIFFFILE_RETURNERR;
00702     }
00703 
00704     // right then, we now know how much data we need to extract from the file...
00705     INT32 ContentsSize =    RIFFDATA_DWORD(ChunkHeader.ckSize) + sizeof(RIFFck);
00706 
00707     // now we need a block of data to get it into
00708     if(!EnsureAquiredSizeIsAtLeast(ContentsSize))
00709         return FALSE;
00710 
00711     // and getting it would be a cunning plan! seek to the beginning
00712     if(File->seek(StartLocation).bad())
00713     {
00714         RIFFFILE_RETURNERR;
00715     }
00716 
00717     // grab the data
00718     if(File->read(AquiredData, ContentsSize).bad())
00719     {
00720         RIFFFILE_RETURNERR;
00721     }
00722     
00723     // seek back to the location we were at the beginning
00724     if(File->seek(Location).bad())
00725     {
00726         RIFFFILE_RETURNERR;
00727     }
00728 
00729     // and set up the return values
00730     *ListSize = ContentsSize;
00731     
00732     return TRUE;
00733 }

RIFFFile::CC_DECLARE_MEMDUMP RIFFFile   )  [private]
 

FOURCC RIFFFile::CheckRIFFHeader ADDR  Header,
DWORD  Size
[static]
 

Checks to see if the header supplied is that of a valid RIFF form. Useful for HowCompatable functions in filter code.

Author:
Ben_Summers (Xara Group Ltd) <camelotdev@xara.com>
Date:
21 03 95
Parameters:
None [INPUTS]
Returns:
0 = not a RIFF file other = RIFF form type
See also:

Definition at line 235 of file rifffile.cpp.

00236 {
00237 PORTNOTE("byteorder", "TODO: Check byte ordering")
00238     RIFFFile_Header *Hdr = (RIFFFile_Header *)Header;
00239 
00240     if(RIFFDATA_FOURCC(Hdr->CK.ckID) != RIFFTYPE_RIFF)
00241         return 0;       // file doesn't start "RIFF"
00242 
00243     if(RIFFDATA_DWORD(Hdr->CK.ckSize) > (Size - sizeof(RIFFFile_Header)) &&
00244                 RIFFDATA_DWORD(Hdr->CK.ckSize) < (Size - sizeof(RIFFFile_Header)))
00245         return 0;       // Size doesn't match that in header. Be a bit relaxed about exact lengths
00246 
00247     return Hdr->FormType;
00248 }

BOOL RIFFFile::EnsureAquiredSizeIsAtLeast INT32  Size  )  [private]
 

Ensures that the aquired block is at least a certain size.

Author:
Ben_Summers (Xara Group Ltd) <camelotdev@xara.com>
Date:
06/06/95
Parameters:
minimum size required [INPUTS]
Returns:
whether an error occured
See also:

Definition at line 619 of file rifffile.cpp.

00620 {
00621     if(AquiredData == 0 || AquiredDataSize < Size)
00622     {
00623         if(AquiredData != 0) 
00624         {
00625             CCFree(AquiredData);
00626             AquiredData = 0;
00627         }
00628 
00629         if((AquiredData = (BYTE *)CCMalloc(Size)) == 0)
00630             RIFFFILE_RETURNERR;
00631 
00632         AquiredDataSize = Size;
00633     }
00634 
00635     return TRUE;
00636 }

BOOL RIFFFile::FindChunkWithinListContents ADDR  ListContents,
INT32  ListSize,
FOURCC  Type,
INT32  Entry,
ADDR Chunk,
INT32 *  ChunkSize
[static]
 

Finds a chunk within a list.

Author:
Ben_Summers (Xara Group Ltd) <camelotdev@xara.com>
Date:
06/06/95
Parameters:
ListContents Pointer to list contents [INPUTS] ListSize Size of the list Type Type of chunk required Entry The number of that type of chunk to skip Chunk Pointer to a pointer to a chunk to be filled in ChunkSize Pointer to a value to be filled in with the chunk length.
Returns:
whether the chunk could be found

Definition at line 849 of file rifffile.cpp.

00851 {
00852     RIFFck *Header;
00853     INT32 OffsetWithin = sizeof(RIFFck) + sizeof(RIFFFile_List);
00854 
00855     while(OffsetWithin < ListSize)
00856     {
00857         Header = (RIFFck *)(ListContents + OffsetWithin);
00858 
00859         INT32 Size = RIFFDATA_DWORD(Header->ckSize);
00860         if(RIFFDATA_FOURCC(Header->ckID) == Type)
00861         {
00862             if(Entry <= 0)
00863             {
00864                 // return this one...
00865                 if(Chunk != 0)
00866                     (*Chunk) = ListContents + OffsetWithin + sizeof(RIFFck);
00867 
00868                 if(ChunkSize != 0)
00869                     (*ChunkSize) = Size;
00870 
00871                 return TRUE;
00872             }
00873             else
00874             {
00875                 Entry--;
00876             }
00877         }
00878         OffsetWithin += Size + sizeof(RIFFck);
00879     }
00880 
00881     return FALSE;
00882 }

ADDR RIFFFile::GetAquiredData void   )  [inline]
 

Definition at line 187 of file rifffile.h.

00187 {return AquiredData;}

BOOL RIFFFile::GetChunkData ADDR  Block,
INT32  BSize,
INT32  Offset
 

Gets a certain amount of the data from a RIFF chunk. ATM it's a bit inefficient.

Author:
Ben_Summers (Xara Group Ltd) <camelotdev@xara.com>
Date:
21 03 95
Parameters:
Pointer to the block where you want the data, and the size of the block [INPUTS] and the offset within the block of the data you want
Returns:
whether an error occured
See also:

Definition at line 505 of file rifffile.cpp.

00506 {
00507     // first of all, check to see if the caller has been a little bit silly
00508     if(ObjType != RIFFOBJECTTYPE_CHUNK)
00509     {
00510         Error = TRUE;       // only chunks have getable data
00511         ERROR2(FALSE, "RIFFFile::GetChunkData called for a non-chunk object\n");
00512     }
00513 
00514     // check offset is OK
00515     if(Offset >= ObjSize)
00516         Offset = ObjSize - 1;
00517 
00518     // check that we'll be grabbing a nice amount of data
00519     if((Offset + BSize) > ObjSize)
00520         BSize = ObjSize - Offset;
00521     
00522     // don't do anything if there's no data to get
00523     if(BSize <= 0)
00524         return TRUE;
00525     
00526     // where in the file do we wish to get data from?
00527     INT32 TargetLocation = ObjLocation + Offset;
00528 
00529     // seek to the data we want, but only if it's necessary
00530     if(TargetLocation != Location)
00531     {
00532         if(File->seek(TargetLocation).bad())
00533             RIFFFILE_RETURNERR;
00534     
00535         Location = TargetLocation;
00536     }
00537 
00538     // and get that data!
00539     if(File->read(Block, BSize).bad())
00540     {
00541 TRACEUSER( "Ben", _T("RIFFFile: file error when reading chunk data\n"));
00542         RIFFFILE_RETURNERR;
00543     }
00544 
00545     // update locations
00546     Location += BSize;
00547 
00548     // and set an essential flag!
00549     GotData = TRUE;
00550 
00551     return TRUE;
00552 }

BOOL RIFFFile::GetChunkData ADDR  Block,
INT32  BSize
 

Gets the all data from a RIFF chunk.

Author:
Ben_Summers (Xara Group Ltd) <camelotdev@xara.com>
Date:
21 03 95
Parameters:
Pointer to the block where you want the data, and the size of the block [INPUTS]
Returns:
whether an error occured
See also:

Definition at line 437 of file rifffile.cpp.

00438 {
00439     // first of all, check to see if the caller has been a little bit silly
00440     if(ObjType != RIFFOBJECTTYPE_CHUNK)
00441     {
00442         Error = TRUE;       // only chunks have getable data
00443         ERROR2(FALSE, "RIFFFile::GetChunkData called for a non-chunk object\n");
00444     }
00445 
00446     if(BSize < ObjSize)
00447     {
00448         Error = TRUE;       // wrong size...
00449         ERROR2(FALSE, "RIFFFile::GetChunkData called with a block which is just *too* small\n");
00450     }
00451 
00452     // has the data already been got for this object?
00453     if(GotData)
00454     {
00455         // yep, go back and get it again
00456 TRACEUSER( "Ben", _T("Chunk data asked for more than once\n"));
00457         if(File->seek(ObjLocation).bad())
00458             RIFFFILE_RETURNERR;
00459 
00460         Location = ObjLocation;
00461     }
00462 
00463     // and get that data!
00464     if(File->read(Block, ObjSize).bad())
00465     {
00466 TRACEUSER( "Ben", _T("RIFFFile: file error when reading chunk data\n"));
00467         RIFFFILE_RETURNERR;
00468     }
00469 
00470     // ensure alignment is maintained within the file
00471     if(ObjSize != AlignedObjectSize)
00472     {
00473         // read a byte to align this to the correct position
00474         BYTE junk;
00475 
00476         if(File->read(&junk, sizeof(junk)).bad())
00477             RIFFFILE_RETURNERR;
00478     }
00479 
00480     // update locations
00481     Location += AlignedObjectSize;
00482 
00483     // and set an essential flag!
00484     GotData = TRUE;
00485 
00486     return TRUE;
00487 }

BOOL RIFFFile::GetListContents ADDR Block,
INT32 *  Size
 

gets the contents from a list. This is in the raw form from the RIFF file

Author:
Ben_Summers (Xara Group Ltd) <camelotdev@xara.com>
Date:
19/04/95
Parameters:
pointer to a pointer for the block address, pointer to size to return size [INPUTS]
Returns:
whether an error occured
See also:

Definition at line 775 of file rifffile.cpp.

00776 {
00777     ERROR2IF(ObjType != RIFFOBJECTTYPE_LISTSTART, FALSE, "Tried an GetListContents on a non-list start RIFF object\n");
00778 
00779     // OK, first thing we need to do is to get the list's header... where is it?
00780     INT32 StartLocation = Location - sizeof(RIFFck) - sizeof(RIFFFile_List);
00781 
00782     // seek there
00783     if(File->seek(StartLocation).bad())
00784     {
00785         RIFFFILE_RETURNERR;
00786     }
00787 
00788     // OK, get the chunk header (not the list header which gives it's type
00789     RIFFck ChunkHeader;
00790 
00791     if(File->read(&ChunkHeader, sizeof(ChunkHeader)).bad())
00792     {
00793         RIFFFILE_RETURNERR;
00794     }
00795 
00796     // right then, we now know how much data we need to extract from the file...
00797     INT32 ContentsSize =    RIFFDATA_DWORD(ChunkHeader.ckSize) + sizeof(RIFFck);
00798 
00799     // now we need a block of data to get it into
00800     ADDR Contents = (ADDR)CCMalloc(ContentsSize);
00801     
00802     if(Contents == 0)
00803         return FALSE;
00804 
00805     // and getting it would be a cunning plan! seek to the beginning
00806     if(File->seek(StartLocation).bad())
00807     {
00808         RIFFFILE_RETURNERR;
00809     }
00810 
00811     // grab the data
00812     if(File->read(Contents, ContentsSize).bad())
00813     {
00814         RIFFFILE_RETURNERR;
00815     }
00816     
00817     // seek back to the location we were at the beginning
00818     if(File->seek(Location).bad())
00819     {
00820         RIFFFILE_RETURNERR;
00821     }
00822 
00823     // and set up the return values
00824     *Block = Contents;
00825     *Size = ContentsSize;
00826     
00827     return TRUE;
00828 }

FOURCC RIFFFile::GetObjChunkType void   )  [inline]
 

Definition at line 184 of file rifffile.h.

00184 {return ObjChunkType;}

UINT32 RIFFFile::GetObjLevel void   )  [inline]
 

Definition at line 186 of file rifffile.h.

00186 {return ObjLevel;}

INT32 RIFFFile::GetObjSize void   )  [inline]
 

Definition at line 185 of file rifffile.h.

00185 {return ObjSize;}

RIFFObjectType RIFFFile::GetObjType void   )  [inline]
 

Definition at line 183 of file rifffile.h.

00183 {return ObjType;}

FOURCC RIFFFile::Init CCLexFile pFile,
BOOL  NoHeader = FALSE
 

Initialises the class for reading in a RIFF file. If NoHeader is TRUE then the file has no header and a RIFF chunk is expected to start immediately.

Author:
Ben_Summers (Xara Group Ltd) <camelotdev@xara.com>
Date:
21/03/95
Parameters:
File to read from, whether it has a header [INPUTS]
Returns:
0 = not a RIFF file 1 = error occured other = RIFF form type
See also:

Definition at line 181 of file rifffile.cpp.

00182 {
00183     // store Mr. NiceCCFile
00184     File = pFile;
00185 
00186     FOURCC FileType = 0;
00187 
00188     // if this file has a header, check it and get the type
00189     if(!NoHeader)
00190     {
00191         // read in the header of the file
00192         RIFFFile_Header Header;
00193 
00194         if(File->read(&Header, sizeof(Header)).bad())
00195             return FALSE;
00196 
00197     
00198         // and check it for being a valid form
00199         FileType = CheckRIFFHeader((ADDR)&Header, File->Size());
00200 
00201         // and was it?
00202         if(FileType == 0)
00203           return 0;     // not a RIFF form
00204     }
00205         
00206     // OK, set up lots of nice variables for the funky business of RIFF reading
00207     ObjType = RIFFOBJECTTYPE_NONE;
00208     RepeatObject = FALSE;
00209     Error = FALSE;
00210     Location = NoHeader?0:sizeof(RIFFFile_Header);
00211     Size = File->Size();
00212     GotData = FALSE;
00213     CurrentLevel = 0;
00214     AquiredData = 0;
00215     AlignedObjectSize = 0;
00216 
00217     return FileType;
00218 }

BOOL RIFFFile::NextObject void   ) 
 

Initialises the class for reading in a RIFF file.

Author:
Ben_Summers (Xara Group Ltd) <camelotdev@xara.com>
Date:
21 03 95
Parameters:
None [INPUTS]
Returns:
whether an error occured
See also:

Definition at line 264 of file rifffile.cpp.

00265 {
00266     if(Error)
00267         return FALSE;
00268 
00269     // do we need to return the current object again?
00270     if(RepeatObject)
00271     {
00272         RepeatObject = FALSE;
00273         return TRUE;            // all data nicely set up already
00274     }
00275 
00276     // skip over any data it it hasn't already been got
00277     if(ObjType == RIFFOBJECTTYPE_CHUNK && (GotData == FALSE || Location != (ObjLocation + AlignedObjectSize)))
00278     {
00279         if(File->seek(ObjLocation + AlignedObjectSize).bad()) {
00280 TRACEUSER( "Ben", _T("RIFFFile: Error on seek when jumping object data\n"));
00281             RIFFFILE_RETURNERR;
00282         }
00283 
00284         Location = ObjLocation + AlignedObjectSize;
00285 
00286         // as we may come this way again...
00287         GotData = TRUE;
00288     }
00289 
00290     // have we gone past the end of the file?
00291     if(Location >= Size)
00292     //if (File->eof())
00293     {
00294         // Yes. Firstly, ensure that all the lists got the end list thingy - is the list empty?
00295         if(!Levels.IsEmpty())
00296         {
00297 TRACEUSER( "Ben", _T("RIFFFile: Ending... terminating list\n"));
00298             RIFFFileLevel *Level = (RIFFFileLevel *)Levels.GetTail();
00299 
00300             ERROR3IF(Level == NULL, "List class returned a null tail for a non empty list! Help!");
00301             
00302             // set up a nice list end object
00303             ObjType = RIFFOBJECTTYPE_LISTEND;
00304             ObjChunkType = Level->Type;
00305             ObjLevel = CurrentLevel;
00306             ObjLocation = Location;
00307             GotData = TRUE;
00308 
00309             // level down one
00310             CurrentLevel--;
00311 
00312             // get rid of the last level on the list
00313             delete Levels.RemoveTail();
00314 
00315             return TRUE;
00316         }
00317 
00318         // And if they all have, say that the file ended
00319         ObjType = RIFFOBJECTTYPE_FILEEND;
00320         ObjChunkType = 0;
00321         ObjSize = 0;
00322         ObjLevel = 0;
00323         ObjLocation = Location;
00324         GotData = TRUE;
00325 TRACEUSER( "Ben", _T("returning file end\n"));
00326         return TRUE;
00327     }
00328 
00329     // check to see if the current list has ended
00330     if(!Levels.IsEmpty())
00331     {
00332         RIFFFileLevel *Level = (RIFFFileLevel *)Levels.GetTail();
00333         
00334         ERROR3IF(Level == NULL, "List class returned a null tail for a non empty list! Help!");
00335 
00336         if(Location >= Level->End)
00337         {
00338             // RIFF list has ended
00339             ObjType = RIFFOBJECTTYPE_LISTEND;
00340             ObjChunkType = Level->Type;
00341             ObjLevel = CurrentLevel;
00342             ObjSize = 0;
00343             ObjLocation = Location;
00344             GotData = TRUE;
00345             
00346             // down a level
00347             CurrentLevel--;
00348 
00349             // delete the last entry in the list
00350             delete Levels.RemoveTail();
00351 
00352             return TRUE;
00353         }
00354     }
00355 
00356     // right then, let's see what the next object in the file is.
00357     RIFFck ChunkHeader;
00358 
00359     if(File->read(&ChunkHeader, sizeof(ChunkHeader)).bad())
00360     {
00361 TRACEUSER( "Ben", _T("RIFFFile: file error on reading chunk header\n"));
00362         RIFFFILE_RETURNERR;
00363     }
00364 
00365     Location += sizeof(ChunkHeader);
00366 
00367     // is it a list chunk?
00368     if(RIFFDATA_FOURCC(ChunkHeader.ckID) == RIFFTYPE_LIST)
00369     {
00370         // yep... process it
00371         RIFFFile_List ListHdr;
00372 
00373         // read in a list header
00374         if(File->read(&ListHdr, sizeof(ListHdr)).bad())
00375         {
00376 TRACEUSER( "Ben", _T("RIFFFile: file error on reading list id\n"));
00377             RIFFFILE_RETURNERR;
00378         }
00379 
00380         Location += sizeof(ListHdr);
00381 
00382         // make a new entry in the list
00383         RIFFFileLevel *NewLevel;
00384 
00385         if((NewLevel = new RIFFFileLevel) == 0)
00386             RIFFFILE_RETURNERR;
00387 
00388         NewLevel->Start = Location;
00389         NewLevel->End = Location + ALIGNSIZE(RIFFDATA_DWORD(ChunkHeader.ckSize)) - sizeof(ListHdr);
00390         NewLevel->Type = RIFFDATA_FOURCC(ListHdr.ListType);
00391 
00392         // and add it to the list
00393         Levels.AddTail(NewLevel);
00394 
00395         // up a level
00396         CurrentLevel++;
00397         
00398         // return a nice list start object
00399         ObjType = RIFFOBJECTTYPE_LISTSTART;
00400         ObjChunkType = RIFFDATA_FOURCC(ListHdr.ListType);
00401         ObjSize = 0;
00402         ObjLevel = CurrentLevel;
00403         ObjLocation = Location;
00404         GotData = TRUE;
00405         return TRUE;
00406     }
00407 
00408     // and after all that excitement, if it was just a normal, boring chunk, return stuff about that
00409     ObjType = RIFFOBJECTTYPE_CHUNK;
00410     ObjChunkType = RIFFDATA_FOURCC(ChunkHeader.ckID);
00411     ObjSize = RIFFDATA_DWORD(ChunkHeader.ckSize);
00412     ObjLevel = CurrentLevel;
00413     ObjLocation = Location;
00414 
00415     // set up some useful data
00416     GotData = FALSE;
00417     AlignedObjectSize = ALIGNSIZE(ObjSize);
00418 
00419     // and that's all folks
00420     return TRUE;
00421 }

INT32 RIFFFile::ProgressLimit void   )  [inline]
 

Definition at line 189 of file rifffile.h.

00189 {return Size;}          // the last value progress will return

INT32 RIFFFile::ProgressNow void   )  [inline]
 

Definition at line 190 of file rifffile.h.

00190 {return Location;}      // the current position for the progress bar

BOOL RIFFFile::RepeatCurrent void   ) 
 

Makes the next NextObject return the current object.

Author:
Ben_Summers (Xara Group Ltd) <camelotdev@xara.com>
Date:
21 03 95
Parameters:
none [INPUTS]
Returns:
whether an error occured
See also:

Definition at line 749 of file rifffile.cpp.

00750 {
00751     if(RepeatObject == TRUE)
00752     {
00753 TRACEUSER( "Ben", _T("RepeatObject already set for this object...\n"));
00754     }
00755 
00756     RepeatObject = TRUE;
00757 
00758     return TRUE;
00759 }

BOOL RIFFFile::SkipToListEnd UINT32  LevelNumber  ) 
 

Skips to the end of a given level. ListEnd objects are not returned for the lists you skip.

Author:
Ben_Summers (Xara Group Ltd) <camelotdev@xara.com>
Date:
21 03 95
Parameters:
The level number of the list to skip to the end of [INPUTS]
Returns:
whether an error occured
See also:

Definition at line 569 of file rifffile.cpp.

00570 {
00571     RIFFFileLevel *Level;
00572     RIFFFileLevel *Next;
00573 
00574 TRACEUSER( "Ben", _T("SkipToListEnd called to level %d\n"), LevelNumber);
00575     Level = (RIFFFileLevel *)Levels.FindItem(LevelNumber - 1);
00576                 // - 1 because level 0 doesn't have an entry as
00577                 // it's the root level of the file
00578 
00579     ERROR2IF(Level == 0, FALSE, "Couldn't find given level to jump to in list");
00580 
00581     // seek to the end of the level
00582     if(File->seek(Level->End).bad())
00583     {
00584 TRACEUSER( "Ben", _T("RIFFFile: file error when seeking to end of level\n"));
00585         RIFFFILE_RETURNERR;
00586     }
00587 
00588     // update the location
00589     Location = Level->End;
00590 
00591     // update the level we're at
00592     CurrentLevel = LevelNumber - 1;
00593     
00594     // remove the last few entries from the list, including this one
00595     while(Level != 0)
00596     {
00597         Next = (RIFFFileLevel *)Levels.GetNext(Level);
00598         delete Levels.RemoveItem(Level);
00599         Level = Next;
00600     }   
00601 
00602     return TRUE;
00603 }


Member Data Documentation

INT32 RIFFFile::AlignedObjectSize [private]
 

Definition at line 209 of file rifffile.h.

BYTE* RIFFFile::AquiredData [private]
 

Definition at line 219 of file rifffile.h.

INT32 RIFFFile::AquiredDataSize [private]
 

Definition at line 220 of file rifffile.h.

UINT32 RIFFFile::CurrentLevel [private]
 

Definition at line 201 of file rifffile.h.

BOOL RIFFFile::Error [private]
 

Definition at line 217 of file rifffile.h.

CCLexFile* RIFFFile::File [private]
 

Definition at line 193 of file rifffile.h.

BOOL RIFFFile::GotData [private]
 

Definition at line 206 of file rifffile.h.

List RIFFFile::Levels [private]
 

Definition at line 212 of file rifffile.h.

INT32 RIFFFile::Location [private]
 

Definition at line 203 of file rifffile.h.

FOURCC RIFFFile::ObjChunkType [private]
 

Definition at line 196 of file rifffile.h.

UINT32 RIFFFile::ObjLevel [private]
 

Definition at line 198 of file rifffile.h.

INT32 RIFFFile::ObjLocation [private]
 

Definition at line 199 of file rifffile.h.

INT32 RIFFFile::ObjSize [private]
 

Definition at line 197 of file rifffile.h.

RIFFObjectType RIFFFile::ObjType [private]
 

Definition at line 195 of file rifffile.h.

BOOL RIFFFile::RepeatObject [private]
 

Definition at line 216 of file rifffile.h.

INT32 RIFFFile::Size [private]
 

Definition at line 204 of file rifffile.h.


The documentation for this class was generated from the following files:
Generated on Sat Nov 10 04:00:35 2007 for Camelot by  doxygen 1.4.4