home *** CD-ROM | disk | FTP | other *** search
/ Aminet 18 / aminetcdnumber181997.iso / Aminet / misc / emu / AROSdev.lha / AROS / workbench / libs / iffparse / collectionhooks.c < prev    next >
Encoding:
C/C++ Source or Header  |  1997-02-03  |  4.2 KB  |  234 lines

  1. /*
  2.     (C) 1995-96 AROS - The Amiga Replacement OS
  3.     $Id: collectionhooks.c,v 1.2 1997/02/03 18:38:01 digulla Exp $
  4.  
  5.     Desc: Hook functions neede for ColectionChunk() entry handlers.
  6.     Lang: English.
  7. */
  8.  
  9. #include "iffparse_intern.h"
  10.  
  11.  
  12.  
  13. /****************************/
  14. /* CollectionLCI Purge func  */
  15. /****************************/
  16.  
  17. #undef SysBase
  18. #define SysBase     IPB(hook->h_Data)->sysbase
  19. #define IFFParseBase    IPB(hook->h_Data)
  20.  
  21. ULONG CollectionPurgeFunc
  22. (
  23.     struct Hook         * hook,
  24.     struct LocalContextItem * lci,
  25.     ULONG              p
  26. )
  27. {
  28.     struct CIPtr       *ciptr;
  29.  
  30.     struct CollectionItem  *node,
  31.               *nextnode;
  32.  
  33.     /* Read the LCI's userdata
  34.     */
  35.     ciptr = (struct CIPtr*)LocalItemData(lci);
  36.  
  37.     /* Free all collectionitems in the linked list */
  38.     node = ciptr->FirstCI;
  39.  
  40.     while (node)
  41.     {
  42.     nextnode = node->ci_Next;
  43.     FreeMem(node->ci_Data, node->ci_Size);
  44.  
  45.     FreeMem(node,sizeof (struct CollectionItem));
  46.  
  47.     node = nextnode;
  48.     }
  49.  
  50.     /* Free the local item itself */
  51.     FreeLocalItem(lci);
  52.  
  53.     return (NULL);
  54. }
  55.  
  56.  
  57.  
  58. /**********************************/
  59. /* CollectionChunk entry-handler  */
  60. /**********************************/
  61.  
  62. struct CF_ResourceInfo
  63. {
  64.     struct LocalContextItem *LCI;
  65.     APTR            Buffer;
  66.     LONG            BufferSize;
  67.     BOOL            LCIStored;
  68.     struct CollectionItem    *CollItem;
  69. };
  70.  
  71. #undef SysBase
  72. #define SysBase     IFFParseBase->sysbase
  73. #undef IFFParseBase
  74.  
  75. VOID CF_FreeResources (struct CF_ResourceInfo * ri,
  76.     struct IFFParseBase_intern * IFFParseBase)
  77. {
  78.     if (ri->LCIStored)  Remove((struct Node*)ri->LCI);
  79.     if (ri->LCI)        FreeLocalItem(ri->LCI);
  80.     if (ri->Buffer)     FreeMem(ri->Buffer,   ri->BufferSize);
  81.     if (ri->CollItem)   FreeMem(ri->CollItem,  sizeof (struct CollectionItem));
  82.  
  83.     return;
  84. }
  85.  
  86. #undef SysBase
  87. #define SysBase     IPB(hook->h_Data)->sysbase
  88. #define IFFParseBase    IPB(hook->h_Data)
  89.  
  90. LONG CollectionFunc
  91. (
  92.     struct Hook     * hook,
  93.     struct IFFHandle    * iff,
  94.     APTR          p
  95. )
  96. {
  97.     struct LocalContextItem *lci;
  98.  
  99.     struct ContextNode        *cn;
  100.     struct CIPtr        *ciptr;
  101.     struct CollectionItem    *collitem;
  102.  
  103.     struct CF_ResourceInfo resinfo = {0}; /* = {0} is important */
  104.  
  105.  
  106.  
  107.     LONG   type,
  108.       id,
  109.       size;
  110.  
  111.     LONG  bytesread,
  112.       err;
  113.  
  114.     APTR buf;
  115.  
  116.     /* The Chunk that caused us to be invoked is always the top chunk */
  117.     cn = TopChunk(iff);
  118.  
  119.     type   = cn->cn_Type;
  120.     id      = cn->cn_ID;
  121.  
  122.     /* IMPORTANT !! For collectionchunks we MUST check if a collection is allready present,
  123.     if so there is no clever to add a new one */
  124.  
  125.     lci = FindLocalItem
  126.     (
  127.     iff,
  128.     type,
  129.     id,
  130.     IFFLCI_COLLECTION
  131.     );
  132.  
  133.     if (!lci)
  134.     {
  135.  
  136.     /* Allocate new LCI for containing the property */
  137.  
  138.     lci = AllocLocalItem
  139.     (
  140.         type,
  141.         id,
  142.         IFFLCI_COLLECTION,
  143.         sizeof (struct CIPtr)
  144.     );
  145.     if (!lci) return (IFFERR_NOMEM);
  146.  
  147.     resinfo.LCI = lci;
  148.  
  149.     /* Store the new LCI into top of stack */
  150.  
  151.     err = StoreLocalItem(iff,lci,IFFSLI_ROOT);
  152.  
  153.     if (err)
  154.     {
  155.         CF_FreeResources(&resinfo, IFFParseBase);
  156.         return (err);
  157.     }
  158.     resinfo.LCIStored = TRUE;
  159.  
  160.     SetLocalItemPurge(lci,&IFFParseBase->collectionpurgehook);
  161.  
  162.     }
  163.  
  164.     /* Allocate a new CollectionItem */
  165.  
  166.     collitem = (struct CollectionItem*)AllocMem
  167.     (
  168.     sizeof (struct CollectionItem),
  169.     MEMF_ANY|MEMF_CLEAR
  170.     );
  171.  
  172.     if (!collitem)
  173.     {
  174.     CF_FreeResources(&resinfo, IFFParseBase);
  175.     return (IFFERR_NOMEM);
  176.     }
  177.  
  178.     resinfo.CollItem = collitem;
  179.  
  180.  
  181.  
  182.     /* Allocate buffer to read chunk into */
  183.     size = cn->cn_Size;
  184.  
  185.     buf = AllocMem
  186.     (
  187.     size,
  188.     MEMF_ANY
  189.     );
  190.  
  191.     if (!buf)
  192.     {
  193.     CF_FreeResources(&resinfo, IFFParseBase);
  194.     return (IFFERR_NOMEM);
  195.     }
  196.  
  197.     resinfo.Buffer = buf;
  198.     resinfo.BufferSize = size;
  199.  
  200.  
  201.     /* Read chunk into the buffer */
  202.  
  203.     bytesread = ReadChunkBytes
  204.     (
  205.     iff,
  206.     buf,
  207.     size
  208.     );
  209.  
  210.     /* Sucess ? */
  211.     if (bytesread != size)
  212.     {
  213.     CF_FreeResources(&resinfo, IFFParseBase);
  214.  
  215.     /* IFFERR_.. ? */
  216.     if (bytesread >= 0)
  217.         err = IFFERR_MANGLED;
  218.     }
  219.  
  220.  
  221.     /* Get pointer to first ContextItem from LCIs userdata */
  222.     ciptr = (struct CIPtr*)LocalItemData(lci);
  223.  
  224.     /* Update pointers in linked list of collectionitems */
  225.     collitem->ci_Next = ciptr->FirstCI;
  226.     ciptr->FirstCI = collitem;
  227.  
  228.     collitem->ci_Data = buf;
  229.     collitem->ci_Size = size;
  230.  
  231.  
  232.     return (NULL);
  233. }
  234.