PageRenderTime 52ms CodeModel.GetById 21ms app.highlight 28ms RepoModel.GetById 1ms app.codeStats 0ms

/indra/llmessage/llsdmessagebuilder.cpp

https://bitbucket.org/lindenlab/viewer-beta/
C++ | 424 lines | 301 code | 73 blank | 50 comment | 17 complexity | 3a49a0504943577fe2b2045e1d97d768 MD5 | raw file
  1/** 
  2 * @file llsdmessagebuilder.cpp
  3 * @brief LLSDMessageBuilder class implementation.
  4 *
  5 * $LicenseInfo:firstyear=2007&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#include "linden_common.h"
 28
 29#include "llsdmessagebuilder.h"
 30
 31#include "llmessagetemplate.h"
 32#include "llmath.h"
 33#include "llquaternion.h"
 34#include "llsdutil.h"
 35#include "llsdutil_math.h"
 36#include "llsdserialize.h"
 37#include "u64.h"
 38#include "v3dmath.h"
 39#include "v3math.h"
 40#include "v4math.h"
 41
 42LLSDMessageBuilder::LLSDMessageBuilder() :
 43	mCurrentMessage(LLSD::emptyMap()),
 44	mCurrentBlock(NULL),
 45	mCurrentMessageName(""),
 46	mCurrentBlockName(""),
 47	mbSBuilt(FALSE),
 48	mbSClear(TRUE)
 49{
 50}
 51
 52//virtual
 53LLSDMessageBuilder::~LLSDMessageBuilder()
 54{
 55}
 56
 57
 58// virtual
 59void LLSDMessageBuilder::newMessage(const char* name)
 60{
 61	mbSBuilt = FALSE;
 62	mbSClear = FALSE;
 63
 64	mCurrentMessage = LLSD::emptyMap();
 65	mCurrentMessageName = (char*)name;
 66}
 67
 68// virtual
 69void LLSDMessageBuilder::clearMessage()
 70{
 71	mbSBuilt = FALSE;
 72	mbSClear = TRUE;
 73
 74	mCurrentMessage = LLSD::emptyMap();
 75	mCurrentMessageName = "";
 76}
 77
 78// virtual
 79void LLSDMessageBuilder::nextBlock(const char* blockname)
 80{
 81	LLSD& block = mCurrentMessage[blockname];
 82	if(block.isUndefined())
 83	{
 84		block[0] = LLSD::emptyMap();
 85		mCurrentBlock = &(block[0]);
 86	}
 87	else if(block.isArray())
 88	{
 89		block[block.size()] = LLSD::emptyMap();
 90		mCurrentBlock = &(block[block.size() - 1]);
 91	}
 92	else
 93	{
 94		llerrs << "existing block not array" << llendl;
 95	}
 96}
 97
 98// TODO: Remove this horror...
 99BOOL LLSDMessageBuilder::removeLastBlock()
100{
101	/* TODO: finish implementing this */
102	return FALSE;
103}
104
105void LLSDMessageBuilder::addBinaryData(
106	const char* varname, 
107	const void* data,
108	S32 size)
109{
110	std::vector<U8> v;
111	v.resize(size);
112	memcpy(&(v[0]), reinterpret_cast<const U8*>(data), size);
113	(*mCurrentBlock)[varname] = v;
114}
115
116void LLSDMessageBuilder::addS8(const char* varname, S8 v)
117{
118	(*mCurrentBlock)[varname] = v;
119}
120
121void LLSDMessageBuilder::addU8(const char* varname, U8 v)
122{
123	(*mCurrentBlock)[varname] = v;
124}
125
126void LLSDMessageBuilder::addS16(const char* varname, S16 v)
127{
128	(*mCurrentBlock)[varname] = v;
129}
130
131void LLSDMessageBuilder::addU16(const char* varname, U16 v)
132{
133	(*mCurrentBlock)[varname] = v;
134}
135
136void LLSDMessageBuilder::addF32(const char* varname, F32 v)
137{
138	(*mCurrentBlock)[varname] = v;
139}
140
141void LLSDMessageBuilder::addS32(const char* varname, S32 v)
142{
143	(*mCurrentBlock)[varname] = v;
144}
145
146void LLSDMessageBuilder::addU32(const char* varname, U32 v)
147{
148	(*mCurrentBlock)[varname] = ll_sd_from_U32(v);
149}
150
151void LLSDMessageBuilder::addU64(const char* varname, U64 v)
152{
153	(*mCurrentBlock)[varname] = ll_sd_from_U64(v);
154}
155
156void LLSDMessageBuilder::addF64(const char* varname, F64 v)
157{
158	(*mCurrentBlock)[varname] = v;
159}
160
161void LLSDMessageBuilder::addIPAddr(const char* varname, U32 v)
162{
163	(*mCurrentBlock)[varname] = ll_sd_from_ipaddr(v);
164}
165
166void LLSDMessageBuilder::addIPPort(const char* varname, U16 v)
167{
168	(*mCurrentBlock)[varname] = v;
169}
170
171void LLSDMessageBuilder::addBOOL(const char* varname, BOOL v)
172{
173	(*mCurrentBlock)[varname] = (v == TRUE);
174}
175
176void LLSDMessageBuilder::addString(const char* varname, const char* v)
177{
178	if (v)
179		(*mCurrentBlock)[varname] = v;  /* Flawfinder: ignore */  
180	else
181		(*mCurrentBlock)[varname] = ""; 
182}
183
184void LLSDMessageBuilder::addString(const char* varname, const std::string& v)
185{
186	if (v.size())
187		(*mCurrentBlock)[varname] = v; 
188	else
189		(*mCurrentBlock)[varname] = ""; 
190}
191
192void LLSDMessageBuilder::addVector3(const char* varname, const LLVector3& v)
193{
194	(*mCurrentBlock)[varname] = ll_sd_from_vector3(v);
195}
196
197void LLSDMessageBuilder::addVector4(const char* varname, const LLVector4& v)
198{
199	(*mCurrentBlock)[varname] = ll_sd_from_vector4(v);
200}
201
202void LLSDMessageBuilder::addVector3d(const char* varname, const LLVector3d& v)
203{
204	(*mCurrentBlock)[varname] = ll_sd_from_vector3d(v);
205}
206
207void LLSDMessageBuilder::addQuat(const char* varname, const LLQuaternion& v)
208{
209	(*mCurrentBlock)[varname] = ll_sd_from_quaternion(v);
210}
211
212void LLSDMessageBuilder::addUUID(const char* varname, const LLUUID& v)
213{
214	(*mCurrentBlock)[varname] = v;
215}
216
217void LLSDMessageBuilder::compressMessage(U8*& buf_ptr, U32& buffer_length)
218{
219}
220
221BOOL LLSDMessageBuilder::isMessageFull(const char* blockname) const
222{
223	return FALSE;
224}
225
226U32 LLSDMessageBuilder::buildMessage(U8*, U32, U8)
227{
228	return 0;
229}
230
231void LLSDMessageBuilder::copyFromMessageData(const LLMsgData& data)
232{
233	// copy the blocks
234	// counting variables used to encode multiple block info
235	S32 block_count = 0;
236    char* block_name = NULL;
237
238	// loop through msg blocks to loop through variables, totalling up size
239	// data and filling the new (send) message
240	LLMsgData::msg_blk_data_map_t::const_iterator iter = 
241		data.mMemberBlocks.begin();
242	LLMsgData::msg_blk_data_map_t::const_iterator end = 
243		data.mMemberBlocks.end();
244	for(; iter != end; ++iter)
245	{
246		const LLMsgBlkData* mbci = iter->second;
247		if(!mbci) continue;
248
249		// do we need to encode a block code?
250		if (block_count == 0)
251		{
252			block_count = mbci->mBlockNumber;
253			block_name = (char*)mbci->mName;
254		}
255
256		// counting down mutliple blocks
257		block_count--;
258
259		nextBlock(block_name);
260
261		// now loop through the variables
262		LLMsgBlkData::msg_var_data_map_t::const_iterator dit = mbci->mMemberVarData.begin();
263		LLMsgBlkData::msg_var_data_map_t::const_iterator dend = mbci->mMemberVarData.end();
264		
265		for(; dit != dend; ++dit)
266		{
267			const LLMsgVarData& mvci = *dit;
268			const char* varname = mvci.getName();
269
270			switch(mvci.getType())
271			{
272			case MVT_FIXED:
273				addBinaryData(varname, mvci.getData(), mvci.getSize());
274				break;
275
276			case MVT_VARIABLE:
277				{
278					const char end = ((const char*)mvci.getData())[mvci.getSize()-1]; // Ensure null terminated
279					if (mvci.getDataSize() == 1 && end == 0) 
280					{
281						addString(varname, (const char*)mvci.getData());
282					}
283					else
284					{
285						addBinaryData(varname, mvci.getData(), mvci.getSize());
286					}
287					break;
288				}
289
290			case MVT_U8:
291				addU8(varname, *(U8*)mvci.getData());
292				break;
293
294			case MVT_U16:
295				addU16(varname, *(U16*)mvci.getData());
296				break;
297
298			case MVT_U32:
299				addU32(varname, *(U32*)mvci.getData());
300				break;
301
302			case MVT_U64:
303				addU64(varname, *(U64*)mvci.getData());
304				break;
305
306			case MVT_S8:
307				addS8(varname, *(S8*)mvci.getData());
308				break;
309
310			case MVT_S16:
311				addS16(varname, *(S16*)mvci.getData());
312				break;
313
314			case MVT_S32:
315				addS32(varname, *(S32*)mvci.getData());
316				break;
317
318			// S64 not supported in LLSD so we just truncate it
319			case MVT_S64:
320				addS32(varname, *(S64*)mvci.getData());
321				break;
322
323			case MVT_F32:
324				addF32(varname, *(F32*)mvci.getData());
325				break;
326
327			case MVT_F64:
328				addF64(varname, *(F64*)mvci.getData());
329				break;
330
331			case MVT_LLVector3:
332				addVector3(varname, *(LLVector3*)mvci.getData());
333				break;
334
335			case MVT_LLVector3d:
336				addVector3d(varname, *(LLVector3d*)mvci.getData());
337				break;
338
339			case MVT_LLVector4:
340				addVector4(varname, *(LLVector4*)mvci.getData());
341				break;
342
343			case MVT_LLQuaternion:
344				{
345					LLVector3 v = *(LLVector3*)mvci.getData();
346					LLQuaternion q;
347					q.unpackFromVector3(v);
348					addQuat(varname, q);
349					break;
350				}
351
352			case MVT_LLUUID:
353				addUUID(varname, *(LLUUID*)mvci.getData());
354				break;	
355
356			case MVT_BOOL:
357				addBOOL(varname, *(BOOL*)mvci.getData());
358				break;
359
360			case MVT_IP_ADDR:
361				addIPAddr(varname, *(U32*)mvci.getData());
362				break;
363
364			case MVT_IP_PORT:
365				addIPPort(varname, *(U16*)mvci.getData());
366				break;
367
368			case MVT_U16Vec3:
369				//treated as an array of 6 bytes
370				addBinaryData(varname, mvci.getData(), 6);
371				break;
372
373			case MVT_U16Quat:
374				//treated as an array of 8 bytes
375				addBinaryData(varname, mvci.getData(), 8);
376				break;
377
378			case MVT_S16Array:
379				addBinaryData(varname, mvci.getData(), mvci.getSize());
380				break;
381
382			default:
383				llwarns << "Unknown type in conversion of message to LLSD" << llendl;
384				break;
385			}
386		}
387	}
388}
389
390//virtual
391void LLSDMessageBuilder::copyFromLLSD(const LLSD& msg)
392{
393	mCurrentMessage = msg;
394	lldebugs << LLSDNotationStreamer(mCurrentMessage) << llendl;
395}
396
397const LLSD& LLSDMessageBuilder::getMessage() const
398{
399	 return mCurrentMessage;
400}
401
402//virtual
403void LLSDMessageBuilder::setBuilt(BOOL b) { mbSBuilt = b; }
404
405//virtual 
406BOOL LLSDMessageBuilder::isBuilt() const {return mbSBuilt;}
407
408//virtual 
409BOOL LLSDMessageBuilder::isClear() const {return mbSClear;}
410
411//virtual 
412S32 LLSDMessageBuilder::getMessageSize()
413{
414	// babbage: size is unknown as message stored as LLSD.
415	// return non-zero if pending data, as send can be skipped for 0 size.
416	// return 1 to encourage senders checking size against splitting message.
417	return mCurrentMessage.size()? 1 : 0;
418}
419
420//virtual 
421const char* LLSDMessageBuilder::getMessageName() const 
422{
423	return mCurrentMessageName.c_str();
424}