source: cpp/gdk/multiparamload.cpp @ 104

Last change on this file since 104 was 104, checked in by sz, 11 years ago

introducing object de/serialization - see serialtest.cpp
the core GDK classes can be now used in multiple threads (ifdef MULTITHREADED)

  • Property svn:eol-style set to native
File size: 4.8 KB
Line 
1// This file is a part of the Framsticks GDK library.
2// Copyright (C) 2002-2011  Szymon Ulatowski.  See LICENSE.txt for details.
3// Refer to http://www.framsticks.com/ for further information.
4
5#include "multiparamload.h"
6#include "framsg.h"
7#include <ctype.h>
8
9void MultiParamLoader::init()
10{
11file=0; ownfile=0;
12status=0;
13reset();
14}
15
16void MultiParamLoader::reset()
17{
18status=0;
19breakcond=OnError;
20emptyparam.setParamTab(empty_paramtab);
21}
22
23int MultiParamLoader::findObject(const ExtObject &o)
24{
25for(int i=0;i<objects.size();i++)
26        if ((*objects(i))==o)
27                return i;
28return -1;
29}
30
31void MultiParamLoader::removeObject(const ExtObject &o)
32{
33int i=findObject(o);
34if (i>=0)
35        {
36        delete objects(i);
37        objects-=i;
38        }
39}
40
41void MultiParamLoader::clearObjects()
42{
43FOREACH(ExtObject*,o,objects)
44        delete o;
45objects.clear();
46}
47
48void MultiParamLoader::load()
49{
50clearstack();
51if (!file)
52        {
53        lasterror="can't open file";
54        status=OnError;
55        return;
56        }
57status=Loading;
58}
59
60void MultiParamLoader::abort()
61{
62if (file && ownfile)
63        {
64        fclose(file);
65        file=0;
66        }
67clearstack();
68status=Finished;
69}
70
71void MultiParamLoader::load(VirtFILE *f)
72{
73abort();
74ownfile=0;
75file=f;
76load();
77}
78
79void MultiParamLoader::load(const char* filename)
80{
81abort();
82ownfile=1;
83file=Vfopen(filename,FOPEN_READ);
84load();
85}
86
87static int isEOL(char ch)
88{
89return (ch=='\n')||(ch=='\r');
90}
91
92static char* fgets0(char*t,int d,VirtFILE *f,int &linlen)
93{
94char *r=fgets(t,d,f);
95if (r)
96        {
97        int d=strlen(r);
98        if (d && isEOL(r[d-1])) { d--; if (d && isEOL(r[d-1])) d--; }
99        linlen=d;
100        r[d]=0;
101        }
102else
103        linlen=0;
104return r;
105}
106
107static char* trim(char*t,int &linlen)
108{
109char *x=t;
110while(isspace(*x)) x++;
111linlen-=(x-t);
112t=x;
113if (!linlen) return t;
114x=t+linlen-1;
115while(isspace(*x)) x--;
116x[1]=0;
117linlen=x-t+1;
118return t;
119}
120
121int MultiParamLoader::go()
122{
123char buf[100];
124char *t;
125int linlen;
126if (status==OnError) return status;
127while (!finished())
128        {
129        if ((status==BeforeObject) || ((status==BeforeUnknown) && !lastobject.isEmpty()))
130                {
131                Param tmp_param;
132                ParamInterface *pi=lastobject.getParamInterface(tmp_param);
133                pi->load(file);
134                if ((status!=Finished) && maybeBreak(AfterObject))
135                        break;
136                continue;
137                }
138        else if (status==BeforeUnknown)
139                {
140                loadObjectNow(&emptyparam);
141                continue;
142                }
143        t=fgets0(buf,100,file,linlen);
144        if (!t)
145                {
146                if (!returnFromIncluded())
147                        {
148                        abort();
149                        break;
150                        }
151                else
152                        continue;
153                }
154        if (buf[0]=='#')
155                {
156                if (!strncmp(buf+1,"include",7))
157                        {
158                        const char* t=strchr(buf,'\"'),*t2=0;
159                        if (t) t2=strchr(t+1,'\"');
160                        if (t2)
161                                {
162                                SString filename(t+1,t2-t-1);
163                                include(filename);
164                                }
165                        else
166                                {
167                                const char* thisfilename=file->VgetPath();
168                                FMprintf("MultiParamLoader","go",FMLV_WARN,"invalid \"%s\"%s%s",buf,
169                                            (thisfilename?" in ":""),(thisfilename?thisfilename:""));
170                                }
171                        continue;
172                        }
173                else if ((status!=Finished) && maybeBreak(OnComment))
174                        {
175                        lastcomment=t+1;
176                        break;
177                        }
178                }
179        t=trim(buf,linlen);
180        if ((linlen>1)&&(t[linlen-1]==':'))
181                {
182                lastunknown=0;
183                lastunknown.append(t,linlen-1);
184                lastobject.setEmpty();
185                FOREACH(ExtObject*,o,objects)
186                        {
187                        if (!strcmp(o->interfaceName(),lastunknown)) {lastobject=*o; break;}
188                        }
189                        if (!lastobject.isEmpty())
190                                {
191                                if (maybeBreak(BeforeObject))
192                                        break;
193                                }
194                        else
195                                {
196                                if (maybeBreak(BeforeUnknown))
197                                        break;
198                                }
199               
200                }
201        }
202return status;
203}
204
205bool MultiParamLoader::alreadyIncluded(const char* filename)
206{
207int i;
208const char* t;
209for(i=0;i<filestack.size();i++)
210        {
211        t=filestack(i)->VgetPath();
212        if (!t) continue;
213        if (!strcmp(filename,t)) return true;
214        }
215return false;
216}
217
218void MultiParamLoader::include(SString& filename)
219{
220const char* thisfilename=file->VgetPath();
221SString newfilename;
222const char* t=thisfilename?strrchr(thisfilename,PATH_SEPARATOR_CHAR):0;
223
224if (thisfilename && t)
225        {
226        newfilename.append(thisfilename,t-thisfilename+1);
227        newfilename+=filename;
228        }
229else
230        newfilename=filename;
231
232if (alreadyIncluded(newfilename))
233        {
234        FMprintf("MultiParamLoader","include",FMLV_WARN,"circular reference ignored (\"%s\")",
235                    (const char*)filename);
236        return;
237        }
238
239VirtFILE *f=Vfopen(newfilename,FOPEN_READ);
240if (!f)
241        {
242        FMprintf("MultiParamLoader","include",FMLV_WARN,"\"%s\" not found",(const char*)newfilename);
243        }
244else
245        {
246        filestack+=file;
247        file=f;
248        }
249}
250
251VirtFILE* MultiParamLoader::popstack()
252{
253if (!filestack.size()) return 0;
254VirtFILE* f=filestack(filestack.size()-1);
255filestack.remove(filestack.size()-1);
256return f;
257}
258
259void MultiParamLoader::clearstack()
260{
261VirtFILE *f;
262while(f=popstack()) fclose(f);
263}
264
265bool MultiParamLoader::returnFromIncluded()
266{
267if (!filestack.size()) return false;
268if (file) fclose(file);
269file=popstack();
270return true;
271}
272
273int MultiParamLoader::loadObjectNow(const ExtObject& o)
274{
275Param tmp_param;
276ParamInterface *pi=o.getParamInterface(tmp_param);
277pi->load(file);
278status=AfterObject;
279return 0;
280}
281
282int MultiParamLoader::run()
283{
284int stat;
285breakOn(OnError);
286while(stat=go())
287        if (stat==OnError)
288                {
289                abort();
290                return 0;
291                }
292return 1;
293}
Note: See TracBrowser for help on using the repository browser.