source: cpp/gdk/extvalue.cpp @ 100

Last change on this file since 100 was 92, checked in by Maciej Komosinski, 11 years ago

SString::valueOf(value) can handle more argument types

  • Property svn:eol-style set to native
File size: 5.5 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 "extvalue.h"
6#include "param.h"
7#include <math.h>
8
9SString ExtObject::toString() const
10{
11if (isEmpty()) return SString("<empty object>");
12ParamInterface *p=getParamInterface();
13int tostr=p->findId("toString");
14if (tostr>=0)
15        {
16        return SString(p->getString(tostr));
17        }
18else
19        {
20        SString tmp("<");
21        tmp+=p->getName();
22        sprintf(tmp.directAppend(30)," object at %p>",
23                (object?object:paraminterface));
24        tmp.endAppend();
25        return tmp;
26        }
27}
28
29///////////////////////////////////////
30
31void ExtValue::set(const ExtValue& src)
32{
33switch(src.type)
34        {
35        case TString: sets(src.sdata()); break;
36        case TInt: seti(src.idata()); break;
37        case TDouble: setd(src.ddata()); break;
38        case TObj: seto(src.odata()); break;
39        case TInvalid: type=TInvalid; break;
40        }
41}
42
43void ExtValue::setEmpty()
44{
45switch(type)
46        {
47#ifdef EXTVALUEUNION
48        case TString: sdata().~SString(); break;
49        case TObj: odata().~ExtObject(); break;
50#else
51        case TString: delete s; break;
52        case TObj: delete o; break;
53#endif
54        }
55type=TUnknown;
56}
57
58static long longsign(long x)
59{
60if (x<0) return -1;
61if (x>0) return 1;
62return 0;
63}
64
65long ExtValue::compare(const ExtValue& src) const
66{
67if (type==TUnknown)
68        {
69        if (src.type==TDouble)
70                return (src.getDouble()!=0.0);
71        if (src.type==TString)
72                return 1;
73        return src.getInt()?1:0;
74        }
75else if (src.type==TUnknown)
76        {
77        if (type==TDouble)
78                return (getDouble()!=0.0);
79        if (type==TString)
80                return 1;
81        return getInt()?1:0;
82        }
83switch(type)
84        {
85        case TInt:
86        {
87        long t=src.getInt();
88        if (idata()>0)
89                {if (t>0) return longsign(idata()-t); else return +1;}
90        else
91                {if (t<=0) return longsign(idata()-t); else return -1;}
92        }
93        case TDouble:
94                {
95                double t=ddata()-src.getDouble();
96                if (t<0) return -1;
97                else if (t>0) return 1;
98                return 0;
99                }
100        case TString:
101        {
102        SString t=src.getString();
103        SString& t2=sdata();
104        const char* s1=(const char*)t2;
105        const char* s2=(const char*)t;
106        return longsign(strcmp(s1,s2));
107        }
108        case TObj:
109        {
110        if (src.type==TObj)
111                return !(odata()==src.odata());
112        return 1;
113        }
114        }
115return 1;
116}
117
118int ExtValue::operator==(const ExtValue& src) const
119{
120if (type!=src.type) return 0;
121switch(type)
122        {
123        case TInt: return idata()==src.idata();
124        case TDouble: return ddata()==src.ddata();
125        case TString: return sdata()==src.sdata();
126        case TObj: return odata()==src.odata();
127        }
128return 1;
129}
130
131void ExtValue::operator+=(const ExtValue& src)
132{
133switch(type)
134        {
135        case TInt: idata()+=src.getInt(); break;
136        case TDouble: ddata()+=src.getDouble(); break;
137        case TString: sdata()+=src.getString(); break;
138        }
139}
140
141void ExtValue::operator-=(const ExtValue& src)
142{
143switch(type)
144        {
145        case TInt: idata()-=src.getInt(); break;
146        case TDouble: ddata()-=src.getDouble(); break;
147        }
148}
149
150void ExtValue::operator*=(const ExtValue& src)
151{
152switch(type)
153        {
154        case TInt: idata()*=src.getInt(); break;
155        case TDouble: ddata()*=src.getDouble(); break;
156        }
157}
158
159#include "framsg.h"
160/*#include "fpu_control.h"
161#include <signal.h>
162
163static int fpuexception;
164void mathhandler(int sig)
165{
166printf("fpu exception!\n");
167fpuexception=1;
168signal(SIGFPE,SIG_IGN);
169} */
170
171void ExtValue::operator/=(const ExtValue& src)
172{
173switch(type)
174        {
175        case TInt:
176        { int a=src.getInt();
177//              idata()/=src.getInt();
178        if (a) idata()/=a;
179        else FMprintf("ExtValue","divide",FMLV_ERROR,"%s/0",(const char*)getString());
180        }
181                break;
182
183        case TDouble:
184// ugly ;-(
185#ifdef FPU_THROWS_EXCEPTIONS
186                try
187                        {
188                        ddata()/=src.getDouble();
189                        }
190                catch(...)
191                        {
192                        FMprintf("ExtValue","divide",FMLV_ERROR,"%s/0.0",(const char*)getString());
193                        }
194#else
195                {
196                double d=ddata();
197                d/=src.getDouble();
198#ifdef IPHONE
199        if (!isinf(d))
200#else
201                if (finite(d))
202#endif
203                        ddata()=d;
204                else
205                        FMprintf("ExtValue","divide",FMLV_ERROR,"%s/0.0",(const char*)getString());
206                }
207#endif
208                break;
209        }
210}
211
212void ExtValue::operator%=(const ExtValue& src)
213{
214switch(type)
215        {
216        case TInt: idata()=idata()%src.getInt(); break;
217        case TDouble: ddata()=fmod(ddata(),src.getDouble()); break;
218        }
219}
220
221long ExtValue::getInt() const
222{
223switch(type)
224        {
225        case TInt: return idata();
226        case TDouble: return (int)ddata();
227        case TString:
228        {
229        const char* s=(const char*)sdata();
230        if ((s[0]=='0')&&(s[1]=='x'))
231                {
232                long val;
233                sscanf(s+2,"%lx",&val);
234                return val;
235                }
236        else
237                {
238                if (strchr(s,'e')||(strchr(s,'E')))
239                        return atof(s);
240                else
241                        return atol(s);
242                }
243        }
244        case TObj: return (long)odata().param;
245        }
246return 0;
247}
248double ExtValue::getDouble() const
249{
250switch(type)
251        {
252        case TDouble: return ddata();
253        case TInt: return (double)idata();
254        case TString:
255        {
256        const char* s=(const char*)sdata();
257        if ((s[0]=='0')&&(s[1]=='x'))
258                {
259                long val;
260                sscanf(s+2,"%lx",&val);
261                return val;
262                }
263        else
264                return atof(s);
265        }
266        case TObj: return (double)(long)odata().param;
267        }
268return 0.0;
269}
270SString ExtValue::getString() const
271{
272switch(type)
273        {
274        case TString: return sdata();
275        case TInt:
276                {
277                SString tmp;
278                sprintf(tmp.directAppend(20),"%d",idata());
279                tmp.endAppend();
280                return tmp;
281                }
282        case TDouble:
283                {
284                SString tmp;
285                sprintf(tmp.directAppend(20),"%.15g",ddata());
286                tmp.endAppend();
287                if ((!strchr(tmp,'.'))&&(!strchr(tmp,'e'))) tmp+=".0";
288                return tmp;
289                }
290        case TObj:
291                return odata().toString();
292        case TInvalid:
293                return SString("undefined");
294        default:
295                return SString("null");
296        }
297}
298
299ExtObject ExtValue::getObject() const
300{
301if (type==TObj) return odata();
302return ExtObject();
303}
304
305ExtValue ExtValue::getExtType()
306{
307if (getType()!=TObj) return ExtValue((long)getType());
308ExtObject& o=odata();
309return ExtValue(SString(o.isEmpty()?"":o.getParamInterface()->getName()));
310}
Note: See TracBrowser for help on using the repository browser.