LONG InvokeHandlers(struct IFFHandle *iff, LONG mode, LONG ident, struct IFFParseBase_intern *IFFParseBase) { struct ContextNode *cn; struct HandlerInfo *hi; struct LocalContextItem *lci; LONG err; /* Either RETURN_2CLIENT or IFFERR_EOC */ LONG stepping_retval; ULONG param; D(bug("InvokeHandlers (Iff=%p, mode=%d, ident=0x%08lx\n", iff, mode, ident )); if (ident == IFFLCI_ENTRYHANDLER) stepping_retval = IFF_RETURN2CLIENT; else stepping_retval = IFFERR_EOC; /* Check for IFFPARSE_RAWSTEP *before* calling evt entryhandlers */ if (mode == IFFPARSE_RAWSTEP) ReturnInt ("InvokeHandlers(1)",LONG,stepping_retval); /* Get top of contextstack */ cn = TopChunk(iff); /* Scan downwards to find a contextnode with a matching LCI */ lci = FindLocalItem ( iff, cn->cn_Type, cn->cn_ID, ident ); if (lci) { /* Get the HandlerInfo userdata */ hi = LocalItemData(lci); /* First check if a hook really is present */ if (! hi->hi_Hook) ReturnInt ("InvokeHandlers",LONG,IFFERR_NOHOOK); /* What kind off command shall the hook receive */ if (ident == IFFLCI_ENTRYHANDLER) param = IFFCMD_ENTRY; else param = IFFCMD_EXIT; /* Call the handler */ if ( (err = CallHookPkt ( hi->hi_Hook, hi->hi_Object, (APTR)param)) ) ReturnInt ("InvokeHandlers(2)",LONG,err); } /* Check for IFFPARSE_STEP. (stepping through file WITH handlers enabled */ if (mode == IFFPARSE_STEP) ReturnInt ("InvokeHandlers(3)",LONG,stepping_retval); ReturnInt ("InvokeHandlers",LONG,0L); }
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; if (node->ci_Data) FreeMem(node->ci_Data, node->ci_Size); FreeMem(node,sizeof (struct CollectionItem)); node = nextnode; } /* Free the local item itself */ FreeLocalItem(lci); return 0; }
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_PROP); 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 */ if ((size = cn->cn_Size)) { buf = AllocMem ( size, MEMF_ANY ); if (!buf) { CF_FreeResources(&resinfo, IFFParseBase); return (IFFERR_NOMEM); } } else buf = NULL; resinfo.Buffer = buf; resinfo.BufferSize = size; if (buf) { /* 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 0; }