source: cpp/gdk/genoconv.cpp @ 94

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

compiles under more platforms and OSes

  • Property svn:eol-style set to native
File size: 4.9 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 "nonstd.h"
6
7#include <stdlib.h>
8#include <math.h>
9#include <stdio.h>
10#include <string.h>
11#include <ctype.h>
12#include <time.h>
13#include <errno.h>
14
15#include "genoconv.h"
16#include "multimap.h"
17
18///////////////////////////////////////////////////////////////////////////
19
20GenoConvParam::GenoConvParam(GenoConvManager *g):Param(0),gcm(g)
21{
22updatetab();
23}
24
25void GenoConvParam::freetab()
26{
27if (tab) free(tab);
28tab=0;
29}
30
31const char *GenoConvParam::id(int i)
32{
33if (i>=gcm->converters.size()) return 0;
34static char t[20];
35sprintf(t,"genkonw%d",i);
36return t;
37}
38
39void GenoConvParam::updatetab()
40{
41int i;
42GenoConverter *gk;
43ParamEntry *pe;
44int ile=gcm->converters.size();
45freetab();
46tab=(ParamEntry*)calloc(2+ile,sizeof(ParamEntry));
47tab[0].id="Genetics: Conversions";
48tab[0].group=1;
49tab[0].flags=ile;
50tab[0].name="gkparam:";
51gcnames.clear();
52for (i=0,pe=tab+1;gk=(GenoConverter *)gcm->converters(i);pe++,i++)
53        {
54        pe->id="?";
55        pe->group=0;
56        pe->flags=0;
57        std::string descr="f";
58        descr+=gk->in_format;
59        descr+=" -> f";
60        descr+=gk->out_format;
61        descr+=" : ";
62        descr+=gk->name;
63        gcnames.push_back(descr);
64        pe->name=descr.c_str();
65        pe->type="d 0 1";
66        pe->help=gk->info;
67        }
68pe->id=0;
69}
70
71GenoConvParam::~GenoConvParam()
72{
73freetab();
74}
75
76void *GenoConvParam::getTarget(int i)
77{
78GenoConverter *gk=(GenoConverter *)gcm->converters(i);
79return &gk->enabled;
80}
81
82GenoConvManager::GenoConvManager()
83        :param(this)
84{
85if (!globalobject) globalobject=this;
86}
87
88GenoConvManager::~GenoConvManager()
89{
90GenoConverter *gc;
91for (converters.start();gc=(GenoConverter*)converters();) delete gc;
92if (globalobject==this) globalobject=NULL;
93}
94
95GenoConvManager *GenoConvManager::globalobject=NULL;
96
97void GenoConvManager::addConverter(GenoConverter *gc)
98{
99converters+=gc;
100param.updatetab();
101}
102void GenoConvManager::removeConverter(GenoConverter *gc)
103{
104converters-=gc;
105param.updatetab();
106}
107
108GenoConverter *GenoConvManager::findConverters(SListTempl<GenoConverter*>* result,char in,char out,int enabled,char* name)
109{
110GenoConverter *gk,*retval=0;
111int i=0;
112for (;gk=(GenoConverter*)converters(i);i++)
113        {
114        if ((in!=-1)&&(in!=gk->in_format)) continue;
115        if ((out!=-1)&&(out!=gk->out_format)) continue;
116        if ((enabled!=-1)&&(enabled!=gk->enabled)) continue;
117        if ((name)&&(strcmp(name,gk->name))) continue;
118        if (!retval) {retval=gk; if (!result) break;}
119        if (result) result->append(gk);
120        }
121return retval;
122}
123
124/// write path into 'path'
125/// return the last path element (return >= path)
126/// null -> path not found
127/// @param mapavailable will receive 1 if conversion map is supported by all converters in path
128/// (can be NULL if you don't need this information)
129
130char *GenoConvManager::getPath(char in,char out,char *path,int maxlen,int *mapavailable)
131{
132if (!maxlen) return 0;
133GenoConverter *gk;
134int i=0;
135for (;gk=(GenoConverter*)converters(i);i++)
136        {
137        if ((gk->enabled)&&(gk->in_format == in))
138                {
139                *path=i;
140                if (gk->out_format == out)
141                        {
142                        if (mapavailable)
143                                *mapavailable=gk->mapsupport;
144                        return path;
145                        }
146                else
147                        {
148                        int mapavail;
149                        char *ret=getPath(gk->out_format,out,path+1,maxlen-1,&mapavail);
150                        if (ret)
151                                {
152                                if (mapavailable)
153                                        *mapavailable=gk->mapsupport && mapavail;
154                                return ret;
155                                }
156                        }
157                }
158        }
159return 0;
160}
161
162char *GenoConvManager::getFormatPath(char in,char out,char *path,int maxlen,int *mapavailable)
163{
164char *ret=getPath(in,out,path,maxlen,mapavailable);
165if (ret)
166        {
167        for (char*t=path;t<=ret;t++)
168                *t=((GenoConverter*)converters(*t))->out_format;
169        }
170return ret;
171}
172
173Geno GenoConvManager::convert(Geno &in,char format,MultiMap *map)
174{
175if (in.getFormat()==format) return in;
176static char path[10];
177int dep;
178char *ret;
179if (in.isInvalid()) { return Geno("",0,"","invalid genotype cannot be converted"); }
180int mapavail;
181for (dep=1;dep<sizeof(path);dep++) // sogenannte iteracyjne poglebianie...
182        if (ret=getPath(in.getFormat(),format,path,dep,&mapavail)) break;
183if (!ret) { return Geno("",0,"","converter not found"); }
184if (!map) mapavail=0;
185char *t=path;
186SString tmp;
187tmp=in.getGene();
188MultiMap lastmap,tmpmap;
189int firstmap=1;
190for (;t<=ret;t++)
191        {
192        GenoConverter *gk=(GenoConverter*)converters(*t);
193        tmp=gk->convert(tmp,mapavail?&tmpmap:0);
194        if (!tmp.len())
195                {
196                char t[100];
197                sprintf(t,"f%c->f%c conversion failed (%s)",gk->in_format,gk->out_format,gk->name);
198                return Geno(0,0,0,t);
199                }
200        if (mapavail)
201                {
202                if (firstmap)
203                        {
204                        lastmap=tmpmap;
205                        firstmap=0;
206                        }
207                else
208                        {
209                        MultiMap m;
210                        m.addCombined(lastmap,tmpmap);
211                        lastmap=m;
212                        }
213                tmpmap.clear();
214                }
215        }
216if (map)
217        *map=lastmap;
218return Geno(tmp, format, in.getName(), in.getComment());
219}
220
221Geno GenoConvManager::globalConvert(Geno &in,char format,MultiMap *map)
222{
223if (globalobject) return globalobject->convert(in,format,map);
224if (format==in.getFormat()) return in;
225return Geno(0,0,0,"GenConvManager not initialized");
226}
227
228/////////////////////////////////
Note: See TracBrowser for help on using the repository browser.