source: cpp/gdk/geno.cpp @ 88

Last change on this file since 88 was 81, checked in by Maciej Komosinski, 12 years ago

improved parsing of properties (e.g. in f0 genotypes)

  • Property svn:eol-style set to native
File size: 5.1 KB
RevLine 
[66]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 "geno.h"
6#include "model.h"
7
[71]8SListTempl<GenoValidator*> Geno::validators;
9
[66]10void Geno::init(const SString& genstring,int genformat,const SString& genname,const SString& comment)
11{
12owner=0;
13f0gen=0;
14mapinshift=0;
15mapoutshift=0;
16isvalid=-1;
17SString gencopy(genstring);
18if (genformat==-1)
19        { // unknown format
20        genformat='1';
21        if (genstring.charAt(0)=='/')
22                {
23                int end;
24                SString newcomment;
25                switch(genstring.charAt(1))
26                        {
27                        case '/':
28                                genformat=genstring.charAt(2);
29                                if ((end=genstring.indexOf('\n'))>=0)
30                                        {
31                                        newcomment=genstring.substr(2,end-2);
32                                        gencopy=genstring.substr(end+1);
33                                        mapinshift=end+1;
34                                        }
35                                else
36                                        {
37                                        gencopy=0;
38                                        mapinshift=genstring.len();
39                                        }
40                                break;
41                        case '*':
42                                genformat=genstring.charAt(2);
43                                if ((end=genstring.indexOf("*/"))>=0)
44                                        {
45                                        newcomment=genstring.substr(2,end-2);
46                                        gencopy=genstring.substr(end+2);
47                                        mapinshift=end+2;
48                                        }
49                                else
50                                        {
51                                        gencopy=0;
52                                        mapinshift=genstring.len();
53                                        }
54                                break;
55                        }
56                if (newcomment.len()>0)
57                        {
58                        SString token; int pos=0;
59                        if (newcomment.getNextToken(pos,token,';'))
60                        if (newcomment.getNextToken(pos,token,';'))
61                                {
62                                if (token.len()) txt=token;
63                        if (newcomment.getNextToken(pos,token,';'))
64                                if (token.len()) name=token;
65                                }
66                        }
67                }
68        }
69
70gen=gencopy;
71format=genformat;
72if (!name.len()) name=genname;
73if (!txt.len()) txt=comment;
74multiline=(strchr((const char*)gen,'\n')!=0);
75// mapoutshift...?
76}
77
78void Geno::freeF0()
79{
80if (f0gen) {delete f0gen; f0gen=0;}
81}
82
83Geno::Geno(const char *genstring,int genformat,const char *genname,const char *comment)
84{
85init(SString(genstring),genformat,SString(genname),SString(comment));
86}
87
88Geno::Geno(const SString& genstring,int genformat,const SString& genname,const SString& comment)
89{
90init(genstring,genformat,genname,comment);
91}
92
93Geno::Geno(const Geno& src)
94        :gen(src.gen),name(src.name),format(src.format),txt(src.txt),isvalid(src.isvalid),
95         mapinshift(src.mapinshift),mapoutshift(src.mapinshift),multiline(src.multiline),
96         f0gen(0),owner(0)
97{f0gen=src.f0gen?new Geno(*src.f0gen):0;}
98
99void Geno::operator=(const Geno& src)
100{
101freeF0();
102gen=src.gen;
103name=src.name;
104format=src.format;
105txt=src.txt;
106isvalid=src.isvalid;
107mapinshift=src.mapinshift;
108mapoutshift=src.mapinshift;
109multiline=src.multiline;
110f0gen=src.f0gen?new Geno(*src.f0gen):0;
111owner=0;
112}
113
114Geno::Geno(const SString& src)
115{
[81]116init(src,-1,SString::empty(),SString::empty());
[66]117}
118
119void Geno::setGene(const SString& g,int newformat)
120{
121gen=g;
122isvalid=-1;
123freeF0();
124if (newformat>=0) format=newformat;
125}
126
127void Geno::setString(const SString& g)
128{
129freeF0();
[81]130init(g,-1,SString::empty(),SString::empty());
[66]131}
132
133void Geno::setName(const SString& n)
134{
135name=n;
136}
137
138void Geno::setComment(const SString& c)
139{
140txt=c;
141}
142
143SString Geno::toString(void)
144{
145SString out;
146int comment=0;
147if ((format!='1')||(comment=(txt.len()||name.len())))
148        {
149        if (multiline)
150                out+="//";
151        else
152                out+="/*";
153        out+=format;
154        if (comment)
155                {
156                if (txt.len()) {out+=";";out+=txt;}
157                if (name.len()){out+=";";out+=name;}
158                }
159        if (multiline)
160                out+="\n";
161        else
162                out+="*/";
163        }
164out+=gen;
165return out;
166}
167
168SString Geno::shortString(void)
169{
170SString out;
171if (format!='1')
172        {
173        if (multiline)
174                out+="//";
175        else
176                out+="/*";
177        if (format==0)
178                out+="invalid";
179        else
180                out+=format;
181        if (multiline)
182                out+="\n";
183        else
184                out+="*/";
185        }
186out+=gen;
187return out;
188}
189
190int Geno::mapGenToString(int genpos) const
191{
192if (genpos>gen.len()) return -2;
193if (genpos<0) return -1;
194return mapinshift+genpos;
195}
196
197int Geno::mapStringToGen(int stringpos) const
198{
199stringpos-=mapinshift;
200if (stringpos>gen.len()) return -2;
201if (stringpos<0) return -1;
202return stringpos;
203}
204
205SString Geno::getGene(void) const {return gen;}
206SString Geno::getName(void) const {return name;}
207int Geno::getFormat(void) const {return format;}
208SString Geno::getComment(void) const {return txt;}
209
[71]210class ModelGenoValidator: public GenoValidator
[66]211{
[71]212public:
213        ModelGenoValidator();
214        int testGenoValidity(Geno& g);
215};
216
217ModelGenoValidator::ModelGenoValidator()
218{
219Geno::validators+=this;
220}
221
222int ModelGenoValidator::testGenoValidity(Geno& g)
223{
224if (g.getFormat()=='0')
[66]225        {
[71]226        Model mod(g);
227        return mod.isValid();
[66]228        }
229else
230        {
[71]231        Geno f0geno=g.getConverted('0');
232        return f0geno.isValid();
[66]233        }
234}
235
[71]236static ModelGenoValidator default_validator;
237
238void Geno::validate()
239{
240if (isvalid>=0) return;
241if (gen.len()==0) { isvalid=0; return; }
242FOREACH(GenoValidator*,v,validators)
243        if ((isvalid=v->testGenoValidity(*this))>=0)
244                break;
245}
246
[66]247int Geno::isValid(void)
248{
249if (isvalid<0) validate();
250return isvalid;
251}
252
253Geno Geno::getConverted(int otherformat,MultiMap *m)
254{
255if (otherformat==getFormat()) return *this;
256#ifndef NO_GENOCONVMANAGER
257if ((otherformat=='0')&&(!m))
258        {
259        if (!f0gen)
260                f0gen=new Geno(GenoConvManager::globalConvert(*this,otherformat));
261        return *f0gen;
262        }
263else
264        return GenoConvManager::globalConvert(*this,otherformat,m);
265#else
266return (otherformat==getFormat())?*this:Geno(0,0,0,"GenConvManager not available");
267#endif
268}
269
270Geno::~Geno()
271{
272if (f0gen) delete f0gen;
273}
Note: See TracBrowser for help on using the repository browser.