Imported existing code
This commit is contained in:
428
indra/llmessage/llsdmessagebuilder.cpp
Executable file
428
indra/llmessage/llsdmessagebuilder.cpp
Executable file
@@ -0,0 +1,428 @@
|
||||
/**
|
||||
* @file llsdmessagebuilder.cpp
|
||||
* @brief LLSDMessageBuilder class implementation.
|
||||
*
|
||||
* $LicenseInfo:firstyear=2007&license=viewergpl$
|
||||
*
|
||||
* Copyright (c) 2007-2009, Linden Research, Inc.
|
||||
*
|
||||
* Second Life Viewer Source Code
|
||||
* The source code in this file ("Source Code") is provided by Linden Lab
|
||||
* to you under the terms of the GNU General Public License, version 2.0
|
||||
* ("GPL"), unless you have obtained a separate licensing agreement
|
||||
* ("Other License"), formally executed by you and Linden Lab. Terms of
|
||||
* the GPL can be found in doc/GPL-license.txt in this distribution, or
|
||||
* online at http://secondlifegrid.net/programs/open_source/licensing/gplv2
|
||||
*
|
||||
* There are special exceptions to the terms and conditions of the GPL as
|
||||
* it is applied to this Source Code. View the full text of the exception
|
||||
* in the file doc/FLOSS-exception.txt in this software distribution, or
|
||||
* online at
|
||||
* http://secondlifegrid.net/programs/open_source/licensing/flossexception
|
||||
*
|
||||
* By copying, modifying or distributing this software, you acknowledge
|
||||
* that you have read and understood your obligations described above,
|
||||
* and agree to abide by those obligations.
|
||||
*
|
||||
* ALL LINDEN LAB SOURCE CODE IS PROVIDED "AS IS." LINDEN LAB MAKES NO
|
||||
* WARRANTIES, EXPRESS, IMPLIED OR OTHERWISE, REGARDING ITS ACCURACY,
|
||||
* COMPLETENESS OR PERFORMANCE.
|
||||
* $/LicenseInfo$
|
||||
*/
|
||||
|
||||
#include "linden_common.h"
|
||||
|
||||
#include "llsdmessagebuilder.h"
|
||||
|
||||
#include "llmessagetemplate.h"
|
||||
#include "llquaternion.h"
|
||||
#include "llsdutil.h"
|
||||
#include "llsdserialize.h"
|
||||
#include "u64.h"
|
||||
#include "v3dmath.h"
|
||||
#include "v3math.h"
|
||||
#include "v4math.h"
|
||||
|
||||
LLSDMessageBuilder::LLSDMessageBuilder() :
|
||||
mCurrentMessage(LLSD::emptyMap()),
|
||||
mCurrentBlock(NULL),
|
||||
mCurrentMessageName(""),
|
||||
mCurrentBlockName(""),
|
||||
mbSBuilt(FALSE),
|
||||
mbSClear(TRUE)
|
||||
{
|
||||
}
|
||||
|
||||
//virtual
|
||||
LLSDMessageBuilder::~LLSDMessageBuilder()
|
||||
{
|
||||
}
|
||||
|
||||
|
||||
// virtual
|
||||
void LLSDMessageBuilder::newMessage(const char* name)
|
||||
{
|
||||
mbSBuilt = FALSE;
|
||||
mbSClear = FALSE;
|
||||
|
||||
mCurrentMessage = LLSD::emptyMap();
|
||||
mCurrentMessageName = (char*)name;
|
||||
}
|
||||
|
||||
// virtual
|
||||
void LLSDMessageBuilder::clearMessage()
|
||||
{
|
||||
mbSBuilt = FALSE;
|
||||
mbSClear = TRUE;
|
||||
|
||||
mCurrentMessage = LLSD::emptyMap();
|
||||
mCurrentMessageName = "";
|
||||
}
|
||||
|
||||
// virtual
|
||||
void LLSDMessageBuilder::nextBlock(const char* blockname)
|
||||
{
|
||||
LLSD& block = mCurrentMessage[blockname];
|
||||
if(block.isUndefined())
|
||||
{
|
||||
block[0] = LLSD::emptyMap();
|
||||
mCurrentBlock = &(block[0]);
|
||||
}
|
||||
else if(block.isArray())
|
||||
{
|
||||
block[block.size()] = LLSD::emptyMap();
|
||||
mCurrentBlock = &(block[block.size() - 1]);
|
||||
}
|
||||
else
|
||||
{
|
||||
llerrs << "existing block not array" << llendl;
|
||||
}
|
||||
}
|
||||
|
||||
// TODO: Remove this horror...
|
||||
BOOL LLSDMessageBuilder::removeLastBlock()
|
||||
{
|
||||
/* TODO: finish implementing this */
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
void LLSDMessageBuilder::addBinaryData(
|
||||
const char* varname,
|
||||
const void* data,
|
||||
S32 size)
|
||||
{
|
||||
std::vector<U8> v;
|
||||
v.resize(size);
|
||||
memcpy(&(v[0]), reinterpret_cast<const U8*>(data), size);
|
||||
(*mCurrentBlock)[varname] = v;
|
||||
}
|
||||
|
||||
void LLSDMessageBuilder::addS8(const char* varname, S8 v)
|
||||
{
|
||||
(*mCurrentBlock)[varname] = v;
|
||||
}
|
||||
|
||||
void LLSDMessageBuilder::addU8(const char* varname, U8 v)
|
||||
{
|
||||
(*mCurrentBlock)[varname] = v;
|
||||
}
|
||||
|
||||
void LLSDMessageBuilder::addS16(const char* varname, S16 v)
|
||||
{
|
||||
(*mCurrentBlock)[varname] = v;
|
||||
}
|
||||
|
||||
void LLSDMessageBuilder::addU16(const char* varname, U16 v)
|
||||
{
|
||||
(*mCurrentBlock)[varname] = v;
|
||||
}
|
||||
|
||||
void LLSDMessageBuilder::addF32(const char* varname, F32 v)
|
||||
{
|
||||
(*mCurrentBlock)[varname] = v;
|
||||
}
|
||||
|
||||
void LLSDMessageBuilder::addS32(const char* varname, S32 v)
|
||||
{
|
||||
(*mCurrentBlock)[varname] = v;
|
||||
}
|
||||
|
||||
void LLSDMessageBuilder::addU32(const char* varname, U32 v)
|
||||
{
|
||||
(*mCurrentBlock)[varname] = ll_sd_from_U32(v);
|
||||
}
|
||||
|
||||
void LLSDMessageBuilder::addU64(const char* varname, U64 v)
|
||||
{
|
||||
(*mCurrentBlock)[varname] = ll_sd_from_U64(v);
|
||||
}
|
||||
|
||||
void LLSDMessageBuilder::addF64(const char* varname, F64 v)
|
||||
{
|
||||
(*mCurrentBlock)[varname] = v;
|
||||
}
|
||||
|
||||
void LLSDMessageBuilder::addIPAddr(const char* varname, U32 v)
|
||||
{
|
||||
(*mCurrentBlock)[varname] = ll_sd_from_ipaddr(v);
|
||||
}
|
||||
|
||||
void LLSDMessageBuilder::addIPPort(const char* varname, U16 v)
|
||||
{
|
||||
(*mCurrentBlock)[varname] = v;
|
||||
}
|
||||
|
||||
void LLSDMessageBuilder::addBOOL(const char* varname, BOOL v)
|
||||
{
|
||||
(*mCurrentBlock)[varname] = (v == TRUE);
|
||||
}
|
||||
|
||||
void LLSDMessageBuilder::addString(const char* varname, const char* v)
|
||||
{
|
||||
if (v)
|
||||
(*mCurrentBlock)[varname] = v; /* Flawfinder: ignore */
|
||||
else
|
||||
(*mCurrentBlock)[varname] = "";
|
||||
}
|
||||
|
||||
void LLSDMessageBuilder::addString(const char* varname, const std::string& v)
|
||||
{
|
||||
if (v.size())
|
||||
(*mCurrentBlock)[varname] = v;
|
||||
else
|
||||
(*mCurrentBlock)[varname] = "";
|
||||
}
|
||||
|
||||
void LLSDMessageBuilder::addVector3(const char* varname, const LLVector3& v)
|
||||
{
|
||||
(*mCurrentBlock)[varname] = ll_sd_from_vector3(v);
|
||||
}
|
||||
|
||||
void LLSDMessageBuilder::addVector4(const char* varname, const LLVector4& v)
|
||||
{
|
||||
(*mCurrentBlock)[varname] = ll_sd_from_vector4(v);
|
||||
}
|
||||
|
||||
void LLSDMessageBuilder::addVector3d(const char* varname, const LLVector3d& v)
|
||||
{
|
||||
(*mCurrentBlock)[varname] = ll_sd_from_vector3d(v);
|
||||
}
|
||||
|
||||
void LLSDMessageBuilder::addQuat(const char* varname, const LLQuaternion& v)
|
||||
{
|
||||
(*mCurrentBlock)[varname] = ll_sd_from_quaternion(v);
|
||||
}
|
||||
|
||||
void LLSDMessageBuilder::addUUID(const char* varname, const LLUUID& v)
|
||||
{
|
||||
(*mCurrentBlock)[varname] = v;
|
||||
}
|
||||
|
||||
void LLSDMessageBuilder::compressMessage(U8*& buf_ptr, U32& buffer_length)
|
||||
{
|
||||
}
|
||||
|
||||
BOOL LLSDMessageBuilder::isMessageFull(const char* blockname) const
|
||||
{
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
U32 LLSDMessageBuilder::buildMessage(U8*, U32, U8)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
void LLSDMessageBuilder::copyFromMessageData(const LLMsgData& data)
|
||||
{
|
||||
// copy the blocks
|
||||
// counting variables used to encode multiple block info
|
||||
S32 block_count = 0;
|
||||
char* block_name = NULL;
|
||||
|
||||
// loop through msg blocks to loop through variables, totalling up size
|
||||
// data and filling the new (send) message
|
||||
LLMsgData::msg_blk_data_map_t::const_iterator iter =
|
||||
data.mMemberBlocks.begin();
|
||||
LLMsgData::msg_blk_data_map_t::const_iterator end =
|
||||
data.mMemberBlocks.end();
|
||||
for(; iter != end; ++iter)
|
||||
{
|
||||
const LLMsgBlkData* mbci = iter->second;
|
||||
if(!mbci) continue;
|
||||
|
||||
// do we need to encode a block code?
|
||||
if (block_count == 0)
|
||||
{
|
||||
block_count = mbci->mBlockNumber;
|
||||
block_name = (char*)mbci->mName;
|
||||
}
|
||||
|
||||
// counting down mutliple blocks
|
||||
block_count--;
|
||||
|
||||
nextBlock(block_name);
|
||||
|
||||
// now loop through the variables
|
||||
LLMsgBlkData::msg_var_data_map_t::const_iterator dit = mbci->mMemberVarData.begin();
|
||||
LLMsgBlkData::msg_var_data_map_t::const_iterator dend = mbci->mMemberVarData.end();
|
||||
|
||||
for(; dit != dend; ++dit)
|
||||
{
|
||||
const LLMsgVarData& mvci = *dit;
|
||||
const char* varname = mvci.getName();
|
||||
|
||||
switch(mvci.getType())
|
||||
{
|
||||
case MVT_FIXED:
|
||||
addBinaryData(varname, mvci.getData(), mvci.getSize());
|
||||
break;
|
||||
|
||||
case MVT_VARIABLE:
|
||||
{
|
||||
const char end = ((const char*)mvci.getData())[mvci.getSize()-1]; // Ensure null terminated
|
||||
if (mvci.getDataSize() == 1 && end == 0)
|
||||
{
|
||||
addString(varname, (const char*)mvci.getData());
|
||||
}
|
||||
else
|
||||
{
|
||||
addBinaryData(varname, mvci.getData(), mvci.getSize());
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
||||
case MVT_U8:
|
||||
addU8(varname, *(U8*)mvci.getData());
|
||||
break;
|
||||
|
||||
case MVT_U16:
|
||||
addU16(varname, *(U16*)mvci.getData());
|
||||
break;
|
||||
|
||||
case MVT_U32:
|
||||
addU32(varname, *(U32*)mvci.getData());
|
||||
break;
|
||||
|
||||
case MVT_U64:
|
||||
addU64(varname, *(U64*)mvci.getData());
|
||||
break;
|
||||
|
||||
case MVT_S8:
|
||||
addS8(varname, *(S8*)mvci.getData());
|
||||
break;
|
||||
|
||||
case MVT_S16:
|
||||
addS16(varname, *(S16*)mvci.getData());
|
||||
break;
|
||||
|
||||
case MVT_S32:
|
||||
addS32(varname, *(S32*)mvci.getData());
|
||||
break;
|
||||
|
||||
// S64 not supported in LLSD so we just truncate it
|
||||
case MVT_S64:
|
||||
addS32(varname, *(S64*)mvci.getData());
|
||||
break;
|
||||
|
||||
case MVT_F32:
|
||||
addF32(varname, *(F32*)mvci.getData());
|
||||
break;
|
||||
|
||||
case MVT_F64:
|
||||
addF64(varname, *(F64*)mvci.getData());
|
||||
break;
|
||||
|
||||
case MVT_LLVector3:
|
||||
addVector3(varname, *(LLVector3*)mvci.getData());
|
||||
break;
|
||||
|
||||
case MVT_LLVector3d:
|
||||
addVector3d(varname, *(LLVector3d*)mvci.getData());
|
||||
break;
|
||||
|
||||
case MVT_LLVector4:
|
||||
addVector4(varname, *(LLVector4*)mvci.getData());
|
||||
break;
|
||||
|
||||
case MVT_LLQuaternion:
|
||||
{
|
||||
LLVector3 v = *(LLVector3*)mvci.getData();
|
||||
LLQuaternion q;
|
||||
q.unpackFromVector3(v);
|
||||
addQuat(varname, q);
|
||||
break;
|
||||
}
|
||||
|
||||
case MVT_LLUUID:
|
||||
addUUID(varname, *(LLUUID*)mvci.getData());
|
||||
break;
|
||||
|
||||
case MVT_BOOL:
|
||||
addBOOL(varname, *(BOOL*)mvci.getData());
|
||||
break;
|
||||
|
||||
case MVT_IP_ADDR:
|
||||
addIPAddr(varname, *(U32*)mvci.getData());
|
||||
break;
|
||||
|
||||
case MVT_IP_PORT:
|
||||
addIPPort(varname, *(U16*)mvci.getData());
|
||||
break;
|
||||
|
||||
case MVT_U16Vec3:
|
||||
//treated as an array of 6 bytes
|
||||
addBinaryData(varname, mvci.getData(), 6);
|
||||
break;
|
||||
|
||||
case MVT_U16Quat:
|
||||
//treated as an array of 8 bytes
|
||||
addBinaryData(varname, mvci.getData(), 8);
|
||||
break;
|
||||
|
||||
case MVT_S16Array:
|
||||
addBinaryData(varname, mvci.getData(), mvci.getSize());
|
||||
break;
|
||||
|
||||
default:
|
||||
llwarns << "Unknown type in conversion of message to LLSD" << llendl;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
//virtual
|
||||
void LLSDMessageBuilder::copyFromLLSD(const LLSD& msg)
|
||||
{
|
||||
mCurrentMessage = msg;
|
||||
lldebugs << LLSDNotationStreamer(mCurrentMessage) << llendl;
|
||||
}
|
||||
|
||||
const LLSD& LLSDMessageBuilder::getMessage() const
|
||||
{
|
||||
return mCurrentMessage;
|
||||
}
|
||||
|
||||
//virtual
|
||||
void LLSDMessageBuilder::setBuilt(BOOL b) { mbSBuilt = b; }
|
||||
|
||||
//virtual
|
||||
BOOL LLSDMessageBuilder::isBuilt() const {return mbSBuilt;}
|
||||
|
||||
//virtual
|
||||
BOOL LLSDMessageBuilder::isClear() const {return mbSClear;}
|
||||
|
||||
//virtual
|
||||
S32 LLSDMessageBuilder::getMessageSize()
|
||||
{
|
||||
// babbage: size is unknown as message stored as LLSD.
|
||||
// return non-zero if pending data, as send can be skipped for 0 size.
|
||||
// return 1 to encourage senders checking size against splitting message.
|
||||
return mCurrentMessage.size()? 1 : 0;
|
||||
}
|
||||
|
||||
//virtual
|
||||
const char* LLSDMessageBuilder::getMessageName() const
|
||||
{
|
||||
return mCurrentMessageName.c_str();
|
||||
}
|
||||
Reference in New Issue
Block a user