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