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