llnamevalue.cpp 19 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952953954955956957958959960961962963964965966967968969970
  1. /**
  2. * @file llnamevalue.cpp
  3. * @brief class for defining name value pairs.
  4. *
  5. * $LicenseInfo:firstyear=2001&license=viewergpl$
  6. *
  7. * Copyright (c) 2001-2009, Linden Research, Inc.
  8. *
  9. * Second Life Viewer Source Code
  10. * The source code in this file ("Source Code") is provided by Linden Lab
  11. * to you under the terms of the GNU General Public License, version 2.0
  12. * ("GPL"), unless you have obtained a separate licensing agreement
  13. * ("Other License"), formally executed by you and Linden Lab. Terms of
  14. * the GPL can be found in doc/GPL-license.txt in this distribution, or
  15. * online at http://secondlifegrid.net/programs/open_source/licensing/gplv2
  16. *
  17. * There are special exceptions to the terms and conditions of the GPL as
  18. * it is applied to this Source Code. View the full text of the exception
  19. * in the file doc/FLOSS-exception.txt in this software distribution, or
  20. * online at
  21. * http://secondlifegrid.net/programs/open_source/licensing/flossexception
  22. *
  23. * By copying, modifying or distributing this software, you acknowledge
  24. * that you have read and understood your obligations described above,
  25. * and agree to abide by those obligations.
  26. *
  27. * ALL LINDEN LAB SOURCE CODE IS PROVIDED "AS IS." LINDEN LAB MAKES NO
  28. * WARRANTIES, EXPRESS, IMPLIED OR OTHERWISE, REGARDING ITS ACCURACY,
  29. * COMPLETENESS OR PERFORMANCE.
  30. * $/LicenseInfo$
  31. */
  32. // Examples:
  33. // AvatarCharacter STRING RW DSV male1
  34. #include "linden_common.h"
  35. #include "llnamevalue.h"
  36. #include "llstring.h"
  37. // Anonymous enumeration to provide constants in this file.
  38. // *NOTE: These values may be used in sscanf statements below as their
  39. // value-1, so search for '2047' if you cange NV_BUFFER_LEN or '63' if you
  40. // change U64_BUFFER_LEN.
  41. enum
  42. {
  43. NV_BUFFER_LEN = 2048,
  44. U64_BUFFER_LEN = 64
  45. };
  46. LLStringTable gNVNameTable(256);
  47. char NameValueTypeStrings[NVT_EOF][NAME_VALUE_TYPE_STRING_LENGTH] =
  48. {
  49. "NULL",
  50. "STRING",
  51. "F32",
  52. "S32",
  53. "VEC3",
  54. "U32",
  55. "CAMERA", // Deprecated, but leaving in case removing completely would cause problems
  56. "ASSET",
  57. "U64"
  58. };
  59. char NameValueClassStrings[NVC_EOF][NAME_VALUE_CLASS_STRING_LENGTH] =
  60. {
  61. "NULL",
  62. "R", // read only
  63. "RW" // read write
  64. };
  65. char NameValueSendtoStrings[NVS_EOF][NAME_VALUE_SENDTO_STRING_LENGTH] =
  66. {
  67. "NULL",
  68. "S", // "Sim", formerly SIM
  69. "DS", // "Data Sim" formerly SIM_SPACE
  70. "SV", // "Sim Viewer" formerly SIM_VIEWER
  71. "DSV" // "Data Sim Viewer", formerly SIM_SPACE_VIEWER
  72. };
  73. //
  74. // Class
  75. //
  76. LLNameValue::LLNameValue()
  77. {
  78. baseInit();
  79. }
  80. void LLNameValue::baseInit()
  81. {
  82. mNVNameTable = &gNVNameTable;
  83. mName = NULL;
  84. mNameValueReference.string = NULL;
  85. mType = NVT_NULL;
  86. mStringType = NameValueTypeStrings[NVT_NULL];
  87. mClass = NVC_NULL;
  88. mStringClass = NameValueClassStrings[NVC_NULL];
  89. mSendto = NVS_NULL;
  90. mStringSendto = NameValueSendtoStrings[NVS_NULL];
  91. }
  92. void LLNameValue::init(const char* name, const char* data, const char* type,
  93. const char* nvclass, const char* nvsendto)
  94. {
  95. mNVNameTable = &gNVNameTable;
  96. mName = mNVNameTable->addString(name);
  97. // Nota Bene: Whatever global structure manages this should have these in
  98. // the name table already !
  99. mStringType = mNVNameTable->addString(type);
  100. if (!strcmp(mStringType, "STRING"))
  101. {
  102. S32 string_length = (S32)strlen(data);
  103. mType = NVT_STRING;
  104. delete[] mNameValueReference.string;
  105. mNameValueReference.string = new char[string_length + 1];
  106. strncpy(mNameValueReference.string, data, string_length + 1);
  107. mNameValueReference.string[string_length] = '\0';
  108. }
  109. else if (!strcmp(mStringType, "F32"))
  110. {
  111. mType = NVT_F32;
  112. mNameValueReference.f32 = new F32((F32)atof(data));
  113. }
  114. else if (!strcmp(mStringType, "S32"))
  115. {
  116. mType = NVT_S32;
  117. mNameValueReference.s32 = new S32(atoi(data));
  118. }
  119. else if (!strcmp(mStringType, "U64"))
  120. {
  121. mType = NVT_U64;
  122. mNameValueReference.u64 = new U64(str_to_U64(ll_safe_string(data)));
  123. }
  124. else if (!strcmp(mStringType, "VEC3"))
  125. {
  126. mType = NVT_VEC3;
  127. F32 t1, t2, t3;
  128. // two options here. . . data can either look like 0, 1, 2 or <0, 1, 2>
  129. if (strchr(data, '<'))
  130. {
  131. sscanf(data, "<%f, %f, %f>", &t1, &t2, &t3);
  132. }
  133. else
  134. {
  135. sscanf(data, "%f, %f, %f", &t1, &t2, &t3);
  136. }
  137. // finite checks
  138. if (!llfinite(t1) || !llfinite(t2) || !llfinite(t3))
  139. {
  140. t1 = 0.f;
  141. t2 = 0.f;
  142. t3 = 0.f;
  143. }
  144. mNameValueReference.vec3 = new LLVector3(t1, t2, t3);
  145. }
  146. else if (!strcmp(mStringType, "U32"))
  147. {
  148. mType = NVT_U32;
  149. mNameValueReference.u32 = new U32(atoi(data));
  150. }
  151. else if (!strcmp(mStringType, (const char*)NameValueTypeStrings[NVT_ASSET]))
  152. {
  153. // assets are treated like strings, except that the name has meaning to
  154. // an LLAssetInfo object
  155. S32 string_length = (S32)strlen(data);
  156. mType = NVT_ASSET;
  157. mNameValueReference.string = new char[string_length + 1];
  158. strncpy(mNameValueReference.string, data, string_length + 1);
  159. mNameValueReference.string[string_length] = '\0';
  160. }
  161. else
  162. {
  163. llwarns << "Unknown name value type string " << mStringType << " for "
  164. << mName << llendl;
  165. mType = NVT_NULL;
  166. }
  167. // Nota Bene: Whatever global structure manages this should have these in
  168. // the name table already!
  169. if (!strcmp(nvclass, "R") || !strcmp(nvclass, "READ_ONLY")) // legacy
  170. {
  171. mClass = NVC_READ_ONLY;
  172. mStringClass = mNVNameTable->addString("R");
  173. }
  174. else if (!strcmp(nvclass, "RW") || !strcmp(nvclass, "READ_WRITE")) // legacy
  175. {
  176. mClass = NVC_READ_WRITE;
  177. mStringClass = mNVNameTable->addString("RW");
  178. }
  179. else
  180. {
  181. // assume it's bad
  182. mClass = NVC_NULL;
  183. mStringClass = mNVNameTable->addString(nvclass);
  184. }
  185. // Initialize the sendto variable
  186. if (!strcmp(nvsendto, "S") || !strcmp(nvsendto, "SIM")) // legacy
  187. {
  188. mSendto = NVS_SIM;
  189. mStringSendto = mNVNameTable->addString("S");
  190. }
  191. else if (!strcmp(nvsendto, "DS") || !strcmp(nvsendto, "SIM_SPACE")) // legacy
  192. {
  193. mSendto = NVS_DATA_SIM;
  194. mStringSendto = mNVNameTable->addString("DS");
  195. }
  196. else if (!strcmp(nvsendto, "SV") || !strcmp(nvsendto, "SIM_VIEWER")) // legacy
  197. {
  198. mSendto = NVS_SIM_VIEWER;
  199. mStringSendto = mNVNameTable->addString("SV");
  200. }
  201. else if (!strcmp(nvsendto, "DSV") ||
  202. !strcmp(nvsendto, "SIM_SPACE_VIEWER")) // legacy
  203. {
  204. mSendto = NVS_DATA_SIM_VIEWER;
  205. mStringSendto = mNVNameTable->addString("DSV");
  206. }
  207. else
  208. {
  209. llwarns << "LLNameValue::init() - unknown sendto field " << nvsendto
  210. << " for NV " << mName << llendl;
  211. mSendto = NVS_NULL;
  212. mStringSendto = mNVNameTable->addString("S");
  213. }
  214. }
  215. LLNameValue::LLNameValue(const char* name, const char* data, const char* type,
  216. const char* nvclass)
  217. {
  218. baseInit();
  219. // if not specified, send to simulator only
  220. init(name, data, type, nvclass, "SIM");
  221. }
  222. LLNameValue::LLNameValue(const char* name, const char* data, const char* type,
  223. const char* nvclass, const char* nvsendto)
  224. {
  225. baseInit();
  226. init(name, data, type, nvclass, nvsendto);
  227. }
  228. // Initialize without any initial data.
  229. LLNameValue::LLNameValue(const char* name, const char* type,
  230. const char* nvclass)
  231. {
  232. baseInit();
  233. mName = mNVNameTable->addString(name);
  234. // Nota Bene: Whatever global structure manages this should have these in
  235. // the name table already !
  236. mStringType = mNVNameTable->addString(type);
  237. if (!strcmp(mStringType, "STRING"))
  238. {
  239. mType = NVT_STRING;
  240. mNameValueReference.string = NULL;
  241. }
  242. else if (!strcmp(mStringType, "F32"))
  243. {
  244. mType = NVT_F32;
  245. mNameValueReference.f32 = NULL;
  246. }
  247. else if (!strcmp(mStringType, "S32"))
  248. {
  249. mType = NVT_S32;
  250. mNameValueReference.s32 = NULL;
  251. }
  252. else if (!strcmp(mStringType, "VEC3"))
  253. {
  254. mType = NVT_VEC3;
  255. mNameValueReference.vec3 = NULL;
  256. }
  257. else if (!strcmp(mStringType, "U32"))
  258. {
  259. mType = NVT_U32;
  260. mNameValueReference.u32 = NULL;
  261. }
  262. else if (!strcmp(mStringType, "U64"))
  263. {
  264. mType = NVT_U64;
  265. mNameValueReference.u64 = NULL;
  266. }
  267. else if (!strcmp(mStringType,
  268. (const char*)NameValueTypeStrings[NVT_ASSET]))
  269. {
  270. mType = NVT_ASSET;
  271. mNameValueReference.string = NULL;
  272. }
  273. else
  274. {
  275. mType = NVT_NULL;
  276. llinfos << "Unknown name-value type " << mStringType << llendl;
  277. }
  278. // Nota Bene: Whatever global structure manages this should have these in
  279. // the name table already!
  280. mStringClass = mNVNameTable->addString(nvclass);
  281. if (!strcmp(mStringClass, "READ_ONLY"))
  282. {
  283. mClass = NVC_READ_ONLY;
  284. }
  285. else if (!strcmp(mStringClass, "READ_WRITE"))
  286. {
  287. mClass = NVC_READ_WRITE;
  288. }
  289. else
  290. {
  291. mClass = NVC_NULL;
  292. }
  293. // Initialize the sendto variable
  294. mStringSendto = mNVNameTable->addString("SIM");
  295. mSendto = NVS_SIM;
  296. }
  297. // data is in the format:
  298. // "NameValueName Type Class Data"
  299. LLNameValue::LLNameValue(const char* data)
  300. {
  301. baseInit();
  302. static char name[NV_BUFFER_LEN];
  303. static char type[NV_BUFFER_LEN];
  304. static char nvclass[NV_BUFFER_LEN];
  305. static char nvsendto[NV_BUFFER_LEN];
  306. static char nvdata[NV_BUFFER_LEN];
  307. S32 i;
  308. S32 character_count = 0;
  309. S32 length = 0;
  310. // go to first non-whitespace character
  311. while (true)
  312. {
  313. if (*(data + character_count) == ' ' ||
  314. *(data + character_count) == '\n' ||
  315. *(data + character_count) == '\t' ||
  316. *(data + character_count) == '\r')
  317. {
  318. ++character_count;
  319. }
  320. else
  321. {
  322. break;
  323. }
  324. }
  325. // read in the name
  326. sscanf(data + character_count, "%2047s", name);
  327. // bump past it and add null terminator
  328. length = (S32)strlen(name);
  329. name[length] = 0;
  330. character_count += length;
  331. // go to the next non-whitespace character
  332. while (true)
  333. {
  334. if (*(data + character_count) == ' ' ||
  335. *(data + character_count) == '\n' ||
  336. *(data + character_count) == '\t' ||
  337. *(data + character_count) == '\r')
  338. {
  339. ++character_count;
  340. }
  341. else
  342. {
  343. break;
  344. }
  345. }
  346. // read in the type
  347. sscanf(data + character_count, "%2047s", type);
  348. // bump past it and add null terminator
  349. length = (S32)strlen(type);
  350. type[length] = 0;
  351. character_count += length;
  352. // go to the next non-whitespace character
  353. while (true)
  354. {
  355. if (*(data + character_count) == ' ' ||
  356. *(data + character_count) == '\n' ||
  357. *(data + character_count) == '\t' ||
  358. *(data + character_count) == '\r')
  359. {
  360. ++character_count;
  361. }
  362. else
  363. {
  364. break;
  365. }
  366. }
  367. // do we have a type argument?
  368. for (i = NVC_READ_ONLY; i < NVC_EOF; ++i)
  369. {
  370. if (!strncmp(NameValueClassStrings[i], data + character_count,
  371. strlen(NameValueClassStrings[i])))
  372. {
  373. break;
  374. }
  375. }
  376. if (i != NVC_EOF)
  377. {
  378. // Yes we do ! Read in the class.
  379. sscanf(data + character_count, "%2047s", nvclass);
  380. // bump past it and add null terminator
  381. length = (S32)strlen(nvclass);
  382. nvclass[length] = 0;
  383. character_count += length;
  384. // go to the next non-whitespace character
  385. while (true)
  386. {
  387. if (*(data + character_count) == ' ' ||
  388. *(data + character_count) == '\n' ||
  389. *(data + character_count) == '\t' ||
  390. *(data + character_count) == '\r')
  391. {
  392. ++character_count;
  393. }
  394. else
  395. {
  396. break;
  397. }
  398. }
  399. }
  400. else
  401. {
  402. // no type argument given, default to read-write
  403. strncpy(nvclass, "READ_WRITE", sizeof(nvclass) - 1);
  404. nvclass[sizeof(nvclass) - 1] = '\0';
  405. }
  406. // Do we have a sendto argument?
  407. for (i = NVS_SIM; i < NVS_EOF; ++i)
  408. {
  409. if (!strncmp(NameValueSendtoStrings[i], data + character_count,
  410. strlen(NameValueSendtoStrings[i])))
  411. {
  412. break;
  413. }
  414. }
  415. if (i != NVS_EOF)
  416. {
  417. // found a sendto argument
  418. sscanf(data + character_count, "%2047s", nvsendto);
  419. // add null terminator
  420. length = (S32)strlen(nvsendto);
  421. nvsendto[length] = 0;
  422. character_count += length;
  423. // seek to next non-whitespace characer
  424. while (true)
  425. {
  426. if (*(data + character_count) == ' ' ||
  427. *(data + character_count) == '\n' ||
  428. *(data + character_count) == '\t' ||
  429. *(data + character_count) == '\r')
  430. {
  431. ++character_count;
  432. }
  433. else
  434. {
  435. break;
  436. }
  437. }
  438. }
  439. else
  440. {
  441. // no sendto argument given, default to sim only
  442. strncpy(nvsendto, "SIM", sizeof(nvsendto) - 1);
  443. nvsendto[sizeof(nvsendto) -1] ='\0';
  444. }
  445. // copy the rest character by character into data
  446. length = 0;
  447. while ((*(nvdata + length++) = *(data + character_count++))) ;
  448. init(name, nvdata, type, nvclass, nvsendto);
  449. }
  450. LLNameValue::~LLNameValue()
  451. {
  452. mNVNameTable->removeString(mName);
  453. mName = NULL;
  454. switch (mType)
  455. {
  456. case NVT_STRING:
  457. case NVT_ASSET:
  458. delete[] mNameValueReference.string;
  459. mNameValueReference.string = NULL;
  460. break;
  461. case NVT_F32:
  462. delete mNameValueReference.f32;
  463. mNameValueReference.string = NULL;
  464. break;
  465. case NVT_S32:
  466. delete mNameValueReference.s32;
  467. mNameValueReference.string = NULL;
  468. break;
  469. case NVT_VEC3:
  470. delete mNameValueReference.vec3;
  471. mNameValueReference.string = NULL;
  472. break;
  473. case NVT_U32:
  474. delete mNameValueReference.u32;
  475. mNameValueReference.u32 = NULL;
  476. break;
  477. case NVT_U64:
  478. delete mNameValueReference.u64;
  479. mNameValueReference.u64 = NULL;
  480. break;
  481. default:
  482. break;
  483. }
  484. delete[] mNameValueReference.string;
  485. mNameValueReference.string = NULL;
  486. }
  487. char* LLNameValue::getString()
  488. {
  489. if (mType == NVT_STRING)
  490. {
  491. return mNameValueReference.string;
  492. }
  493. else
  494. {
  495. llerrs << mName << " is not a string !" << llendl;
  496. return NULL;
  497. }
  498. }
  499. const char* LLNameValue::getAsset() const
  500. {
  501. if (mType == NVT_ASSET)
  502. {
  503. return mNameValueReference.string;
  504. }
  505. else
  506. {
  507. llerrs << mName << " is not an asset !" << llendl;
  508. return NULL;
  509. }
  510. }
  511. F32* LLNameValue::getF32()
  512. {
  513. if (mType == NVT_F32)
  514. {
  515. return mNameValueReference.f32;
  516. }
  517. else
  518. {
  519. llerrs << mName << " is not a F32 !" << llendl;
  520. return NULL;
  521. }
  522. }
  523. S32* LLNameValue::getS32()
  524. {
  525. if (mType == NVT_S32)
  526. {
  527. return mNameValueReference.s32;
  528. }
  529. else
  530. {
  531. llerrs << mName << " is not a S32 !" << llendl;
  532. return NULL;
  533. }
  534. }
  535. U32* LLNameValue::getU32()
  536. {
  537. if (mType == NVT_U32)
  538. {
  539. return mNameValueReference.u32;
  540. }
  541. else
  542. {
  543. llerrs << mName << " is not an U32 !" << llendl;
  544. return NULL;
  545. }
  546. }
  547. U64* LLNameValue::getU64()
  548. {
  549. if (mType == NVT_U64)
  550. {
  551. return mNameValueReference.u64;
  552. }
  553. else
  554. {
  555. llerrs << mName << " is not an U64 !" << llendl;
  556. return NULL;
  557. }
  558. }
  559. void LLNameValue::getVec3(LLVector3 &vec)
  560. {
  561. if (mType == NVT_VEC3)
  562. {
  563. vec = *mNameValueReference.vec3;
  564. }
  565. else
  566. {
  567. llerrs << mName << " is not a Vec3 !" << llendl;
  568. }
  569. }
  570. LLVector3* LLNameValue::getVec3()
  571. {
  572. if (mType == NVT_VEC3)
  573. {
  574. return mNameValueReference.vec3;
  575. }
  576. else
  577. {
  578. llerrs << mName << " is not a Vec3 !" << llendl;
  579. return NULL;
  580. }
  581. }
  582. bool LLNameValue::sendToData() const
  583. {
  584. return mSendto == NVS_DATA_SIM || mSendto == NVS_DATA_SIM_VIEWER;
  585. }
  586. bool LLNameValue::sendToViewer() const
  587. {
  588. return mSendto == NVS_SIM_VIEWER || mSendto == NVS_DATA_SIM_VIEWER;
  589. }
  590. LLNameValue& LLNameValue::operator=(const LLNameValue& a)
  591. {
  592. if (mClass == NVC_READ_ONLY || mType != a.mType)
  593. {
  594. return *this;
  595. }
  596. switch (a.mType)
  597. {
  598. case NVT_STRING:
  599. case NVT_ASSET:
  600. if (mNameValueReference.string)
  601. {
  602. delete[] mNameValueReference.string;
  603. }
  604. mNameValueReference.string = new char[strlen(a.mNameValueReference.string) + 1];
  605. if (mNameValueReference.string != NULL)
  606. {
  607. strcpy(mNameValueReference.string,
  608. a.mNameValueReference.string);
  609. }
  610. break;
  611. case NVT_F32:
  612. *mNameValueReference.f32 = *a.mNameValueReference.f32;
  613. break;
  614. case NVT_S32:
  615. *mNameValueReference.s32 = *a.mNameValueReference.s32;
  616. break;
  617. case NVT_VEC3:
  618. *mNameValueReference.vec3 = *a.mNameValueReference.vec3;
  619. break;
  620. case NVT_U32:
  621. *mNameValueReference.u32 = *a.mNameValueReference.u32;
  622. break;
  623. case NVT_U64:
  624. *mNameValueReference.u64 = *a.mNameValueReference.u64;
  625. break;
  626. default:
  627. llerrs << "Unknown Name value type " << (U32)a.mType << llendl;
  628. }
  629. return *this;
  630. }
  631. void LLNameValue::setString(const char* a)
  632. {
  633. if (mClass == NVC_READ_ONLY)
  634. {
  635. return;
  636. }
  637. switch (mType)
  638. {
  639. case NVT_STRING:
  640. if (a)
  641. {
  642. if (mNameValueReference.string)
  643. {
  644. delete[] mNameValueReference.string;
  645. }
  646. mNameValueReference.string = new char[strlen(a) + 1];
  647. if (mNameValueReference.string != NULL)
  648. {
  649. strcpy(mNameValueReference.string, a);
  650. }
  651. }
  652. else
  653. {
  654. if (mNameValueReference.string)
  655. {
  656. delete[] mNameValueReference.string;
  657. }
  658. mNameValueReference.string = new char[1];
  659. mNameValueReference.string[0] = 0;
  660. }
  661. break;
  662. default:
  663. break;
  664. }
  665. }
  666. void LLNameValue::setAsset(const char* a)
  667. {
  668. if (mClass == NVC_READ_ONLY)
  669. {
  670. return;
  671. }
  672. switch (mType)
  673. {
  674. case NVT_ASSET:
  675. if (a)
  676. {
  677. if (mNameValueReference.string)
  678. {
  679. delete[] mNameValueReference.string;
  680. }
  681. mNameValueReference.string = new char[strlen(a) + 1];
  682. if (mNameValueReference.string != NULL)
  683. {
  684. strcpy(mNameValueReference.string, a);
  685. }
  686. }
  687. else
  688. {
  689. if (mNameValueReference.string)
  690. {
  691. delete[] mNameValueReference.string;
  692. }
  693. mNameValueReference.string = new char[1];
  694. mNameValueReference.string[0] = 0;
  695. }
  696. break;
  697. default:
  698. break;
  699. }
  700. }
  701. void LLNameValue::setF32(F32 a)
  702. {
  703. if (mClass != NVC_READ_ONLY && mType == NVT_F32)
  704. {
  705. *mNameValueReference.f32 = a;
  706. }
  707. }
  708. void LLNameValue::setS32(S32 a)
  709. {
  710. if (mClass == NVC_READ_ONLY)
  711. {
  712. return;
  713. }
  714. switch (mType)
  715. {
  716. case NVT_S32:
  717. *mNameValueReference.s32 = a;
  718. break;
  719. case NVT_U32:
  720. *mNameValueReference.u32 = a;
  721. break;
  722. case NVT_F32:
  723. *mNameValueReference.f32 = (F32)a;
  724. break;
  725. default:
  726. break;
  727. }
  728. }
  729. void LLNameValue::setU32(U32 a)
  730. {
  731. if (mClass == NVC_READ_ONLY)
  732. {
  733. return;
  734. }
  735. switch (mType)
  736. {
  737. case NVT_S32:
  738. *mNameValueReference.s32 = a;
  739. break;
  740. case NVT_U32:
  741. *mNameValueReference.u32 = a;
  742. break;
  743. case NVT_F32:
  744. *mNameValueReference.f32 = (F32)a;
  745. break;
  746. default:
  747. llerrs << "Trying to set U32 into a " << mStringType
  748. << ", unknown conversion" << llendl;
  749. }
  750. }
  751. void LLNameValue::setVec3(const LLVector3& a)
  752. {
  753. if (mClass == NVC_READ_ONLY)
  754. {
  755. return;
  756. }
  757. switch (mType)
  758. {
  759. case NVT_VEC3:
  760. *mNameValueReference.vec3 = a;
  761. break;
  762. default:
  763. llerrs << "Trying to set LLVector3 into a " << mStringType
  764. << ", unknown conversion" << llendl;
  765. }
  766. }
  767. std::string LLNameValue::printNameValue() const
  768. {
  769. std::string buffer;
  770. buffer = llformat("%s %s %s %s ", mName, mStringType, mStringClass,
  771. mStringSendto);
  772. buffer += printData();
  773. return buffer;
  774. }
  775. std::string LLNameValue::printData() const
  776. {
  777. std::string buffer;
  778. switch (mType)
  779. {
  780. case NVT_STRING:
  781. case NVT_ASSET:
  782. {
  783. buffer = mNameValueReference.string;
  784. break;
  785. }
  786. case NVT_F32:
  787. {
  788. buffer = llformat("%f", *mNameValueReference.f32);
  789. break;
  790. }
  791. case NVT_S32:
  792. {
  793. buffer = llformat("%d", *mNameValueReference.s32);
  794. break;
  795. }
  796. case NVT_U32:
  797. {
  798. buffer = llformat("%u", *mNameValueReference.u32);
  799. break;
  800. }
  801. case NVT_U64:
  802. {
  803. char u64_string[U64_BUFFER_LEN];
  804. U64_to_str(*mNameValueReference.u64, u64_string,
  805. sizeof(u64_string));
  806. buffer = u64_string;
  807. break;
  808. }
  809. case NVT_VEC3:
  810. {
  811. buffer = llformat("%f, %f, %f", mNameValueReference.vec3->mV[VX],
  812. mNameValueReference.vec3->mV[VY],
  813. mNameValueReference.vec3->mV[VZ]);
  814. break;
  815. }
  816. default:
  817. {
  818. llerrs << "Trying to print unknown NameValue type " << mStringType
  819. << llendl;
  820. }
  821. }
  822. return buffer;
  823. }
  824. std::ostream& operator<<(std::ostream& s, const LLNameValue& a)
  825. {
  826. switch (a.mType)
  827. {
  828. case NVT_STRING:
  829. case NVT_ASSET:
  830. s << a.mNameValueReference.string;
  831. break;
  832. case NVT_F32:
  833. s << (*a.mNameValueReference.f32);
  834. break;
  835. case NVT_S32:
  836. s << *(a.mNameValueReference.s32);
  837. break;
  838. case NVT_U32:
  839. s << *(a.mNameValueReference.u32);
  840. break;
  841. case NVT_U64:
  842. {
  843. char u64_string[U64_BUFFER_LEN];
  844. U64_to_str(*a.mNameValueReference.u64, u64_string, sizeof(u64_string));
  845. s << u64_string;
  846. }
  847. break;
  848. case NVT_VEC3:
  849. s << *(a.mNameValueReference.vec3);
  850. break;
  851. default:
  852. llerrs << "Trying to print unknown NameValue type " << a.mStringType << llendl;
  853. break;
  854. }
  855. return s;
  856. }