00001
00033 #include "linden_common.h"
00034 #include "llmessagetemplateparser.h"
00035 #include "lltut.h"
00036
00037 namespace tut
00038 {
00039 struct LLMessageTemplateParserTestData {
00040 LLMessageTemplateParserTestData() : mMessage("unset message")
00041 {
00042 }
00043
00044 ~LLMessageTemplateParserTestData()
00045 {
00046 }
00047
00048 void ensure_next(LLTemplateTokenizer & tokens,
00049 std::string value,
00050 U32 line)
00051 {
00052 std::string next = tokens.next();
00053 ensure_equals(mMessage + " token matches", next, value);
00054 ensure_equals(mMessage + " line matches", tokens.line(), line);
00055 }
00056
00057 char * prehash(const char * name)
00058 {
00059 return gMessageStringTable.getString(name);
00060 }
00061
00062 void ensure_block_attributes(std::string identifier,
00063 const LLMessageTemplate * message,
00064 const char * name,
00065 EMsgBlockType type,
00066 S32 number,
00067 S32 total_size)
00068 {
00069 const LLMessageBlock * block = message->getBlock(prehash(name));
00070 identifier = identifier + ":" + message->mName + ":" + name + " block";
00071 ensure(identifier + " exists", block != NULL);
00072 ensure_equals(identifier + " name", block->mName, prehash(name));
00073 ensure_equals(identifier + " type", block->mType, type);
00074 ensure_equals(identifier + " number", block->mNumber, number);
00075 ensure_equals(identifier + " total size", block->mTotalSize, total_size);
00076 }
00077
00078 void ensure_variable_attributes(std::string identifier,
00079 const LLMessageBlock * block,
00080 const char * name,
00081 EMsgVariableType type,
00082 S32 size)
00083 {
00084 const LLMessageVariable * var = block->getVariable(prehash(name));
00085 identifier = identifier + ":" + block->mName + ":" + name + " variable";
00086 ensure(identifier + " exists", var != NULL);
00087 ensure_equals(
00088 identifier + " name", var->getName(), prehash(name));
00089 ensure_equals(
00090 identifier + " type", var->getType(), type);
00091 ensure_equals(identifier + " size", var->getSize(), size);
00092 }
00093
00094 std::string mMessage;
00095
00096 };
00097
00098 typedef test_group<LLMessageTemplateParserTestData> LLMessageTemplateParserTestGroup;
00099 typedef LLMessageTemplateParserTestGroup::object LLMessageTemplateParserTestObject;
00100 LLMessageTemplateParserTestGroup llMessageTemplateParserTestGroup("LLMessageTemplateParser");
00101
00102 template<> template<>
00103 void LLMessageTemplateParserTestObject::test<1>()
00104
00105 {
00106 mMessage = "test method 1 walkthrough";
00107 LLTemplateTokenizer tokens("first line\nnext\t line\n\nfourth");
00108 ensure_next(tokens, "first", 1);
00109 ensure_next(tokens, "line", 1);
00110 ensure_next(tokens, "next", 2);
00111 ensure_next(tokens, "line", 2);
00112 ensure_next(tokens, "fourth", 4);
00113
00114 tokens = LLTemplateTokenizer("\n\t{ \t Test1 Fixed \n 523 }\n\n");
00115 ensure(tokens.want("{"));
00116 ensure_next(tokens, "Test1", 2);
00117 ensure_next(tokens, "Fixed", 2);
00118 ensure_next(tokens, "523", 3);
00119 ensure(tokens.want("}"));
00120
00121 tokens = LLTemplateTokenizer("first line\nnext\t line\n\nfourth");
00122 ensure(tokens.want("first"));
00123 ensure_next(tokens, "line", 1);
00124 ensure_next(tokens, "next", 2);
00125 ensure_next(tokens, "line", 2);
00126 ensure(tokens.want("fourth"));
00127 }
00128
00129 template<> template<>
00130 void LLMessageTemplateParserTestObject::test<2>()
00131
00132 {
00133
00134 LLTemplateTokenizer tokens("first line\nnext\t line\n\nfourth");
00135 ensure_equals("wants first token", tokens.want("first"), true);
00136 ensure_equals("doesn't want blar token", tokens.want("blar"), false);
00137 ensure_equals("wants line token", tokens.want("line"), true);
00138 }
00139
00140 template<> template<>
00141 void LLMessageTemplateParserTestObject::test<3>()
00142
00143 {
00144 LLTemplateTokenizer tokens("single\n\n");
00145 ensure_equals("is not at eof at beginning", tokens.atEOF(), false);
00146 ensure_equals("doesn't want eof", tokens.wantEOF(), false);
00147 ensure_equals("wants the first token just to consume it",
00148 tokens.want("single"), true);
00149 ensure_equals("is not at eof in middle", tokens.atEOF(), false);
00150 ensure_equals("wants eof", tokens.wantEOF(), true);
00151 ensure_equals("is at eof at end", tokens.atEOF(), true);
00152 }
00153
00154 template<> template<>
00155 void LLMessageTemplateParserTestObject::test<4>()
00156
00157 {
00158 LLTemplateTokenizer tokens(std::string("{ Test0 \n\t\n U32 \n\n }"));
00159 LLMessageVariable * var = LLTemplateParser::parseVariable(tokens);
00160
00161 ensure("test0 var parsed", var != 0);
00162 ensure_equals("name of variable", std::string(var->getName()), std::string("Test0"));
00163 ensure_equals("type of variable is U32", var->getType(), MVT_U32);
00164 ensure_equals("size of variable", var->getSize(), 4);
00165
00166 delete var;
00167
00168 std::string message_string("\n\t{ \t Test1 Fixed \n 523 }\n\n");
00169 tokens = LLTemplateTokenizer(message_string);
00170 var = LLTemplateParser::parseVariable(tokens);
00171
00172 ensure("test1 var parsed", var != 0);
00173 ensure_equals("name of variable", std::string(var->getName()), std::string("Test1"));
00174 ensure_equals("type of variable is Fixed", var->getType(), MVT_FIXED);
00175 ensure_equals("size of variable", var->getSize(), 523);
00176
00177 delete var;
00178
00179
00180
00181 }
00182
00183 template<> template<>
00184 void LLMessageTemplateParserTestObject::test<5>()
00185
00186 {
00187 LLTemplateTokenizer tokens("{ BlockA Single { VarX F32 } }");
00188 LLMessageBlock * block = LLTemplateParser::parseBlock(tokens);
00189
00190 ensure("blockA block parsed", block != 0);
00191 ensure_equals("name of block", std::string(block->mName), std::string("BlockA"));
00192 ensure_equals("type of block is Single", block->mType, MBT_SINGLE);
00193 ensure_equals("total size of block", block->mTotalSize, 4);
00194 ensure_equals("number of block defaults to 1", block->mNumber, 1);
00195 ensure_equals("variable type of VarX is F32",
00196 block->getVariableType(prehash("VarX")), MVT_F32);
00197 ensure_equals("variable size of VarX",
00198 block->getVariableSize(prehash("VarX")), 4);
00199
00200 delete block;
00201
00202 tokens = LLTemplateTokenizer("{ Stuff Variable { Id LLUUID } }");
00203 block = LLTemplateParser::parseBlock(tokens);
00204
00205 ensure("stuff block parsed", block != 0);
00206 ensure_equals("name of block", std::string(block->mName), std::string("Stuff"));
00207 ensure_equals("type of block is Multiple", block->mType, MBT_VARIABLE);
00208 ensure_equals("total size of block", block->mTotalSize, 16);
00209 ensure_equals("number of block defaults to 1", block->mNumber, 1);
00210 ensure_equals("variable type of Id is LLUUID",
00211 block->getVariableType(prehash("Id")), MVT_LLUUID);
00212 ensure_equals("variable size of Id",
00213 block->getVariableSize(prehash("Id")), 16);
00214
00215 delete block;
00216
00217 tokens = LLTemplateTokenizer("{ Stuff2 Multiple 45 { Shid LLVector3d } }");
00218 block = LLTemplateParser::parseBlock(tokens);
00219
00220 ensure("stuff2 block parsed", block != 0);
00221 ensure_equals("name of block", std::string(block->mName), std::string("Stuff2"));
00222 ensure_equals("type of block is Multiple", block->mType, MBT_MULTIPLE);
00223 ensure_equals("total size of block", block->mTotalSize, 24);
00224 ensure_equals("number of blocks", block->mNumber, 45);
00225 ensure_equals("variable type of Shid is Vector3d",
00226 block->getVariableType(prehash("Shid")), MVT_LLVector3d);
00227 ensure_equals("variable size of Shid",
00228 block->getVariableSize(prehash("Shid")), 24);
00229
00230 delete block;
00231 }
00232
00233 template<> template<>
00234 void LLMessageTemplateParserTestObject::test<6>()
00235
00236 {
00237 std::string message_skel(
00238 "{\n"
00239 "TestMessage Low 1 NotTrusted Zerocoded\n"
00240 "// comment \n"
00241 " {\n"
00242 "TestBlock1 Single\n"
00243 " { Test1 U32 }\n"
00244 " }\n"
00245 " {\n"
00246 " NeighborBlock Multiple 4\n"
00247 " { Test0 U32 }\n"
00248 " { Test1 U32 }\n"
00249 " { Test2 U32 }\n"
00250 " }\n"
00251 "}");
00252 LLTemplateTokenizer tokens(message_skel);
00253 LLMessageTemplate * message = LLTemplateParser::parseMessage(tokens);
00254
00255 ensure("simple message parsed", message != 0);
00256 ensure_equals("name of message", std::string(message->mName), std::string("TestMessage"));
00257 ensure_equals("frequency is Low", message->mFrequency, MFT_LOW);
00258 ensure_equals("trust is untrusted", message->mTrust, MT_NOTRUST);
00259 ensure_equals("message number", message->mMessageNumber, (U32)((255 << 24) | (255 << 16) | 1));
00260 ensure_equals("message encoding is zerocoded", message->mEncoding, ME_ZEROCODED);
00261 ensure_equals("message deprecation is notdeprecated", message->mDeprecation, MD_NOTDEPRECATED);
00262
00263 LLMessageBlock * block = message->getBlock(prehash("NonexistantBlock"));
00264 ensure("Nonexistant block does not exist", block == 0);
00265
00266 delete message;
00267 }
00268
00269 template<> template<>
00270 void LLMessageTemplateParserTestObject::test<7>()
00271
00272 {
00273 std::string message_skel(
00274 "{\n"
00275 "TestMessageDeprecated High 34 Trusted Unencoded Deprecated\n"
00276 " {\n"
00277 "TestBlock2 Single\n"
00278 " { Test2 S32 }\n"
00279 " }\n"
00280 "}");
00281 LLTemplateTokenizer tokens(message_skel);
00282 LLMessageTemplate * message = LLTemplateParser::parseMessage(tokens);
00283
00284 ensure("deprecated message parsed", message != 0);
00285 ensure_equals("name of message", std::string(message->mName), std::string("TestMessageDeprecated"));
00286 ensure_equals("frequency is High", message->mFrequency, MFT_HIGH);
00287 ensure_equals("trust is trusted", message->mTrust, MT_TRUST);
00288 ensure_equals("message number", message->mMessageNumber, (U32)34);
00289 ensure_equals("message encoding is unencoded", message->mEncoding, ME_UNENCODED);
00290 ensure_equals("message deprecation is deprecated", message->mDeprecation, MD_DEPRECATED);
00291
00292 delete message;
00293 }
00294
00295 void LLMessageTemplateParserTestObject::test<8>()
00296
00297 {
00298 std::string message_skel(
00299 "{\n\
00300 RezMultipleAttachmentsFromInv Low 452 NotTrusted Zerocoded\n\
00301 {\n\
00302 AgentData Single\n\
00303 { AgentID LLUUID }\n\
00304 { SessionID LLUUID }\n\
00305 } \n\
00306 {\n\
00307 HeaderData Single\n\
00308 { CompoundMsgID LLUUID } // All messages a single \"compound msg\" must have the same id\n\
00309 { TotalObjects U8 }\n\
00310 { FirstDetachAll BOOL }\n\
00311 }\n\
00312 {\n\
00313 ObjectData Variable // 1 to 4 of these per packet\n\
00314 { ItemID LLUUID }\n\
00315 { OwnerID LLUUID }\n\
00316 { AttachmentPt U8 } // 0 for default\n\
00317 { ItemFlags U32 }\n\
00318 { GroupMask U32 }\n\
00319 { EveryoneMask U32 }\n\
00320 { NextOwnerMask U32 }\n\
00321 { Name Variable 1 }\n\
00322 { Description Variable 1 }\n\
00323 }\n\
00324 }\n\
00325 ");
00326 LLTemplateTokenizer tokens(message_skel);
00327 LLMessageTemplate * message = LLTemplateParser::parseMessage(tokens);
00328
00329 ensure("RezMultipleAttachmentsFromInv message parsed", message != 0);
00330 ensure_equals("name of message", message->mName, prehash("RezMultipleAttachmentsFromInv"));
00331 ensure_equals("frequency is low", message->mFrequency, MFT_LOW);
00332 ensure_equals("trust is not trusted", message->mTrust, MT_NOTRUST);
00333 ensure_equals("message number", message->mMessageNumber, (U32)((255 << 24) | (255 << 16) | 452));
00334 ensure_equals("message encoding is zerocoded", message->mEncoding, ME_ZEROCODED);
00335
00336 ensure_block_attributes(
00337 "RMAFI", message, "AgentData", MBT_SINGLE, 1, 16+16);
00338 LLMessageBlock * block = message->getBlock(prehash("AgentData"));
00339 ensure_variable_attributes("RMAFI",
00340 block, "AgentID", MVT_LLUUID, 16);
00341 ensure_variable_attributes("RMAFI",
00342 block, "SessionID", MVT_LLUUID, 16);
00343
00344 ensure_block_attributes(
00345 "RMAFI", message, "HeaderData", MBT_SINGLE, 1, 16+1+1);
00346 block = message->getBlock(prehash("HeaderData"));
00347 ensure_variable_attributes(
00348 "RMAFI", block, "CompoundMsgID", MVT_LLUUID, 16);
00349 ensure_variable_attributes(
00350 "RMAFI", block, "TotalObjects", MVT_U8, 1);
00351 ensure_variable_attributes(
00352 "RMAFI", block, "FirstDetachAll", MVT_BOOL, 1);
00353
00354
00355 ensure_block_attributes(
00356 "RMAFI", message, "ObjectData", MBT_VARIABLE, 1, -1);
00357 block = message->getBlock(prehash("ObjectData"));
00358 ensure_variable_attributes("RMAFI", block, "ItemID", MVT_LLUUID, 16);
00359 ensure_variable_attributes("RMAFI", block, "OwnerID", MVT_LLUUID, 16);
00360 ensure_variable_attributes("RMAFI", block, "AttachmentPt", MVT_U8, 1);
00361 ensure_variable_attributes("RMAFI", block, "ItemFlags", MVT_U32, 4);
00362 ensure_variable_attributes("RMAFI", block, "GroupMask", MVT_U32, 4);
00363 ensure_variable_attributes("RMAFI", block, "EveryoneMask", MVT_U32, 4);
00364 ensure_variable_attributes("RMAFI", block, "NextOwnerMask", MVT_U32, 4);
00365 ensure_variable_attributes("RMAFI", block, "Name", MVT_VARIABLE, 1);
00366 ensure_variable_attributes("RMAFI", block, "Description", MVT_VARIABLE, 1);
00367
00368 delete message;
00369 }
00370
00371
00372
00373 }