start service tasks separately in-case platforms need to perform additional set-up...
[AROS.git] / workbench / libs / iffparse / popchunk.c
blob8b34bf1aa78acf5e1bb0cc83c21596dc26cc82b5
1 /*
2 Copyright © 1995-2007, The AROS Development Team. All rights reserved.
3 $Id$
4 */
6 #include "iffparse_intern.h"
8 /*****************************************************************************
10 NAME */
11 #include <proto/iffparse.h>
13 AROS_LH1(LONG, PopChunk,
15 /* SYNOPSIS */
16 AROS_LHA(struct IFFHandle *, iff, A0),
18 /* LOCATION */
19 struct Library *, IFFParseBase, 15, IFFParse)
21 /* FUNCTION
22 Pops a context node of the context stack. Usually called
23 in write mode to signal the end of a chunk.
26 INPUTS
27 iff - pointer to IFFHandle struct.
29 RESULT
30 error - 0 if successfull, IFFERR_#? otherwise.
32 NOTES
34 EXAMPLE
36 BUGS
38 SEE ALSO
39 PushChunk()
41 INTERNALS
43 Frees a contextnode an all its related LCIs and removes it from the stack-list
44 If we are in write mode, we will update the cn_Size in the chunk according
45 t cn_Scan, and we will also insert an align byte if necessary
48 If the stream was of PushChunked() as IFFSIZE_UNKNOWN, we have to seek backwards
49 and write the correct size.
50 Since non RSEEK streams are automagically buffered by
51 WriteStream, we don't have to fiddle with it here.
52 However if the stream is buffered, we MUST see if we are
53 about to pop the chunk that started the Buffering (in PushChunk)
55 *****************************************************************************/
57 AROS_LIBFUNC_INIT
59 struct ContextNode *cn;
61 LONG err;
63 LONG size;
65 UBYTE nullbyte = 0;
67 DEBUG_POPCHUNK(dprintf("PopChunk: iff 0x%lx\n", iff));
69 /* Get current chunk */
70 cn = TopChunk(iff);
72 /* Is the IFFHandle opened in Read or Write mode ? */
73 if (iff->iff_Flags & IFFF_WRITE)
75 /* Write mode. We should update cn_Size *INSIDE the stream,
76 if the chunk was pushed with IFFSIZE_UNKNOWN */
78 if (cn->cn_Size == IFFSIZE_UNKNOWN)
81 err = SeekStream
83 iff,
84 /* minus is for seeking backwards. Remember: evt. chunk types
85 for composite chunks are allready in cn_Scan */
86 - ( cn->cn_Scan + sizeof(ULONG) ),
87 IPB(IFFParseBase)
90 if (err) return (err);
92 size = cn->cn_Scan;
94 /* Write the chunk size */
95 err = WriteStreamLong
97 iff,
98 &size,
99 IPB(IFFParseBase)
102 if (err < 0) return (err);
104 /* Seek towards end of chunk again */
105 err = SeekStream
107 iff,
108 size,
109 IPB(IFFParseBase)
112 if (err) return (err);
115 else /* IFFSIZE known at PushChunk() time */
116 size = cn->cn_Size;
119 /* Write a pad byte if chunk is not word-aligned */
120 if (size % 2)
122 err = WriteStream
124 iff,
125 &nullbyte,
127 IPB(IFFParseBase)
130 if (err < 0) return (err);
131 size++;
136 GetIntIH(iff)->iff_BufferStartDepth
138 iff->iff_Depth
141 /* a routine that writes the buffer to stream and reinstallss the old streamhandler */
143 err = ExitBufferedStream(iff, IPB(IFFParseBase));
144 if (err) return (err);
149 /* Actually pop the top context-node. (Done for both handles in Read & Write mode) */
151 PopContextNode(iff, IPB(IFFParseBase));
153 /* stegerg: is this okay!? */
155 if (iff->iff_Flags & IFFF_WRITE)
157 cn = TopChunk(iff);
159 /* Might work without this check, because there seems to be always at
160 least one contextnode --> see AllocIFF) */
161 if (cn->cn_Node.mln_Succ)
163 cn->cn_Scan += size + sizeof(ULONG) + sizeof(ULONG);
167 return 0;
169 AROS_LIBFUNC_EXIT
170 } /* PopChunk */