00001
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
00144
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
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
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
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
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
01095 if (type == t) return true;
01096
01097
01098
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
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
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
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
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 }