00001
00032 #include "linden_common.h"
00033
00034 #include "lltemplatemessagebuilder.h"
00035
00036 #include "llmessagetemplate.h"
00037 #include "llquaternion.h"
00038 #include "u64.h"
00039 #include "v3dmath.h"
00040 #include "v3math.h"
00041 #include "v4math.h"
00042
00043 LLTemplateMessageBuilder::LLTemplateMessageBuilder(message_template_name_map_t& name_template_map) :
00044 mCurrentSMessageData(NULL),
00045 mCurrentSMessageTemplate(NULL),
00046 mCurrentSDataBlock(NULL),
00047 mCurrentSMessageName(NULL),
00048 mCurrentSBlockName(NULL),
00049 mbSBuilt(FALSE),
00050 mbSClear(TRUE),
00051 mCurrentSendTotal(0),
00052 mMessageTemplates(name_template_map)
00053 {
00054 }
00055
00056
00057 LLTemplateMessageBuilder::~LLTemplateMessageBuilder()
00058 {
00059 delete mCurrentSMessageData;
00060 mCurrentSMessageData = NULL;
00061 }
00062
00063
00064
00065 void LLTemplateMessageBuilder::newMessage(const char *name)
00066 {
00067 mbSBuilt = FALSE;
00068 mbSClear = FALSE;
00069
00070 mCurrentSendTotal = 0;
00071
00072 delete mCurrentSMessageData;
00073 mCurrentSMessageData = NULL;
00074
00075 char* namep = (char*)name;
00076 if (mMessageTemplates.count(namep) > 0)
00077 {
00078 mCurrentSMessageTemplate = mMessageTemplates[namep];
00079 mCurrentSMessageData = new LLMsgData(namep);
00080 mCurrentSMessageName = namep;
00081 mCurrentSDataBlock = NULL;
00082 mCurrentSBlockName = NULL;
00083
00084
00085 const LLMessageTemplate* msg_template = mMessageTemplates[namep];
00086
00087 if (msg_template->getDeprecation() != MD_NOTDEPRECATED)
00088 {
00089 llwarns << "Sending deprecated message " << namep << llendl;
00090 }
00091
00092 LLMessageTemplate::message_block_map_t::const_iterator iter;
00093 for(iter = msg_template->mMemberBlocks.begin();
00094 iter != msg_template->mMemberBlocks.end();
00095 ++iter)
00096 {
00097 LLMessageBlock* ci = *iter;
00098 LLMsgBlkData* tblockp = new LLMsgBlkData(ci->mName, 0);
00099 mCurrentSMessageData->addBlock(tblockp);
00100 }
00101 }
00102 else
00103 {
00104 llerrs << "newMessage - Message " << name << " not registered" << llendl;
00105 }
00106 }
00107
00108
00109 void LLTemplateMessageBuilder::clearMessage()
00110 {
00111 mbSBuilt = FALSE;
00112 mbSClear = TRUE;
00113
00114 mCurrentSendTotal = 0;
00115
00116 mCurrentSMessageTemplate = NULL;
00117
00118 delete mCurrentSMessageData;
00119 mCurrentSMessageData = NULL;
00120
00121 mCurrentSMessageName = NULL;
00122 mCurrentSDataBlock = NULL;
00123 mCurrentSBlockName = NULL;
00124 }
00125
00126
00127 void LLTemplateMessageBuilder::nextBlock(const char* blockname)
00128 {
00129 char *bnamep = (char *)blockname;
00130
00131 if (!mCurrentSMessageTemplate)
00132 {
00133 llerrs << "newMessage not called prior to setBlock" << llendl;
00134 return;
00135 }
00136
00137
00138 const LLMessageBlock* template_data = mCurrentSMessageTemplate->getBlock(bnamep);
00139 if (!template_data)
00140 {
00141 llerrs << "LLTemplateMessageBuilder::nextBlock " << bnamep
00142 << " not a block in " << mCurrentSMessageTemplate->mName << llendl;
00143 return;
00144 }
00145
00146
00147 LLMsgBlkData* block_data = mCurrentSMessageData->mMemberBlocks[bnamep];
00148 if (block_data->mBlockNumber == 0)
00149 {
00150
00151 block_data->mBlockNumber = 1;
00152 mCurrentSDataBlock = block_data;
00153 mCurrentSBlockName = bnamep;
00154
00155
00156 for (LLMessageBlock::message_variable_map_t::const_iterator iter = template_data->mMemberVariables.begin();
00157 iter != template_data->mMemberVariables.end(); iter++)
00158 {
00159 LLMessageVariable& ci = **iter;
00160 mCurrentSDataBlock->addVariable(ci.getName(), ci.getType());
00161 }
00162 return;
00163 }
00164 else
00165 {
00166
00167
00168
00169
00170 if (template_data->mType == MBT_SINGLE)
00171 {
00172 llerrs << "LLTemplateMessageBuilder::nextBlock called multiple times"
00173 << " for " << bnamep << " but is type MBT_SINGLE" << llendl;
00174 return;
00175 }
00176
00177
00178
00179
00180 if ( (template_data->mType == MBT_MULTIPLE)
00181 &&(mCurrentSDataBlock->mBlockNumber == template_data->mNumber))
00182 {
00183 llerrs << "LLTemplateMessageBuilder::nextBlock called "
00184 << mCurrentSDataBlock->mBlockNumber << " times for " << bnamep
00185 << " exceeding " << template_data->mNumber
00186 << " specified in type MBT_MULTIPLE." << llendl;
00187 return;
00188 }
00189
00190
00191
00192 S32 count = block_data->mBlockNumber;
00193
00194
00195 block_data->mBlockNumber++;
00196
00197 if (block_data->mBlockNumber > MAX_BLOCKS)
00198 {
00199 llerrs << "Trying to pack too many blocks into MBT_VARIABLE type "
00200 << "(limited to " << MAX_BLOCKS << ")" << llendl;
00201 }
00202
00203
00204
00205
00206
00207
00208 char *nbnamep = bnamep + count;
00209
00210 mCurrentSDataBlock = new LLMsgBlkData(bnamep, count);
00211 mCurrentSDataBlock->mName = nbnamep;
00212 mCurrentSMessageData->mMemberBlocks[nbnamep] = mCurrentSDataBlock;
00213
00214
00215 for (LLMessageBlock::message_variable_map_t::const_iterator
00216 iter = template_data->mMemberVariables.begin(),
00217 end = template_data->mMemberVariables.end();
00218 iter != end; iter++)
00219 {
00220 LLMessageVariable& ci = **iter;
00221 mCurrentSDataBlock->addVariable(ci.getName(), ci.getType());
00222 }
00223 return;
00224 }
00225 }
00226
00227
00228 BOOL LLTemplateMessageBuilder::removeLastBlock()
00229 {
00230 if (mCurrentSBlockName)
00231 {
00232 if ( (mCurrentSMessageData)
00233 &&(mCurrentSMessageTemplate))
00234 {
00235 if (mCurrentSMessageData->mMemberBlocks[mCurrentSBlockName]->mBlockNumber >= 1)
00236 {
00237
00238
00239
00240 char *block_name = mCurrentSBlockName;
00241
00242
00243
00244
00245 const LLMessageBlock* template_data = mCurrentSMessageTemplate->getBlock(mCurrentSBlockName);
00246
00247 for (LLMessageBlock::message_variable_map_t::const_iterator iter = template_data->mMemberVariables.begin();
00248 iter != template_data->mMemberVariables.end(); iter++)
00249 {
00250 LLMessageVariable& ci = **iter;
00251 mCurrentSendTotal -= ci.getSize();
00252 }
00253
00254
00255
00256
00257
00258 LLMsgBlkData* block_data = mCurrentSMessageData->mMemberBlocks[block_name];
00259 S32 num_blocks = block_data->mBlockNumber;
00260
00261
00262
00263 char *block_getting_whacked = block_name + num_blocks - 1;
00264 LLMsgBlkData* whacked_data = mCurrentSMessageData->mMemberBlocks[block_getting_whacked];
00265 delete whacked_data;
00266 mCurrentSMessageData->mMemberBlocks.erase(block_getting_whacked);
00267
00268 if (num_blocks <= 1)
00269 {
00270
00271 llwarns << "not blowing away the only block of message "
00272 << mCurrentSMessageName
00273 << ". Block: " << block_name
00274 << ". Number: " << num_blocks
00275 << llendl;
00276 return FALSE;
00277 }
00278 else
00279 {
00280
00281 block_data->mBlockNumber--;
00282 return TRUE;
00283 }
00284 }
00285 }
00286 }
00287 return FALSE;
00288 }
00289
00290
00291 void LLTemplateMessageBuilder::addData(const char *varname, const void *data, EMsgVariableType type, S32 size)
00292 {
00293 char *vnamep = (char *)varname;
00294
00295
00296 if (!mCurrentSMessageTemplate)
00297 {
00298 llerrs << "newMessage not called prior to addData" << llendl;
00299 return;
00300 }
00301
00302
00303 if (!mCurrentSDataBlock)
00304 {
00305 llerrs << "setBlock not called prior to addData" << llendl;
00306 return;
00307 }
00308
00309
00310 const LLMessageVariable* var_data = mCurrentSMessageTemplate->getBlock(mCurrentSBlockName)->getVariable(vnamep);
00311 if (!var_data || !var_data->getName())
00312 {
00313 llerrs << vnamep << " not a variable in block " << mCurrentSBlockName << " of " << mCurrentSMessageTemplate->mName << llendl;
00314 return;
00315 }
00316
00317
00318 if (var_data->getType() == MVT_VARIABLE)
00319 {
00320
00321 if ((var_data->getSize() == 1) &&
00322 (size > 255))
00323 {
00324 llwarns << "Field " << varname << " is a Variable 1 but program "
00325 << "attempted to stuff more than 255 bytes in "
00326 << "(" << size << "). Clamping size and truncating data." << llendl;
00327 size = 255;
00328 char *truncate = (char *)data;
00329 truncate[255] = 0;
00330 }
00331
00332
00333 mCurrentSDataBlock->addData(vnamep, data, size, type, var_data->getSize());
00334 mCurrentSendTotal += size;
00335 }
00336 else
00337 {
00338 if (size != var_data->getSize())
00339 {
00340 llerrs << varname << " is type MVT_FIXED but request size " << size << " doesn't match template size "
00341 << var_data->getSize() << llendl;
00342 return;
00343 }
00344
00345 mCurrentSDataBlock->addData(vnamep, data, size, type);
00346 mCurrentSendTotal += size;
00347 }
00348 }
00349
00350
00351 void LLTemplateMessageBuilder::addData(const char *varname, const void *data, EMsgVariableType type)
00352 {
00353 char *vnamep = (char *)varname;
00354
00355
00356 if (!mCurrentSMessageTemplate)
00357 {
00358 llerrs << "newMessage not called prior to addData" << llendl;
00359 return;
00360 }
00361
00362
00363 if (!mCurrentSDataBlock)
00364 {
00365 llerrs << "setBlock not called prior to addData" << llendl;
00366 return;
00367 }
00368
00369
00370 const LLMessageVariable* var_data = mCurrentSMessageTemplate->getBlock(mCurrentSBlockName)->getVariable(vnamep);
00371 if (!var_data->getName())
00372 {
00373 llerrs << vnamep << " not a variable in block " << mCurrentSBlockName << " of " << mCurrentSMessageTemplate->mName << llendl;
00374 return;
00375 }
00376
00377
00378 if (var_data->getType() == MVT_VARIABLE)
00379 {
00380
00381 llerrs << vnamep << " is type MVT_VARIABLE. Call using addData(name, data, size)" << llendl;
00382 return;
00383 }
00384 else
00385 {
00386 mCurrentSDataBlock->addData(vnamep, data, var_data->getSize(), type);
00387 mCurrentSendTotal += var_data->getSize();
00388 }
00389 }
00390
00391 void LLTemplateMessageBuilder::addBinaryData(const char *varname,
00392 const void *data, S32 size)
00393 {
00394 addData(varname, data, MVT_FIXED, size);
00395 }
00396
00397 void LLTemplateMessageBuilder::addS8(const char *varname, S8 s)
00398 {
00399 addData(varname, &s, MVT_S8, sizeof(s));
00400 }
00401
00402 void LLTemplateMessageBuilder::addU8(const char *varname, U8 u)
00403 {
00404 addData(varname, &u, MVT_U8, sizeof(u));
00405 }
00406
00407 void LLTemplateMessageBuilder::addS16(const char *varname, S16 i)
00408 {
00409 addData(varname, &i, MVT_S16, sizeof(i));
00410 }
00411
00412 void LLTemplateMessageBuilder::addU16(const char *varname, U16 i)
00413 {
00414 addData(varname, &i, MVT_U16, sizeof(i));
00415 }
00416
00417 void LLTemplateMessageBuilder::addF32(const char *varname, F32 f)
00418 {
00419 addData(varname, &f, MVT_F32, sizeof(f));
00420 }
00421
00422 void LLTemplateMessageBuilder::addS32(const char *varname, S32 s)
00423 {
00424 addData(varname, &s, MVT_S32, sizeof(s));
00425 }
00426
00427 void LLTemplateMessageBuilder::addU32(const char *varname, U32 u)
00428 {
00429 addData(varname, &u, MVT_U32, sizeof(u));
00430 }
00431
00432 void LLTemplateMessageBuilder::addU64(const char *varname, U64 lu)
00433 {
00434 addData(varname, &lu, MVT_U64, sizeof(lu));
00435 }
00436
00437 void LLTemplateMessageBuilder::addF64(const char *varname, F64 d)
00438 {
00439 addData(varname, &d, MVT_F64, sizeof(d));
00440 }
00441
00442 void LLTemplateMessageBuilder::addIPAddr(const char *varname, U32 u)
00443 {
00444 addData(varname, &u, MVT_IP_ADDR, sizeof(u));
00445 }
00446
00447 void LLTemplateMessageBuilder::addIPPort(const char *varname, U16 u)
00448 {
00449 u = htons(u);
00450 addData(varname, &u, MVT_IP_PORT, sizeof(u));
00451 }
00452
00453 void LLTemplateMessageBuilder::addBOOL(const char* varname, BOOL b)
00454 {
00455
00456
00457 U8 temp = (b != 0);
00458 addData(varname, &temp, MVT_BOOL, sizeof(temp));
00459 }
00460
00461 void LLTemplateMessageBuilder::addString(const char* varname, const char* s)
00462 {
00463 if (s)
00464 addData( varname, (void *)s, MVT_VARIABLE, (S32)strlen(s) + 1);
00465 else
00466 addData( varname, NULL, MVT_VARIABLE, 0);
00467 }
00468
00469 void LLTemplateMessageBuilder::addString(const char* varname, const std::string& s)
00470 {
00471 if (s.size())
00472 addData( varname, (void *)s.c_str(), MVT_VARIABLE, (S32)(s.size()) + 1);
00473 else
00474 addData( varname, NULL, MVT_VARIABLE, 0);
00475 }
00476
00477 void LLTemplateMessageBuilder::addVector3(const char *varname, const LLVector3& vec)
00478 {
00479 addData(varname, vec.mV, MVT_LLVector3, sizeof(vec.mV));
00480 }
00481
00482 void LLTemplateMessageBuilder::addVector4(const char *varname, const LLVector4& vec)
00483 {
00484 addData(varname, vec.mV, MVT_LLVector4, sizeof(vec.mV));
00485 }
00486
00487 void LLTemplateMessageBuilder::addVector3d(const char *varname, const LLVector3d& vec)
00488 {
00489 addData(varname, vec.mdV, MVT_LLVector3d, sizeof(vec.mdV));
00490 }
00491
00492 void LLTemplateMessageBuilder::addQuat(const char *varname, const LLQuaternion& quat)
00493 {
00494 addData(varname, quat.packToVector3().mV, MVT_LLQuaternion, sizeof(LLVector3));
00495 }
00496
00497 void LLTemplateMessageBuilder::addUUID(const char *varname, const LLUUID& uuid)
00498 {
00499 addData(varname, uuid.mData, MVT_LLUUID, sizeof(uuid.mData));
00500 }
00501
00502 static S32 zero_code(U8 **data, U32 *data_size)
00503 {
00504
00505
00506 static U8 encodedSendBuffer[2 * MAX_BUFFER_SIZE];
00507
00508 S32 count = *data_size;
00509
00510 S32 net_gain = 0;
00511 U8 num_zeroes = 0;
00512
00513 U8 *inptr = (U8 *)*data;
00514 U8 *outptr = (U8 *)encodedSendBuffer;
00515
00516
00517
00518 for (U32 ii = 0; ii < LL_PACKET_ID_SIZE ; ++ii)
00519 {
00520 count--;
00521 *outptr++ = *inptr++;
00522 }
00523
00524
00525
00526
00527
00528
00529 while (count--)
00530 {
00531 if (!(*inptr))
00532 {
00533 if (num_zeroes)
00534 {
00535 if (++num_zeroes > 254)
00536 {
00537 *outptr++ = num_zeroes;
00538 num_zeroes = 0;
00539 }
00540 net_gain--;
00541 }
00542 else
00543 {
00544 *outptr++ = 0;
00545 net_gain++;
00546 num_zeroes = 1;
00547 }
00548 inptr++;
00549 }
00550 else
00551 {
00552 if (num_zeroes)
00553 {
00554 *outptr++ = num_zeroes;
00555 num_zeroes = 0;
00556 }
00557 *outptr++ = *inptr++;
00558 }
00559 }
00560
00561 if (num_zeroes)
00562 {
00563 *outptr++ = num_zeroes;
00564 }
00565
00566 if (net_gain < 0)
00567 {
00568
00569
00570
00571
00572 *data = encodedSendBuffer;
00573 *data_size += net_gain;
00574 encodedSendBuffer[0] |= LL_ZERO_CODE_FLAG;
00575
00576
00577
00578 }
00579
00580
00581 return(net_gain);
00582 }
00583
00584 void LLTemplateMessageBuilder::compressMessage(U8*& buf_ptr, U32& buffer_length)
00585 {
00586 if(ME_ZEROCODED == mCurrentSMessageTemplate->getEncoding())
00587 {
00588 zero_code(&buf_ptr, &buffer_length);
00589 }
00590 }
00591
00592 BOOL LLTemplateMessageBuilder::isMessageFull(const char* blockname) const
00593 {
00594 if(mCurrentSendTotal > MTUBYTES)
00595 {
00596 return TRUE;
00597 }
00598 if(!blockname)
00599 {
00600 return FALSE;
00601 }
00602 char* bnamep = (char*)blockname;
00603 S32 max;
00604
00605 const LLMessageBlock* template_data = mCurrentSMessageTemplate->getBlock(bnamep);
00606
00607 switch(template_data->mType)
00608 {
00609 case MBT_SINGLE:
00610 max = 1;
00611 break;
00612 case MBT_MULTIPLE:
00613 max = template_data->mNumber;
00614 break;
00615 case MBT_VARIABLE:
00616 default:
00617 max = MAX_BLOCKS;
00618 break;
00619 }
00620 if(mCurrentSMessageData->mMemberBlocks[bnamep]->mBlockNumber >= max)
00621 {
00622 return TRUE;
00623 }
00624 return FALSE;
00625 }
00626
00627 static S32 buildBlock(U8* buffer, S32 buffer_size, const LLMessageBlock* template_data, LLMsgData* message_data)
00628 {
00629 S32 result = 0;
00630 LLMsgData::msg_blk_data_map_t::const_iterator block_iter = message_data->mMemberBlocks.find(template_data->mName);
00631 const LLMsgBlkData* mbci = block_iter->second;
00632
00633
00634
00635
00636 S32 block_count = mbci->mBlockNumber;
00637 if (template_data->mType == MBT_VARIABLE)
00638 {
00639
00640 U8 temp_block_number = (U8)mbci->mBlockNumber;
00641 if ((S32)(result + sizeof(U8)) < MAX_BUFFER_SIZE)
00642 {
00643 memcpy(&buffer[result], &temp_block_number, sizeof(U8));
00644 result += sizeof(U8);
00645 }
00646 else
00647 {
00648
00649
00650
00651 llerrs << "buildBlock failed. Message excedding "
00652 << "sendBuffersize." << llendl;
00653 }
00654 }
00655 else if (template_data->mType == MBT_MULTIPLE)
00656 {
00657 if (block_count != template_data->mNumber)
00658 {
00659
00660 llerrs << "Block " << mbci->mName
00661 << " is type MBT_MULTIPLE but only has data for "
00662 << block_count << " out of its "
00663 << template_data->mNumber << " blocks" << llendl;
00664 }
00665 }
00666
00667 while(block_count > 0)
00668 {
00669
00670 for (LLMsgBlkData::msg_var_data_map_t::const_iterator iter = mbci->mMemberVarData.begin();
00671 iter != mbci->mMemberVarData.end(); iter++)
00672 {
00673 const LLMsgVarData& mvci = *iter;
00674 if (mvci.getSize() == -1)
00675 {
00676
00677 llerrs << "The variable " << mvci.getName() << " in block "
00678 << mbci->mName << " of message "
00679 << template_data->mName
00680 << " wasn't set prior to buildMessage call" << llendl;
00681 }
00682 else
00683 {
00684 S32 data_size = mvci.getDataSize();
00685 if(data_size > 0)
00686 {
00687
00688
00689
00690 S32 size = mvci.getSize();
00691 U8 sizeb;
00692 U16 sizeh;
00693 switch(data_size)
00694 {
00695 case 1:
00696 sizeb = size;
00697 htonmemcpy(&buffer[result], &sizeb, MVT_U8, 1);
00698 break;
00699 case 2:
00700 sizeh = size;
00701 htonmemcpy(&buffer[result], &sizeh, MVT_U16, 2);
00702 break;
00703 case 4:
00704 htonmemcpy(&buffer[result], &size, MVT_S32, 4);
00705 break;
00706 default:
00707 llerrs << "Attempting to build variable field with unknown size of " << size << llendl;
00708 break;
00709 }
00710 result += mvci.getDataSize();
00711 }
00712
00713
00714 if((mvci.getData() != NULL) && mvci.getSize())
00715 {
00716 if(result + mvci.getSize() < buffer_size)
00717 {
00718 memcpy(
00719 &buffer[result],
00720 mvci.getData(),
00721 mvci.getSize());
00722 result += mvci.getSize();
00723 }
00724 else
00725 {
00726
00727
00728
00729 llerrs << "buildBlock failed. "
00730 << "Attempted to pack "
00731 << result + mvci.getSize()
00732 << " bytes into a buffer with size "
00733 << buffer_size << "." << llendl
00734 }
00735 }
00736 }
00737 }
00738
00739 --block_count;
00740 ++block_iter;
00741 if (block_iter != message_data->mMemberBlocks.end())
00742 {
00743 mbci = block_iter->second;
00744 }
00745 }
00746
00747 return result;
00748 }
00749
00750
00751
00752 U32 LLTemplateMessageBuilder::buildMessage(
00753 U8* buffer,
00754 U32 buffer_size,
00755 U8 offset_to_data)
00756 {
00757
00758
00759
00760
00761
00762 if (!mCurrentSMessageTemplate)
00763 {
00764 llerrs << "newMessage not called prior to buildMessage" << llendl;
00765 return 0;
00766 }
00767
00768
00769
00770 buffer[PHL_OFFSET] = offset_to_data;
00771 U32 result = LL_PACKET_ID_SIZE;
00772
00773
00774 if (mCurrentSMessageTemplate->mFrequency == MFT_HIGH)
00775 {
00776
00777
00778
00779
00780 buffer[result] = (U8)mCurrentSMessageTemplate->mMessageNumber;
00781 result += sizeof(U8);
00782 }
00783 else if (mCurrentSMessageTemplate->mFrequency == MFT_MEDIUM)
00784 {
00785 U8 temp = 255;
00786 memcpy(&buffer[result], &temp, sizeof(U8));
00787 result += sizeof(U8);
00788
00789
00790 temp = mCurrentSMessageTemplate->mMessageNumber & 255;
00791 memcpy(&buffer[result], &temp, sizeof(U8));
00792 result += sizeof(U8);
00793 }
00794 else if (mCurrentSMessageTemplate->mFrequency == MFT_LOW)
00795 {
00796 U8 temp = 255;
00797 U16 message_num;
00798 memcpy(&buffer[result], &temp, sizeof(U8));
00799 result += sizeof(U8);
00800 memcpy(&buffer[result], &temp, sizeof(U8));
00801 result += sizeof(U8);
00802
00803
00804 message_num = mCurrentSMessageTemplate->mMessageNumber & 0xFFFF;
00805
00806
00807 message_num = htons(message_num);
00808 memcpy(&buffer[result], &message_num, sizeof(U16));
00809 result += sizeof(U16);
00810 }
00811 else
00812 {
00813 llerrs << "unexpected message frequency in buildMessage" << llendl;
00814 return 0;
00815 }
00816
00817
00818 result += offset_to_data;
00819 for(LLMessageTemplate::message_block_map_t::const_iterator
00820 iter = mCurrentSMessageTemplate->mMemberBlocks.begin(),
00821 end = mCurrentSMessageTemplate->mMemberBlocks.end();
00822 iter != end;
00823 ++iter)
00824 {
00825 result += buildBlock(buffer + result, buffer_size - result, *iter, mCurrentSMessageData);
00826 }
00827 mbSBuilt = TRUE;
00828
00829 return result;
00830 }
00831
00832 void LLTemplateMessageBuilder::copyFromMessageData(const LLMsgData& data)
00833 {
00834
00835
00836 S32 block_count = 0;
00837 char *block_name = NULL;
00838
00839
00840
00841 LLMsgData::msg_blk_data_map_t::const_iterator iter =
00842 data.mMemberBlocks.begin();
00843 LLMsgData::msg_blk_data_map_t::const_iterator end =
00844 data.mMemberBlocks.end();
00845 for(; iter != end; ++iter)
00846 {
00847 const LLMsgBlkData* mbci = iter->second;
00848 if(!mbci) continue;
00849
00850
00851 if (block_count == 0)
00852 {
00853 block_count = mbci->mBlockNumber;
00854 block_name = (char *)mbci->mName;
00855 }
00856
00857
00858 block_count--;
00859
00860 nextBlock(block_name);
00861
00862
00863 LLMsgBlkData::msg_var_data_map_t::const_iterator dit = mbci->mMemberVarData.begin();
00864 LLMsgBlkData::msg_var_data_map_t::const_iterator dend = mbci->mMemberVarData.end();
00865
00866 for(; dit != dend; ++dit)
00867 {
00868 const LLMsgVarData& mvci = *dit;
00869 addData(mvci.getName(), mvci.getData(), mvci.getType(), mvci.getSize());
00870 }
00871 }
00872 }
00873
00874
00875 void LLTemplateMessageBuilder::copyFromLLSD(const LLSD&)
00876 {
00877
00878 }
00879
00880
00881 void LLTemplateMessageBuilder::setBuilt(BOOL b) { mbSBuilt = b; }
00882
00883
00884 BOOL LLTemplateMessageBuilder::isBuilt() const {return mbSBuilt;}
00885
00886
00887 BOOL LLTemplateMessageBuilder::isClear() const {return mbSClear;}
00888
00889
00890 S32 LLTemplateMessageBuilder::getMessageSize() {return mCurrentSendTotal;}
00891
00892
00893 const char* LLTemplateMessageBuilder::getMessageName() const
00894 {
00895 return mCurrentSMessageName;
00896 }