Some fixes by MorphOS coders.
[tangerine.git] / workbench / libs / iffparse / collectionhooks.c
blob30c7a2d994dace31fc45bcb45c52f239a3e93407
1 /*
2 Copyright © 1995-2004, The AROS Development Team. All rights reserved.
3 $Id$
5 Hook functions neede for ColectionChunk() entry handlers.
6 */
8 #include "iffparse_intern.h"
12 /****************************/
13 /* CollectionLCI Purge func */
14 /****************************/
16 #define IFFParseBase IPB(hook->h_Data)
18 ULONG CollectionPurgeFunc
20 struct Hook * hook,
21 struct LocalContextItem * lci,
22 ULONG p
25 struct CIPtr *ciptr;
27 struct CollectionItem *node,
28 *nextnode;
30 /* Read the LCI's userdata
32 ciptr = (struct CIPtr*)LocalItemData(lci);
34 /* Free all collectionitems in the linked list */
35 node = ciptr->FirstCI;
37 while (node)
39 nextnode = node->ci_Next;
40 if (node->ci_Data) FreeMem(node->ci_Data, node->ci_Size);
42 FreeMem(node,sizeof (struct CollectionItem));
44 node = nextnode;
47 /* Free the local item itself */
48 FreeLocalItem(lci);
50 return 0;
55 /**********************************/
56 /* CollectionChunk entry-handler */
57 /**********************************/
59 struct CF_ResourceInfo
61 struct LocalContextItem *LCI;
62 APTR Buffer;
63 LONG BufferSize;
64 BOOL LCIStored;
65 struct CollectionItem *CollItem;
68 #undef IFFParseBase
70 VOID CF_FreeResources (struct CF_ResourceInfo * ri,
71 struct IFFParseBase_intern * IFFParseBase)
73 if (ri->LCIStored) Remove((struct Node*)ri->LCI);
74 if (ri->LCI) FreeLocalItem(ri->LCI);
75 if (ri->Buffer) FreeMem(ri->Buffer, ri->BufferSize);
76 if (ri->CollItem) FreeMem(ri->CollItem, sizeof (struct CollectionItem));
78 return;
81 #define IFFParseBase IPB(hook->h_Data)
83 LONG CollectionFunc
85 struct Hook * hook,
86 struct IFFHandle * iff,
87 APTR p
90 struct LocalContextItem *lci;
92 struct ContextNode *cn;
93 struct CIPtr *ciptr;
94 struct CollectionItem *collitem;
96 struct CF_ResourceInfo resinfo = {0}; /* = {0} is important */
100 LONG type,
102 size;
104 LONG bytesread,
105 err;
107 APTR buf;
109 /* The Chunk that caused us to be invoked is always the top chunk */
110 cn = TopChunk(iff);
112 type = cn->cn_Type;
113 id = cn->cn_ID;
115 /* IMPORTANT !! For collectionchunks we MUST check if a collection is allready present,
116 if so there is no clever to add a new one */
118 lci = FindLocalItem
120 iff,
121 type,
123 IFFLCI_COLLECTION
126 if (!lci)
129 /* Allocate new LCI for containing the property */
131 lci = AllocLocalItem
133 type,
135 IFFLCI_COLLECTION,
136 sizeof (struct CIPtr)
138 if (!lci) return (IFFERR_NOMEM);
140 resinfo.LCI = lci;
142 /* Store the new LCI into top of stack */
144 err = StoreLocalItem(iff,lci,IFFSLI_PROP);
146 if (err)
148 CF_FreeResources(&resinfo, IFFParseBase);
149 return (err);
151 resinfo.LCIStored = TRUE;
153 SetLocalItemPurge(lci,&IFFParseBase->collectionpurgehook);
157 /* Allocate a new CollectionItem */
159 collitem = (struct CollectionItem*)AllocMem
161 sizeof (struct CollectionItem),
162 MEMF_ANY|MEMF_CLEAR
165 if (!collitem)
167 CF_FreeResources(&resinfo, IFFParseBase);
168 return (IFFERR_NOMEM);
171 resinfo.CollItem = collitem;
175 /* Allocate buffer to read chunk into */
176 if ((size = cn->cn_Size))
178 buf = AllocMem
180 size,
181 MEMF_ANY
184 if (!buf)
186 CF_FreeResources(&resinfo, IFFParseBase);
187 return (IFFERR_NOMEM);
190 else buf = NULL;
192 resinfo.Buffer = buf;
193 resinfo.BufferSize = size;
195 if (buf)
197 /* Read chunk into the buffer */
199 bytesread = ReadChunkBytes
201 iff,
202 buf,
203 size
206 /* Sucess ? */
207 if (bytesread != size)
209 CF_FreeResources(&resinfo, IFFParseBase);
211 /* IFFERR_.. ? */
212 if (bytesread >= 0)
213 err = IFFERR_MANGLED;
218 /* Get pointer to first ContextItem from LCIs userdata */
219 ciptr = (struct CIPtr*)LocalItemData(lci);
221 /* Update pointers in linked list of collectionitems */
222 collitem->ci_Next = ciptr->FirstCI;
223 ciptr->FirstCI = collitem;
225 collitem->ci_Data = buf;
226 collitem->ci_Size = size;
229 return 0;