summaryrefslogtreecommitdiff
path: root/indra/llmessage/lltemplatemessagebuilder.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'indra/llmessage/lltemplatemessagebuilder.cpp')
-rw-r--r--indra/llmessage/lltemplatemessagebuilder.cpp309
1 files changed, 163 insertions, 146 deletions
diff --git a/indra/llmessage/lltemplatemessagebuilder.cpp b/indra/llmessage/lltemplatemessagebuilder.cpp
index 806f03422d..18e96f26e4 100644
--- a/indra/llmessage/lltemplatemessagebuilder.cpp
+++ b/indra/llmessage/lltemplatemessagebuilder.cpp
@@ -1,3 +1,11 @@
+/**
+ * @file lltemplatemessagebuilder.cpp
+ * @brief LLTemplateMessageBuilder class implementation.
+ *
+ * Copyright (c) 2007-$CurrentYear$, Linden Research, Inc.
+ * $License$
+ */
+
#include "linden_common.h"
#include "lltemplatemessagebuilder.h"
@@ -41,28 +49,30 @@ void LLTemplateMessageBuilder::newMessage(const char *name)
delete mCurrentSMessageData;
mCurrentSMessageData = NULL;
- char *namep = (char *)name;
-
+ char* namep = (char*)name;
if (mMessageTemplates.count(namep) > 0)
{
mCurrentSMessageTemplate = mMessageTemplates[namep];
- if (mCurrentSMessageData)
- {
- delete mCurrentSMessageData;
- }
mCurrentSMessageData = new LLMsgData(namep);
mCurrentSMessageName = namep;
mCurrentSDataBlock = NULL;
mCurrentSBlockName = NULL;
// add at one of each block
- LLMessageTemplate* msg_template = mMessageTemplates[namep];
- for (LLMessageTemplate::message_block_map_t::iterator iter = msg_template->mMemberBlocks.begin();
- iter != msg_template->mMemberBlocks.end(); iter++)
+ const LLMessageTemplate* msg_template = mMessageTemplates[namep];
+
+ if (msg_template->getDeprecation() != MD_NOTDEPRECATED)
{
- LLMessageBlock* ci = iter->second;
- LLMsgBlkData *tblockp;
- tblockp = new LLMsgBlkData(ci->mName, 0);
+ llwarns << "Sending deprecated message " << namep << llendl;
+ }
+
+ LLMessageTemplate::message_block_map_t::const_iterator iter;
+ for(iter = msg_template->mMemberBlocks.begin();
+ iter != msg_template->mMemberBlocks.end();
+ ++iter)
+ {
+ LLMessageBlock* ci = *iter;
+ LLMsgBlkData* tblockp = new LLMsgBlkData(ci->mName, 0);
mCurrentSMessageData->addBlock(tblockp);
}
}
@@ -102,16 +112,14 @@ void LLTemplateMessageBuilder::nextBlock(const char* blockname)
}
// now, does this block exist?
- LLMessageTemplate::message_block_map_t::iterator temp_iter = mCurrentSMessageTemplate->mMemberBlocks.find(bnamep);
- if (temp_iter == mCurrentSMessageTemplate->mMemberBlocks.end())
+ const LLMessageBlock* template_data = mCurrentSMessageTemplate->getBlock(bnamep);
+ if (!template_data)
{
llerrs << "LLTemplateMessageBuilder::nextBlock " << bnamep
<< " not a block in " << mCurrentSMessageTemplate->mName << llendl;
return;
}
- LLMessageBlock* template_data = temp_iter->second;
-
// ok, have we already set this block?
LLMsgBlkData* block_data = mCurrentSMessageData->mMemberBlocks[bnamep];
if (block_data->mBlockNumber == 0)
@@ -122,10 +130,10 @@ void LLTemplateMessageBuilder::nextBlock(const char* blockname)
mCurrentSBlockName = bnamep;
// add placeholders for each of the variables
- for (LLMessageBlock::message_variable_map_t::iterator iter = template_data->mMemberVariables.begin();
+ for (LLMessageBlock::message_variable_map_t::const_iterator iter = template_data->mMemberVariables.begin();
iter != template_data->mMemberVariables.end(); iter++)
{
- LLMessageVariable& ci = *(iter->second);
+ LLMessageVariable& ci = **iter;
mCurrentSDataBlock->addVariable(ci.getName(), ci.getType());
}
return;
@@ -181,12 +189,12 @@ void LLTemplateMessageBuilder::nextBlock(const char* blockname)
mCurrentSMessageData->mMemberBlocks[nbnamep] = mCurrentSDataBlock;
// add placeholders for each of the variables
- for (LLMessageBlock::message_variable_map_t::iterator
+ for (LLMessageBlock::message_variable_map_t::const_iterator
iter = template_data->mMemberVariables.begin(),
end = template_data->mMemberVariables.end();
iter != end; iter++)
{
- LLMessageVariable& ci = *(iter->second);
+ LLMessageVariable& ci = **iter;
mCurrentSDataBlock->addVariable(ci.getName(), ci.getType());
}
return;
@@ -211,12 +219,12 @@ BOOL LLTemplateMessageBuilder::removeLastBlock()
// Decrement the sent total by the size of the
// data in the message block that we're currently building.
- LLMessageBlock* template_data = mCurrentSMessageTemplate->mMemberBlocks[mCurrentSBlockName];
+ const LLMessageBlock* template_data = mCurrentSMessageTemplate->getBlock(mCurrentSBlockName);
- for (LLMessageBlock::message_variable_map_t::iterator iter = template_data->mMemberVariables.begin();
+ for (LLMessageBlock::message_variable_map_t::const_iterator iter = template_data->mMemberVariables.begin();
iter != template_data->mMemberVariables.end(); iter++)
{
- LLMessageVariable& ci = *(iter->second);
+ LLMessageVariable& ci = **iter;
mCurrentSendTotal -= ci.getSize();
}
@@ -276,7 +284,7 @@ void LLTemplateMessageBuilder::addData(const char *varname, const void *data, EM
}
// kewl, add the data if it exists
- LLMessageVariable* var_data = mCurrentSMessageTemplate->mMemberBlocks[mCurrentSBlockName]->mMemberVariables[vnamep];
+ const LLMessageVariable* var_data = mCurrentSMessageTemplate->getBlock(mCurrentSBlockName)->getVariable(vnamep);
if (!var_data || !var_data->getName())
{
llerrs << vnamep << " not a variable in block " << mCurrentSBlockName << " of " << mCurrentSMessageTemplate->mName << llendl;
@@ -336,7 +344,7 @@ void LLTemplateMessageBuilder::addData(const char *varname, const void *data, EM
}
// kewl, add the data if it exists
- LLMessageVariable* var_data = mCurrentSMessageTemplate->mMemberBlocks[mCurrentSBlockName]->mMemberVariables[vnamep];
+ const LLMessageVariable* var_data = mCurrentSMessageTemplate->getBlock(mCurrentSBlockName)->getVariable(vnamep);
if (!var_data->getName())
{
llerrs << vnamep << " not a variable in block " << mCurrentSBlockName << " of " << mCurrentSMessageTemplate->mName << llendl;
@@ -484,7 +492,7 @@ static S32 zero_code(U8 **data, U32 *data_size)
// skip the packet id field
- for (U32 i=0;i<LL_PACKET_ID_SIZE;i++)
+ for (U32 ii = 0; ii < LL_PACKET_ID_SIZE ; ++ii)
{
count--;
*outptr++ = *inptr++;
@@ -571,7 +579,7 @@ BOOL LLTemplateMessageBuilder::isMessageFull(const char* blockname) const
char* bnamep = (char*)blockname;
S32 max;
- LLMessageBlock* template_data = mCurrentSMessageTemplate->mMemberBlocks[bnamep];
+ const LLMessageBlock* template_data = mCurrentSMessageTemplate->getBlock(bnamep);
switch(template_data->mType)
{
@@ -593,138 +601,59 @@ BOOL LLTemplateMessageBuilder::isMessageFull(const char* blockname) const
return FALSE;
}
-
-// make sure that all the desired data is in place and then copy the data into MAX_BUFFER_SIZEd buffer
-U32 LLTemplateMessageBuilder::buildMessage(U8* buffer, U32 buffer_size)
+static S32 buildBlock(U8* buffer, S32 buffer_size, const LLMessageBlock* template_data, LLMsgData* message_data)
{
- // basic algorithm is to loop through the various pieces, building
- // size and offset info if we encounter a -1 for mSize at any
- // point that variable wasn't given data
-
- // do we have a current message?
- if (!mCurrentSMessageTemplate)
- {
- llerrs << "newMessage not called prior to buildMessage" << llendl;
- return 0;
- }
-
- // zero out some useful values
-
- // leave room for circuit counter
- U32 result = LL_PACKET_ID_SIZE;
-
- // encode message number and adjust total_offset
- if (mCurrentSMessageTemplate->mFrequency == MFT_HIGH)
- {
-// old, endian-dependant way
-// memcpy(&buffer[result], &mCurrentMessageTemplate->mMessageNumber, sizeof(U8));
-
-// new, independant way
- buffer[result] = (U8)mCurrentSMessageTemplate->mMessageNumber;
- result += sizeof(U8);
- }
- else if (mCurrentSMessageTemplate->mFrequency == MFT_MEDIUM)
- {
- U8 temp = 255;
- memcpy(&buffer[result], &temp, sizeof(U8)); /*Flawfinder: ignore*/
- result += sizeof(U8);
-
- // mask off unsightly bits
- temp = mCurrentSMessageTemplate->mMessageNumber & 255;
- memcpy(&buffer[result], &temp, sizeof(U8)); /*Flawfinder: ignore*/
- result += sizeof(U8);
- }
- else if (mCurrentSMessageTemplate->mFrequency == MFT_LOW)
- {
- U8 temp = 255;
- U16 message_num;
- memcpy(&buffer[result], &temp, sizeof(U8)); /*Flawfinder: ignore*/
- result += sizeof(U8);
- memcpy(&buffer[result], &temp, sizeof(U8)); /*Flawfinder: ignore*/
- result += sizeof(U8);
-
- // mask off unsightly bits
- message_num = mCurrentSMessageTemplate->mMessageNumber & 0xFFFF;
-
- // convert to network byte order
- message_num = htons(message_num);
- memcpy(&buffer[result], &message_num, sizeof(U16)); /*Flawfinder: ignore*/
- result += sizeof(U16);
- }
- else
- {
- llerrs << "unexpected message frequency in buildMessage" << llendl;
- return 0;
+ S32 result = 0;
+ LLMsgData::msg_blk_data_map_t::const_iterator block_iter = message_data->mMemberBlocks.find(template_data->mName);
+ const LLMsgBlkData* mbci = block_iter->second;
+
+ // ok, if this is the first block of a repeating pack, set
+ // block_count and, if it's type MBT_VARIABLE encode a byte
+ // for how many there are
+ S32 block_count = mbci->mBlockNumber;
+ if (template_data->mType == MBT_VARIABLE)
+ {
+ // remember that mBlockNumber is a S32
+ U8 temp_block_number = (U8)mbci->mBlockNumber;
+ if ((S32)(result + sizeof(U8)) < MAX_BUFFER_SIZE)
+ {
+ memcpy(&buffer[result], &temp_block_number, sizeof(U8));
+ result += sizeof(U8);
+ }
+ else
+ {
+ // Just reporting error is likely not enough. Need
+ // to check how to abort or error out gracefully
+ // from this function. XXXTBD
+ llerrs << "buildBlock failed. Message excedding "
+ << "sendBuffersize." << llendl;
+ }
}
-
- // counting variables used to encode multiple block info
- S32 block_count = 0;
- U8 temp_block_number;
-
- // loop through msg blocks to loop through variables,
- // totalling up size data and copying into buffer
- for (LLMsgData::msg_blk_data_map_t::iterator
- iter = mCurrentSMessageData->mMemberBlocks.begin(),
- end = mCurrentSMessageData->mMemberBlocks.end();
- iter != end; iter++)
+ else if (template_data->mType == MBT_MULTIPLE)
{
- LLMsgBlkData* mbci = iter->second;
- // do we need to encode a block code?
- if (block_count == 0)
+ if (block_count != template_data->mNumber)
{
- block_count = mbci->mBlockNumber;
-
- LLMessageBlock* template_data =
- mCurrentSMessageTemplate->mMemberBlocks[mbci->mName];
-
- // ok, if this is the first block of a repeating pack, set
- // block_count and, if it's type MBT_VARIABLE encode a byte
- // for how many there are
- if (template_data->mType == MBT_VARIABLE)
- {
- // remember that mBlockNumber is a S32
- temp_block_number = (U8)mbci->mBlockNumber;
- if ((S32)(result + sizeof(U8)) < MAX_BUFFER_SIZE)
- {
- memcpy(&buffer[result], &temp_block_number, sizeof(U8));
- result += sizeof(U8);
- }
- else
- {
- // Just reporting error is likely not enough. Need
- // to check how to abort or error out gracefully
- // from this function. XXXTBD
- llerrs << "buildMessage failed. Message excedding "
- << "sendBuffersize." << llendl;
- }
- }
- else if (template_data->mType == MBT_MULTIPLE)
- {
- if (block_count != template_data->mNumber)
- {
- // nope! need to fill it in all the way!
- llerrs << "Block " << mbci->mName
- << " is type MBT_MULTIPLE but only has data for "
- << block_count << " out of its "
- << template_data->mNumber << " blocks" << llendl;
- }
- }
+ // nope! need to fill it in all the way!
+ llerrs << "Block " << mbci->mName
+ << " is type MBT_MULTIPLE but only has data for "
+ << block_count << " out of its "
+ << template_data->mNumber << " blocks" << llendl;
}
+ }
- // counting down multiple blocks
- block_count--;
-
+ while(block_count > 0)
+ {
// now loop through the variables
- for (LLMsgBlkData::msg_var_data_map_t::iterator iter = mbci->mMemberVarData.begin();
+ for (LLMsgBlkData::msg_var_data_map_t::const_iterator iter = mbci->mMemberVarData.begin();
iter != mbci->mMemberVarData.end(); iter++)
{
- LLMsgVarData& mvci = *iter;
+ const LLMsgVarData& mvci = *iter;
if (mvci.getSize() == -1)
{
// oops, this variable wasn't ever set!
llerrs << "The variable " << mvci.getName() << " in block "
<< mbci->mName << " of message "
- << mCurrentSMessageData->mName
+ << template_data->mName
<< " wasn't set prior to buildMessage call" << llendl;
}
else
@@ -774,7 +703,7 @@ U32 LLTemplateMessageBuilder::buildMessage(U8* buffer, U32 buffer_size)
// Just reporting error is likely not
// enough. Need to check how to abort or error
// out gracefully from this function. XXXTBD
- llerrs << "LLMessageSystem::buildMessage failed. "
+ llerrs << "buildBlock failed. "
<< "Attempted to pack "
<< result + mvci.getSize()
<< " bytes into a buffer with size "
@@ -783,6 +712,94 @@ U32 LLTemplateMessageBuilder::buildMessage(U8* buffer, U32 buffer_size)
}
}
}
+
+ --block_count;
+ ++block_iter;
+ if (block_iter != message_data->mMemberBlocks.end())
+ {
+ mbci = block_iter->second;
+ }
+ }
+
+ return result;
+}
+
+
+// make sure that all the desired data is in place and then copy the data into MAX_BUFFER_SIZEd buffer
+U32 LLTemplateMessageBuilder::buildMessage(
+ U8* buffer,
+ U32 buffer_size,
+ U8 offset_to_data)
+{
+ // basic algorithm is to loop through the various pieces, building
+ // size and offset info if we encounter a -1 for mSize at any
+ // point that variable wasn't given data
+
+ // do we have a current message?
+ if (!mCurrentSMessageTemplate)
+ {
+ llerrs << "newMessage not called prior to buildMessage" << llendl;
+ return 0;
+ }
+
+ // leave room for flags, packet sequence #, and data offset
+ // information.
+ buffer[PHL_OFFSET] = offset_to_data;
+ U32 result = LL_PACKET_ID_SIZE;
+
+ // encode message number and adjust total_offset
+ if (mCurrentSMessageTemplate->mFrequency == MFT_HIGH)
+ {
+// old, endian-dependant way
+// memcpy(&buffer[result], &mCurrentMessageTemplate->mMessageNumber, sizeof(U8));
+
+// new, independant way
+ buffer[result] = (U8)mCurrentSMessageTemplate->mMessageNumber;
+ result += sizeof(U8);
+ }
+ else if (mCurrentSMessageTemplate->mFrequency == MFT_MEDIUM)
+ {
+ U8 temp = 255;
+ memcpy(&buffer[result], &temp, sizeof(U8)); /*Flawfinder: ignore*/
+ result += sizeof(U8);
+
+ // mask off unsightly bits
+ temp = mCurrentSMessageTemplate->mMessageNumber & 255;
+ memcpy(&buffer[result], &temp, sizeof(U8)); /*Flawfinder: ignore*/
+ result += sizeof(U8);
+ }
+ else if (mCurrentSMessageTemplate->mFrequency == MFT_LOW)
+ {
+ U8 temp = 255;
+ U16 message_num;
+ memcpy(&buffer[result], &temp, sizeof(U8)); /*Flawfinder: ignore*/
+ result += sizeof(U8);
+ memcpy(&buffer[result], &temp, sizeof(U8)); /*Flawfinder: ignore*/
+ result += sizeof(U8);
+
+ // mask off unsightly bits
+ message_num = mCurrentSMessageTemplate->mMessageNumber & 0xFFFF;
+
+ // convert to network byte order
+ message_num = htons(message_num);
+ memcpy(&buffer[result], &message_num, sizeof(U16)); /*Flawfinder: ignore*/
+ result += sizeof(U16);
+ }
+ else
+ {
+ llerrs << "unexpected message frequency in buildMessage" << llendl;
+ return 0;
+ }
+
+ // fast forward through the offset and build the message
+ result += offset_to_data;
+ for(LLMessageTemplate::message_block_map_t::const_iterator
+ iter = mCurrentSMessageTemplate->mMemberBlocks.begin(),
+ end = mCurrentSMessageTemplate->mMemberBlocks.end();
+ iter != end;
+ ++iter)
+ {
+ result += buildBlock(buffer + result, buffer_size - result, *iter, mCurrentSMessageData);
}
mbSBuilt = TRUE;