Quotes are needed around a variable value that has a space in it.
[AROS.git] / workbench / libs / popupmenu / iff.c
blob3f4c885fbc73f75d3b66b9d59ad018a0ba816976
3 /* Standard module for reading/writing simple IFF files */
5 #include "pmpriv.h"
7 #include <exec/types.h>
8 #include <dos/dos.h>
9 #include <dos/dosextens.h>
10 #include <libraries/iffparse.h>
11 #include <proto/exec.h>
12 #include <proto/dos.h>
13 #include <proto/iffparse.h>
14 #include <prefs/prefhdr.h>
15 #include "prefs/popupmenu.h"
17 /* This function opens an IFF file and prepares it for reading or writing. */
18 /* If the file is opened for writing, it is initialized as a FORM of the */
19 /* specified 'type'. If an error occurs, it is returned in 'error'. */
21 struct IFFHandle *OpenIFFFile(STRPTR name, LONG type, ULONG mode, LONG *error, struct Library *IFFParseBase)
23 struct IFFHandle *iffh;
24 BPTR file;
25 LONG dosmode = (mode == IFFF_WRITE)? MODE_NEWFILE: MODE_OLDFILE;
27 *error = 42;
29 if ((file = Open(name,dosmode)))
31 *error = IFFERR_NOMEM;
33 if ((iffh = AllocIFF()))
35 iffh->iff_Stream = (IPTR)file;
36 InitIFFasDOS(iffh);
38 *error = OpenIFF(iffh,mode);
40 if (*error == 0L)
42 if (mode == IFFF_WRITE)
44 *error = PushChunk(iffh,type,ID_FORM,IFFSIZE_UNKNOWN);
45 if (*error) PopChunk(iffh);
48 if (*error == 0L) return (iffh);
51 CloseIFF(iffh);
52 FreeIFF(iffh);
55 Close(file);
58 return (NULL);
61 /* This function closes a previously opened IFF file. */
63 void CloseIFFFile(struct IFFHandle *iffh, struct Library *IFFParseBase)
65 if (iffh)
67 if (iffh->iff_Flags & IFFF_WRITE)
69 PopChunk(iffh);
72 CloseIFF(iffh);
73 Close((BPTR)(iffh->iff_Stream));
74 FreeIFF(iffh);
78 /* This function resets the reading/writing position of an IFF file */
79 /* so that the next I/O operation restarts from the beginning. */
81 LONG ResetIFFFile(struct IFFHandle *iffh, struct Library *IFFParseBase)
83 ULONG flags;
84 BPTR file;
85 LONG error = 0L;
87 if (iffh)
89 file = (BPTR)(iffh->iff_Stream);
90 flags = iffh->iff_Flags;
91 CloseIFF(iffh);
92 Seek(file,0,OFFSET_BEGINNING);
93 error = OpenIFF(iffh,flags & IFFF_RWBITS);
96 return (error);
99 /* This function can be used to read a chunk of the specified ID, or just */
100 /* the next chunk if 'id' is zero. You can read a series of chunks having */
101 /* the same ID just by calling ReadChunk() multiple times, as it remembers */
102 /* its current position. By doing this with an 'id' of zero, you can even */
103 /* read all the chunks in the IFF file. If you need to read chunks having */
104 /* different IDs, you should call ResetIFFFile() before each new search, */
105 /* to make sure the scan always starts from the beginning. If the wanted */
106 /* chunk is found, no more than 'size' bytes are copied from it to the */
107 /* buffer pointed to by 'data'; if either 'data' or 'size' is zero, no */
108 /* copy occurs. You can always retrieve the chunk bytes from the returned */
109 /* ContextNode structure; a NULL return value means that no more chunks of */
110 /* the specified ID were found (or the end of file was reached). */
112 struct ContextNode *ReadChunk(struct IFFHandle *iffh, LONG id, APTR data, ULONG size, struct Library *IFFParseBase)
114 LONG error;
115 struct ContextNode *cn = NULL;
117 if (iffh && ((iffh->iff_Flags & IFFF_RWBITS) == IFFF_READ))
119 while (TRUE)
121 error = ParseIFF(iffh,IFFPARSE_RAWSTEP);
123 if (error == IFFERR_EOC)
125 continue;
127 else if (error)
129 break;
131 else
133 cn = CurrentChunk(iffh);
135 if (!id || (cn->cn_ID == id))
137 if (data && size && (cn->cn_ID != ID_FORM) && (cn->cn_ID != ID_PROP))
139 error = ReadChunkBytes(iffh,data,size);
142 if (error < 0L) cn = NULL;
143 break;
146 cn = NULL;
151 return (cn);
155 void PM_LoadPrefsFile(STRPTR filename, ULONG flags, struct PopupMenuPrefs *prefs, struct PopupMenuPrefs *defprefs)
157 struct IFFHandle *iffh = NULL;
158 struct ContextNode *cn;
159 struct Library *IFFParseBase;
160 ULONG read;
161 LONG error;
164 if((IFFParseBase = OpenLibrary("iffparse.library", 0))) {
165 if ((iffh = OpenIFFFile(filename,ID_PREF,IFFF_READ,&error, IFFParseBase))) {
166 if ((cn = ReadChunk(iffh,ID_PMNU,prefs,sizeof(struct PopupMenuPrefs),IFFParseBase))) {
167 read = cn->cn_Size;
168 } else {
169 read = 0L;
172 if (read != sizeof(struct PopupMenuPrefs)) {
173 error = IFFERR_READ;
176 CloseIFFFile(iffh, IFFParseBase);
179 CloseLibrary(IFFParseBase);
180 } else {
183 if (!iffh || (error != 0L)) {
184 CopyMem(defprefs, prefs, sizeof(struct PopupMenuPrefs));