PageRenderTime 121ms CodeModel.GetById 0ms RepoModel.GetById 0ms app.codeStats 0ms

/indra/llmessage/llnamevalue.cpp

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