aboutsummaryrefslogtreecommitdiffstatshomepage
path: root/linden/indra/llmessage/lltemplatemessagebuilder.cpp
diff options
context:
space:
mode:
Diffstat (limited to '')
-rw-r--r--linden/indra/llmessage/lltemplatemessagebuilder.cpp329
1 files changed, 183 insertions, 146 deletions
diff --git a/linden/indra/llmessage/lltemplatemessagebuilder.cpp b/linden/indra/llmessage/lltemplatemessagebuilder.cpp
index 806f034..9473343 100644
--- a/linden/indra/llmessage/lltemplatemessagebuilder.cpp
+++ b/linden/indra/llmessage/lltemplatemessagebuilder.cpp
@@ -1,3 +1,31 @@
1/**
2 * @file lltemplatemessagebuilder.cpp
3 * @brief LLTemplateMessageBuilder class implementation.
4 *
5 * Copyright (c) 2007-2007, Linden Research, Inc.
6 *
7 * Second Life Viewer Source Code
8 * The source code in this file ("Source Code") is provided by Linden Lab
9 * to you under the terms of the GNU General Public License, version 2.0
10 * ("GPL"), unless you have obtained a separate licensing agreement
11 * ("Other License"), formally executed by you and Linden Lab. Terms of
12 * the GPL can be found in doc/GPL-license.txt in this distribution, or
13 * online at http://secondlife.com/developers/opensource/gplv2
14 *
15 * There are special exceptions to the terms and conditions of the GPL as
16 * it is applied to this Source Code. View the full text of the exception
17 * in the file doc/FLOSS-exception.txt in this software distribution, or
18 * online at http://secondlife.com/developers/opensource/flossexception
19 *
20 * By copying, modifying or distributing this software, you acknowledge
21 * that you have read and understood your obligations described above,
22 * and agree to abide by those obligations.
23 *
24 * ALL LINDEN LAB SOURCE CODE IS PROVIDED "AS IS." LINDEN LAB MAKES NO
25 * WARRANTIES, EXPRESS, IMPLIED OR OTHERWISE, REGARDING ITS ACCURACY,
26 * COMPLETENESS OR PERFORMANCE.
27 */
28
1#include "linden_common.h" 29#include "linden_common.h"
2 30
3#include "lltemplatemessagebuilder.h" 31#include "lltemplatemessagebuilder.h"
@@ -41,28 +69,30 @@ void LLTemplateMessageBuilder::newMessage(const char *name)
41 delete mCurrentSMessageData; 69 delete mCurrentSMessageData;
42 mCurrentSMessageData = NULL; 70 mCurrentSMessageData = NULL;
43 71
44 char *namep = (char *)name; 72 char* namep = (char*)name;
45
46 if (mMessageTemplates.count(namep) > 0) 73 if (mMessageTemplates.count(namep) > 0)
47 { 74 {
48 mCurrentSMessageTemplate = mMessageTemplates[namep]; 75 mCurrentSMessageTemplate = mMessageTemplates[namep];
49 if (mCurrentSMessageData)
50 {
51 delete mCurrentSMessageData;
52 }
53 mCurrentSMessageData = new LLMsgData(namep); 76 mCurrentSMessageData = new LLMsgData(namep);
54 mCurrentSMessageName = namep; 77 mCurrentSMessageName = namep;
55 mCurrentSDataBlock = NULL; 78 mCurrentSDataBlock = NULL;
56 mCurrentSBlockName = NULL; 79 mCurrentSBlockName = NULL;
57 80
58 // add at one of each block 81 // add at one of each block
59 LLMessageTemplate* msg_template = mMessageTemplates[namep]; 82 const LLMessageTemplate* msg_template = mMessageTemplates[namep];
60 for (LLMessageTemplate::message_block_map_t::iterator iter = msg_template->mMemberBlocks.begin(); 83
61 iter != msg_template->mMemberBlocks.end(); iter++) 84 if (msg_template->getDeprecation() != MD_NOTDEPRECATED)
62 { 85 {
63 LLMessageBlock* ci = iter->second; 86 llwarns << "Sending deprecated message " << namep << llendl;
64 LLMsgBlkData *tblockp; 87 }
65 tblockp = new LLMsgBlkData(ci->mName, 0); 88
89 LLMessageTemplate::message_block_map_t::const_iterator iter;
90 for(iter = msg_template->mMemberBlocks.begin();
91 iter != msg_template->mMemberBlocks.end();
92 ++iter)
93 {
94 LLMessageBlock* ci = *iter;
95 LLMsgBlkData* tblockp = new LLMsgBlkData(ci->mName, 0);
66 mCurrentSMessageData->addBlock(tblockp); 96 mCurrentSMessageData->addBlock(tblockp);
67 } 97 }
68 } 98 }
@@ -102,16 +132,14 @@ void LLTemplateMessageBuilder::nextBlock(const char* blockname)
102 } 132 }
103 133
104 // now, does this block exist? 134 // now, does this block exist?
105 LLMessageTemplate::message_block_map_t::iterator temp_iter = mCurrentSMessageTemplate->mMemberBlocks.find(bnamep); 135 const LLMessageBlock* template_data = mCurrentSMessageTemplate->getBlock(bnamep);
106 if (temp_iter == mCurrentSMessageTemplate->mMemberBlocks.end()) 136 if (!template_data)
107 { 137 {
108 llerrs << "LLTemplateMessageBuilder::nextBlock " << bnamep 138 llerrs << "LLTemplateMessageBuilder::nextBlock " << bnamep
109 << " not a block in " << mCurrentSMessageTemplate->mName << llendl; 139 << " not a block in " << mCurrentSMessageTemplate->mName << llendl;
110 return; 140 return;
111 } 141 }
112 142
113 LLMessageBlock* template_data = temp_iter->second;
114
115 // ok, have we already set this block? 143 // ok, have we already set this block?
116 LLMsgBlkData* block_data = mCurrentSMessageData->mMemberBlocks[bnamep]; 144 LLMsgBlkData* block_data = mCurrentSMessageData->mMemberBlocks[bnamep];
117 if (block_data->mBlockNumber == 0) 145 if (block_data->mBlockNumber == 0)
@@ -122,10 +150,10 @@ void LLTemplateMessageBuilder::nextBlock(const char* blockname)
122 mCurrentSBlockName = bnamep; 150 mCurrentSBlockName = bnamep;
123 151
124 // add placeholders for each of the variables 152 // add placeholders for each of the variables
125 for (LLMessageBlock::message_variable_map_t::iterator iter = template_data->mMemberVariables.begin(); 153 for (LLMessageBlock::message_variable_map_t::const_iterator iter = template_data->mMemberVariables.begin();
126 iter != template_data->mMemberVariables.end(); iter++) 154 iter != template_data->mMemberVariables.end(); iter++)
127 { 155 {
128 LLMessageVariable& ci = *(iter->second); 156 LLMessageVariable& ci = **iter;
129 mCurrentSDataBlock->addVariable(ci.getName(), ci.getType()); 157 mCurrentSDataBlock->addVariable(ci.getName(), ci.getType());
130 } 158 }
131 return; 159 return;
@@ -181,12 +209,12 @@ void LLTemplateMessageBuilder::nextBlock(const char* blockname)
181 mCurrentSMessageData->mMemberBlocks[nbnamep] = mCurrentSDataBlock; 209 mCurrentSMessageData->mMemberBlocks[nbnamep] = mCurrentSDataBlock;
182 210
183 // add placeholders for each of the variables 211 // add placeholders for each of the variables
184 for (LLMessageBlock::message_variable_map_t::iterator 212 for (LLMessageBlock::message_variable_map_t::const_iterator
185 iter = template_data->mMemberVariables.begin(), 213 iter = template_data->mMemberVariables.begin(),
186 end = template_data->mMemberVariables.end(); 214 end = template_data->mMemberVariables.end();
187 iter != end; iter++) 215 iter != end; iter++)
188 { 216 {
189 LLMessageVariable& ci = *(iter->second); 217 LLMessageVariable& ci = **iter;
190 mCurrentSDataBlock->addVariable(ci.getName(), ci.getType()); 218 mCurrentSDataBlock->addVariable(ci.getName(), ci.getType());
191 } 219 }
192 return; 220 return;
@@ -211,12 +239,12 @@ BOOL LLTemplateMessageBuilder::removeLastBlock()
211 // Decrement the sent total by the size of the 239 // Decrement the sent total by the size of the
212 // data in the message block that we're currently building. 240 // data in the message block that we're currently building.
213 241
214 LLMessageBlock* template_data = mCurrentSMessageTemplate->mMemberBlocks[mCurrentSBlockName]; 242 const LLMessageBlock* template_data = mCurrentSMessageTemplate->getBlock(mCurrentSBlockName);
215 243
216 for (LLMessageBlock::message_variable_map_t::iterator iter = template_data->mMemberVariables.begin(); 244 for (LLMessageBlock::message_variable_map_t::const_iterator iter = template_data->mMemberVariables.begin();
217 iter != template_data->mMemberVariables.end(); iter++) 245 iter != template_data->mMemberVariables.end(); iter++)
218 { 246 {
219 LLMessageVariable& ci = *(iter->second); 247 LLMessageVariable& ci = **iter;
220 mCurrentSendTotal -= ci.getSize(); 248 mCurrentSendTotal -= ci.getSize();
221 } 249 }
222 250
@@ -276,7 +304,7 @@ void LLTemplateMessageBuilder::addData(const char *varname, const void *data, EM
276 } 304 }
277 305
278 // kewl, add the data if it exists 306 // kewl, add the data if it exists
279 LLMessageVariable* var_data = mCurrentSMessageTemplate->mMemberBlocks[mCurrentSBlockName]->mMemberVariables[vnamep]; 307 const LLMessageVariable* var_data = mCurrentSMessageTemplate->getBlock(mCurrentSBlockName)->getVariable(vnamep);
280 if (!var_data || !var_data->getName()) 308 if (!var_data || !var_data->getName())
281 { 309 {
282 llerrs << vnamep << " not a variable in block " << mCurrentSBlockName << " of " << mCurrentSMessageTemplate->mName << llendl; 310 llerrs << vnamep << " not a variable in block " << mCurrentSBlockName << " of " << mCurrentSMessageTemplate->mName << llendl;
@@ -336,7 +364,7 @@ void LLTemplateMessageBuilder::addData(const char *varname, const void *data, EM
336 } 364 }
337 365
338 // kewl, add the data if it exists 366 // kewl, add the data if it exists
339 LLMessageVariable* var_data = mCurrentSMessageTemplate->mMemberBlocks[mCurrentSBlockName]->mMemberVariables[vnamep]; 367 const LLMessageVariable* var_data = mCurrentSMessageTemplate->getBlock(mCurrentSBlockName)->getVariable(vnamep);
340 if (!var_data->getName()) 368 if (!var_data->getName())
341 { 369 {
342 llerrs << vnamep << " not a variable in block " << mCurrentSBlockName << " of " << mCurrentSMessageTemplate->mName << llendl; 370 llerrs << vnamep << " not a variable in block " << mCurrentSBlockName << " of " << mCurrentSMessageTemplate->mName << llendl;
@@ -484,7 +512,7 @@ static S32 zero_code(U8 **data, U32 *data_size)
484 512
485// skip the packet id field 513// skip the packet id field
486 514
487 for (U32 i=0;i<LL_PACKET_ID_SIZE;i++) 515 for (U32 ii = 0; ii < LL_PACKET_ID_SIZE ; ++ii)
488 { 516 {
489 count--; 517 count--;
490 *outptr++ = *inptr++; 518 *outptr++ = *inptr++;
@@ -571,7 +599,7 @@ BOOL LLTemplateMessageBuilder::isMessageFull(const char* blockname) const
571 char* bnamep = (char*)blockname; 599 char* bnamep = (char*)blockname;
572 S32 max; 600 S32 max;
573 601
574 LLMessageBlock* template_data = mCurrentSMessageTemplate->mMemberBlocks[bnamep]; 602 const LLMessageBlock* template_data = mCurrentSMessageTemplate->getBlock(bnamep);
575 603
576 switch(template_data->mType) 604 switch(template_data->mType)
577 { 605 {
@@ -593,138 +621,59 @@ BOOL LLTemplateMessageBuilder::isMessageFull(const char* blockname) const
593 return FALSE; 621 return FALSE;
594} 622}
595 623
596 624static S32 buildBlock(U8* buffer, S32 buffer_size, const LLMessageBlock* template_data, LLMsgData* message_data)
597// make sure that all the desired data is in place and then copy the data into MAX_BUFFER_SIZEd buffer
598U32 LLTemplateMessageBuilder::buildMessage(U8* buffer, U32 buffer_size)
599{ 625{
600 // basic algorithm is to loop through the various pieces, building 626 S32 result = 0;
601 // size and offset info if we encounter a -1 for mSize at any 627 LLMsgData::msg_blk_data_map_t::const_iterator block_iter = message_data->mMemberBlocks.find(template_data->mName);
602 // point that variable wasn't given data 628 const LLMsgBlkData* mbci = block_iter->second;
603 629
604 // do we have a current message? 630 // ok, if this is the first block of a repeating pack, set
605 if (!mCurrentSMessageTemplate) 631 // block_count and, if it's type MBT_VARIABLE encode a byte
606 { 632 // for how many there are
607 llerrs << "newMessage not called prior to buildMessage" << llendl; 633 S32 block_count = mbci->mBlockNumber;
608 return 0; 634 if (template_data->mType == MBT_VARIABLE)
609 } 635 {
610 636 // remember that mBlockNumber is a S32
611 // zero out some useful values 637 U8 temp_block_number = (U8)mbci->mBlockNumber;
612 638 if ((S32)(result + sizeof(U8)) < MAX_BUFFER_SIZE)
613 // leave room for circuit counter 639 {
614 U32 result = LL_PACKET_ID_SIZE; 640 memcpy(&buffer[result], &temp_block_number, sizeof(U8));
615 641 result += sizeof(U8);
616 // encode message number and adjust total_offset 642 }
617 if (mCurrentSMessageTemplate->mFrequency == MFT_HIGH) 643 else
618 { 644 {
619// old, endian-dependant way 645 // Just reporting error is likely not enough. Need
620// memcpy(&buffer[result], &mCurrentMessageTemplate->mMessageNumber, sizeof(U8)); 646 // to check how to abort or error out gracefully
621 647 // from this function. XXXTBD
622// new, independant way 648 llerrs << "buildBlock failed. Message excedding "
623 buffer[result] = (U8)mCurrentSMessageTemplate->mMessageNumber; 649 << "sendBuffersize." << llendl;
624 result += sizeof(U8); 650 }
625 }
626 else if (mCurrentSMessageTemplate->mFrequency == MFT_MEDIUM)
627 {
628 U8 temp = 255;
629 memcpy(&buffer[result], &temp, sizeof(U8)); /*Flawfinder: ignore*/
630 result += sizeof(U8);
631
632 // mask off unsightly bits
633 temp = mCurrentSMessageTemplate->mMessageNumber & 255;
634 memcpy(&buffer[result], &temp, sizeof(U8)); /*Flawfinder: ignore*/
635 result += sizeof(U8);
636 }
637 else if (mCurrentSMessageTemplate->mFrequency == MFT_LOW)
638 {
639 U8 temp = 255;
640 U16 message_num;
641 memcpy(&buffer[result], &temp, sizeof(U8)); /*Flawfinder: ignore*/
642 result += sizeof(U8);
643 memcpy(&buffer[result], &temp, sizeof(U8)); /*Flawfinder: ignore*/
644 result += sizeof(U8);
645
646 // mask off unsightly bits
647 message_num = mCurrentSMessageTemplate->mMessageNumber & 0xFFFF;
648
649 // convert to network byte order
650 message_num = htons(message_num);
651 memcpy(&buffer[result], &message_num, sizeof(U16)); /*Flawfinder: ignore*/
652 result += sizeof(U16);
653 }
654 else
655 {
656 llerrs << "unexpected message frequency in buildMessage" << llendl;
657 return 0;
658 } 651 }
659 652 else if (template_data->mType == MBT_MULTIPLE)
660 // counting variables used to encode multiple block info
661 S32 block_count = 0;
662 U8 temp_block_number;
663
664 // loop through msg blocks to loop through variables,
665 // totalling up size data and copying into buffer
666 for (LLMsgData::msg_blk_data_map_t::iterator
667 iter = mCurrentSMessageData->mMemberBlocks.begin(),
668 end = mCurrentSMessageData->mMemberBlocks.end();
669 iter != end; iter++)
670 { 653 {
671 LLMsgBlkData* mbci = iter->second; 654 if (block_count != template_data->mNumber)
672 // do we need to encode a block code?
673 if (block_count == 0)
674 { 655 {
675 block_count = mbci->mBlockNumber; 656 // nope! need to fill it in all the way!
676 657 llerrs << "Block " << mbci->mName
677 LLMessageBlock* template_data = 658 << " is type MBT_MULTIPLE but only has data for "
678 mCurrentSMessageTemplate->mMemberBlocks[mbci->mName]; 659 << block_count << " out of its "
679 660 << template_data->mNumber << " blocks" << llendl;
680 // ok, if this is the first block of a repeating pack, set
681 // block_count and, if it's type MBT_VARIABLE encode a byte
682 // for how many there are
683 if (template_data->mType == MBT_VARIABLE)
684 {
685 // remember that mBlockNumber is a S32
686 temp_block_number = (U8)mbci->mBlockNumber;
687 if ((S32)(result + sizeof(U8)) < MAX_BUFFER_SIZE)
688 {
689 memcpy(&buffer[result], &temp_block_number, sizeof(U8));
690 result += sizeof(U8);
691 }
692 else
693 {
694 // Just reporting error is likely not enough. Need
695 // to check how to abort or error out gracefully
696 // from this function. XXXTBD
697 llerrs << "buildMessage failed. Message excedding "
698 << "sendBuffersize." << llendl;
699 }
700 }
701 else if (template_data->mType == MBT_MULTIPLE)
702 {
703 if (block_count != template_data->mNumber)
704 {
705 // nope! need to fill it in all the way!
706 llerrs << "Block " << mbci->mName
707 << " is type MBT_MULTIPLE but only has data for "
708 << block_count << " out of its "
709 << template_data->mNumber << " blocks" << llendl;
710 }
711 }
712 } 661 }
662 }
713 663
714 // counting down multiple blocks 664 while(block_count > 0)
715 block_count--; 665 {
716
717 // now loop through the variables 666 // now loop through the variables
718 for (LLMsgBlkData::msg_var_data_map_t::iterator iter = mbci->mMemberVarData.begin(); 667 for (LLMsgBlkData::msg_var_data_map_t::const_iterator iter = mbci->mMemberVarData.begin();
719 iter != mbci->mMemberVarData.end(); iter++) 668 iter != mbci->mMemberVarData.end(); iter++)
720 { 669 {
721 LLMsgVarData& mvci = *iter; 670 const LLMsgVarData& mvci = *iter;
722 if (mvci.getSize() == -1) 671 if (mvci.getSize() == -1)
723 { 672 {
724 // oops, this variable wasn't ever set! 673 // oops, this variable wasn't ever set!
725 llerrs << "The variable " << mvci.getName() << " in block " 674 llerrs << "The variable " << mvci.getName() << " in block "
726 << mbci->mName << " of message " 675 << mbci->mName << " of message "
727 << mCurrentSMessageData->mName 676 << template_data->mName
728 << " wasn't set prior to buildMessage call" << llendl; 677 << " wasn't set prior to buildMessage call" << llendl;
729 } 678 }
730 else 679 else
@@ -774,7 +723,7 @@ U32 LLTemplateMessageBuilder::buildMessage(U8* buffer, U32 buffer_size)
774 // Just reporting error is likely not 723 // Just reporting error is likely not
775 // enough. Need to check how to abort or error 724 // enough. Need to check how to abort or error
776 // out gracefully from this function. XXXTBD 725 // out gracefully from this function. XXXTBD
777 llerrs << "LLMessageSystem::buildMessage failed. " 726 llerrs << "buildBlock failed. "
778 << "Attempted to pack " 727 << "Attempted to pack "
779 << result + mvci.getSize() 728 << result + mvci.getSize()
780 << " bytes into a buffer with size " 729 << " bytes into a buffer with size "
@@ -783,6 +732,94 @@ U32 LLTemplateMessageBuilder::buildMessage(U8* buffer, U32 buffer_size)
783 } 732 }
784 } 733 }
785 } 734 }
735
736 --block_count;
737 ++block_iter;
738 if (block_iter != message_data->mMemberBlocks.end())
739 {
740 mbci = block_iter->second;
741 }
742 }
743
744 return result;
745}
746
747
748// make sure that all the desired data is in place and then copy the data into MAX_BUFFER_SIZEd buffer
749U32 LLTemplateMessageBuilder::buildMessage(
750 U8* buffer,
751 U32 buffer_size,
752 U8 offset_to_data)
753{
754 // basic algorithm is to loop through the various pieces, building
755 // size and offset info if we encounter a -1 for mSize at any
756 // point that variable wasn't given data
757
758 // do we have a current message?
759 if (!mCurrentSMessageTemplate)
760 {
761 llerrs << "newMessage not called prior to buildMessage" << llendl;
762 return 0;
763 }
764
765 // leave room for flags, packet sequence #, and data offset
766 // information.
767 buffer[PHL_OFFSET] = offset_to_data;
768 U32 result = LL_PACKET_ID_SIZE;
769
770 // encode message number and adjust total_offset
771 if (mCurrentSMessageTemplate->mFrequency == MFT_HIGH)
772 {
773// old, endian-dependant way
774// memcpy(&buffer[result], &mCurrentMessageTemplate->mMessageNumber, sizeof(U8));
775
776// new, independant way
777 buffer[result] = (U8)mCurrentSMessageTemplate->mMessageNumber;
778 result += sizeof(U8);
779 }
780 else if (mCurrentSMessageTemplate->mFrequency == MFT_MEDIUM)
781 {
782 U8 temp = 255;
783 memcpy(&buffer[result], &temp, sizeof(U8)); /*Flawfinder: ignore*/
784 result += sizeof(U8);
785
786 // mask off unsightly bits
787 temp = mCurrentSMessageTemplate->mMessageNumber & 255;
788 memcpy(&buffer[result], &temp, sizeof(U8)); /*Flawfinder: ignore*/
789 result += sizeof(U8);
790 }
791 else if (mCurrentSMessageTemplate->mFrequency == MFT_LOW)
792 {
793 U8 temp = 255;
794 U16 message_num;
795 memcpy(&buffer[result], &temp, sizeof(U8)); /*Flawfinder: ignore*/
796 result += sizeof(U8);
797 memcpy(&buffer[result], &temp, sizeof(U8)); /*Flawfinder: ignore*/
798 result += sizeof(U8);
799
800 // mask off unsightly bits
801 message_num = mCurrentSMessageTemplate->mMessageNumber & 0xFFFF;
802
803 // convert to network byte order
804 message_num = htons(message_num);
805 memcpy(&buffer[result], &message_num, sizeof(U16)); /*Flawfinder: ignore*/
806 result += sizeof(U16);
807 }
808 else
809 {
810 llerrs << "unexpected message frequency in buildMessage" << llendl;
811 return 0;
812 }
813
814 // fast forward through the offset and build the message
815 result += offset_to_data;
816 for(LLMessageTemplate::message_block_map_t::const_iterator
817 iter = mCurrentSMessageTemplate->mMemberBlocks.begin(),
818 end = mCurrentSMessageTemplate->mMemberBlocks.end();
819 iter != end;
820 ++iter)
821 {
822 result += buildBlock(buffer + result, buffer_size - result, *iter, mCurrentSMessageData);
786 } 823 }
787 mbSBuilt = TRUE; 824 mbSBuilt = TRUE;
788 825