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); }
VOID PopContextNode(struct IFFHandle* iff, struct IFFParseBase_intern *IFFParseBase) { struct LocalContextItem *node, *nextnode; struct IntContextNode *cn; D(bug("PopContextNode(iff=%p)\n", iff)); cn = GetIntCN( TopChunk( iff ) ); if (cn) { D(bug("(%c%c%c%c, %c%c%c%c)\n", dmkid(cn->CN.cn_Type), dmkid(cn->CN.cn_ID) )); } else { D(bug("\n")); } /* Free all localcontextitems */ node = (struct LocalContextItem*)cn->cn_LCIList.mlh_Head; while ((nextnode = (struct LocalContextItem*)node->lci_Node.mln_Succ)) { PurgeLCI((struct LocalContextItem*)node, IFFParseBase); node = nextnode; } /* Free the contextnode itself */ Remove((struct Node*)cn); FreeMem(cn,sizeof (struct IntContextNode)); /*One less node on stack */ iff->iff_Depth --; }
LONG PushContextNode ( struct IFFHandle *iff, LONG type, LONG id, LONG size, LONG scan, struct IFFParseBase_intern *IFFParseBase ) { /* Allocates and puts a new context-node into the top of the context-stack Also does GoodType and GoodID checking */ struct ContextNode *cn; BOOL composite; D(bug("PushContextNode(iff=%p, type=%c%c%c%c, id=%c%c%c%c, size=%d, scan=%d)\n", iff, dmkid(type), dmkid(id), size, scan )); /* Set the composite flag if we have a composite contextnnode */ if (id == ID_FORM || id == ID_LIST || id == ID_CAT || id == ID_PROP) { composite = TRUE; /* We have a new type, check it */ } else { composite = FALSE; /* No composite type found. Get old type from top contextnode */ cn = TopChunk(iff); type = cn->cn_Type; } /* Check if type and ids are valid */ if (!(GoodType(type) && GoodID(id)) ) ReturnInt ("PushContextNode",LONG,IFFERR_MANGLED); /* Allocate a new context node */ if ( !(cn = AllocMem ( sizeof (struct IntContextNode), MEMF_ANY ) ) ) ReturnInt ("PushContextNode",LONG,IFFERR_NOMEM); /* Put the context node at top of the stack */ AddHead ( (struct List*)&( GetIntIH(iff)->iff_CNStack ), (struct Node*)cn ); /* Set the contextnode attrs */ cn->cn_Type = type; cn->cn_ID = id; cn->cn_Size = size; cn->cn_Scan = scan; GetIntCN(cn)->cn_Composite = composite; /* Initialize the LCI-list */ NewList ((struct List*)&( GetIntCN(cn)->cn_LCIList )); /* Deeper stack */ iff->iff_Depth ++; ReturnInt ("PushContextNode",LONG,0L); }
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; }