llnamevalue.cpp

Go to the documentation of this file.
00001 
00032 // Examples:
00033 // AvatarCharacter STRING RW DSV male1
00034 
00035 #include "linden_common.h"
00036 
00037 #include <map>
00038 
00039 #include "llnamevalue.h"
00040 #include "u64.h"
00041 #include "llstring.h"
00042 #include "llcamera.h"
00043 
00044 // Anonymous enumeration to provide constants in this file.
00045 // *NOTE: These values may be used in sscanf statements below as their
00046 // value-1, so search for '2047' if you cange NV_BUFFER_LEN or '63' if
00047 // you change U64_BUFFER_LEN.
00048 enum
00049 {
00050         NV_BUFFER_LEN = 2048,
00051         U64_BUFFER_LEN = 64
00052 };
00053 
00054 struct user_callback_t
00055 {
00056         user_callback_t() {};
00057         user_callback_t(TNameValueCallback cb, void** data) : m_Callback(cb), m_Data(data) {}
00058         TNameValueCallback      m_Callback;
00059         void **                         m_Data;
00060 };
00061 typedef std::map<char *, user_callback_t> user_callback_map_t;
00062 user_callback_map_t gUserCallbackMap;
00063 
00064 LLStringTable   gNVNameTable(16384);
00065 
00066 char NameValueTypeStrings[NVT_EOF][NAME_VALUE_TYPE_STRING_LENGTH] = /*Flawfinder: Ignore*/
00067 {
00068         "NULL",
00069         "STRING",
00070         "F32",
00071         "S32",
00072         "VEC3",
00073         "U32",
00074         "CAMERA", // Deprecated, but leaving in case removing completely would cause problems
00075         "ASSET",
00076         "U64"
00077 };              
00078 
00079 char NameValueClassStrings[NVC_EOF][NAME_VALUE_CLASS_STRING_LENGTH] = /*Flawfinder: Ignore*/
00080 {
00081         "NULL",
00082         "R",                    // read only
00083         "RW",                   // read write
00084         "CB"                    // callback
00085 };              
00086 
00087 char NameValueSendtoStrings[NVS_EOF][NAME_VALUE_SENDTO_STRING_LENGTH] = /*Flawfinder: Ignore*/
00088 {
00089         "NULL",
00090         "S",    // "Sim", formerly SIM
00091         "DS",   // "Data Sim" formerly SIM_SPACE
00092         "SV",   // "Sim Viewer" formerly SIM_VIEWER
00093         "DSV"   // "Data Sim Viewer", formerly SIM_SPACE_VIEWER
00094 };              /*Flawfinder: Ignore*/
00095 
00096 
00097 void add_use_callback(char *name, TNameValueCallback ucb, void **user_data)
00098 {
00099         char *temp = gNVNameTable.addString(name);
00100         gUserCallbackMap[temp] = user_callback_t(ucb,user_data);
00101 }
00102 
00103 
00104 //
00105 // Class
00106 //
00107 
00108 LLNameValue::LLNameValue()
00109 {
00110         baseInit();
00111 }
00112 
00113 void LLNameValue::baseInit()
00114 {
00115         mNVNameTable = &gNVNameTable;
00116 
00117         mName = NULL;
00118         mNameValueReference.string = NULL;
00119 
00120         mType = NVT_NULL;
00121         mStringType = NameValueTypeStrings[NVT_NULL];
00122         
00123         mClass = NVC_NULL;
00124         mStringClass = NameValueClassStrings[NVC_NULL];
00125         
00126         mSendto = NVS_NULL;
00127         mStringSendto = NameValueSendtoStrings[NVS_NULL];
00128 
00129         mNameValueCB = NULL;
00130         mUserData = NULL;
00131 }
00132 
00133 void LLNameValue::init(const char *name, const char *data, const char *type, const char *nvclass, const char *nvsendto, TNameValueCallback nvcb, void **user_data)
00134 {
00135         mNVNameTable = &gNVNameTable;
00136 
00137         mName = mNVNameTable->addString(name);
00138         
00139         // Nota Bene: Whatever global structure manages this should have these in the name table already!
00140         mStringType = mNVNameTable->addString(type);
00141         if (!strcmp(mStringType, "STRING"))
00142         {
00143                 S32 string_length = (S32)strlen(data);          /*Flawfinder: Ignore*/
00144                 mType = NVT_STRING;
00145 
00146                 delete[] mNameValueReference.string;
00147                 
00148                 // two options here. . .  data can either look like foo or "foo"
00149                 // WRONG! - this is a poorly implemented and incomplete escape
00150                 // mechanism. For example, using this scheme, there is no way
00151                 // to tell an intentional double quotes from a zero length
00152                 // string. This needs to excised. Phoenix
00153                 //if (strchr(data, '\"'))
00154                 //{
00155                 //      string_length -= 2;
00156                 //      mNameValueReference.string = new char[string_length + 1];;
00157                 //      strncpy(mNameValueReference.string, data + 1, string_length);
00158                 //}
00159                 //else
00160                 //{
00161                 mNameValueReference.string = new char[string_length + 1];;
00162                 strncpy(mNameValueReference.string, data, string_length);               /*Flawfinder: Ignore*/
00163                 //}
00164                 mNameValueReference.string[string_length] = 0;
00165         }
00166         else if (!strcmp(mStringType, "F32"))
00167         {
00168                 mType = NVT_F32;
00169                 mNameValueReference.f32 = new F32((F32)atof(data));
00170         }
00171         else if (!strcmp(mStringType, "S32"))
00172         {
00173                 mType = NVT_S32;
00174                 mNameValueReference.s32 = new S32(atoi(data));
00175         }
00176         else if (!strcmp(mStringType, "U64"))
00177         {
00178                 mType = NVT_U64;
00179                 mNameValueReference.u64 = new U64(str_to_U64(data));
00180         }
00181         else if (!strcmp(mStringType, "VEC3"))
00182         {
00183                 mType = NVT_VEC3;
00184                 F32 t1, t2, t3;
00185 
00186                 // two options here. . .  data can either look like 0, 1, 2 or <0, 1, 2>
00187 
00188                 if (strchr(data, '<'))
00189                 {
00190                         sscanf(data, "<%f, %f, %f>", &t1, &t2, &t3);
00191                 }
00192                 else
00193                 {
00194                         sscanf(data, "%f, %f, %f", &t1, &t2, &t3);
00195                 }
00196 
00197                 // finite checks
00198                 if (!llfinite(t1) || !llfinite(t2) || !llfinite(t3))
00199                 {
00200                         t1 = 0.f;
00201                         t2 = 0.f;
00202                         t3 = 0.f;
00203                 }
00204 
00205                 mNameValueReference.vec3 = new LLVector3(t1, t2, t3);
00206         }
00207         else if (!strcmp(mStringType, "U32"))
00208         {
00209                 mType = NVT_U32;
00210                 mNameValueReference.u32 = new U32(atoi(data));
00211         }
00212         else if(!strcmp(mStringType, (const char*)NameValueTypeStrings[NVT_ASSET]))
00213         {
00214                 // assets are treated like strings, except that the name has
00215                 // meaning to an LLAssetInfo object
00216                 S32 string_length = (S32)strlen(data);          /*Flawfinder: Ignore*/
00217                 mType = NVT_ASSET;
00218 
00219                 // two options here. . .  data can either look like foo or "foo"
00220                 // WRONG! - this is a poorly implemented and incomplete escape
00221                 // mechanism. For example, using this scheme, there is no way
00222                 // to tell an intentional double quotes from a zero length
00223                 // string. This needs to excised. Phoenix
00224                 //if (strchr(data, '\"'))
00225                 //{
00226                 //      string_length -= 2;
00227                 //      mNameValueReference.string = new char[string_length + 1];;
00228                 //      strncpy(mNameValueReference.string, data + 1, string_length);
00229                 //}
00230                 //else
00231                 //{
00232                 mNameValueReference.string = new char[string_length + 1];;
00233                 strncpy(mNameValueReference.string, data, string_length);               /*Flawfinder: Ignore*/
00234                 //}
00235                 mNameValueReference.string[string_length] = 0;
00236         }
00237         else
00238         {
00239                 llwarns << "Unknown name value type string " << mStringType << " for " << mName << llendl;
00240                 mType = NVT_NULL;
00241         }
00242 
00243 
00244         // Nota Bene: Whatever global structure manages this should have these in the name table already!
00245         if (!strcmp(nvclass, "R") ||
00246                 !strcmp(nvclass, "READ_ONLY"))                  // legacy
00247         {
00248                 mClass = NVC_READ_ONLY;
00249                 mStringClass = mNVNameTable->addString("R");
00250         }
00251         else if (!strcmp(nvclass, "RW") ||
00252                         !strcmp(nvclass, "READ_WRITE")) // legacy
00253         {
00254                 mClass = NVC_READ_WRITE;
00255                 mStringClass = mNVNameTable->addString("RW");
00256         }
00257         else if (!strcmp(nvclass, "CB") ||
00258                         !strcmp(nvclass, "CALLBACK"))           // legacy
00259         {
00260                 mClass = NVC_CALLBACK;
00261                 mStringClass = mNVNameTable->addString("CB");
00262                 mNameValueCB = nvcb;
00263                 mUserData = user_data;
00264         }
00265         else
00266         {
00267                 // assume it's bad
00268                 mClass = NVC_NULL;
00269                 mStringClass = mNVNameTable->addString(nvclass);
00270                 mNameValueCB = NULL;
00271                 mUserData = NULL;
00272 
00273                 // are we a user-defined call back?
00274                 for (user_callback_map_t::iterator iter = gUserCallbackMap.begin();
00275                          iter != gUserCallbackMap.end(); iter++)
00276                 {
00277                         char* tname = iter->first;
00278                         if (tname == mStringClass)
00279                         {
00280                                 mClass = NVC_CALLBACK;
00281                                 mNameValueCB = (iter->second).m_Callback;
00282                                 mUserData = (iter->second).m_Data;
00283                         }
00284                 }
00285 
00286                 // Warn if we didn't find a callback
00287                 if (mClass == NVC_NULL)
00288                 {
00289                         llwarns << "Unknown user callback in name value init() for " << mName << llendl;
00290                 }
00291         }
00292 
00293         // Initialize the sendto variable
00294         if (!strcmp(nvsendto, "S") ||
00295                 !strcmp(nvsendto, "SIM"))                       // legacy
00296         {
00297                 mSendto = NVS_SIM;
00298                 mStringSendto = mNVNameTable->addString("S");
00299         }
00300         else if (!strcmp(nvsendto, "DS") ||
00301                 !strcmp(nvsendto, "SIM_SPACE")) // legacy
00302         {
00303                 mSendto = NVS_DATA_SIM;
00304                 mStringSendto = mNVNameTable->addString("DS");
00305         }
00306         else if (!strcmp(nvsendto, "SV") ||
00307                         !strcmp(nvsendto, "SIM_VIEWER"))        // legacy
00308         {
00309                 mSendto = NVS_SIM_VIEWER;
00310                 mStringSendto = mNVNameTable->addString("SV");
00311         }
00312         else if (!strcmp(nvsendto, "DSV") ||
00313                         !strcmp(nvsendto, "SIM_SPACE_VIEWER"))  // legacy
00314         {
00315                 mSendto = NVS_DATA_SIM_VIEWER;
00316                 mStringSendto = mNVNameTable->addString("DSV");
00317         }
00318         else
00319         {
00320                 llwarns << "LLNameValue::init() - unknown sendto field " 
00321                                 << nvsendto << " for NV " << mName << llendl;
00322                 mSendto = NVS_NULL;
00323                 mStringSendto = mNVNameTable->addString("S");
00324         }
00325 
00326 }
00327 
00328 
00329 LLNameValue::LLNameValue(const char *name, const char *data, const char *type, const char *nvclass, TNameValueCallback nvcb, void **user_data)
00330 {
00331         baseInit();
00332         // if not specified, send to simulator only
00333         init(name, data, type, nvclass, "SIM", nvcb, user_data);
00334 }
00335 
00336 
00337 LLNameValue::LLNameValue(const char *name, const char *data, const char *type, const char *nvclass, const char *nvsendto, TNameValueCallback nvcb, void **user_data)
00338 {
00339         baseInit();
00340         init(name, data, type, nvclass, nvsendto, nvcb, user_data);
00341 }
00342 
00343 
00344 
00345 // Initialize without any initial data.
00346 LLNameValue::LLNameValue(const char *name, const char *type, const char *nvclass, TNameValueCallback nvcb, void **user_data)
00347 {
00348         baseInit();
00349         mName = mNVNameTable->addString(name);
00350         
00351         // Nota Bene: Whatever global structure manages this should have these in the name table already!
00352         mStringType = mNVNameTable->addString(type);
00353         if (!strcmp(mStringType, "STRING"))
00354         {
00355                 mType = NVT_STRING;
00356                 mNameValueReference.string = NULL;
00357         }
00358         else if (!strcmp(mStringType, "F32"))
00359         {
00360                 mType = NVT_F32;
00361                 mNameValueReference.f32 = NULL;
00362         }
00363         else if (!strcmp(mStringType, "S32"))
00364         {
00365                 mType = NVT_S32;
00366                 mNameValueReference.s32 = NULL;
00367         }
00368         else if (!strcmp(mStringType, "VEC3"))
00369         {
00370                 mType = NVT_VEC3;
00371                 mNameValueReference.vec3 = NULL;
00372         }
00373         else if (!strcmp(mStringType, "U32"))
00374         {
00375                 mType = NVT_U32;
00376                 mNameValueReference.u32 = NULL;
00377         }
00378         else if (!strcmp(mStringType, "U64"))
00379         {
00380                 mType = NVT_U64;
00381                 mNameValueReference.u64 = NULL;
00382         }
00383         else if(!strcmp(mStringType, (const char*)NameValueTypeStrings[NVT_ASSET]))
00384         {
00385                 mType = NVT_ASSET;
00386                 mNameValueReference.string = NULL;
00387         }
00388         else
00389         {
00390                 mType = NVT_NULL;
00391                 llinfos << "Unknown name-value type " << mStringType << llendl;
00392         }
00393 
00394         // Nota Bene: Whatever global structure manages this should have these in the name table already!
00395         mStringClass = mNVNameTable->addString(nvclass);
00396         if (!strcmp(mStringClass, "READ_ONLY"))
00397         {
00398                 mClass = NVC_READ_ONLY;
00399         }
00400         else if (!strcmp(mStringClass, "READ_WRITE"))
00401         {
00402                 mClass = NVC_READ_WRITE;
00403         }
00404         else if (!strcmp(mStringClass, "CALLBACK"))
00405         {
00406                 mClass = NVC_READ_WRITE;
00407                 mNameValueCB = nvcb;
00408                 mUserData = user_data;
00409         }
00410 
00411         // Initialize the sendto variable
00412         mStringSendto = mNVNameTable->addString("SIM");
00413         mSendto = NVS_SIM;
00414 }
00415 
00416 
00417 // data is in the format:
00418 // "NameValueName       Type    Class   Data"
00419 LLNameValue::LLNameValue(const char *data)
00420 {
00421         baseInit();
00422         static char name[NV_BUFFER_LEN];        /*Flawfinder: ignore*/
00423         static char type[NV_BUFFER_LEN];        /*Flawfinder: ignore*/
00424         static char nvclass[NV_BUFFER_LEN];     /*Flawfinder: ignore*/
00425         static char nvsendto[NV_BUFFER_LEN];    /*Flawfinder: ignore*/
00426         static char nvdata[NV_BUFFER_LEN];      /*Flawfinder: ignore*/
00427 
00428         S32 i;
00429 
00430         S32     character_count = 0;
00431         S32     length = 0;
00432 
00433         // go to first non-whitespace character
00434         while (1)
00435         {
00436                 if (  (*(data + character_count) == ' ')
00437                         ||(*(data + character_count) == '\n')
00438                         ||(*(data + character_count) == '\t')
00439                         ||(*(data + character_count) == '\r'))
00440                 {
00441                         character_count++;
00442                 }
00443                 else
00444                 {
00445                         break;
00446                 }
00447         }
00448 
00449         // read in the name
00450         sscanf((data + character_count), "%2047s", name);       /*Flawfinder: ignore*/
00451 
00452         // bump past it and add null terminator
00453         length = (S32)strlen(name);                     /* Flawfinder: ignore */
00454         name[length] = 0;
00455         character_count += length;
00456 
00457         // go to the next non-whitespace character
00458         while (1)
00459         {
00460                 if (  (*(data + character_count) == ' ')
00461                         ||(*(data + character_count) == '\n')
00462                         ||(*(data + character_count) == '\t')
00463                         ||(*(data + character_count) == '\r'))
00464                 {
00465                         character_count++;
00466                 }
00467                 else
00468                 {
00469                         break;
00470                 }
00471         }
00472 
00473         // read in the type
00474         sscanf((data + character_count), "%2047s", type);       /*Flawfinder: ignore*/
00475 
00476         // bump past it and add null terminator
00477         length = (S32)strlen(type);             /* Flawfinder: ignore */
00478         type[length] = 0;
00479         character_count += length;
00480 
00481         // go to the next non-whitespace character
00482         while (1)
00483         {
00484                 if (  (*(data + character_count) == ' ')
00485                         ||(*(data + character_count) == '\n')
00486                         ||(*(data + character_count) == '\t')
00487                         ||(*(data + character_count) == '\r'))
00488                 {
00489                         character_count++;
00490                 }
00491                 else
00492                 {
00493                         break;
00494                 }
00495         }
00496 
00497         // do we have a type argument?
00498         for (i = NVC_READ_ONLY; i < NVC_EOF; i++)
00499         {
00500                 if (!strncmp(NameValueClassStrings[i], data + character_count, strlen(NameValueClassStrings[i])))               /* Flawfinder: ignore */
00501                 {
00502                         break;
00503                 }
00504         }
00505 
00506         if (i != NVC_EOF)
00507         {
00508                 // yes we do!
00509                 // read in the class
00510                 sscanf((data + character_count), "%2047s", nvclass);    /*Flawfinder: ignore*/
00511 
00512                 // bump past it and add null terminator
00513                 length = (S32)strlen(nvclass);          /* Flawfinder: ignore */
00514                 nvclass[length] = 0;
00515                 character_count += length;
00516 
00517                 // go to the next non-whitespace character
00518                 while (1)
00519                 {
00520                         if (  (*(data + character_count) == ' ')
00521                                 ||(*(data + character_count) == '\n')
00522                                 ||(*(data + character_count) == '\t')
00523                                 ||(*(data + character_count) == '\r'))
00524                         {
00525                                 character_count++;
00526                         }
00527                         else
00528                         {
00529                                 break;
00530                         }
00531                 }
00532         }
00533         else
00534         {
00535                 // no type argument given, default to read-write
00536                 strncpy(nvclass, "READ_WRITE", sizeof(nvclass) -1);             /* Flawfinder: ignore */
00537                 nvclass[sizeof(nvclass) -1] = '\0';
00538         }
00539 
00540         // Do we have a sendto argument?
00541         for (i = NVS_SIM; i < NVS_EOF; i++)
00542         {
00543                 if (!strncmp(NameValueSendtoStrings[i], data + character_count, strlen(NameValueSendtoStrings[i])))             /* Flawfinder: ignore */
00544                 {
00545                         break;
00546                 }
00547         }
00548 
00549         if (i != NVS_EOF)
00550         {
00551                 // found a sendto argument
00552                 sscanf((data + character_count), "%2047s", nvsendto);   /*Flawfinder: ignore*/
00553 
00554                 // add null terminator
00555                 length = (S32)strlen(nvsendto);         /* Flawfinder: ignore */
00556                 nvsendto[length] = 0;
00557                 character_count += length;
00558 
00559                 // seek to next non-whitespace characer
00560                 while (1)
00561                 {
00562                         if (  (*(data + character_count) == ' ')
00563                                 ||(*(data + character_count) == '\n')
00564                                 ||(*(data + character_count) == '\t')
00565                                 ||(*(data + character_count) == '\r'))
00566                         {
00567                                 character_count++;
00568                         }
00569                         else
00570                         {
00571                                 break;
00572                         }
00573                 }
00574         }
00575         else
00576         {
00577                 // no sendto argument given, default to sim only
00578                 strncpy(nvsendto, "SIM", sizeof(nvsendto) -1);          /* Flawfinder: ignore */
00579                 nvsendto[sizeof(nvsendto) -1] ='\0';
00580         }
00581 
00582 
00583         // copy the rest character by character into data
00584         length = 0;
00585 
00586         while ( (*(nvdata + length++) = *(data + character_count++)) )
00587                 ;
00588 
00589         init(name, nvdata, type, nvclass, nvsendto);
00590 }
00591 
00592 
00593 LLNameValue::~LLNameValue()
00594 {
00595         mNVNameTable->removeString(mName);
00596         mName = NULL;
00597         
00598         switch(mType)
00599         {
00600         case NVT_STRING:
00601         case NVT_ASSET:
00602                 delete [] mNameValueReference.string;
00603                 mNameValueReference.string = NULL;
00604                 break;
00605         case NVT_F32:
00606                 delete mNameValueReference.f32;
00607                 mNameValueReference.string = NULL;
00608                 break;
00609         case NVT_S32:
00610                 delete mNameValueReference.s32;
00611                 mNameValueReference.string = NULL;
00612                 break;
00613         case NVT_VEC3:
00614                 delete mNameValueReference.vec3;
00615                 mNameValueReference.string = NULL;
00616                 break;
00617         case NVT_U32:
00618                 delete mNameValueReference.u32;
00619                 mNameValueReference.u32 = NULL;
00620                 break;
00621         case NVT_U64:
00622                 delete mNameValueReference.u64;
00623                 mNameValueReference.u64 = NULL;
00624                 break;
00625         default:
00626                 break;
00627         }
00628 
00629         delete[] mNameValueReference.string;
00630         mNameValueReference.string = NULL;
00631 }
00632 
00633 char    *LLNameValue::getString()
00634 {
00635         if (mType == NVT_STRING)
00636         {
00637                 return mNameValueReference.string;
00638         }
00639         else
00640         {
00641                 llerrs << mName << " not a string!" << llendl;
00642                 return NULL;
00643         }
00644 }
00645 
00646 const char *LLNameValue::getAsset() const
00647 {
00648         if (mType == NVT_ASSET)
00649         {
00650                 return mNameValueReference.string;
00651         }
00652         else
00653         {
00654                 llerrs << mName << " not an asset!" << llendl;
00655                 return NULL;
00656         }
00657 }
00658 
00659 F32             *LLNameValue::getF32()
00660 {
00661         if (mType == NVT_F32)
00662         {
00663                 return mNameValueReference.f32;
00664         }
00665         else
00666         {
00667                 llerrs << mName << " not a F32!" << llendl;
00668                 return NULL;
00669         }
00670 }
00671 
00672 S32             *LLNameValue::getS32()
00673 {
00674         if (mType == NVT_S32)
00675         {
00676                 return mNameValueReference.s32;
00677         }
00678         else
00679         {
00680                 llerrs << mName << " not a S32!" << llendl;
00681                 return NULL;
00682         }
00683 }
00684 
00685 U32             *LLNameValue::getU32()
00686 {
00687         if (mType == NVT_U32)
00688         {
00689                 return mNameValueReference.u32;
00690         }
00691         else
00692         {
00693                 llerrs << mName << " not a U32!" << llendl;
00694                 return NULL;
00695         }
00696 }
00697 
00698 U64             *LLNameValue::getU64()
00699 {
00700         if (mType == NVT_U64)
00701         {
00702                 return mNameValueReference.u64;
00703         }
00704         else
00705         {
00706                 llerrs << mName << " not a U64!" << llendl;
00707                 return NULL;
00708         }
00709 }
00710 
00711 void    LLNameValue::getVec3(LLVector3 &vec)
00712 {
00713         if (mType == NVT_VEC3)
00714         {
00715                 vec = *mNameValueReference.vec3;
00716         }
00717         else
00718         {
00719                 llerrs << mName << " not a Vec3!" << llendl;
00720         }
00721 }
00722 
00723 LLVector3       *LLNameValue::getVec3()
00724 {
00725         if (mType == NVT_VEC3)
00726         {
00727                  return (mNameValueReference.vec3);
00728         }
00729         else
00730         {
00731                 llerrs << mName << " not a Vec3!" << llendl;
00732                 return NULL;
00733         }
00734 }
00735 
00736 
00737 F32 LLNameValue::magnitude()
00738 {
00739         switch(mType)
00740         {
00741         case NVT_STRING:
00742                 return (F32)(strlen(mNameValueReference.string));               /* Flawfinder: ignore */
00743                 break;
00744         case NVT_F32:
00745                 return (fabsf(*mNameValueReference.f32));
00746                 break;
00747         case NVT_S32:
00748                 return (fabsf((F32)(*mNameValueReference.s32)));
00749                 break;
00750         case NVT_VEC3:
00751                 return (mNameValueReference.vec3->magVec());
00752                 break;
00753         case NVT_U32:
00754                 return (F32)(*mNameValueReference.u32);
00755                 break;
00756         default:
00757                 llerrs << "No magnitude operation for NV type " << mStringType << llendl;
00758                 break;
00759         }
00760         return 0.f;
00761 }
00762 
00763 
00764 void LLNameValue::callCallback()
00765 {
00766         if (mNameValueCB)
00767         {
00768                 (*mNameValueCB)(this, mUserData);
00769         }
00770         else
00771         {
00772                 llinfos << mName << " has no callback!" << llendl;
00773         }
00774 }
00775 
00776 
00777 BOOL LLNameValue::sendToData() const
00778 {
00779         return (mSendto == NVS_DATA_SIM || mSendto == NVS_DATA_SIM_VIEWER);
00780 }
00781 
00782 
00783 BOOL LLNameValue::sendToViewer() const
00784 {
00785         return (mSendto == NVS_SIM_VIEWER || mSendto == NVS_DATA_SIM_VIEWER);
00786 }
00787 
00788 
00789 LLNameValue &LLNameValue::operator=(const LLNameValue &a)
00790 {
00791         if (mType != a.mType)
00792         {
00793                 return *this;
00794         }
00795         if (mClass == NVC_READ_ONLY)
00796                 return *this;
00797 
00798         BOOL b_changed = FALSE;
00799         if (  (mClass == NVC_CALLBACK)
00800                 &&(*this != a))
00801         {
00802                 b_changed = TRUE;
00803         }
00804 
00805         switch(a.mType)
00806         {
00807         case NVT_STRING:
00808         case NVT_ASSET:
00809                 if (mNameValueReference.string)
00810                         delete [] mNameValueReference.string;
00811 
00812                 mNameValueReference.string = new char [strlen(a.mNameValueReference.string) + 1];               /* Flawfinder: ignore */
00813                 if(mNameValueReference.string != NULL)
00814                 {
00815                         strcpy(mNameValueReference.string, a.mNameValueReference.string);               /* Flawfinder: ignore */
00816                 }
00817                 break;
00818         case NVT_F32:
00819                 *mNameValueReference.f32 = *a.mNameValueReference.f32;
00820                 break;
00821         case NVT_S32:
00822                 *mNameValueReference.s32 = *a.mNameValueReference.s32;
00823                 break;
00824         case NVT_VEC3:
00825                 *mNameValueReference.vec3 = *a.mNameValueReference.vec3;
00826                 break;
00827         case NVT_U32:
00828                 *mNameValueReference.u32 = *a.mNameValueReference.u32;
00829                 break;
00830         case NVT_U64:
00831                 *mNameValueReference.u64 = *a.mNameValueReference.u64;
00832                 break;
00833         default:
00834                 llerrs << "Unknown Name value type " << (U32)a.mType << llendl;
00835                 break;
00836         }
00837 
00838         if (b_changed)
00839         {
00840                 callCallback();
00841         }
00842 
00843         return *this;
00844 }
00845 
00846 void LLNameValue::setString(const char *a)
00847 {
00848         if (mClass == NVC_READ_ONLY)
00849                 return;
00850         BOOL b_changed = FALSE;
00851 
00852         switch(mType)
00853         {
00854         case NVT_STRING:
00855                 if (a)
00856                 {
00857                         if (  (mClass == NVC_CALLBACK)
00858                                 &&(strcmp(this->mNameValueReference.string,a)))
00859                         {
00860                                 b_changed = TRUE;
00861                         }
00862 
00863                         if (mNameValueReference.string)
00864                         {
00865                                 delete [] mNameValueReference.string;
00866                         }
00867 
00868                         mNameValueReference.string = new char [strlen(a) + 1];          /* Flawfinder: ignore */
00869                         if(mNameValueReference.string != NULL)
00870                         {
00871                                 strcpy(mNameValueReference.string,  a);         /* Flawfinder: ignore */
00872                         }
00873                         
00874                         if (b_changed)
00875                         {
00876                                 callCallback();
00877                         }
00878                 }
00879                 else
00880                 {
00881                         if (mNameValueReference.string)
00882                                 delete [] mNameValueReference.string;
00883 
00884                         mNameValueReference.string = new char [1];
00885                         mNameValueReference.string[0] = 0;
00886                 }
00887                 break;
00888         default:
00889                 break;
00890         }
00891 
00892         if (b_changed)
00893         {
00894                 callCallback();
00895         }
00896 
00897         return;
00898 }
00899 
00900 
00901 void LLNameValue::setAsset(const char *a)
00902 {
00903         if (mClass == NVC_READ_ONLY)
00904                 return;
00905         BOOL b_changed = FALSE;
00906 
00907         switch(mType)
00908         {
00909         case NVT_ASSET:
00910                 if (a)
00911                 {
00912                         if (  (mClass == NVC_CALLBACK)
00913                                 &&(strcmp(this->mNameValueReference.string,a)))
00914                         {
00915                                 b_changed = TRUE;
00916                         }
00917 
00918                         if (mNameValueReference.string)
00919                         {
00920                                 delete [] mNameValueReference.string;
00921                         }
00922                         mNameValueReference.string = new char [strlen(a) + 1];                  /* Flawfinder: ignore */
00923                         if(mNameValueReference.string != NULL)
00924                         {
00925                                 strcpy(mNameValueReference.string,  a);         /* Flawfinder: ignore */
00926                         }
00927                         
00928                         if (b_changed)
00929                         {
00930                                 callCallback();
00931                         }
00932                 }
00933                 else
00934                 {
00935                         if (mNameValueReference.string)
00936                                 delete [] mNameValueReference.string;
00937 
00938                         mNameValueReference.string = new char [1];
00939                         mNameValueReference.string[0] = 0;
00940                 }
00941                 break;
00942         default:
00943                 break;
00944         }
00945         if (b_changed)
00946         {
00947                 callCallback();
00948         }
00949 }
00950 
00951 
00952 void LLNameValue::setF32(const F32 a)
00953 {
00954         if (mClass == NVC_READ_ONLY)
00955                 return;
00956         BOOL b_changed = FALSE;
00957 
00958         switch(mType)
00959         {
00960         case NVT_F32:
00961                 if (  (mClass == NVC_CALLBACK)
00962                         &&(*this->mNameValueReference.f32 != a))
00963                 {
00964                         b_changed = TRUE;
00965                 }
00966                 *mNameValueReference.f32 = a;
00967                 if (b_changed)
00968                 {
00969                         callCallback();
00970                 }
00971                 break;
00972         default:
00973                 break;
00974         }
00975         if (b_changed)
00976         {
00977                 callCallback();
00978         }
00979 
00980         return;
00981 }
00982 
00983 
00984 void LLNameValue::setS32(const S32 a)
00985 {
00986         if (mClass == NVC_READ_ONLY)
00987                 return;
00988         BOOL b_changed = FALSE;
00989 
00990         switch(mType)
00991         {
00992         case NVT_S32:
00993                 if (  (mClass == NVC_CALLBACK)
00994                         &&(*this->mNameValueReference.s32 != a))
00995                 {
00996                         b_changed = TRUE;
00997                 }
00998                 *mNameValueReference.s32 = a;
00999                 if (b_changed)
01000                 {
01001                         callCallback();
01002                 }
01003                 break;
01004         case NVT_U32:
01005                 if (  (mClass == NVC_CALLBACK)
01006                         && ((S32) (*this->mNameValueReference.u32) != a))
01007                 {
01008                         b_changed = TRUE;
01009                 }
01010                 *mNameValueReference.u32 = a;
01011                 if (b_changed)
01012                 {
01013                         callCallback();
01014                 }
01015                 break;
01016         case NVT_F32:
01017                 if (  (mClass == NVC_CALLBACK)
01018                         &&(*this->mNameValueReference.f32 != a))
01019                 {
01020                         b_changed = TRUE;
01021                 }
01022                 *mNameValueReference.f32 = (F32)a;
01023                 if (b_changed)
01024                 {
01025                         callCallback();
01026                 }
01027                 break;
01028         default:
01029                 break;
01030         }
01031         if (b_changed)
01032         {
01033                 callCallback();
01034         }
01035 
01036         return;
01037 }
01038 
01039 
01040 void LLNameValue::setU32(const U32 a)
01041 {
01042         if (mClass == NVC_READ_ONLY)
01043                 return;
01044         BOOL b_changed = FALSE;
01045 
01046         switch(mType)
01047         {
01048         case NVT_S32:
01049                 if (  (mClass == NVC_CALLBACK)
01050                         &&(*this->mNameValueReference.s32 != (S32) a))
01051                 {
01052                         b_changed = TRUE;
01053                 }
01054                 *mNameValueReference.s32 = a;
01055                 if (b_changed)
01056                 {
01057                         callCallback();
01058                 }
01059                 break;
01060         case NVT_U32:
01061                 if (  (mClass == NVC_CALLBACK)
01062                         &&(*this->mNameValueReference.u32 != a))
01063                 {
01064                         b_changed = TRUE;
01065                 }
01066                 *mNameValueReference.u32 = a;
01067                 if (b_changed)
01068                 {
01069                         callCallback();
01070                 }
01071                 break;
01072         case NVT_F32:
01073                 if (  (mClass == NVC_CALLBACK)
01074                         &&(*this->mNameValueReference.f32 != a))
01075                 {
01076                         b_changed = TRUE;
01077                 }
01078                 *mNameValueReference.f32 = (F32)a;
01079                 if (b_changed)
01080                 {
01081                         callCallback();
01082                 }
01083                 break;
01084         default:
01085                 llerrs << "NameValue: Trying to set U32 into a " << mStringType << ", unknown conversion" << llendl;
01086                 break;
01087         }
01088         return;
01089 }
01090 
01091 
01092 void LLNameValue::setVec3(const LLVector3 &a)
01093 {
01094         if (mClass == NVC_READ_ONLY)
01095                 return;
01096         BOOL b_changed = FALSE;
01097 
01098         switch(mType)
01099         {
01100         case NVT_VEC3:
01101                 if (  (mClass == NVC_CALLBACK)
01102                         &&(*this->mNameValueReference.vec3 != a))
01103                 {
01104                         b_changed = TRUE;
01105                 }
01106                 *mNameValueReference.vec3 = a;
01107                 if (b_changed)
01108                 {
01109                         callCallback();
01110                 }
01111                 break;
01112         default:
01113                 llerrs << "NameValue: Trying to set LLVector3 into a " << mStringType << ", unknown conversion" << llendl;
01114                 break;
01115         }
01116         return;
01117 }
01118 
01119 
01120 BOOL LLNameValue::nonzero()
01121 {
01122         switch(mType)
01123         {
01124         case NVT_STRING:
01125                 if (!mNameValueReference.string)
01126                         return 0;
01127                 return (mNameValueReference.string[0] != 0);
01128         case NVT_F32:
01129                 return (*mNameValueReference.f32 != 0.f);
01130         case NVT_S32:
01131                 return (*mNameValueReference.s32 != 0);
01132         case NVT_U32:
01133                 return (*mNameValueReference.u32 != 0);
01134         case NVT_VEC3:
01135                 return (mNameValueReference.vec3->magVecSquared() != 0.f);
01136         default:
01137                 llerrs << "NameValue: Trying to call nonzero on a " << mStringType << ", unknown conversion" << llendl;
01138                 break;
01139         }
01140         return FALSE;
01141 }
01142 
01143 std::string LLNameValue::printNameValue()
01144 {
01145         std::string buffer;
01146         buffer = llformat("%s %s %s %s ", mName, mStringType, mStringClass, mStringSendto);
01147         buffer += printData();
01148 //      llinfos << "Name Value Length: " << buffer.size() + 1 << llendl;
01149         return buffer;
01150 }
01151 
01152 std::string LLNameValue::printData()
01153 {
01154         std::string buffer;
01155         switch(mType)
01156         {
01157         case NVT_STRING:
01158         case NVT_ASSET:
01159                 buffer = mNameValueReference.string;
01160                 break;
01161         case NVT_F32:
01162                 buffer = llformat("%f", *mNameValueReference.f32);
01163                 break;
01164         case NVT_S32:
01165                 buffer = llformat("%d", *mNameValueReference.s32);
01166                 break;
01167         case NVT_U32:
01168                 buffer = llformat("%u", *mNameValueReference.u32);
01169                 break;
01170         case NVT_U64:
01171                 {
01172                         char u64_string[U64_BUFFER_LEN];        /* Flawfinder: ignore */
01173                         U64_to_str(*mNameValueReference.u64, u64_string, sizeof(u64_string));
01174                         buffer = u64_string;
01175                 }
01176                 break;
01177         case NVT_VEC3:
01178                 buffer = llformat( "%f, %f, %f", mNameValueReference.vec3->mV[VX], mNameValueReference.vec3->mV[VY], mNameValueReference.vec3->mV[VZ]);
01179                 break;
01180         default:
01181                 llerrs << "Trying to print unknown NameValue type " << mStringType << llendl;
01182                 break;
01183         }
01184         return buffer;
01185 }
01186 
01187 std::ostream&           operator<<(std::ostream& s, const LLNameValue &a)
01188 {
01189         switch(a.mType)
01190         {
01191         case NVT_STRING:
01192         case NVT_ASSET:
01193                 s << a.mNameValueReference.string;
01194                 break;
01195         case NVT_F32:
01196                 s << (*a.mNameValueReference.f32);
01197                 break;
01198         case NVT_S32:
01199                 s << *(a.mNameValueReference.s32);
01200                 break;
01201         case NVT_U32:
01202                 s << *(a.mNameValueReference.u32);
01203                 break;
01204         case NVT_U64:
01205                 {
01206                         char u64_string[U64_BUFFER_LEN];        /* Flawfinder: ignore */
01207                         U64_to_str(*a.mNameValueReference.u64, u64_string, sizeof(u64_string));
01208                         s << u64_string;
01209                 }
01210         case NVT_VEC3:
01211                 s << *(a.mNameValueReference.vec3);
01212                 break;
01213         default:
01214                 llerrs << "Trying to print unknown NameValue type " << a.mStringType << llendl;
01215                 break;
01216         }
01217         return s;
01218 }
01219 
01220 
01221 // nota bene: return values aren't static for now to prevent memory leaks
01222 
01223 LLNameValue     &operator+(const LLNameValue &a, const LLNameValue &b)
01224 {
01225         static LLNameValue retval;
01226 
01227         switch(a.mType)
01228         {
01229         case NVT_STRING:
01230                 if (b.mType == NVT_STRING)
01231                 {
01232                         retval.mType = a.mType;
01233                         retval.mStringType = NameValueTypeStrings[a.mType];
01234 
01235                         S32 length1 = (S32)strlen(a.mNameValueReference.string);                /* Flawfinder: Ignore */
01236                         S32 length2 = (S32)strlen(b.mNameValueReference.string);                /* Flawfinder: Ignore */
01237                         delete [] retval.mNameValueReference.string;
01238                         retval.mNameValueReference.string = new char[length1 + length2 + 1];
01239                         if(retval.mNameValueReference.string != NULL)
01240                         {
01241                                 strcpy(retval.mNameValueReference.string, a.mNameValueReference.string);        /* Flawfinder: Ignore */
01242                                 strcat(retval.mNameValueReference.string, b.mNameValueReference.string);                /* Flawfinder: Ignore */
01243                         }
01244                 }
01245                 break;
01246         case NVT_F32:
01247                 if (b.mType == NVT_F32)
01248                 {
01249                         retval.mType = NVT_F32;
01250                         retval.mStringType = NameValueTypeStrings[NVT_F32];
01251                         delete retval.mNameValueReference.f32;
01252                         retval.mNameValueReference.f32 = new F32(*a.mNameValueReference.f32 + *b.mNameValueReference.f32);
01253                 }
01254                 else if (b.mType == NVT_S32)
01255                 {
01256                         retval.mType = NVT_F32;
01257                         retval.mStringType = NameValueTypeStrings[NVT_F32];
01258                         delete retval.mNameValueReference.f32;
01259                         retval.mNameValueReference.f32 = new F32(*a.mNameValueReference.f32 + *b.mNameValueReference.s32);
01260                 }
01261                 else if (b.mType == NVT_U32)
01262                 {
01263                         retval.mType = NVT_F32;
01264                         retval.mStringType = NameValueTypeStrings[NVT_F32];
01265                         delete retval.mNameValueReference.f32;
01266                         retval.mNameValueReference.f32 = new F32(*a.mNameValueReference.f32 + *b.mNameValueReference.u32);
01267                 }
01268                 break;
01269         case NVT_S32:
01270                 if (b.mType == NVT_F32)
01271                 {
01272                         retval.mType = NVT_F32;
01273                         retval.mStringType = NameValueTypeStrings[NVT_F32];
01274                         delete retval.mNameValueReference.f32;
01275                         retval.mNameValueReference.f32 = new F32(*a.mNameValueReference.s32 + *b.mNameValueReference.f32);
01276                 }
01277                 else if (b.mType == NVT_S32)
01278                 {
01279                         retval.mType = NVT_S32;
01280                         retval.mStringType = NameValueTypeStrings[NVT_S32];
01281                         delete retval.mNameValueReference.s32;
01282                         retval.mNameValueReference.s32 = new S32(*a.mNameValueReference.s32 + *b.mNameValueReference.s32);
01283                 }
01284                 else if (b.mType == NVT_U32)
01285                 {
01286                         retval.mType = NVT_S32;
01287                         retval.mStringType = NameValueTypeStrings[NVT_S32];
01288                         delete retval.mNameValueReference.s32;
01289                         retval.mNameValueReference.s32 = new S32(*a.mNameValueReference.s32 + *b.mNameValueReference.u32);
01290                 }
01291                 break;
01292         case NVT_U32:
01293                 if (b.mType == NVT_F32)
01294                 {
01295                         retval.mType = NVT_F32;
01296                         retval.mStringType = NameValueTypeStrings[NVT_F32];
01297                         delete retval.mNameValueReference.f32;
01298                         retval.mNameValueReference.f32 = new F32(*a.mNameValueReference.u32 + *b.mNameValueReference.f32);
01299                 }
01300                 else if (b.mType == NVT_S32)
01301                 {
01302                         retval.mType = NVT_S32;
01303                         retval.mStringType = NameValueTypeStrings[NVT_S32];
01304                         delete retval.mNameValueReference.s32;
01305                         retval.mNameValueReference.s32 = new S32(*a.mNameValueReference.u32 + *b.mNameValueReference.s32);
01306                 }
01307                 else if (b.mType == NVT_U32)
01308                 {
01309                         retval.mType = NVT_U32;
01310                         retval.mStringType = NameValueTypeStrings[NVT_U32];
01311                         delete retval.mNameValueReference.u32;
01312                         retval.mNameValueReference.u32 = new U32(*a.mNameValueReference.u32 + *b.mNameValueReference.u32);
01313                 }
01314                 break;
01315         case NVT_VEC3:
01316                 if (  (a.mType == b.mType)
01317                         &&(a.mType == NVT_VEC3))
01318                 {
01319                         retval.mType = a.mType;
01320                         retval.mStringType = NameValueTypeStrings[a.mType];
01321                         delete retval.mNameValueReference.vec3;
01322                         retval.mNameValueReference.vec3 = new LLVector3(*a.mNameValueReference.vec3 + *b.mNameValueReference.vec3);
01323                 }
01324                 break;
01325         default:
01326                 llerrs << "Unknown add of NV type " << a.mStringType << " to " << b.mStringType << llendl;
01327                 break;
01328         }
01329         return retval;
01330 }
01331 
01332 LLNameValue     &operator-(const LLNameValue &a, const LLNameValue &b)
01333 {
01334         static LLNameValue retval;
01335 
01336         switch(a.mType)
01337         {
01338         case NVT_STRING:
01339                 break;
01340         case NVT_F32:
01341                 if (b.mType == NVT_F32)
01342                 {
01343                         retval.mType = NVT_F32;
01344                         retval.mStringType = NameValueTypeStrings[NVT_F32];
01345                         delete retval.mNameValueReference.f32;
01346                         retval.mNameValueReference.f32 = new F32(*a.mNameValueReference.f32 - *b.mNameValueReference.f32);
01347                 }
01348                 else if (b.mType == NVT_S32)
01349                 {
01350                         retval.mType = NVT_F32;
01351                         retval.mStringType = NameValueTypeStrings[NVT_F32];
01352                         delete retval.mNameValueReference.f32;
01353                         retval.mNameValueReference.f32 = new F32(*a.mNameValueReference.f32 - *b.mNameValueReference.s32);
01354                 }
01355                 else if (b.mType == NVT_U32)
01356                 {
01357                         retval.mType = NVT_F32;
01358                         retval.mStringType = NameValueTypeStrings[NVT_F32];
01359                         delete retval.mNameValueReference.f32;
01360                         retval.mNameValueReference.f32 = new F32(*a.mNameValueReference.f32 - *b.mNameValueReference.u32);
01361                 }
01362                 break;
01363         case NVT_S32:
01364                 if (b.mType == NVT_F32)
01365                 {
01366                         retval.mType = NVT_F32;
01367                         retval.mStringType = NameValueTypeStrings[NVT_F32];
01368                         delete retval.mNameValueReference.f32;
01369                         retval.mNameValueReference.f32 = new F32(*a.mNameValueReference.s32 - *b.mNameValueReference.f32);
01370                 }
01371                 else if (b.mType == NVT_S32)
01372                 {
01373                         retval.mType = NVT_S32;
01374                         retval.mStringType = NameValueTypeStrings[NVT_S32];
01375                         delete retval.mNameValueReference.s32;
01376                         retval.mNameValueReference.s32 = new S32(*a.mNameValueReference.s32 - *b.mNameValueReference.s32);
01377                 }
01378                 else if (b.mType == NVT_U32)
01379                 {
01380                         retval.mType = NVT_S32;
01381                         retval.mStringType = NameValueTypeStrings[NVT_S32];
01382                         delete retval.mNameValueReference.s32;
01383                         retval.mNameValueReference.s32 = new S32(*a.mNameValueReference.s32 - *b.mNameValueReference.u32);
01384                 }
01385                 break;
01386         case NVT_U32:
01387                 if (b.mType == NVT_F32)
01388                 {
01389                         retval.mType = NVT_F32;
01390                         retval.mStringType = NameValueTypeStrings[NVT_F32];
01391                         delete retval.mNameValueReference.f32;
01392                         retval.mNameValueReference.f32 = new F32(*a.mNameValueReference.u32 - *b.mNameValueReference.f32);
01393                 }
01394                 else if (b.mType == NVT_S32)
01395                 {
01396                         retval.mType = NVT_S32;
01397                         retval.mStringType = NameValueTypeStrings[NVT_S32];
01398                         delete retval.mNameValueReference.s32;
01399                         retval.mNameValueReference.s32 = new S32(*a.mNameValueReference.u32 - *b.mNameValueReference.s32);
01400                 }
01401                 else if (b.mType == NVT_U32)
01402                 {
01403                         retval.mType = NVT_U32;
01404                         retval.mStringType = NameValueTypeStrings[NVT_U32];
01405                         delete retval.mNameValueReference.u32;
01406                         retval.mNameValueReference.u32 = new U32(*a.mNameValueReference.u32 - *b.mNameValueReference.u32);
01407                 }
01408                 break;
01409         case NVT_VEC3:
01410                 if (  (a.mType == b.mType)
01411                         &&(a.mType == NVT_VEC3))
01412                 {
01413                         retval.mType = a.mType;
01414                         retval.mStringType = NameValueTypeStrings[a.mType];
01415                         delete retval.mNameValueReference.vec3;
01416                         retval.mNameValueReference.vec3 = new LLVector3(*a.mNameValueReference.vec3 - *b.mNameValueReference.vec3);
01417                 }
01418                 break;
01419         default:
01420                 llerrs << "Unknown subtract of NV type " << a.mStringType << " to " << b.mStringType << llendl;
01421                 break;
01422         }
01423         return retval;
01424 }
01425 
01426 LLNameValue     &operator*(const LLNameValue &a, const LLNameValue &b)
01427 {
01428         static LLNameValue retval;
01429 
01430         switch(a.mType)
01431         {
01432         case NVT_STRING:
01433                 break;
01434         case NVT_F32:
01435                 if (b.mType == NVT_F32)
01436                 {
01437                         retval.mType = NVT_F32;
01438                         retval.mStringType = NameValueTypeStrings[NVT_F32];
01439                         delete retval.mNameValueReference.f32;
01440                         retval.mNameValueReference.f32 = new F32(*a.mNameValueReference.f32 * *b.mNameValueReference.f32);
01441                 }
01442                 else if (b.mType == NVT_S32)
01443                 {
01444                         retval.mType = NVT_F32;
01445                         retval.mStringType = NameValueTypeStrings[NVT_F32];
01446                         delete retval.mNameValueReference.f32;
01447                         retval.mNameValueReference.f32 = new F32(*a.mNameValueReference.f32 * *b.mNameValueReference.s32);
01448                 }
01449                 else if (b.mType == NVT_U32)
01450                 {
01451                         retval.mType = NVT_F32;
01452                         retval.mStringType = NameValueTypeStrings[NVT_F32];
01453                         delete retval.mNameValueReference.f32;
01454                         retval.mNameValueReference.f32 = new F32(*a.mNameValueReference.f32 * *b.mNameValueReference.u32);
01455                 }
01456                 break;
01457         case NVT_S32:
01458                 if (b.mType == NVT_F32)
01459                 {
01460                         retval.mType = NVT_F32;
01461                         retval.mStringType = NameValueTypeStrings[NVT_F32];
01462                         delete retval.mNameValueReference.f32;
01463                         retval.mNameValueReference.f32 = new F32(*a.mNameValueReference.s32 * *b.mNameValueReference.f32);
01464                 }
01465                 else if (b.mType == NVT_S32)
01466                 {
01467                         retval.mType = NVT_S32;
01468                         retval.mStringType = NameValueTypeStrings[NVT_S32];
01469                         delete retval.mNameValueReference.s32;
01470                         retval.mNameValueReference.s32 = new S32(*a.mNameValueReference.s32 * *b.mNameValueReference.s32);
01471                 }
01472                 else if (b.mType == NVT_U32)
01473                 {
01474                         retval.mType = NVT_S32;
01475                         retval.mStringType = NameValueTypeStrings[NVT_S32];
01476                         delete retval.mNameValueReference.s32;
01477                         retval.mNameValueReference.s32 = new S32(*a.mNameValueReference.s32 * *b.mNameValueReference.u32);
01478                 }
01479                 break;
01480         case NVT_U32:
01481                 if (b.mType == NVT_F32)
01482                 {
01483                         retval.mType = NVT_F32;
01484                         retval.mStringType = NameValueTypeStrings[NVT_F32];
01485                         delete retval.mNameValueReference.f32;
01486                         retval.mNameValueReference.f32 = new F32(*a.mNameValueReference.u32 * *b.mNameValueReference.f32);
01487                 }
01488                 else if (b.mType == NVT_S32)
01489                 {
01490                         retval.mType = NVT_S32;
01491                         retval.mStringType = NameValueTypeStrings[NVT_S32];
01492                         delete retval.mNameValueReference.s32;
01493                         retval.mNameValueReference.s32 = new S32(*a.mNameValueReference.u32 * *b.mNameValueReference.s32);
01494                 }
01495                 else if (b.mType == NVT_U32)
01496                 {
01497                         retval.mType = NVT_U32;
01498                         retval.mStringType = NameValueTypeStrings[NVT_U32];
01499                         delete retval.mNameValueReference.u32;
01500                         retval.mNameValueReference.u32 = new U32(*a.mNameValueReference.u32 * *b.mNameValueReference.u32);
01501                 }
01502                 break;
01503         case NVT_VEC3:
01504                 if (  (a.mType == b.mType)
01505                         &&(a.mType == NVT_VEC3))
01506                 {
01507                         retval.mType = NVT_F32;
01508                         retval.mStringType = NameValueTypeStrings[a.mType];
01509                         delete retval.mNameValueReference.f32;
01510                         retval.mNameValueReference.f32 = new F32((*a.mNameValueReference.vec3) * (*b.mNameValueReference.vec3));
01511                 }
01512                 break;
01513         default:
01514                 llerrs << "Unknown multiply of NV type " << a.mStringType << " to " << b.mStringType << llendl;
01515                 break;
01516         }
01517         return retval;
01518 }
01519 
01520 LLNameValue     &operator/(const LLNameValue &a, const LLNameValue &b)
01521 {
01522         static LLNameValue retval;
01523 
01524         switch(a.mType)
01525         {
01526         case NVT_STRING:
01527                 break;
01528         case NVT_F32:
01529                 if (b.mType == NVT_F32)
01530                 {
01531                         retval.mType = NVT_F32;
01532                         retval.mStringType = NameValueTypeStrings[NVT_F32];
01533                         delete retval.mNameValueReference.f32;
01534                         retval.mNameValueReference.f32 = new F32(*a.mNameValueReference.f32 / *b.mNameValueReference.f32);
01535                 }
01536                 else if (b.mType == NVT_S32)
01537                 {
01538                         retval.mType = NVT_F32;
01539                         retval.mStringType = NameValueTypeStrings[NVT_F32];
01540                         delete retval.mNameValueReference.f32;
01541                         retval.mNameValueReference.f32 = new F32(*a.mNameValueReference.f32 / *b.mNameValueReference.s32);
01542                 }
01543                 else if (b.mType == NVT_U32)
01544                 {
01545                         retval.mType = NVT_F32;
01546                         retval.mStringType = NameValueTypeStrings[NVT_F32];
01547                         delete retval.mNameValueReference.f32;
01548                         retval.mNameValueReference.f32 = new F32(*a.mNameValueReference.f32 / *b.mNameValueReference.u32);
01549                 }
01550                 break;
01551         case NVT_S32:
01552                 if (b.mType == NVT_F32)
01553                 {
01554                         retval.mType = NVT_F32;
01555                         retval.mStringType = NameValueTypeStrings[NVT_F32];
01556                         delete retval.mNameValueReference.f32;
01557                         retval.mNameValueReference.f32 = new F32(*a.mNameValueReference.s32 / *b.mNameValueReference.f32);
01558                 }
01559                 else if (b.mType == NVT_S32)
01560                 {
01561                         retval.mType = NVT_S32;
01562                         retval.mStringType = NameValueTypeStrings[NVT_S32];
01563                         delete retval.mNameValueReference.s32;
01564                         retval.mNameValueReference.s32 = new S32(*a.mNameValueReference.s32 / *b.mNameValueReference.s32);
01565                 }
01566                 else if (b.mType == NVT_U32)
01567                 {
01568                         retval.mType = NVT_S32;
01569                         retval.mStringType = NameValueTypeStrings[NVT_S32];
01570                         delete retval.mNameValueReference.s32;
01571                         retval.mNameValueReference.s32 = new S32(*a.mNameValueReference.s32 / *b.mNameValueReference.u32);
01572                 }
01573                 break;
01574         case NVT_U32:
01575                 if (b.mType == NVT_F32)
01576                 {
01577                         retval.mType = NVT_F32;
01578                         retval.mStringType = NameValueTypeStrings[NVT_F32];
01579                         delete retval.mNameValueReference.f32;
01580                         retval.mNameValueReference.f32 = new F32(*a.mNameValueReference.u32 / *b.mNameValueReference.f32);
01581                 }
01582                 else if (b.mType == NVT_S32)
01583                 {
01584                         retval.mType = NVT_S32;
01585                         retval.mStringType = NameValueTypeStrings[NVT_S32];
01586                         delete retval.mNameValueReference.s32;
01587                         retval.mNameValueReference.s32 = new S32(*a.mNameValueReference.u32 / *b.mNameValueReference.s32);
01588                 }
01589                 else if (b.mType == NVT_U32)
01590                 {
01591                         retval.mType = NVT_U32;
01592                         retval.mStringType = NameValueTypeStrings[NVT_U32];
01593                         delete retval.mNameValueReference.u32;
01594                         retval.mNameValueReference.u32 = new U32(*a.mNameValueReference.u32 / *b.mNameValueReference.u32);
01595                 }
01596                 break;
01597         default:
01598                 llerrs << "Unknown divide of NV type " << a.mStringType << " to " << b.mStringType << llendl;
01599                 break;
01600         }
01601         return retval;
01602 }
01603 
01604 LLNameValue     &operator%(const LLNameValue &a, const LLNameValue &b)
01605 {
01606         static LLNameValue retval;
01607 
01608         switch(a.mType)
01609         {
01610         case NVT_STRING:
01611                 break;
01612         case NVT_F32:
01613                 break;
01614         case NVT_S32:
01615                 if (b.mType == NVT_S32)
01616                 {
01617                         retval.mType = NVT_S32;
01618                         retval.mStringType = NameValueTypeStrings[NVT_S32];
01619                         delete retval.mNameValueReference.s32;
01620                         retval.mNameValueReference.s32 = new S32(*a.mNameValueReference.s32 % *b.mNameValueReference.s32);
01621                 }
01622                 else if (b.mType == NVT_U32)
01623                 {
01624                         retval.mType = NVT_S32;
01625                         retval.mStringType = NameValueTypeStrings[NVT_S32];
01626                         delete retval.mNameValueReference.s32;
01627                         retval.mNameValueReference.s32 = new S32(*a.mNameValueReference.s32 % *b.mNameValueReference.u32);
01628                 }
01629                 break;
01630         case NVT_U32:
01631                 if (b.mType == NVT_S32)
01632                 {
01633                         retval.mType = NVT_S32;
01634                         retval.mStringType = NameValueTypeStrings[NVT_S32];
01635                         delete retval.mNameValueReference.s32;
01636                         retval.mNameValueReference.s32 = new S32(*a.mNameValueReference.u32 % *b.mNameValueReference.s32);
01637                 }
01638                 else if (b.mType == NVT_U32)
01639                 {
01640                         retval.mType = NVT_U32;
01641                         retval.mStringType = NameValueTypeStrings[NVT_U32];
01642                         delete retval.mNameValueReference.u32;
01643                         retval.mNameValueReference.u32 = new U32(*a.mNameValueReference.u32 % *b.mNameValueReference.u32);
01644                 }
01645                 break;
01646         case NVT_VEC3:
01647                 if (  (a.mType == b.mType)
01648                         &&(a.mType == NVT_VEC3))
01649                 {
01650                         retval.mType = a.mType;
01651                         retval.mStringType = NameValueTypeStrings[a.mType];
01652                         delete retval.mNameValueReference.vec3;
01653                         retval.mNameValueReference.vec3 = new LLVector3(*a.mNameValueReference.vec3 % *b.mNameValueReference.vec3);
01654                 }
01655                 break;
01656         default:
01657                 llerrs << "Unknown % of NV type " << a.mStringType << " to " << b.mStringType << llendl;
01658                 break;
01659         }
01660         return retval;
01661 }
01662 
01663 
01664 // Multiplying anything times a float gives you some floats
01665 LLNameValue     &operator*(const LLNameValue &a, F32 k)
01666 {
01667         static LLNameValue retval;
01668 
01669         switch(a.mType)
01670         {
01671         case NVT_STRING:
01672                 break;
01673         case NVT_F32:
01674                 retval.mType = NVT_F32;
01675                 retval.mStringType = NameValueTypeStrings[NVT_F32];
01676                 delete retval.mNameValueReference.f32;
01677                 retval.mNameValueReference.f32 = new F32(*a.mNameValueReference.f32 * k);
01678                 break;
01679         case NVT_S32:
01680                 retval.mType = NVT_F32;
01681                 retval.mStringType = NameValueTypeStrings[NVT_F32];
01682                 delete retval.mNameValueReference.f32;
01683                 retval.mNameValueReference.f32 = new F32(*a.mNameValueReference.s32 * k);
01684                 break;
01685         case NVT_U32:
01686                 retval.mType = NVT_F32;
01687                 retval.mStringType = NameValueTypeStrings[NVT_F32];
01688                 delete retval.mNameValueReference.f32;
01689                 retval.mNameValueReference.f32 = new F32(*a.mNameValueReference.u32 * k);
01690                 break;
01691         case NVT_VEC3:
01692                 retval.mType = a.mType;
01693                 retval.mStringType = NameValueTypeStrings[a.mType];
01694                 delete retval.mNameValueReference.vec3;
01695                 retval.mNameValueReference.vec3 = new LLVector3(*a.mNameValueReference.vec3 * k);
01696                 break;
01697         default:
01698                 llerrs << "Unknown multiply of NV type " << a.mStringType << " with F32" << llendl;
01699                 break;
01700         }
01701         return retval;
01702 }
01703 
01704 
01705 LLNameValue     &operator*(F32 k, const LLNameValue &a)
01706 {
01707         static LLNameValue retval;
01708 
01709         switch(a.mType)
01710         {
01711         case NVT_STRING:
01712                 break;
01713         case NVT_F32:
01714                 retval.mType = NVT_F32;
01715                 retval.mStringType = NameValueTypeStrings[NVT_F32];
01716                 delete retval.mNameValueReference.f32;
01717                 retval.mNameValueReference.f32 = new F32(*a.mNameValueReference.f32 * k);
01718                 break;
01719         case NVT_S32:
01720                 retval.mType = NVT_F32;
01721                 retval.mStringType = NameValueTypeStrings[NVT_F32];
01722                 delete retval.mNameValueReference.f32;
01723                 retval.mNameValueReference.f32 = new F32(*a.mNameValueReference.s32 * k);
01724                 break;
01725         case NVT_U32:
01726                 retval.mType = NVT_F32;
01727                 retval.mStringType = NameValueTypeStrings[NVT_F32];
01728                 delete retval.mNameValueReference.f32;
01729                 retval.mNameValueReference.f32 = new F32(*a.mNameValueReference.u32 * k);
01730                 break;
01731         case NVT_VEC3:
01732                 retval.mType = a.mType;
01733                 retval.mStringType = NameValueTypeStrings[a.mType];
01734                 delete retval.mNameValueReference.vec3;
01735                 retval.mNameValueReference.vec3 = new LLVector3(*a.mNameValueReference.vec3 * k);
01736                 break;
01737         default:
01738                 llerrs << "Unknown multiply of NV type " << a.mStringType << " with F32" << llendl;
01739                 break;
01740         }
01741         return retval;
01742 }
01743 
01744 
01745 bool operator==(const LLNameValue &a, const LLNameValue &b)
01746 {
01747         switch(a.mType)
01748         {
01749         case NVT_STRING:
01750                 if (b.mType == NVT_STRING)
01751                 {
01752                         if (!a.mNameValueReference.string)
01753                                 return FALSE;
01754                         if (!b.mNameValueReference.string)
01755                                 return FALSE;
01756                         return (!strcmp(a.mNameValueReference.string, b.mNameValueReference.string));
01757                 }
01758                 break;
01759         case NVT_F32:
01760                 if (b.mType == NVT_F32)
01761                 {
01762                         return (*a.mNameValueReference.f32 == *b.mNameValueReference.f32);
01763                 }
01764                 else if (b.mType == NVT_S32)
01765                 {
01766                         return (*a.mNameValueReference.f32 == *b.mNameValueReference.s32);
01767                 }
01768                 else if (b.mType == NVT_U32)
01769                 {
01770                         return (*a.mNameValueReference.f32 == *b.mNameValueReference.u32);
01771                 }
01772                 break;
01773         case NVT_S32:
01774                 if (b.mType == NVT_F32)
01775                 {
01776                         return (*a.mNameValueReference.s32 == *b.mNameValueReference.f32);
01777                 }
01778                 else if (b.mType == NVT_S32)
01779                 {
01780                         return (*a.mNameValueReference.s32 == *b.mNameValueReference.s32);
01781                 }
01782                 else if (b.mType == NVT_U32)
01783                 {
01784                         return (*a.mNameValueReference.s32 == (S32) *b.mNameValueReference.u32);
01785                 }
01786                 break;
01787         case NVT_U32:
01788                 if (b.mType == NVT_F32)
01789                 {
01790                         return (*a.mNameValueReference.u32 == *b.mNameValueReference.f32);
01791                 }
01792                 else if (b.mType == NVT_S32)
01793                 {
01794                         return ((S32) *a.mNameValueReference.u32 == *b.mNameValueReference.s32);
01795                 }
01796                 else if (b.mType == NVT_U32)
01797                 {
01798                         return (*a.mNameValueReference.u32 == *b.mNameValueReference.u32);
01799                 }
01800                 break;
01801         case NVT_VEC3:
01802                 if (  (a.mType == b.mType)
01803                         &&(a.mType == NVT_VEC3))
01804                 {
01805                         return (*a.mNameValueReference.vec3 == *b.mNameValueReference.vec3);
01806                 }
01807                 break;
01808         default:
01809                 llerrs << "Unknown == NV type " << a.mStringType << " with " << b.mStringType << llendl;
01810                 break;
01811         }
01812         return FALSE;
01813 }
01814 
01815 bool operator<=(const LLNameValue &a, const LLNameValue &b)
01816 {
01817         switch(a.mType)
01818         {
01819         case NVT_STRING:
01820                 if (b.mType == NVT_STRING)
01821                 {
01822                         S32 retval = strcmp(a.mNameValueReference.string, b.mNameValueReference.string);
01823                         return (retval <= 0);
01824                 }
01825                 break;
01826         case NVT_F32:
01827                 if (b.mType == NVT_F32)
01828                 {
01829                         return (*a.mNameValueReference.f32 <= *b.mNameValueReference.f32);
01830                 }
01831                 else if (b.mType == NVT_S32)
01832                 {
01833                         return (*a.mNameValueReference.f32 <= *b.mNameValueReference.s32);
01834                 }
01835                 else if (b.mType == NVT_U32)
01836                 {
01837                         return (*a.mNameValueReference.f32 <= *b.mNameValueReference.u32);
01838                 }
01839                 break;
01840         case NVT_S32:
01841                 if (b.mType == NVT_F32)
01842                 {
01843                         return (*a.mNameValueReference.s32 <= *b.mNameValueReference.f32);
01844                 }
01845                 else if (b.mType == NVT_S32)
01846                 {
01847                         return (*a.mNameValueReference.s32 <= *b.mNameValueReference.s32);
01848                 }
01849                 else if (b.mType == NVT_U32)
01850                 {
01851                         return (*a.mNameValueReference.s32 <= (S32) *b.mNameValueReference.u32);
01852                 }
01853                 break;
01854         case NVT_U32:
01855                 if (b.mType == NVT_F32)
01856                 {
01857                         return (*a.mNameValueReference.u32 <= *b.mNameValueReference.f32);
01858                 }
01859                 else if (b.mType == NVT_S32)
01860                 {
01861                         return ((S32) *a.mNameValueReference.u32 <= *b.mNameValueReference.s32);
01862                 }
01863                 else if (b.mType == NVT_U32)
01864                 {
01865                         return (*a.mNameValueReference.u32 <= *b.mNameValueReference.u32);
01866                 }
01867                 break;
01868         default:
01869                 llerrs << "Unknown <= NV type " << a.mStringType << " with " << b.mStringType << llendl;
01870                 break;
01871         }
01872         return FALSE;
01873 }
01874 
01875 
01876 bool                    operator>=(const LLNameValue &a, const LLNameValue &b)
01877 {
01878         switch(a.mType)
01879         {
01880         case NVT_STRING:
01881                 if (  (a.mType == b.mType)
01882                         &&(a.mType == NVT_STRING))
01883                 {
01884                         S32 retval = strcmp(a.mNameValueReference.string, b.mNameValueReference.string);
01885                         return (retval >= 0);
01886                 }
01887                 break;
01888         case NVT_F32:
01889                 if (b.mType == NVT_F32)
01890                 {
01891                         return (*a.mNameValueReference.f32 >= *b.mNameValueReference.f32);
01892                 }
01893                 else if (b.mType == NVT_S32)
01894                 {
01895                         return (*a.mNameValueReference.f32 >= *b.mNameValueReference.s32);
01896                 }
01897                 else if (b.mType == NVT_U32)
01898                 {
01899                         return (*a.mNameValueReference.f32 >= *b.mNameValueReference.u32);
01900                 }
01901                 break;
01902         case NVT_S32:
01903                 if (b.mType == NVT_F32)
01904                 {
01905                         return (*a.mNameValueReference.s32 >= *b.mNameValueReference.f32);
01906                 }
01907                 else if (b.mType == NVT_S32)
01908                 {
01909                         return (*a.mNameValueReference.s32 >= *b.mNameValueReference.s32);
01910                 }
01911                 else if (b.mType == NVT_U32)
01912                 {
01913                         return (*a.mNameValueReference.s32 >= (S32) *b.mNameValueReference.u32);
01914                 }
01915                 break;
01916         case NVT_U32:
01917                 if (b.mType == NVT_F32)
01918                 {
01919                         return (*a.mNameValueReference.u32 >= *b.mNameValueReference.f32);
01920                 }
01921                 else if (b.mType == NVT_S32)
01922                 {
01923                         return ((S32) *a.mNameValueReference.u32 >= *b.mNameValueReference.s32);
01924                 }
01925                 else if (b.mType == NVT_U32)
01926                 {
01927                         return (*a.mNameValueReference.u32 >= *b.mNameValueReference.u32);
01928                 }
01929                 break;
01930         default:
01931                 llerrs << "Unknown >= NV type " << a.mStringType << " with " << b.mStringType << llendl;
01932                 break;
01933         }
01934         return FALSE;
01935 }
01936 
01937 
01938 bool                    operator<(const LLNameValue &a, const LLNameValue &b)
01939 {
01940         switch(a.mType)
01941         {
01942         case NVT_STRING:
01943                 if (  (a.mType == b.mType)
01944                         &&(a.mType == NVT_STRING))
01945                 {
01946                         S32 retval = strcmp(a.mNameValueReference.string, b.mNameValueReference.string);
01947                         return (retval < 0);
01948                 }
01949                 break;
01950         case NVT_F32:
01951                 if (b.mType == NVT_F32)
01952                 {
01953                         return (*a.mNameValueReference.f32 < *b.mNameValueReference.f32);
01954                 }
01955                 else if (b.mType == NVT_S32)
01956                 {
01957                         return (*a.mNameValueReference.f32 < *b.mNameValueReference.s32);
01958                 }
01959                 else if (b.mType == NVT_U32)
01960                 {
01961                         return (*a.mNameValueReference.f32 < *b.mNameValueReference.u32);
01962                 }
01963                 break;
01964         case NVT_S32:
01965                 if (b.mType == NVT_F32)
01966                 {
01967                         return (*a.mNameValueReference.s32 < *b.mNameValueReference.f32);
01968                 }
01969                 else if (b.mType == NVT_S32)
01970                 {
01971                         return (*a.mNameValueReference.s32 < *b.mNameValueReference.s32);
01972                 }
01973                 else if (b.mType == NVT_U32)
01974                 {
01975                         return (*a.mNameValueReference.s32 < (S32) *b.mNameValueReference.u32);
01976                 }
01977                 break;
01978         case NVT_U32:
01979                 if (b.mType == NVT_F32)
01980                 {
01981                         return (*a.mNameValueReference.u32 < *b.mNameValueReference.f32);
01982                 }
01983                 else if (b.mType == NVT_S32)
01984                 {
01985                         return ((S32) *a.mNameValueReference.u32 < *b.mNameValueReference.s32);
01986                 }
01987                 else if (b.mType == NVT_U32)
01988                 {
01989                         return (*a.mNameValueReference.u32 < *b.mNameValueReference.u32);
01990                 }
01991                 break;
01992         default:
01993                 llerrs << "Unknown < NV type " << a.mStringType << " with " << b.mStringType << llendl;
01994                 break;
01995         }
01996         return FALSE;
01997 }
01998 
01999 
02000 bool                    operator>(const LLNameValue &a, const LLNameValue &b)
02001 {
02002         switch(a.mType)
02003         {
02004         case NVT_STRING:
02005                 if (  (a.mType == b.mType)
02006                         &&(a.mType == NVT_STRING))
02007                 {
02008                         S32 retval = strcmp(a.mNameValueReference.string, b.mNameValueReference.string);
02009                         return (retval > 0);
02010                 }
02011                 break;
02012         case NVT_F32:
02013                 if (b.mType == NVT_F32)
02014                 {
02015                         return (*a.mNameValueReference.f32 > *b.mNameValueReference.f32);
02016                 }
02017                 else if (b.mType == NVT_S32)
02018                 {
02019                         return (*a.mNameValueReference.f32 > *b.mNameValueReference.s32);
02020                 }
02021                 else if (b.mType == NVT_U32)
02022                 {
02023                         return (*a.mNameValueReference.f32 > *b.mNameValueReference.u32);
02024                 }
02025                 break;
02026         case NVT_S32:
02027                 if (b.mType == NVT_F32)
02028                 {
02029                         return (*a.mNameValueReference.s32 > *b.mNameValueReference.f32);
02030                 }
02031                 else if (b.mType == NVT_S32)
02032                 {
02033                         return (*a.mNameValueReference.s32 > *b.mNameValueReference.s32);
02034                 }
02035                 else if (b.mType == NVT_U32)
02036                 {
02037                         return (*a.mNameValueReference.s32 > (S32) *b.mNameValueReference.u32);
02038                 }
02039                 break;
02040         case NVT_U32:
02041                 if (b.mType == NVT_F32)
02042                 {
02043                         return (*a.mNameValueReference.u32 > *b.mNameValueReference.f32);
02044                 }
02045                 else if (b.mType == NVT_S32)
02046                 {
02047                         return ((S32) *a.mNameValueReference.u32 > *b.mNameValueReference.s32);
02048                 }
02049                 else if (b.mType == NVT_U32)
02050                 {
02051                         return (*a.mNameValueReference.u32 > *b.mNameValueReference.u32);
02052                 }
02053                 break;
02054         default:
02055                 llerrs << "Unknown > NV type " << a.mStringType << " with " << b.mStringType << llendl;
02056                 break;
02057         }
02058         return FALSE;
02059 }
02060 
02061 bool                    operator!=(const LLNameValue &a, const LLNameValue &b)
02062 {
02063         switch(a.mType)
02064         {
02065         case NVT_STRING:
02066                 if (  (a.mType == b.mType)
02067                         &&(a.mType == NVT_STRING))
02068                 {
02069                         return (strcmp(a.mNameValueReference.string, b.mNameValueReference.string)) ? true : false;
02070                 }
02071                 break;
02072         case NVT_F32:
02073                 if (b.mType == NVT_F32)
02074                 {
02075                         return (*a.mNameValueReference.f32 != *b.mNameValueReference.f32);
02076                 }
02077                 else if (b.mType == NVT_S32)
02078                 {
02079                         return (*a.mNameValueReference.f32 != *b.mNameValueReference.s32);
02080                 }
02081                 else if (b.mType == NVT_U32)
02082                 {
02083                         return (*a.mNameValueReference.f32 != *b.mNameValueReference.u32);
02084                 }
02085                 break;
02086         case NVT_S32:
02087                 if (b.mType == NVT_F32)
02088                 {
02089                         return (*a.mNameValueReference.s32 != *b.mNameValueReference.f32);
02090                 }
02091                 else if (b.mType == NVT_S32)
02092                 {
02093                         return (*a.mNameValueReference.s32 != *b.mNameValueReference.s32);
02094                 }
02095                 else if (b.mType == NVT_U32)
02096                 {
02097                         return (*a.mNameValueReference.s32 != (S32) *b.mNameValueReference.u32);
02098                 }
02099                 break;
02100         case NVT_U32:
02101                 if (b.mType == NVT_F32)
02102                 {
02103                         return (*a.mNameValueReference.u32 != *b.mNameValueReference.f32);
02104                 }
02105                 else if (b.mType == NVT_S32)
02106                 {
02107                         return ((S32) *a.mNameValueReference.u32 != *b.mNameValueReference.s32);
02108                 }
02109                 else if (b.mType == NVT_U32)
02110                 {
02111                         return (*a.mNameValueReference.u32 != *b.mNameValueReference.u32);
02112                 }
02113                 break;
02114         case NVT_VEC3:
02115                 if (  (a.mType == b.mType)
02116                         &&(a.mType == NVT_VEC3))
02117                 {
02118                         return (*a.mNameValueReference.vec3 != *b.mNameValueReference.vec3);
02119                 }
02120                 break;
02121         default:
02122                 llerrs << "Unknown != NV type " << a.mStringType << " with " << b.mStringType << llendl;
02123                 break;
02124         }
02125         return FALSE;
02126 }
02127 
02128 
02129 LLNameValue     &operator-(const LLNameValue &a)
02130 {
02131         static LLNameValue retval;
02132 
02133         switch(a.mType)
02134         {
02135         case NVT_STRING:
02136                 break;
02137         case NVT_F32:
02138                 retval.mType = a.mType;
02139                 retval.mStringType = NameValueTypeStrings[a.mType];
02140                 delete retval.mNameValueReference.f32;
02141                 retval.mNameValueReference.f32 = new F32(-*a.mNameValueReference.f32);
02142                 break;
02143         case NVT_S32:
02144                 retval.mType = a.mType;
02145                 retval.mStringType = NameValueTypeStrings[a.mType];
02146                 delete retval.mNameValueReference.s32;
02147                 retval.mNameValueReference.s32 = new S32(-*a.mNameValueReference.s32);
02148                 break;
02149         case NVT_U32:
02150                 retval.mType = NVT_S32;
02151                 retval.mStringType = NameValueTypeStrings[NVT_S32];
02152                 delete retval.mNameValueReference.s32;
02153                 // Can't do unary minus on U32, doesn't work.
02154                 retval.mNameValueReference.s32 = new S32(-S32(*a.mNameValueReference.u32));
02155                 break;
02156         case NVT_VEC3:
02157                 retval.mType = a.mType;
02158                 retval.mStringType = NameValueTypeStrings[a.mType];
02159                 delete retval.mNameValueReference.vec3;
02160                 retval.mNameValueReference.vec3 = new LLVector3(-*a.mNameValueReference.vec3);
02161                 break;
02162         default:
02163                 llerrs << "Unknown - NV type " << a.mStringType << llendl;
02164                 break;
02165         }
02166         return retval;
02167 }

Generated on Thu Jul 1 06:08:54 2010 for Second Life Viewer by  doxygen 1.4.7