home *** CD-ROM | disk | FTP | other *** search
- /*
- (C) 1995-96 AROS - The Amiga Replacement OS
- $Id: collectionhooks.c,v 1.2 1997/02/03 18:38:01 digulla Exp $
-
- Desc: Hook functions neede for ColectionChunk() entry handlers.
- Lang: English.
- */
-
- #include "iffparse_intern.h"
-
-
-
- /****************************/
- /* CollectionLCI Purge func */
- /****************************/
-
- #undef SysBase
- #define SysBase IPB(hook->h_Data)->sysbase
- #define IFFParseBase IPB(hook->h_Data)
-
- ULONG CollectionPurgeFunc
- (
- struct Hook * hook,
- struct LocalContextItem * lci,
- ULONG p
- )
- {
- struct CIPtr *ciptr;
-
- struct CollectionItem *node,
- *nextnode;
-
- /* Read the LCI's userdata
- */
- ciptr = (struct CIPtr*)LocalItemData(lci);
-
- /* Free all collectionitems in the linked list */
- node = ciptr->FirstCI;
-
- while (node)
- {
- nextnode = node->ci_Next;
- FreeMem(node->ci_Data, node->ci_Size);
-
- FreeMem(node,sizeof (struct CollectionItem));
-
- node = nextnode;
- }
-
- /* Free the local item itself */
- FreeLocalItem(lci);
-
- return (NULL);
- }
-
-
-
- /**********************************/
- /* CollectionChunk entry-handler */
- /**********************************/
-
- struct CF_ResourceInfo
- {
- struct LocalContextItem *LCI;
- APTR Buffer;
- LONG BufferSize;
- BOOL LCIStored;
- struct CollectionItem *CollItem;
- };
-
- #undef SysBase
- #define SysBase IFFParseBase->sysbase
- #undef IFFParseBase
-
- VOID CF_FreeResources (struct CF_ResourceInfo * ri,
- struct IFFParseBase_intern * IFFParseBase)
- {
- if (ri->LCIStored) Remove((struct Node*)ri->LCI);
- if (ri->LCI) FreeLocalItem(ri->LCI);
- if (ri->Buffer) FreeMem(ri->Buffer, ri->BufferSize);
- if (ri->CollItem) FreeMem(ri->CollItem, sizeof (struct CollectionItem));
-
- return;
- }
-
- #undef SysBase
- #define SysBase IPB(hook->h_Data)->sysbase
- #define IFFParseBase IPB(hook->h_Data)
-
- LONG CollectionFunc
- (
- struct Hook * hook,
- struct IFFHandle * iff,
- APTR p
- )
- {
- struct LocalContextItem *lci;
-
- struct ContextNode *cn;
- struct CIPtr *ciptr;
- struct CollectionItem *collitem;
-
- struct CF_ResourceInfo resinfo = {0}; /* = {0} is important */
-
-
-
- LONG type,
- id,
- size;
-
- LONG bytesread,
- err;
-
- APTR buf;
-
- /* The Chunk that caused us to be invoked is always the top chunk */
- cn = TopChunk(iff);
-
- type = cn->cn_Type;
- id = cn->cn_ID;
-
- /* IMPORTANT !! For collectionchunks we MUST check if a collection is allready present,
- if so there is no clever to add a new one */
-
- lci = FindLocalItem
- (
- iff,
- type,
- id,
- IFFLCI_COLLECTION
- );
-
- if (!lci)
- {
-
- /* Allocate new LCI for containing the property */
-
- lci = AllocLocalItem
- (
- type,
- id,
- IFFLCI_COLLECTION,
- sizeof (struct CIPtr)
- );
- if (!lci) return (IFFERR_NOMEM);
-
- resinfo.LCI = lci;
-
- /* Store the new LCI into top of stack */
-
- err = StoreLocalItem(iff,lci,IFFSLI_ROOT);
-
- if (err)
- {
- CF_FreeResources(&resinfo, IFFParseBase);
- return (err);
- }
- resinfo.LCIStored = TRUE;
-
- SetLocalItemPurge(lci,&IFFParseBase->collectionpurgehook);
-
- }
-
- /* Allocate a new CollectionItem */
-
- collitem = (struct CollectionItem*)AllocMem
- (
- sizeof (struct CollectionItem),
- MEMF_ANY|MEMF_CLEAR
- );
-
- if (!collitem)
- {
- CF_FreeResources(&resinfo, IFFParseBase);
- return (IFFERR_NOMEM);
- }
-
- resinfo.CollItem = collitem;
-
-
-
- /* Allocate buffer to read chunk into */
- size = cn->cn_Size;
-
- buf = AllocMem
- (
- size,
- MEMF_ANY
- );
-
- if (!buf)
- {
- CF_FreeResources(&resinfo, IFFParseBase);
- return (IFFERR_NOMEM);
- }
-
- resinfo.Buffer = buf;
- resinfo.BufferSize = size;
-
-
- /* Read chunk into the buffer */
-
- bytesread = ReadChunkBytes
- (
- iff,
- buf,
- size
- );
-
- /* Sucess ? */
- if (bytesread != size)
- {
- CF_FreeResources(&resinfo, IFFParseBase);
-
- /* IFFERR_.. ? */
- if (bytesread >= 0)
- err = IFFERR_MANGLED;
- }
-
-
- /* Get pointer to first ContextItem from LCIs userdata */
- ciptr = (struct CIPtr*)LocalItemData(lci);
-
- /* Update pointers in linked list of collectionitems */
- collitem->ci_Next = ciptr->FirstCI;
- ciptr->FirstCI = collitem;
-
- collitem->ci_Data = buf;
- collitem->ci_Size = size;
-
-
- return (NULL);
- }
-