AnyType.cc

Go to the documentation of this file.
00001 // $Id: AnyType.cc 172 2006-06-04 18:03:21Z bingmann $
00002 
00003 #include "AnyType.h"
00004 #include "GraphPort.h"
00005 
00006 #include <stdlib.h>
00007 #include <functional>
00008 
00009 namespace VGServer {
00010 
00012 static char *convert_unsigned_decimal(unsigned int val, char *buf, int bufsize)
00013 {
00014     int n = bufsize-1;
00015     buf[n] = 0;
00016     n--;
00017         
00018     while(n > 0)
00019     {
00020         buf[n] = "0123456789"[val % 10];
00021         val /= 10;
00022         if (val == 0) break;
00023         n--;
00024     }
00025 
00026     return buf+n;
00027 }
00028 
00030 static char *convert_signed_decimal(int val, char *buf, int bufsize)
00031 {
00032     int n = bufsize-1;
00033     buf[n] = 0;
00034     n--;
00035 
00036     char sign = 0;
00037     if (val < 0) {
00038         sign = '-';
00039         val = -val;
00040     }
00041 
00042     while(n > 0)
00043     {
00044         buf[n] = "0123456789"[val % 10];
00045         val /= 10;
00046         if (val == 0) break;
00047         n--;
00048     }
00049 
00050     if (sign) buf[--n] = sign;
00051 
00052     return buf+n;
00053 }
00054 
00056 static char *convert_unsigned64_decimal(unsigned long long val, char *buf, int bufsize)
00057 {
00058     int n = bufsize-1;
00059     buf[n] = 0;
00060     n--;
00061         
00062     while(n > 0)
00063     {
00064         buf[n] = "0123456789"[val % 10];
00065         val /= 10;
00066         if (val == 0) break;
00067         n--;
00068     }
00069 
00070     return buf+n;
00071 }
00072 
00074 static char *convert_signed64_decimal(long long val, char *buf, int bufsize)
00075 {
00076     int n = bufsize-1;
00077     buf[n] = 0;
00078     n--;
00079 
00080     char sign = 0;
00081     if (val < 0) {
00082         sign = '-';
00083         val = -val;
00084     }
00085 
00086     while(n > 0)
00087     {
00088         buf[n] = "0123456789"[val % 10];
00089         val /= 10;
00090         if (val == 0) break;
00091         n--;
00092     }
00093 
00094     if (sign) buf[--n] = sign;
00095 
00096     return buf+n;
00097 }
00098 
00099 bool AnyType::operator==(const AnyType &a) const
00100 {
00101     if (type != a.type) return false;
00102 
00103     switch(type)
00104     {
00105     case ATTRTYPE_INVALID:
00106         assert(0);
00107         return false;
00108 
00109     case ATTRTYPE_BOOL:
00110     case ATTRTYPE_CHAR:
00111     case ATTRTYPE_SHORT:
00112     case ATTRTYPE_INTEGER:
00113         return (_int == a._int);
00114 
00115     case ATTRTYPE_BYTE:
00116     case ATTRTYPE_WORD:
00117     case ATTRTYPE_DWORD:
00118         return (_uint == a._uint);
00119 
00120     case ATTRTYPE_LONG:
00121         return (_long == a._long);
00122 
00123     case ATTRTYPE_QWORD:
00124         return (_ulong == a._ulong);
00125 
00126     case ATTRTYPE_FLOAT:
00127         return (_float == a._float);
00128 
00129     case ATTRTYPE_DOUBLE:
00130         return (_double == a._double);
00131 
00132     case ATTRTYPE_STRING:
00133     case ATTRTYPE_LONGSTRING:
00134         assert(_string && a._string);
00135         return (*_string == *a._string);
00136     }
00137     assert(0);
00138     return false;
00139 }
00140 
00141 attrtype_t AnyType::stringToType(const char* s)
00142 {
00143     // stupid method, but maybe faster than using a biggy std::map with a
00144     // case-insensitive equality.
00145 
00146     if (g_strcasecmp(s, "bool") == 0)
00147         return ATTRTYPE_BOOL;
00148 
00149     if (g_strcasecmp(s, "char") == 0)
00150         return ATTRTYPE_CHAR;
00151     if (g_strcasecmp(s, "short") == 0)
00152         return ATTRTYPE_SHORT;
00153     if (g_strcasecmp(s, "integer") == 0)
00154         return ATTRTYPE_INTEGER;
00155     if (g_strcasecmp(s, "long") == 0)
00156         return ATTRTYPE_LONG;
00157 
00158     if (g_strcasecmp(s, "byte") == 0)
00159         return ATTRTYPE_BYTE;
00160     if (g_strcasecmp(s, "word") == 0)
00161         return ATTRTYPE_WORD;
00162     if (g_strcasecmp(s, "dword") == 0)
00163         return ATTRTYPE_DWORD;
00164     if (g_strcasecmp(s, "qword") == 0)
00165         return ATTRTYPE_QWORD;
00166     
00167     if (g_strcasecmp(s, "float") == 0)
00168         return ATTRTYPE_FLOAT;
00169     if (g_strcasecmp(s, "double") == 0)
00170         return ATTRTYPE_DOUBLE;
00171 
00172     if (g_strcasecmp(s, "string") == 0)
00173         return ATTRTYPE_STRING;
00174     if (g_strcasecmp(s, "longstring") == 0)
00175         return ATTRTYPE_LONGSTRING;
00176 
00177     throw(ConversionException("Invalid type name."));
00178 }
00179 
00180 bool AnyType::isValidAttrtype(attrtype_t at)
00181 {
00182     switch(at)
00183     {
00184     default:
00185     case ATTRTYPE_INVALID:
00186         return false;
00187 
00188     case ATTRTYPE_BOOL:
00189     case ATTRTYPE_CHAR:
00190     case ATTRTYPE_SHORT:
00191     case ATTRTYPE_INTEGER:
00192     case ATTRTYPE_LONG:
00193     case ATTRTYPE_BYTE:
00194     case ATTRTYPE_WORD:
00195     case ATTRTYPE_DWORD:
00196     case ATTRTYPE_QWORD:
00197     case ATTRTYPE_FLOAT:
00198     case ATTRTYPE_DOUBLE:
00199     case ATTRTYPE_STRING:
00200     case ATTRTYPE_LONGSTRING:
00201         return true;
00202     }
00203 }
00204 
00205 std::string AnyType::getTypeString(attrtype_t at)
00206 {
00207     switch(at)
00208     {
00209     case ATTRTYPE_INVALID:      return "invalid";
00210     case ATTRTYPE_BOOL:         return "bool";
00211     case ATTRTYPE_CHAR:         return "char";
00212     case ATTRTYPE_SHORT:        return "short";
00213     case ATTRTYPE_INTEGER:      return "integer";
00214     case ATTRTYPE_LONG:         return "long";
00215     case ATTRTYPE_BYTE:         return "byte";
00216     case ATTRTYPE_WORD:         return "word";
00217     case ATTRTYPE_DWORD:        return "dword";
00218     case ATTRTYPE_QWORD:        return "qword";
00219     case ATTRTYPE_FLOAT:        return "float";
00220     case ATTRTYPE_DOUBLE:       return "double";
00221     case ATTRTYPE_STRING:       return "string";
00222     case ATTRTYPE_LONGSTRING:   return "longstring";
00223     }
00224     return "unknown";
00225 }
00226 
00227 int AnyType::getTypeLength(attrtype_t t)
00228 {
00229     switch(t)
00230     {
00231     case ATTRTYPE_INVALID:
00232         assert(0);
00233         return 0;
00234 
00235     case ATTRTYPE_BOOL:
00236         // weird value. beware!
00237         return 0;
00238 
00239     case ATTRTYPE_CHAR:
00240         return sizeof(char);
00241 
00242     case ATTRTYPE_BYTE:
00243         return sizeof(unsigned char);
00244 
00245     case ATTRTYPE_SHORT:
00246         return sizeof(short);
00247 
00248     case ATTRTYPE_WORD:
00249         return sizeof(unsigned short);
00250 
00251     case ATTRTYPE_INTEGER:
00252         return sizeof(int);
00253 
00254     case ATTRTYPE_DWORD:
00255         return sizeof(unsigned int);
00256 
00257     case ATTRTYPE_LONG:
00258         return sizeof(long long);
00259 
00260     case ATTRTYPE_QWORD:
00261         return sizeof(unsigned long long);
00262 
00263     case ATTRTYPE_FLOAT:
00264         return sizeof(float);
00265 
00266     case ATTRTYPE_DOUBLE:
00267         return sizeof(double);
00268 
00269     case ATTRTYPE_STRING:
00270     case ATTRTYPE_LONGSTRING:
00271         return -1;
00272 
00273     }
00274     assert(0);
00275     return -1;
00276 }
00277 
00278 unsigned int AnyType::getValueLength() const
00279 {
00280     switch(type)
00281     {
00282     case ATTRTYPE_INVALID:
00283         assert(0);
00284         return 0;
00285 
00286     case ATTRTYPE_BOOL:
00287         // weird value. beware!
00288         return 0;
00289 
00290     case ATTRTYPE_CHAR:
00291         return sizeof(char);
00292 
00293     case ATTRTYPE_BYTE:
00294         return sizeof(unsigned char);
00295 
00296     case ATTRTYPE_SHORT:
00297         return sizeof(short);
00298 
00299     case ATTRTYPE_WORD:
00300         return sizeof(unsigned short);
00301 
00302     case ATTRTYPE_INTEGER:
00303         return sizeof(int);
00304 
00305     case ATTRTYPE_DWORD:
00306         return sizeof(unsigned int);
00307 
00308     case ATTRTYPE_LONG:
00309         return sizeof(long long);
00310 
00311     case ATTRTYPE_QWORD:
00312         return sizeof(unsigned long long);
00313 
00314     case ATTRTYPE_FLOAT:
00315         return sizeof(float);
00316 
00317     case ATTRTYPE_DOUBLE:
00318         return sizeof(double);
00319 
00320     case ATTRTYPE_STRING:
00321         assert(_string);
00322         return sizeof(unsigned char) + static_cast<unsigned int>(_string->size());
00323 
00324     case ATTRTYPE_LONGSTRING:
00325         assert(_string);
00326         return sizeof(unsigned int) + static_cast<unsigned int>(_string->size());
00327     }
00328     assert(0);
00329     return 0;
00330 }
00331 
00332 bool AnyType::setInteger(int i)
00333 {
00334     switch(type)
00335     {
00336     case ATTRTYPE_INVALID:
00337         assert(0);
00338         return false;
00339 
00340     case ATTRTYPE_BOOL:
00341         _int = (i != 0) ? 1 : 0;
00342         return true;
00343 
00344     case ATTRTYPE_CHAR:
00345         if (SCHAR_MIN <= i and i <= SCHAR_MAX) {
00346             _int = i;
00347             return true;
00348         }
00349         if (SCHAR_MIN > i) _int = SCHAR_MIN;
00350         if (i > SCHAR_MAX) _int = SCHAR_MAX;
00351         return false;
00352 
00353     case ATTRTYPE_BYTE:
00354         if (i <= UCHAR_MAX) {
00355             _uint = static_cast<unsigned char>(i);
00356             return true;
00357         }
00358         if (0 > i) _uint = 0;
00359         if (i > UCHAR_MAX) _uint = UCHAR_MAX;
00360         return false;
00361 
00362     case ATTRTYPE_SHORT:
00363         if (SHRT_MIN <= i and i <= SHRT_MAX) {
00364             _int = i;
00365             return true;
00366         }
00367         if (SHRT_MIN > i) _int = SHRT_MIN;
00368         if (i > SHRT_MAX) _int = SHRT_MAX;
00369         return false;
00370 
00371     case ATTRTYPE_WORD:
00372         if (i <= USHRT_MAX) {
00373             _uint = static_cast<unsigned short>(i);
00374             return true;
00375         }
00376         if (0 > i) _uint = 0;
00377         if (i > USHRT_MAX) _uint = USHRT_MAX;
00378         return false;
00379 
00380     case ATTRTYPE_INTEGER:
00381         if (INT_MIN <= i and i <= INT_MAX) {
00382             _int = i;
00383             return true;
00384         }
00385         if (INT_MIN > i) _int = INT_MIN;
00386         if (i > INT_MAX) _int = INT_MAX;
00387         return false;
00388 
00389     case ATTRTYPE_DWORD:
00390         if (static_cast<unsigned int>(i) <= UINT_MAX) {
00391             _uint = i;
00392             return true;
00393         }
00394         if (0 > i) _uint = 0;
00395         return false;
00396 
00397     case ATTRTYPE_LONG:
00398         _long = i;
00399         return true;
00400 
00401     case ATTRTYPE_QWORD:
00402         _ulong = i;
00403         return true;
00404 
00405     case ATTRTYPE_FLOAT:
00406         _float = static_cast<float>(i);
00407         return true;
00408 
00409     case ATTRTYPE_DOUBLE:
00410         _double = static_cast<double>(i);
00411         return true;
00412 
00413     case ATTRTYPE_STRING:
00414     case ATTRTYPE_LONGSTRING:
00415     {
00416         char buf[32];
00417         assert(_string);
00418         *_string = convert_signed_decimal(i, buf, sizeof(buf));
00419         return true;
00420     }
00421     }
00422     assert(0);
00423     return false;
00424 }
00425 
00426 bool AnyType::setLong(long long l)
00427 {
00428     switch(type)
00429     {
00430     case ATTRTYPE_INVALID:
00431         assert(0);
00432         return false;
00433 
00434     case ATTRTYPE_BOOL:
00435         _int = (l != 0) ? 1 : 0;
00436         return true;
00437 
00438     case ATTRTYPE_CHAR:
00439         if (SCHAR_MIN <= l and l <= SCHAR_MAX) {
00440             _int = static_cast<char>(l);
00441             return true;
00442         }
00443         if (SCHAR_MIN > l) _int = SCHAR_MIN;
00444         if (l > SCHAR_MAX) _int = SCHAR_MAX;
00445         return false;
00446 
00447     case ATTRTYPE_BYTE:
00448         if (0 <= l and l <= UCHAR_MAX) {
00449             _uint = static_cast<unsigned char>(l);
00450             return true;
00451         }
00452         if (0 > l) _uint = 0;
00453         if (l > UCHAR_MAX) _uint = UCHAR_MAX;
00454         return false;
00455 
00456     case ATTRTYPE_SHORT:
00457         if (SHRT_MIN <= l and l <= SHRT_MAX) {
00458             _int = static_cast<short>(l);
00459             return true;
00460         }
00461         if (SHRT_MIN > l) _int = SHRT_MIN;
00462         if (l > SHRT_MAX) _int = SHRT_MAX;
00463         return false;
00464 
00465     case ATTRTYPE_WORD:
00466         if (l <= USHRT_MAX) {
00467             _uint = static_cast<unsigned short>(l);
00468             return true;
00469         }
00470         if (0 > l) _uint = 0;
00471         if (l > USHRT_MAX) _uint = USHRT_MAX;
00472         return false;
00473 
00474     case ATTRTYPE_INTEGER:
00475         if (INT_MIN <= l and l <= INT_MAX) {
00476             _int = l;
00477             return true;
00478         }
00479         if (INT_MIN > l) _int = INT_MIN;
00480         if (l > INT_MAX) _int = INT_MAX;
00481         return false;
00482 
00483     case ATTRTYPE_DWORD:
00484         if (static_cast<unsigned int>(l) <= UINT_MAX) {
00485             _uint = l;
00486             return true;
00487         }
00488         if (0 > l) _uint = 0;
00489         if (l > UINT_MAX) _uint = UINT_MAX;
00490         return false;
00491 
00492     case ATTRTYPE_LONG:
00493         _long = l;
00494         return true;
00495 
00496     case ATTRTYPE_QWORD:
00497         _ulong = l;
00498         return true;
00499 
00500     case ATTRTYPE_FLOAT:
00501         _float = static_cast<float>(l);
00502         return true;
00503 
00504     case ATTRTYPE_DOUBLE:
00505         _double = static_cast<double>(l);
00506         return true;
00507 
00508     case ATTRTYPE_STRING:
00509     case ATTRTYPE_LONGSTRING:
00510     {
00511         char buf[32];
00512         assert(_string);
00513         *_string = convert_signed64_decimal(l, buf, sizeof(buf));
00514         return true;
00515     }
00516     }
00517     assert(0);
00518     return false;
00519 }
00520 
00521 bool AnyType::setDouble(double d)
00522 {
00523     switch(type)
00524     {
00525     case ATTRTYPE_INVALID:
00526         assert(0);
00527         return false;
00528 
00529     case ATTRTYPE_BOOL:
00530         if (0 <= d and d <= 0.5) {
00531             _int = 0;
00532             return true;
00533         }
00534         if (0.5 < d and d <= 1) {
00535             _int = 1;
00536             return true;
00537         }
00538         return false;
00539 
00540     case ATTRTYPE_CHAR:
00541     case ATTRTYPE_SHORT:
00542     case ATTRTYPE_INTEGER:
00543         return setInteger( static_cast<int>(d) );
00544 
00545     case ATTRTYPE_LONG:
00546         return setLong( static_cast<long long>(d) );
00547 
00548     case ATTRTYPE_BYTE:
00549     case ATTRTYPE_WORD:
00550     case ATTRTYPE_DWORD:
00551         return setInteger( static_cast<unsigned int>(d) );
00552 
00553     case ATTRTYPE_QWORD:
00554         return setLong( static_cast<unsigned long long>(d) );
00555 
00556     case ATTRTYPE_FLOAT:
00557         _float = static_cast<float>(d);
00558         return true;
00559 
00560     case ATTRTYPE_DOUBLE:
00561         _double = d;
00562         return true;
00563 
00564     case ATTRTYPE_STRING:
00565     case ATTRTYPE_LONGSTRING:
00566     {
00567         char buf[64];
00568         assert(_string);
00569         g_snprintf(buf, sizeof(buf), "%.2f", d);
00570         *_string = buf;
00571         return true;
00572     }
00573     }
00574     assert(0);
00575     return false;
00576 }
00577 
00578 bool AnyType::setString(const std::string &s)
00579 {
00580     switch(type)
00581     {
00582     case ATTRTYPE_INVALID:
00583         assert(0);
00584         return false;
00585 
00586     case ATTRTYPE_BOOL:
00587         if (s == "0" or s == "f" or s == "false" or s == "n" or s == "no") {
00588             _int = 0;
00589             return true;
00590         }
00591         if (s == "1" or s == "t" or s == "true" or s == "y" or s == "yes") {
00592             _int = 1;
00593             return true;
00594         }
00595         return false;
00596 
00597     case ATTRTYPE_CHAR:
00598     case ATTRTYPE_SHORT:
00599     case ATTRTYPE_INTEGER:
00600     {
00601         char *endptr;
00602         long i = strtol(s.c_str(), &endptr, 10);
00603         if (endptr != NULL and *endptr == 0)
00604             return setInteger(i);
00605         return false;
00606     }
00607 
00608     case ATTRTYPE_LONG:
00609     {
00610         char *endptr;
00611         long long l = strtoll(s.c_str(), &endptr, 10);
00612         if (endptr != NULL and *endptr == 0)
00613             return setLong(l);
00614         return false;
00615     }
00616 
00617     case ATTRTYPE_BYTE:
00618     case ATTRTYPE_WORD:
00619     case ATTRTYPE_DWORD:
00620     {
00621         char *endptr;
00622         unsigned long u = strtoul(s.c_str(), &endptr, 10);
00623         if (endptr != NULL and *endptr == 0)
00624             return setInteger(u);
00625         return false;
00626     }
00627     
00628     case ATTRTYPE_QWORD:
00629     {
00630         char *endptr;
00631         unsigned long long u = strtoull(s.c_str(), &endptr, 10);
00632         if (endptr != NULL and *endptr == 0)
00633             return setLong(u);
00634         return false;
00635     }
00636 
00637     case ATTRTYPE_FLOAT:
00638     {
00639         char *endptr;
00640         float f = static_cast<float>(strtod(s.c_str(), &endptr));
00641         if (endptr != NULL and *endptr == 0) {
00642             _float = f;
00643             return true;
00644         }
00645         return false;
00646     }
00647 
00648     case ATTRTYPE_DOUBLE:
00649     {
00650         char *endptr;
00651         double d = strtod(s.c_str(), &endptr);
00652         if (endptr != NULL and *endptr == 0) {
00653             _double = d;
00654             return true;
00655         }
00656         return false;
00657     }
00658 
00659     case ATTRTYPE_STRING:
00660     case ATTRTYPE_LONGSTRING:
00661     {
00662         assert(_string);
00663         *_string = s;
00664         return true;
00665     }
00666     }
00667     assert(0);
00668     return false;
00669 }
00670 
00671 bool AnyType::setStringQuoted(const std::string &s)
00672 {
00673     // unescape string
00674     if (s.size() < 2) return false;
00675     if (s[0] != '"') return false;
00676     if (s[s.size()-1] != '"') return false;
00677 
00678     std::string t;
00679     t.reserve(s.size() + s.size() / 32);
00680 
00681     for(unsigned int i = 1; i + 1 < s.size(); i++)
00682     {
00683         if (s[i] == '\\')
00684         {
00685             i++;
00686             if (i >= s.size() - 1) return false;
00687 
00688             switch(s[i])
00689             {
00690             case 'a':   t += '\a';      break;
00691             case 'b':   t += '\b';      break;
00692             case 'f':   t += '\f';      break;
00693             case 'n':   t += '\n';      break;
00694             case 'r':   t += '\r';      break;
00695             case 't':   t += '\t';      break;
00696             case 'v':   t += '\v';      break;
00697             case '\'':  t += '\'';      break;
00698             case '"':   t += '"';       break;
00699             case '\\':  t += '\\';      break;
00700             case '?':   t += '?';       break;
00701 
00702             default:
00703                 t += '\\';
00704                 t += s[i];
00705                 break;
00706             }
00707         }
00708         else {
00709             t += s[i];
00710         }
00711     }
00712 
00713     return setString(t);
00714 }
00715 
00716 bool AnyType::getBoolean() const
00717 {
00718     switch(type)
00719     {
00720     case ATTRTYPE_INVALID:
00721         assert(0);
00722         return false;
00723 
00724     case ATTRTYPE_BOOL:
00725         return (_int != 0);
00726 
00727     case ATTRTYPE_CHAR:
00728     case ATTRTYPE_SHORT:
00729     case ATTRTYPE_INTEGER:
00730         return (_int != 0);
00731 
00732     case ATTRTYPE_BYTE:
00733     case ATTRTYPE_WORD:
00734     case ATTRTYPE_DWORD:
00735         return (_uint != 0);
00736 
00737     case ATTRTYPE_LONG:
00738         return (_long != 0);
00739 
00740     case ATTRTYPE_QWORD:
00741         return (_ulong != 0);
00742 
00743     case ATTRTYPE_FLOAT:
00744         return (_float != 0.0f);
00745 
00746     case ATTRTYPE_DOUBLE:
00747         return (_double != 0.0f);
00748 
00749     case ATTRTYPE_STRING:
00750     case ATTRTYPE_LONGSTRING:
00751     {
00752         assert(_string);
00753 
00754         if (*_string == "0" or *_string == "f" or *_string == "false"
00755             or *_string == "n" or *_string == "no") {
00756             return false;
00757         }
00758         if (*_string == "1" or *_string == "t" or *_string == "true"
00759             or *_string == "y" or *_string == "yes") {
00760             return true;
00761         }
00762 
00763         throw(ConversionException("Cannot convert string to bool."));
00764     }
00765     }
00766     assert(0);
00767     return false;
00768 }
00769 
00770 int AnyType::getInteger() const
00771 {
00772     switch(type)
00773     {
00774     case ATTRTYPE_INVALID:
00775         assert(0);
00776         return false;
00777 
00778     case ATTRTYPE_BOOL:
00779         return _int;
00780 
00781     case ATTRTYPE_CHAR:
00782     case ATTRTYPE_SHORT:
00783     case ATTRTYPE_INTEGER:
00784         return _int;
00785 
00786     case ATTRTYPE_BYTE:
00787     case ATTRTYPE_WORD:
00788     case ATTRTYPE_DWORD:
00789         return _uint;
00790 
00791     case ATTRTYPE_LONG:
00792         if (_long > INT_MAX) return INT_MAX;
00793         if (_long < INT_MIN) return INT_MIN;
00794 
00795         return static_cast<int>(_long);
00796 
00797     case ATTRTYPE_QWORD:
00798         if (_ulong > UINT_MAX) return UINT_MAX;
00799         return static_cast<int>(_ulong);
00800 
00801     case ATTRTYPE_FLOAT:
00802         return static_cast<int>(_float);
00803 
00804     case ATTRTYPE_DOUBLE:
00805         return static_cast<int>(_double);
00806 
00807     case ATTRTYPE_STRING:
00808     case ATTRTYPE_LONGSTRING:
00809     {
00810         assert(_string);
00811         char *endptr;
00812         long i = strtol(_string->c_str(), &endptr, 10);
00813         if (endptr != NULL and *endptr == 0)
00814             return i;
00815 
00816         throw(ConversionException("Cannot convert string to integer."));
00817     }
00818     }
00819     assert(0);
00820     return false;
00821 }
00822 
00823 unsigned int AnyType::getUnsignedInteger() const
00824 {
00825     switch(type)
00826     {
00827     case ATTRTYPE_INVALID:
00828         assert(0);
00829         return false;
00830 
00831     case ATTRTYPE_BOOL:
00832     case ATTRTYPE_CHAR:
00833     case ATTRTYPE_SHORT:
00834     case ATTRTYPE_INTEGER:
00835         return static_cast<unsigned int>(_int);
00836 
00837     case ATTRTYPE_BYTE:
00838     case ATTRTYPE_WORD:
00839     case ATTRTYPE_DWORD:
00840         return _uint;
00841 
00842     case ATTRTYPE_LONG:
00843         return static_cast<unsigned int>(_long);
00844 
00845     case ATTRTYPE_QWORD:
00846         return static_cast<unsigned int>(_ulong);
00847 
00848     case ATTRTYPE_FLOAT:
00849         return static_cast<unsigned int>(_float);
00850 
00851     case ATTRTYPE_DOUBLE:
00852         return static_cast<unsigned int>(_double);
00853 
00854     case ATTRTYPE_STRING:
00855     case ATTRTYPE_LONGSTRING:
00856     {
00857         assert(_string);
00858         char *endptr;
00859         unsigned long i = strtoul(_string->c_str(), &endptr, 10);
00860         if (endptr != NULL and *endptr == 0)
00861             return i;
00862 
00863         throw(ConversionException("Cannot convert string to unsigned integer."));
00864     }
00865     }
00866     assert(0);
00867     return false;
00868 }
00869 
00870 long long AnyType::getLong() const
00871 {
00872     switch(type)
00873     {
00874     case ATTRTYPE_INVALID:
00875         assert(0);
00876         return false;
00877 
00878     case ATTRTYPE_BOOL:
00879     case ATTRTYPE_CHAR:
00880     case ATTRTYPE_SHORT:
00881     case ATTRTYPE_INTEGER:
00882     case ATTRTYPE_BYTE:
00883     case ATTRTYPE_WORD:
00884     case ATTRTYPE_DWORD:
00885         return static_cast<long long>(_int);
00886 
00887     case ATTRTYPE_LONG:
00888         return _long;
00889 
00890     case ATTRTYPE_QWORD:
00891         return _ulong;
00892 
00893     case ATTRTYPE_FLOAT:
00894         return static_cast<long long>(_float);
00895 
00896     case ATTRTYPE_DOUBLE:
00897         return static_cast<long long>(_double);
00898 
00899     case ATTRTYPE_STRING:
00900     case ATTRTYPE_LONGSTRING:
00901     {
00902         assert(_string);
00903         char *endptr;
00904         long long l = strtoll(_string->c_str(), &endptr, 10);
00905         if (endptr != NULL and *endptr == 0)
00906             return l;
00907 
00908         throw(ConversionException("Cannot convert string to long long."));
00909     }
00910     }
00911     assert(0);
00912     return false;
00913 }
00914 
00915 unsigned long long AnyType::getUnsignedLong() const
00916 {
00917     switch(type)
00918     {
00919     case ATTRTYPE_INVALID:
00920         assert(0);
00921         return false;
00922 
00923     case ATTRTYPE_BOOL:
00924     case ATTRTYPE_CHAR:
00925     case ATTRTYPE_SHORT:
00926     case ATTRTYPE_INTEGER:
00927         return static_cast<unsigned long long>(_int);
00928 
00929     case ATTRTYPE_BYTE:
00930     case ATTRTYPE_WORD:
00931     case ATTRTYPE_DWORD:
00932         return static_cast<unsigned long long>(_uint);
00933 
00934     case ATTRTYPE_LONG:
00935         return static_cast<unsigned long long>(_long);
00936 
00937     case ATTRTYPE_QWORD:
00938         return _ulong;
00939 
00940     case ATTRTYPE_FLOAT:
00941         return static_cast<unsigned long long>(_float);
00942 
00943     case ATTRTYPE_DOUBLE:
00944         return static_cast<unsigned long long>(_double);
00945 
00946     case ATTRTYPE_STRING:
00947     case ATTRTYPE_LONGSTRING:
00948     {
00949         assert(_string);
00950         char *endptr;
00951         unsigned long long l = strtoul(_string->c_str(), &endptr, 10);
00952         if (endptr != NULL and *endptr == 0)
00953             return l;
00954 
00955         throw(ConversionException("Cannot convert string to unsigned long long."));
00956     }
00957     }
00958     assert(0);
00959     return false;
00960 }
00961 
00962 double AnyType::getDouble() const
00963 {
00964     switch(type)
00965     {
00966     case ATTRTYPE_INVALID:
00967         assert(0);
00968         return false;
00969 
00970     case ATTRTYPE_BOOL:
00971     case ATTRTYPE_CHAR:
00972     case ATTRTYPE_SHORT:
00973     case ATTRTYPE_INTEGER:
00974     case ATTRTYPE_BYTE:
00975     case ATTRTYPE_WORD:
00976     case ATTRTYPE_DWORD:
00977         return static_cast<double>(_int);
00978 
00979     case ATTRTYPE_FLOAT:
00980         return static_cast<double>(_float);
00981 
00982     case ATTRTYPE_LONG:
00983         return static_cast<double>(_long);
00984 
00985     case ATTRTYPE_QWORD:
00986         return static_cast<double>(_ulong);
00987 
00988     case ATTRTYPE_DOUBLE:
00989         return _double;
00990 
00991     case ATTRTYPE_STRING:
00992     case ATTRTYPE_LONGSTRING:
00993     {
00994         assert(_string);
00995         char *endptr;
00996         double d = strtod(_string->c_str(), &endptr);
00997         if (endptr != NULL and *endptr == 0)
00998             return d;
00999 
01000         throw(ConversionException("Cannot convert string to double."));
01001     }
01002     }
01003     assert(0);
01004     return false;
01005 }
01006 
01007 std::string AnyType::getString() const
01008 {
01009     switch(type)
01010     {
01011     case ATTRTYPE_INVALID:
01012         assert(0);
01013         return false;
01014 
01015     case ATTRTYPE_BOOL:
01016         if (_int == 0) return "false";
01017         if (_int == 1) return "true";
01018         return "invalid";
01019 
01020     case ATTRTYPE_CHAR:
01021     case ATTRTYPE_SHORT:
01022     case ATTRTYPE_INTEGER:
01023     {
01024         char buf[32];
01025         return convert_signed_decimal(_int, buf, sizeof(buf));
01026     }
01027 
01028     case ATTRTYPE_BYTE:
01029     case ATTRTYPE_WORD:
01030     case ATTRTYPE_DWORD:
01031     {
01032         char buf[32];
01033         return convert_unsigned_decimal(_uint, buf, sizeof(buf));
01034     }
01035 
01036     case ATTRTYPE_LONG:
01037     {
01038         char buf[64];
01039         return convert_signed64_decimal(_long, buf, sizeof(buf));
01040     }
01041 
01042     case ATTRTYPE_QWORD:
01043     {
01044         char buf[64];
01045         return convert_unsigned64_decimal(_ulong, buf, sizeof(buf));
01046     }
01047 
01048     case ATTRTYPE_FLOAT:
01049     {
01050         char buf[32];
01051         g_snprintf(buf, sizeof(buf), "%.2f", _float);
01052         return buf;
01053     }
01054 
01055     case ATTRTYPE_DOUBLE:
01056     {
01057         char buf[32];
01058         g_snprintf(buf, sizeof(buf), "%.2f", _double);
01059         return buf;
01060     }
01061 
01062     case ATTRTYPE_STRING:
01063     case ATTRTYPE_LONGSTRING:
01064     {
01065         assert(_string);
01066         return *_string;
01067     } 
01068     }
01069     assert(0);
01070     return false;
01071 }
01072 
01073 void AnyType::resetType(attrtype_t t)
01074 {
01075     // if setting to a string and this is not a string, create the object
01076     if (t == ATTRTYPE_STRING or t == ATTRTYPE_LONGSTRING) {
01077         if (type != ATTRTYPE_STRING and t != ATTRTYPE_LONGSTRING) {
01078             _string = new std::string;
01079         }
01080     }
01081     else {
01082         if (type == ATTRTYPE_STRING or type == ATTRTYPE_LONGSTRING) {
01083             delete _string;
01084         }
01085 
01086         _double = 0;
01087     }
01088 
01089     type = t;
01090 }
01091 
01092 bool AnyType::convertType(attrtype_t t)
01093 {
01094     // same source and target type?
01095     if (type == t) return true;
01096 
01097     // special case if this object was initialised with the ATTRTYPE_INVALID:
01098     // all the get...() below would assert.
01099     if (type == ATTRTYPE_INVALID)
01100     {
01101         type = t;
01102         if (type == ATTRTYPE_STRING or type == ATTRTYPE_LONGSTRING) {
01103             _string = new std::string;
01104         }
01105         return true;
01106     }
01107     
01108     switch(t)
01109     {
01110     case ATTRTYPE_INVALID:
01111         assert(0);
01112         return false;
01113 
01114     case ATTRTYPE_BOOL:
01115     {
01116         bool v = getBoolean();
01117         if (type == ATTRTYPE_STRING or type == ATTRTYPE_LONGSTRING) delete _string;
01118         _int = v;
01119         type = t;
01120         return true;
01121     }
01122 
01123     case ATTRTYPE_CHAR:
01124     case ATTRTYPE_SHORT:
01125     case ATTRTYPE_INTEGER:
01126     {
01127         int v = getInteger();
01128         if (type == ATTRTYPE_STRING or type == ATTRTYPE_LONGSTRING) delete _string;
01129         _int = v;
01130         type = t;
01131         return true;
01132     }
01133 
01134     case ATTRTYPE_BYTE:
01135     case ATTRTYPE_WORD:
01136     case ATTRTYPE_DWORD:
01137     {
01138         unsigned int v = getUnsignedInteger();
01139         if (type == ATTRTYPE_STRING or type == ATTRTYPE_LONGSTRING) delete _string;
01140         _uint = v;
01141         type = t;
01142         return true;
01143     }
01144 
01145     case ATTRTYPE_LONG:
01146     {
01147         long long v = getLong();
01148         if (type == ATTRTYPE_STRING or type == ATTRTYPE_LONGSTRING) delete _string;
01149         _long = v;
01150         type = t;
01151         return true;
01152     }
01153 
01154     case ATTRTYPE_QWORD:
01155     {
01156         unsigned long long v = getLong();
01157         if (type == ATTRTYPE_STRING or type == ATTRTYPE_LONGSTRING) delete _string;
01158         _ulong = v;
01159         type = t;
01160         return true;
01161     }
01162 
01163     case ATTRTYPE_FLOAT:
01164     {
01165         float f = static_cast<float>(getDouble());
01166         if (type == ATTRTYPE_STRING or type == ATTRTYPE_LONGSTRING) delete _string;
01167         _float = f;
01168         type = t;
01169         return true;
01170     }
01171 
01172     case ATTRTYPE_DOUBLE:
01173     {
01174         double d = getDouble();
01175         if (type == ATTRTYPE_STRING or type == ATTRTYPE_LONGSTRING) delete _string;
01176         _double = d;
01177         type = t;
01178         return true;
01179     }
01180 
01181     case ATTRTYPE_STRING:
01182     case ATTRTYPE_LONGSTRING:
01183     {
01184         // dont allocate a new string in this case
01185         if (type == ATTRTYPE_STRING or type == ATTRTYPE_LONGSTRING) {
01186             type = t;
01187             return true;
01188         }
01189 
01190         _string = new std::string(getString());
01191         type = t;
01192         return true;
01193     } 
01194     }
01195     assert(0);
01196     return false;
01197 }
01198 
01202 AnyType AnyType::operator-() const
01203 {
01204     AnyType at = *this;
01205     
01206     switch(at.type)
01207     {
01208     case ATTRTYPE_INVALID: assert(0); throw(ConversionException("Negating invalid type."));
01209         
01210     case ATTRTYPE_BOOL:
01211         if (at._int > 0) at._int = 0;
01212         else at._int = 1;
01213         break;
01214 
01215     case ATTRTYPE_CHAR:
01216     case ATTRTYPE_SHORT:
01217     case ATTRTYPE_INTEGER:
01218         at._int = - at._int;
01219         break;
01220 
01221     case ATTRTYPE_BYTE:
01222     case ATTRTYPE_WORD:
01223     case ATTRTYPE_DWORD:
01224         at._uint = - at._uint;
01225         break;
01226 
01227     case ATTRTYPE_LONG:
01228         at._long = - at._long;
01229         break;
01230 
01231     case ATTRTYPE_QWORD:
01232         at._ulong = - at._ulong;
01233         break;
01234 
01235     case ATTRTYPE_FLOAT:
01236         at._float = - at._float;
01237         break;
01238 
01239     case ATTRTYPE_DOUBLE:
01240         at._double = - at._double;
01241         break;
01242 
01243     case ATTRTYPE_STRING:
01244     case ATTRTYPE_LONGSTRING:
01245     {
01246         if (not at.convertType(ATTRTYPE_DOUBLE))
01247             throw(ConversionException("Cannot convert string to double for negation."));
01248 
01249         at._double = - at._double;
01250         break;
01251     }
01252     }
01253 
01254     return at;
01255 }
01256 
01261 template <template <typename Type> class Operator, char OpName>
01262 AnyType AnyType::binary_arith_op(const AnyType &b) const
01263 {
01264     switch(type)
01265     {
01266     case ATTRTYPE_INVALID: assert(0); throw(ConversionException(std::string("Invalid type for first operand of binary operator ")+OpName+"."));
01267 
01268     case ATTRTYPE_BOOL:
01269         throw(ConversionException("No binary operators are allowed on bool values."));
01270 
01271     case ATTRTYPE_CHAR:
01272     case ATTRTYPE_SHORT:
01273     case ATTRTYPE_INTEGER:
01274     {
01275         switch(b.type)
01276         {
01277         case ATTRTYPE_INVALID: assert(0); throw(ConversionException(std::string("Invalid type for second operand of binary operator ")+OpName+"."));
01278 
01279         case ATTRTYPE_BOOL: throw(ConversionException(std::string("Binary operator ")+OpName+" is not permitted on bool values."));
01280 
01281         case ATTRTYPE_CHAR:
01282         case ATTRTYPE_SHORT:
01283         case ATTRTYPE_INTEGER:
01284         {
01285             Operator<int> op;
01286             return AnyType( op(_int, b._int) );
01287         }
01288 
01289         case ATTRTYPE_BYTE:
01290         case ATTRTYPE_WORD:
01291         case ATTRTYPE_DWORD:
01292         {
01293             Operator<int> op;
01294             return AnyType( op(_int, static_cast<signed int>(b._uint)) );
01295         }
01296 
01297         case ATTRTYPE_LONG:
01298         {
01299             Operator<long long> op;
01300             return AnyType( op(_int, b._long) );
01301         }
01302             
01303         case ATTRTYPE_QWORD:
01304         {
01305             Operator<long long> op;
01306             return AnyType( op(static_cast<long long>(_int), static_cast<long long>(b._ulong)) );
01307         }
01308             
01309         case ATTRTYPE_FLOAT:
01310         {
01311             Operator<float> op;
01312             return AnyType( op(static_cast<float>(_int), b._float));
01313         }
01314 
01315         case ATTRTYPE_DOUBLE:
01316         {
01317             Operator<double> op;
01318             return AnyType( op(static_cast<double>(_int), b._double) );
01319         }
01320 
01321         case ATTRTYPE_STRING:
01322         case ATTRTYPE_LONGSTRING:
01323         {
01324             AnyType bc = b;
01325             
01326             if (not bc.convertType(ATTRTYPE_INTEGER))
01327                 throw(ConversionException(std::string("Could not convert string to integer for binary operator ")+OpName+"."));
01328 
01329             Operator<int> op;
01330 
01331             return AnyType( op(_int, bc.getInteger()) );
01332         }
01333         }
01334         break;
01335     }
01336 
01337     case ATTRTYPE_BYTE:
01338     case ATTRTYPE_WORD:
01339     case ATTRTYPE_DWORD:
01340     {
01341         switch(b.type)
01342         {
01343         case ATTRTYPE_INVALID: assert(0); throw(ConversionException(std::string("Invalid type for second operand of binary operator ")+OpName+"."));
01344 
01345         case ATTRTYPE_BOOL: throw(ConversionException(std::string("Binary operator ")+OpName+" is not permitted on bool values."));
01346 
01347         case ATTRTYPE_CHAR:
01348         case ATTRTYPE_SHORT:
01349         case ATTRTYPE_INTEGER:
01350         {
01351             Operator<int> op;
01352             return AnyType( op(static_cast<signed int>(_uint), b._int) );
01353         }
01354 
01355         case ATTRTYPE_BYTE:
01356         case ATTRTYPE_WORD:
01357         case ATTRTYPE_DWORD:
01358         {
01359             Operator<unsigned int> op;
01360             return AnyType( op(_uint, b._uint) );
01361         }
01362             
01363         case ATTRTYPE_LONG:
01364         {
01365             Operator<long long> op;
01366             return AnyType( op(static_cast<signed long long>(_uint), b._long) );
01367         }
01368 
01369         case ATTRTYPE_QWORD:
01370         {
01371             Operator<unsigned long long> op;
01372             return AnyType( op(static_cast<unsigned long long>(_uint), b._ulong) );
01373         }
01374             
01375         case ATTRTYPE_FLOAT:
01376         {
01377             Operator<float> op;
01378             return AnyType( op(static_cast<float>(_uint), b._float));
01379         }
01380 
01381         case ATTRTYPE_DOUBLE:
01382         {
01383             Operator<double> op;
01384             return AnyType( op(static_cast<double>(_uint), b._double) );
01385         }
01386 
01387         case ATTRTYPE_STRING:
01388         case ATTRTYPE_LONGSTRING:
01389         {
01390             AnyType bc = b;
01391             
01392             if (not bc.convertType(ATTRTYPE_DWORD))
01393                 throw(ConversionException(std::string("Could not convert string to unsigned integer for binary operator ")+OpName+"."));
01394 
01395             Operator<unsigned int> op;
01396 
01397             return AnyType( op(_int, bc.getInteger()) );
01398         }
01399         }
01400         break;
01401     }
01402 
01403     case ATTRTYPE_LONG:
01404     {
01405         switch(b.type)
01406         {
01407         case ATTRTYPE_INVALID: assert(0); throw(ConversionException(std::string("Invalid type for second operand of binary operator ")+OpName+"."));
01408 
01409         case ATTRTYPE_BOOL: throw(ConversionException(std::string("Binary operator ")+OpName+" is not permitted on bool values."));
01410 
01411         case ATTRTYPE_CHAR:
01412         case ATTRTYPE_SHORT:
01413         case ATTRTYPE_INTEGER:
01414         {
01415             Operator<long long> op;
01416             return AnyType( op(_long, static_cast<long long>(b._int)) );
01417         }
01418 
01419         case ATTRTYPE_BYTE:
01420         case ATTRTYPE_WORD:
01421         case ATTRTYPE_DWORD:
01422         {
01423             Operator<long long> op;
01424             return AnyType( op(_long, static_cast<signed long long>(b._uint)) );
01425         }
01426             
01427         case ATTRTYPE_LONG:
01428         {
01429             Operator<long long> op;
01430             return AnyType( op(_long, b._long) );
01431         }
01432 
01433         case ATTRTYPE_QWORD:
01434         {
01435             Operator<long long> op;
01436             return AnyType( op(_long, static_cast<signed long long>(b._ulong)) );
01437         }
01438             
01439         case ATTRTYPE_FLOAT:
01440         {
01441             Operator<float> op;
01442             return AnyType( op(static_cast<float>(_long), b._float));
01443         }
01444 
01445         case ATTRTYPE_DOUBLE:
01446         {
01447             Operator<double> op;
01448             return AnyType( op(static_cast<double>(_long), b._double) );
01449         }
01450 
01451         case ATTRTYPE_STRING:
01452         case ATTRTYPE_LONGSTRING:
01453         {
01454             AnyType bc = b;
01455             
01456             if (not bc.convertType(ATTRTYPE_LONG))
01457                 throw(ConversionException(std::string("Could not convert string to long for binary operator ")+OpName+"."));
01458 
01459             Operator<long long> op;
01460 
01461             return AnyType( op(_long, bc.getLong()) );
01462         }
01463         }
01464         break;
01465     }
01466 
01467     case ATTRTYPE_QWORD:
01468     {
01469         switch(b.type)
01470         {
01471         case ATTRTYPE_INVALID: assert(0); throw(ConversionException(std::string("Invalid type for second operand of binary operator ")+OpName+"."));
01472 
01473         case ATTRTYPE_BOOL: throw(ConversionException(std::string("Binary operator ")+OpName+" is not permitted on bool values."));
01474 
01475         case ATTRTYPE_CHAR:
01476         case ATTRTYPE_SHORT:
01477         case ATTRTYPE_INTEGER:
01478         {
01479             Operator<long long> op;
01480             return AnyType( op(static_cast<signed long long>(_ulong), b._int) );
01481         }
01482 
01483         case ATTRTYPE_BYTE:
01484         case ATTRTYPE_WORD:
01485         case ATTRTYPE_DWORD:
01486         {
01487             Operator<unsigned long long> op;
01488             return AnyType( op(_ulong, static_cast<unsigned long long>(b._uint)) );
01489         }
01490             
01491         case ATTRTYPE_LONG:
01492         {
01493             Operator<long long> op;
01494             return AnyType( op(static_cast<signed long long>(_ulong), b._long) );
01495         }
01496 
01497         case ATTRTYPE_QWORD:
01498         {
01499             Operator<unsigned long long> op;
01500             return AnyType( op(_ulong, b._ulong) );
01501         }
01502             
01503         case ATTRTYPE_FLOAT:
01504         {
01505             Operator<float> op;
01506             return AnyType( op(static_cast<float>(_ulong), b._float));
01507         }
01508 
01509         case ATTRTYPE_DOUBLE:
01510         {
01511             Operator<double> op;
01512             return AnyType( op(static_cast<double>(_ulong), b._double) );
01513         }
01514 
01515         case ATTRTYPE_STRING:
01516         case ATTRTYPE_LONGSTRING:
01517         {
01518             AnyType bc = b;
01519             
01520             if (not bc.convertType(ATTRTYPE_QWORD))
01521                 throw(ConversionException(std::string("Could not convert string to unsigned long long for binary operator ")+OpName+"."));
01522 
01523             Operator<unsigned long long> op;
01524 
01525             return AnyType( op(_ulong, bc.getLong()) );
01526         }
01527         }
01528         break;
01529     }
01530 
01531     case ATTRTYPE_FLOAT:
01532     {
01533         switch(b.type)
01534         {
01535         case ATTRTYPE_INVALID: assert(0); throw(ConversionException(std::string("Invalid type for second operand of binary operator ")+OpName+"."));
01536 
01537         case ATTRTYPE_BOOL: throw(ConversionException(std::string("Binary operator ")+OpName+" is not permitted on bool values."));
01538 
01539         case ATTRTYPE_CHAR:
01540         case ATTRTYPE_SHORT:
01541         case ATTRTYPE_INTEGER:
01542         {
01543             Operator<float> op;
01544             return AnyType( op(_float, static_cast<float>(b._int)) );
01545         }
01546 
01547         case ATTRTYPE_BYTE:
01548         case ATTRTYPE_WORD:
01549         case ATTRTYPE_DWORD:
01550         {
01551             Operator<float> op;
01552             return AnyType( op(_float, static_cast<float>(b._uint)) );
01553         }
01554             
01555         case ATTRTYPE_LONG:
01556         {
01557             Operator<float> op;
01558             return AnyType( op(_float, static_cast<float>(b._long)) );
01559         }
01560 
01561         case ATTRTYPE_QWORD:
01562         {
01563             Operator<float> op;
01564             return AnyType( op(_float, static_cast<float>(b._ulong)) );
01565         }
01566 
01567         case ATTRTYPE_FLOAT:
01568         {
01569             Operator<float> op;
01570             return AnyType( op(_float, b._float));
01571         }
01572 
01573         case ATTRTYPE_DOUBLE:
01574         {
01575             Operator<double> op;
01576             return AnyType( op(static_cast<double>(_float), b._double) );
01577         }
01578 
01579         case ATTRTYPE_STRING:
01580         case ATTRTYPE_LONGSTRING:
01581         {
01582             AnyType bc = b;
01583             
01584             if (not bc.convertType(ATTRTYPE_FLOAT))
01585                 throw(ConversionException(std::string("Could not convert string to float for binary operator ")+OpName+"."));
01586 
01587             Operator<float> op;
01588 
01589             return AnyType( op(_float, bc._float) );
01590         }
01591         }
01592 
01593         break;
01594     }
01595 
01596     case ATTRTYPE_DOUBLE:
01597     {
01598         switch(b.type)
01599         {
01600         case ATTRTYPE_INVALID: assert(0); throw(ConversionException(std::string("Invalid type for second operand of binary operator ")+OpName+"."));
01601 
01602         case ATTRTYPE_BOOL: throw(ConversionException(std::string("Binary operator ")+OpName+" is not permitted on bool values."));
01603 
01604         case ATTRTYPE_CHAR:
01605         case ATTRTYPE_SHORT:
01606         case ATTRTYPE_INTEGER:
01607         {
01608             Operator<double> op;
01609             return AnyType( op(_double, static_cast<double>(b._int)) );
01610         }
01611 
01612         case ATTRTYPE_BYTE:
01613         case ATTRTYPE_WORD:
01614         case ATTRTYPE_DWORD:
01615         {
01616             Operator<double> op;
01617             return AnyType( op(_double, static_cast<double>(b._uint)) );
01618         }
01619             
01620         case ATTRTYPE_LONG:
01621         {
01622             Operator<double> op;
01623             return AnyType( op(_double, static_cast<double>(b._long)) );
01624         }
01625 
01626         case ATTRTYPE_QWORD:
01627         {
01628             Operator<double> op;
01629             return AnyType( op(_double, static_cast<double>(b._ulong)) );
01630         }
01631 
01632         case ATTRTYPE_FLOAT:
01633         {
01634             Operator<double> op;
01635             return AnyType( op(_double, static_cast<double>(b._float)));
01636         }
01637 
01638         case ATTRTYPE_DOUBLE:
01639         {
01640             Operator<double> op;
01641             return AnyType( op(_double, b._double) );
01642         }
01643 
01644         case ATTRTYPE_STRING:
01645         case ATTRTYPE_LONGSTRING:
01646         {
01647             AnyType bc = b;
01648             
01649             if (not bc.convertType(ATTRTYPE_DOUBLE))
01650                 throw(ConversionException(std::string("Could not convert string to double for binary operator ")+OpName+"."));
01651 
01652             Operator<double> op;
01653 
01654             return AnyType( op(_double, bc.getDouble()) );
01655         }
01656         }
01657 
01658         break;
01659     }
01660 
01661     // if this is a string, then the other type defines the conversion
01662     case ATTRTYPE_STRING:
01663     case ATTRTYPE_LONGSTRING:
01664     {
01665         switch(b.type)
01666         {
01667         case ATTRTYPE_INVALID: assert(0); throw(ConversionException(std::string("Invalid type for second operand of binary operator ")+OpName+"."));
01668 
01669         case ATTRTYPE_BOOL: throw(ConversionException(std::string("Binary operator ")+OpName+" is not permitted on bool values."));
01670 
01671         case ATTRTYPE_CHAR:
01672         case ATTRTYPE_SHORT:
01673         case ATTRTYPE_INTEGER:
01674         {
01675             Operator<int> op;
01676             return AnyType( op(this->getInteger(), b._int) );
01677         }
01678 
01679         case ATTRTYPE_BYTE:
01680         case ATTRTYPE_WORD:
01681         case ATTRTYPE_DWORD:
01682         {
01683             Operator<unsigned int> op;
01684             return AnyType( op(this->getUnsignedInteger(), b._int) );
01685         }
01686             
01687         case ATTRTYPE_LONG:
01688         {
01689             Operator<long long> op;
01690             return AnyType( op(this->getLong(), b._long) );
01691         }
01692 
01693         case ATTRTYPE_QWORD:
01694         {
01695             Operator<unsigned long long> op;
01696             return AnyType( op(this->getUnsignedLong(), b._ulong) );
01697         }
01698 
01699         case ATTRTYPE_FLOAT:
01700         {
01701             Operator<float> op;
01702             return AnyType( op(static_cast<float>(this->getDouble()), b._float) );
01703         }
01704 
01705         case ATTRTYPE_DOUBLE:
01706         {
01707             Operator<double> op;
01708             return AnyType( op(this->getDouble(), b._double) );
01709         }
01710 
01711         case ATTRTYPE_STRING:
01712         case ATTRTYPE_LONGSTRING:
01713             throw(ConversionException("No binary operators are allowed between two string values."));
01714         }
01715         break;
01716     }
01717     }
01718     assert(0);
01719     throw(ConversionException("Invalid binary operator call. (PROGRAM ERROR)"));
01720 }
01721 
01722 // *** Instanciate binary_op for the four arithmetic operators
01723 template AnyType AnyType::binary_arith_op<std::plus, '+'>(const AnyType &b) const;
01724 template AnyType AnyType::binary_arith_op<std::minus, '-'>(const AnyType &b) const;
01725 template AnyType AnyType::binary_arith_op<std::multiplies, '*'>(const AnyType &b) const;
01726 template AnyType AnyType::binary_arith_op<std::divides, '/'>(const AnyType &b) const;
01727 
01732 template <template <typename Type> class Operator, int OpNum>
01733 bool AnyType::binary_comp_op(const AnyType &b) const
01734 {
01735     static const char *OpNameArray[] = { "==", "!=", "<", ">", "<=", ">=" };
01736 
01737     switch(type)
01738     {
01739     case ATTRTYPE_INVALID: assert(0); throw(ConversionException(std::string("Invalid type for first operand of binary operator ")+OpNameArray[OpNum]+"."));
01740 
01741     case ATTRTYPE_BOOL:
01742     {
01743         switch(b.type)
01744         {
01745         case ATTRTYPE_INVALID: assert(0); throw(ConversionException(std::string("Invalid type for second operand of binary operator ")+OpNameArray[OpNum]+"."));
01746 
01747         case ATTRTYPE_BOOL:
01748         {
01749             Operator<bool> op;
01750             return op(_int, b._int);
01751         }
01752 
01753         case ATTRTYPE_CHAR:
01754         case ATTRTYPE_SHORT:
01755         case ATTRTYPE_INTEGER:
01756         {
01757             Operator<int> op;
01758             return op(_int, b._int);
01759         }
01760 
01761         case ATTRTYPE_BYTE:
01762         case ATTRTYPE_WORD:
01763         case ATTRTYPE_DWORD:
01764         {
01765             Operator<int> op;
01766             return op(_int, static_cast<signed int>(b._uint));
01767         }
01768             
01769         case ATTRTYPE_LONG:
01770         {
01771             Operator<long long> op;
01772             return op(_int, b._long);
01773         }
01774 
01775         case ATTRTYPE_QWORD:
01776         {
01777             Operator<long long> op;
01778             return op(_int, static_cast<signed long long>(b._ulong));
01779         }
01780 
01781         case ATTRTYPE_FLOAT:
01782         {
01783             Operator<float> op;
01784             return op(static_cast<float>(_int), b._float);
01785         }
01786 
01787         case ATTRTYPE_DOUBLE:
01788         {
01789             Operator<double> op;
01790             return op(static_cast<double>(_int), b._double);
01791         }
01792 
01793         case ATTRTYPE_STRING:
01794         case ATTRTYPE_LONGSTRING:
01795         {
01796             AnyType bc = b;
01797             
01798             if (not bc.convertType(ATTRTYPE_BOOL))
01799                 throw(ConversionException(std::string("Could not convert string to bool for binary operator ")+OpNameArray[OpNum]+"."));
01800 
01801             Operator<int> op;
01802 
01803             return op(_int, bc.getInteger());
01804         }
01805         }
01806         break;
01807     }
01808 
01809     case ATTRTYPE_CHAR:
01810     case ATTRTYPE_SHORT:
01811     case ATTRTYPE_INTEGER:
01812     {
01813         switch(b.type)
01814         {
01815         case ATTRTYPE_INVALID: assert(0); throw(ConversionException(std::string("Invalid type for second operand of binary operator ")+OpNameArray[OpNum]+"."));
01816 
01817         case ATTRTYPE_BOOL: throw(ConversionException(std::string("Binary operator ")+OpNameArray[OpNum]+" is not permitted on bool values."));
01818 
01819         case ATTRTYPE_CHAR:
01820         case ATTRTYPE_SHORT:
01821         case ATTRTYPE_INTEGER:
01822         {
01823             Operator<int> op;
01824             return op(_int, b._int);
01825         }
01826 
01827         case ATTRTYPE_BYTE:
01828         case ATTRTYPE_WORD:
01829         case ATTRTYPE_DWORD:
01830         {
01831             Operator<int> op;
01832             return op(_int, static_cast<signed int>(b._uint));
01833         }
01834 
01835         case ATTRTYPE_LONG:
01836         {
01837             Operator<long long> op;
01838             return op(_int, b._long);
01839         }
01840 
01841         case ATTRTYPE_QWORD:
01842         {
01843             Operator<long long> op;
01844             return op(_int, static_cast<signed long long>(b._ulong));
01845         }
01846 
01847         case ATTRTYPE_FLOAT:
01848         {
01849             Operator<float> op;
01850             return op(static_cast<float>(_int), b._float);
01851         }
01852 
01853         case ATTRTYPE_DOUBLE:
01854         {
01855             Operator<double> op;
01856             return op(static_cast<double>(_int), b._double);
01857         }
01858 
01859         case ATTRTYPE_STRING:
01860         case ATTRTYPE_LONGSTRING:
01861         {
01862             AnyType bc = b;
01863             
01864             if (not bc.convertType(ATTRTYPE_INTEGER))
01865                 throw(ConversionException(std::string("Could not convert string to integer for binary operator ")+OpNameArray[OpNum]+"."));
01866 
01867             Operator<int> op;
01868 
01869             return op(_int, bc.getInteger());
01870         }
01871         }
01872         break;
01873     }
01874 
01875     case ATTRTYPE_BYTE:
01876     case ATTRTYPE_WORD:
01877     case ATTRTYPE_DWORD:
01878     {
01879         switch(b.type)
01880         {
01881         case ATTRTYPE_INVALID: assert(0); throw(ConversionException(std::string("Invalid type for second operand of binary operator ")+OpNameArray[OpNum]+"."));
01882 
01883         case ATTRTYPE_BOOL: throw(ConversionException(std::string("Binary operator ")+OpNameArray[OpNum]+" is not permitted on bool values."));
01884 
01885         case ATTRTYPE_CHAR:
01886         case ATTRTYPE_SHORT:
01887         case ATTRTYPE_INTEGER:
01888         {
01889             Operator<int> op;
01890             return op(static_cast<signed int>(_uint), b._int);
01891         }
01892 
01893         case ATTRTYPE_BYTE:
01894         case ATTRTYPE_WORD:
01895         case ATTRTYPE_DWORD:
01896         {
01897             Operator<unsigned int> op;
01898             return op(_uint, b._uint);
01899         }
01900             
01901         case ATTRTYPE_LONG:
01902         {
01903             Operator<long long> op;
01904             return op(static_cast<signed long long>(_uint), b._long);
01905         }
01906 
01907         case ATTRTYPE_QWORD:
01908         {
01909             Operator<unsigned long long> op;
01910             return op(static_cast<unsigned long long>(_uint), b._ulong);
01911         }
01912 
01913         case ATTRTYPE_FLOAT:
01914         {
01915             Operator<float> op;
01916             return op(static_cast<float>(_uint), b._float);
01917         }
01918 
01919         case ATTRTYPE_DOUBLE:
01920         {
01921             Operator<double> op;
01922             return op(static_cast<double>(_uint), b._double);
01923         }
01924 
01925         case ATTRTYPE_STRING:
01926         case ATTRTYPE_LONGSTRING:
01927         {
01928             AnyType bc = b;
01929             
01930             if (not bc.convertType(ATTRTYPE_DWORD))
01931                 throw(ConversionException(std::string("Could not convert string to unsigned integer for binary operator ")+OpNameArray[OpNum]+"."));
01932 
01933             Operator<unsigned int> op;
01934 
01935             return op(_int, bc.getInteger());
01936         }
01937         }
01938         break;
01939     }
01940 
01941     case ATTRTYPE_LONG:
01942     {
01943         switch(b.type)
01944         {
01945         case ATTRTYPE_INVALID: assert(0); throw(ConversionException(std::string("Invalid type for second operand of binary operator ")+OpNameArray[OpNum]+"."));
01946 
01947         case ATTRTYPE_BOOL: throw(ConversionException(std::string("Binary operator ")+OpNameArray[OpNum]+" is not permitted on bool values."));
01948 
01949         case ATTRTYPE_CHAR:
01950         case ATTRTYPE_SHORT:
01951         case ATTRTYPE_INTEGER:
01952         {
01953             Operator<long long> op;
01954             return op(_long, static_cast<long long>(b._int));
01955         }
01956 
01957         case ATTRTYPE_BYTE:
01958         case ATTRTYPE_WORD:
01959         case ATTRTYPE_DWORD:
01960         {
01961             Operator<long long> op;
01962             return op(_long, static_cast<signed long long>(b._uint));
01963         }
01964 
01965         case ATTRTYPE_LONG:
01966         {
01967             Operator<long long> op;
01968             return op(_long, b._long);
01969         }
01970 
01971         case ATTRTYPE_QWORD:
01972         {
01973             Operator<long long> op;
01974             return op(_long, static_cast<signed long long>(b._ulong));
01975         }
01976 
01977         case ATTRTYPE_FLOAT:
01978         {
01979             Operator<float> op;
01980             return op(static_cast<float>(_long), b._float);
01981         }
01982 
01983         case ATTRTYPE_DOUBLE:
01984         {
01985             Operator<double> op;
01986             return op(static_cast<double>(_long), b._double);
01987         }
01988 
01989         case ATTRTYPE_STRING:
01990         case ATTRTYPE_LONGSTRING:
01991         {
01992             AnyType bc = b;
01993             
01994             if (not bc.convertType(ATTRTYPE_LONG))
01995                 throw(ConversionException(std::string("Could not convert string to long long for binary operator ")+OpNameArray[OpNum]+"."));
01996 
01997             Operator<long long> op;
01998 
01999             return op(_long, bc.getLong());
02000         }
02001         }
02002         break;
02003     }
02004 
02005     case ATTRTYPE_QWORD:
02006     {
02007         switch(b.type)
02008         {
02009         case ATTRTYPE_INVALID: assert(0); throw(ConversionException(std::string("Invalid type for second operand of binary operator ")+OpNameArray[OpNum]+"."));
02010 
02011         case ATTRTYPE_BOOL: throw(ConversionException(std::string("Binary operator ")+OpNameArray[OpNum]+" is not permitted on bool values."));
02012 
02013         case ATTRTYPE_CHAR:
02014         case ATTRTYPE_SHORT:
02015         case ATTRTYPE_INTEGER:
02016         {
02017             Operator<long long> op;
02018             return op(_ulong, static_cast<signed long long>(b._int));
02019         }
02020 
02021         case ATTRTYPE_BYTE:
02022         case ATTRTYPE_WORD:
02023         case ATTRTYPE_DWORD:
02024         {
02025             Operator<unsigned long long> op;
02026             return op(_ulong, b._uint);
02027         }
02028             
02029         case ATTRTYPE_LONG:
02030         {
02031             Operator<long long> op;
02032             return op(static_cast<signed long long>(_ulong), b._long);
02033         }
02034 
02035         case ATTRTYPE_QWORD:
02036         {
02037             Operator<unsigned long long> op;
02038             return op(_ulong, b._ulong);
02039         }
02040 
02041         case ATTRTYPE_FLOAT:
02042         {
02043             Operator<float> op;
02044             return op(static_cast<float>(_ulong), b._float);
02045         }
02046 
02047         case ATTRTYPE_DOUBLE:
02048         {
02049             Operator<double> op;
02050             return op(static_cast<double>(_ulong), b._double);
02051         }
02052 
02053         case ATTRTYPE_STRING:
02054         case ATTRTYPE_LONGSTRING:
02055         {
02056             AnyType bc = b;
02057             
02058             if (not bc.convertType(ATTRTYPE_QWORD))
02059                 throw(ConversionException(std::string("Could not convert string to unsigned long long for binary operator ")+OpNameArray[OpNum]+"."));
02060 
02061             Operator<unsigned long long> op;
02062 
02063             return op(_int, bc.getUnsignedLong());
02064         }
02065         }
02066         break;
02067     }
02068 
02069     case ATTRTYPE_FLOAT:
02070     {
02071         switch(b.type)
02072         {
02073         case ATTRTYPE_INVALID: assert(0); throw(ConversionException(std::string("Invalid type for second operand of binary operator ")+OpNameArray[OpNum]+"."));
02074 
02075         case ATTRTYPE_BOOL: throw(ConversionException(std::string("Binary operator ")+OpNameArray[OpNum]+" is not permitted on bool values."));
02076 
02077         case ATTRTYPE_CHAR:
02078         case ATTRTYPE_SHORT:
02079         case ATTRTYPE_INTEGER:
02080         {
02081             Operator<float> op;
02082             return op(_float, static_cast<float>(b._int));
02083         }
02084 
02085         case ATTRTYPE_BYTE:
02086         case ATTRTYPE_WORD:
02087         case ATTRTYPE_DWORD:
02088         {
02089             Operator<float> op;
02090             return op(_float, static_cast<float>(b._uint));
02091         }
02092             
02093         case ATTRTYPE_LONG:
02094         {
02095             Operator<float> op;
02096             return op(_float, static_cast<float>(b._long));
02097         }
02098 
02099         case ATTRTYPE_QWORD:
02100         {
02101             Operator<float> op;
02102             return op(_float, static_cast<float>(b._ulong));
02103         }
02104             
02105         case ATTRTYPE_FLOAT:
02106         {
02107             Operator<float> op;
02108             return op(_float, b._float);
02109         }
02110 
02111         case ATTRTYPE_DOUBLE:
02112         {
02113             Operator<double> op;
02114             return op(static_cast<double>(_float), b._double);
02115         }
02116 
02117         case ATTRTYPE_STRING:
02118         case ATTRTYPE_LONGSTRING:
02119         {
02120             AnyType bc = b;
02121             
02122             if (not bc.convertType(ATTRTYPE_FLOAT))
02123                 throw(ConversionException(std::string("Could not convert string to float for binary operator ")+OpNameArray[OpNum]+"."));
02124 
02125             Operator<float> op;
02126 
02127             return op(_float, bc._float);
02128         }
02129         }
02130 
02131         break;
02132     }
02133 
02134     case ATTRTYPE_DOUBLE:
02135     {
02136         switch(b.type)
02137         {
02138         case ATTRTYPE_INVALID: assert(0); throw(ConversionException(std::string("Invalid type for second operand of binary operator ")+OpNameArray[OpNum]+"."));
02139 
02140         case ATTRTYPE_BOOL: throw(ConversionException(std::string("Binary operator ")+OpNameArray[OpNum]+" is not permitted on bool values."));
02141 
02142         case ATTRTYPE_CHAR:
02143         case ATTRTYPE_SHORT:
02144         case ATTRTYPE_INTEGER:
02145         {
02146             Operator<double> op;
02147             return op(_double, static_cast<double>(b._int));
02148         }
02149 
02150         case ATTRTYPE_BYTE:
02151         case ATTRTYPE_WORD:
02152         case ATTRTYPE_DWORD:
02153         {
02154             Operator<double> op;
02155             return op(_double, static_cast<double>(b._uint));
02156         }
02157             
02158         case ATTRTYPE_LONG:
02159         {
02160             Operator<double> op;
02161             return op(_double, static_cast<double>(b._long));
02162         }
02163 
02164         case ATTRTYPE_QWORD:
02165         {
02166             Operator<double> op;
02167             return op(_double, static_cast<double>(b._ulong));
02168         }
02169             
02170         case ATTRTYPE_FLOAT:
02171         {
02172             Operator<double> op;
02173             return op(_double, static_cast<double>(b._float));
02174         }
02175 
02176         case ATTRTYPE_DOUBLE:
02177         {
02178             Operator<double> op;
02179             return op(_double, b._double);
02180         }
02181 
02182         case ATTRTYPE_STRING:
02183         case ATTRTYPE_LONGSTRING:
02184         {
02185             AnyType bc = b;
02186             
02187             if (not bc.convertType(ATTRTYPE_DOUBLE))
02188                 throw(ConversionException(std::string("Could not convert string to double for binary operator ")+OpNameArray[OpNum]+"."));
02189 
02190             Operator<double> op;
02191 
02192             return op(_double, bc.getDouble());
02193         }
02194         }
02195 
02196         break;
02197     }
02198 
02199     // if this is a string, then the other type defines the conversion
02200     case ATTRTYPE_STRING:
02201     case ATTRTYPE_LONGSTRING:
02202     {
02203         switch(b.type)
02204         {
02205         case ATTRTYPE_INVALID: assert(0); throw(ConversionException(std::string("Invalid type for second operand of binary operator ")+OpNameArray[OpNum]+"."));
02206 
02207         case ATTRTYPE_BOOL: throw(ConversionException(std::string("Binary operator ")+OpNameArray[OpNum]+" is not permitted on bool values."));
02208 
02209         case ATTRTYPE_CHAR:
02210         case ATTRTYPE_SHORT:
02211         case ATTRTYPE_INTEGER:
02212         {
02213             Operator<int> op;
02214             return op(this->getInteger(), b._int);
02215         }
02216 
02217         case ATTRTYPE_BYTE:
02218         case ATTRTYPE_WORD:
02219         case ATTRTYPE_DWORD:
02220         {
02221             Operator<unsigned int> op;
02222             return op(this->getUnsignedInteger(), b._int);
02223         }
02224             
02225         case ATTRTYPE_LONG:
02226         {
02227             Operator<long long> op;
02228             return op(this->getLong(), b._long);
02229         }
02230 
02231         case ATTRTYPE_QWORD:
02232         {
02233             Operator<unsigned long long> op;
02234             return op(this->getUnsignedLong(), b._ulong);
02235         }
02236 
02237         case ATTRTYPE_FLOAT:
02238         {
02239             Operator<float> op;
02240             return op(static_cast<float>(this->getDouble()), b._float);
02241         }
02242 
02243         case ATTRTYPE_DOUBLE:
02244         {
02245             Operator<double> op;
02246             return op(this->getDouble(), b._double);
02247         }
02248 
02249         case ATTRTYPE_STRING:
02250         case ATTRTYPE_LONGSTRING:
02251             throw(ConversionException("No binary operators are allowed between two string values."));
02252         }
02253         break;
02254     }
02255     }
02256     assert(0);
02257     throw(ConversionException("Invalid binary operator call. (PROGRAM ERROR)"));
02258 }
02259 
02260 template bool AnyType::binary_comp_op<std::equal_to, 0>(const AnyType &b) const;
02261 template bool AnyType::binary_comp_op<std::not_equal_to, 1>(const AnyType &b) const;
02262 template bool AnyType::binary_comp_op<std::less, 2>(const AnyType &b) const;
02263 template bool AnyType::binary_comp_op<std::greater, 3>(const AnyType &b) const;
02264 template bool AnyType::binary_comp_op<std::less_equal, 4>(const AnyType &b) const;
02265 template bool AnyType::binary_comp_op<std::greater_equal, 5>(const AnyType &b) const;
02266 
02267 } // namespace VGServer

Generated on Wed Sep 27 14:34:00 2006 for VGServer by  doxygen 1.4.7