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

  1. /*
  2.     (C) 1995-96 AROS - The Amiga Replacement OS
  3.     $Id: popchunk.c,v 1.2 1997/02/03 18:38:02 digulla Exp $
  4.  
  5.     Desc:
  6.     Lang: english
  7. */
  8. #include "iffparse_intern.h"
  9.  
  10. /*****************************************************************************
  11.  
  12.     NAME */
  13. #include <proto/iffparse.h>
  14.  
  15.     AROS_LH1(LONG, PopChunk,
  16.  
  17. /*  SYNOPSIS */
  18.     AROS_LHA(struct IFFHandle *, iff, A0),
  19.  
  20. /*  LOCATION */
  21.     struct Library *, IFFParseBase, 15, IFFParse)
  22.  
  23. /*  FUNCTION
  24.     Pops a context node of the context stack. Usually called
  25.     in write mode to signal the end of a chunk.
  26.  
  27.  
  28.     INPUTS
  29.     iff    - pointer to IFFHandle struct.
  30.  
  31.     RESULT
  32.     error  -  0 if successfull, IFFERR_#? otherwise.
  33.  
  34.     NOTES
  35.  
  36.     EXAMPLE
  37.  
  38.     BUGS
  39.  
  40.     SEE ALSO
  41.     PushChunk()
  42.  
  43.     INTERNALS
  44.  
  45.     Frees a contextnode an all its related LCIs and removes it from the stack-list
  46.     If we are in write mode, we will update the cn_Size in the chunk according
  47.     t cn_Scan, and we will also insert an align byte if necessary
  48.  
  49.  
  50.     If the stream was of PushChunked() as IFFSIZE_UNKNOWN, we have to seek backwards
  51.     and write the correct size.
  52.     Since non RSEEK streams are automagically buffered by
  53.     WriteStream, we don't have to fiddle with it here.
  54.     However if the stream is buffered, we MUST see if we are
  55.     about to pop the chunk that started the Buffering (in PushChunk)
  56.  
  57.  
  58.  
  59.     HISTORY
  60.   27-11-96    digulla automatically created from
  61.       iffparse_lib.fd and clib/iffparse_protos.h
  62.  
  63. *****************************************************************************/
  64. {
  65.     AROS_LIBFUNC_INIT
  66.     AROS_LIBBASE_EXT_DECL(struct Library *,IFFParseBase)
  67.  
  68.  
  69.     struct ContextNode    *cn;
  70.  
  71.     LONG err;
  72.  
  73.     LONG size;
  74.  
  75.     UBYTE nullbyte = 0;
  76.  
  77.     /* Get current chunk */
  78.     cn = TopChunk(iff);
  79.  
  80.     /* Is the IFFHandle opened in Read or Write mode ? */
  81.     if (iff->iff_Flags & IFFF_WRITE)
  82.     {
  83.     /* Write mode. We should update cn_Size *INSIDE the stream,
  84.     if the chunk was pushed with IFFSIZE_UNKNOWN */
  85.  
  86.     if (cn->cn_Size == IFFSIZE_UNKNOWN)
  87.     {
  88.  
  89.         err = SeekStream
  90.         (
  91.         iff,
  92.         /* minus is for seeking backwards. Remember: evt. chunk types
  93.         for composite chunks are allready in cn_Scan */
  94.         - ( cn->cn_Scan + sizeof(ULONG) ),
  95.         IPB(IFFParseBase)
  96.         );
  97.  
  98.         if (err) return (err);
  99.  
  100.         size = cn->cn_Scan;
  101.  
  102.         /* Write the chunk size */
  103.         err = WriteStreamLong
  104.         (
  105.         iff,
  106.         &size,
  107.         IPB(IFFParseBase)
  108.         );
  109.  
  110.         if (err < 0) return (err);
  111.  
  112.         /* Seek towards end of chunk again */
  113.         err = SeekStream
  114.         (
  115.         iff,
  116.         size - 4,
  117.         IPB(IFFParseBase)
  118.         );
  119.  
  120.         if (err) return (err);
  121.  
  122.  
  123.  
  124.  
  125.     }
  126.     else  /* IFFSIZE known at PushChunk() time */
  127.         size = cn->cn_Size;
  128.  
  129.  
  130.     /* Write a pad byte if chunk is not word-aligned */
  131.     if (size % 2)
  132.     {
  133.         err =  WriteStream
  134.         (
  135.         iff,
  136.         &nullbyte,
  137.         1,
  138.         IPB(IFFParseBase)
  139.         );
  140.  
  141.         if (err) return (err);
  142.  
  143.     }
  144.  
  145.  
  146.  
  147.     if
  148.     (
  149.         GetIntIH(iff)->iff_BufferStartDepth
  150.     ==
  151.         iff->iff_Depth
  152.     )
  153.     {
  154.         /* a routine that writes the buffer to stream and reinstallss the old streamhandler */
  155.  
  156.         err = ExitBufferedStream(iff, IPB(IFFParseBase));
  157.         if (err) return (err);
  158.  
  159.     }
  160.     }
  161.  
  162.  
  163.     /* Actually pop the top context-node. (Done for both handles in Read & Write mode) */
  164.  
  165.     PopContextNode(iff, IPB(IFFParseBase));
  166.  
  167.     return (NULL);
  168.  
  169.  
  170.     AROS_LIBFUNC_EXIT
  171. } /* PopChunk */
  172.