PageRenderTime 84ms CodeModel.GetById 1ms app.highlight 75ms RepoModel.GetById 1ms app.codeStats 1ms

/indra/test/lltemplatemessagebuilder_tut.cpp

https://bitbucket.org/lindenlab/viewer-beta/
C++ | 971 lines | 790 code | 83 blank | 98 comment | 3 complexity | f1b7ead1fc25863e91c39b463891db91 MD5 | raw file
  1/**
  2 * @file lltemplatemessagebuilder_tut.cpp
  3 * @date 2007-04
  4 * @brief Tests for building messages.
  5 *
  6 * $LicenseInfo:firstyear=2007&license=viewerlgpl$
  7 * Second Life Viewer Source Code
  8 * Copyright (C) 2010, Linden Research, Inc.
  9 * 
 10 * This library is free software; you can redistribute it and/or
 11 * modify it under the terms of the GNU Lesser General Public
 12 * License as published by the Free Software Foundation;
 13 * version 2.1 of the License only.
 14 * 
 15 * This library is distributed in the hope that it will be useful,
 16 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 17 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
 18 * Lesser General Public License for more details.
 19 * 
 20 * You should have received a copy of the GNU Lesser General Public
 21 * License along with this library; if not, write to the Free Software
 22 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA
 23 * 
 24 * Linden Research, Inc., 945 Battery Street, San Francisco, CA  94111  USA
 25 * $/LicenseInfo$
 26 */
 27
 28#include <tut/tut.hpp>
 29#include "linden_common.h"
 30#include "lltut.h"
 31
 32#include "llapr.h"
 33#include "llmessagetemplate.h"
 34#include "llmath.h"
 35#include "llquaternion.h"
 36#include "lltemplatemessagebuilder.h"
 37#include "lltemplatemessagereader.h"
 38#include "llversionserver.h"
 39#include "message_prehash.h"
 40#include "u64.h"
 41#include "v3dmath.h"
 42#include "v3math.h"
 43#include "v4math.h"
 44
 45namespace tut
 46{	
 47	static LLTemplateMessageBuilder::message_template_name_map_t nameMap;
 48	static LLTemplateMessageReader::message_template_number_map_t numberMap;
 49
 50	struct LLTemplateMessageBuilderTestData 
 51	{
 52		static LLMessageTemplate defaultTemplate()
 53		{
 54			static bool init = false;
 55			if(! init)
 56			{
 57				ll_init_apr();
 58				const F32 circuit_heartbeat_interval=5;
 59				const F32 circuit_timeout=100;
 60
 61				start_messaging_system("notafile", 13035,
 62									   LL_VERSION_MAJOR,
 63									   LL_VERSION_MINOR,        
 64									   LL_VERSION_PATCH,        
 65									   FALSE,        
 66									   "notasharedsecret",
 67									   NULL,
 68									   false,
 69									   circuit_heartbeat_interval,
 70									   circuit_timeout);
 71				//init_prehash_data();
 72				init = true;
 73			}
 74			return LLMessageTemplate(_PREHASH_TestMessage, 1, MFT_HIGH);
 75		}
 76
 77		static LLMessageBlock* defaultBlock(const EMsgVariableType type = MVT_NULL, const S32 size = 0, EMsgBlockType block = MBT_VARIABLE)
 78		{
 79			return createBlock(const_cast<char*>(_PREHASH_Test0), type, size, block);
 80		}
 81
 82		static LLMessageBlock* createBlock(char* name, const EMsgVariableType type = MVT_NULL, const S32 size = 0, EMsgBlockType block = MBT_VARIABLE)
 83		{
 84			LLMessageBlock* result = new LLMessageBlock(name, block);
 85			if(type != MVT_NULL)
 86			{
 87				result->addVariable(const_cast<char*>(_PREHASH_Test0), type, size);
 88			}
 89			return result;
 90		}
 91
 92		static LLTemplateMessageBuilder* defaultBuilder(LLMessageTemplate& messageTemplate, char* name = const_cast<char*>(_PREHASH_Test0))
 93		{
 94			nameMap[_PREHASH_TestMessage] = &messageTemplate;
 95			LLTemplateMessageBuilder* builder = new LLTemplateMessageBuilder(nameMap);
 96			builder->newMessage(_PREHASH_TestMessage);
 97			builder->nextBlock(name);
 98			return builder;
 99		}
100
101		/** Takes ownership of builder */
102		static LLTemplateMessageReader* setReader(
103			LLMessageTemplate& messageTemplate,
104			LLTemplateMessageBuilder* builder,
105			U8 offset = 0)
106		{
107			numberMap[1] = &messageTemplate;
108			const U32 bufferSize = 1024;
109			U8 buffer[bufferSize];
110			// zero out the packet ID field
111			memset(buffer, 0, LL_PACKET_ID_SIZE);
112			U32 builtSize = builder->buildMessage(buffer, bufferSize, offset);
113			delete builder;
114			LLTemplateMessageReader* reader = new LLTemplateMessageReader(numberMap);
115			reader->validateMessage(buffer, builtSize, LLHost());
116			reader->readMessage(buffer, LLHost());
117			return reader;
118		}
119
120	};
121	
122	typedef test_group<LLTemplateMessageBuilderTestData>	LLTemplateMessageBuilderTestGroup;
123	typedef LLTemplateMessageBuilderTestGroup::object		LLTemplateMessageBuilderTestObject;
124	LLTemplateMessageBuilderTestGroup templateMessageBuilderTestGroup("LLTemplateMessageBuilder");
125	
126	template<> template<>
127	void LLTemplateMessageBuilderTestObject::test<1>()
128		// construction and test of undefined
129	{
130		LLMessageTemplate messageTemplate = defaultTemplate();
131		messageTemplate.addBlock(defaultBlock());
132		LLTemplateMessageBuilder* builder = defaultBuilder(messageTemplate);
133		LLTemplateMessageReader* reader = setReader(messageTemplate, builder);
134		delete reader;
135	}
136	
137	template<> template<>
138	void LLTemplateMessageBuilderTestObject::test<2>()
139		 // BOOL
140	{
141		LLMessageTemplate messageTemplate = defaultTemplate();
142		messageTemplate.addBlock(defaultBlock(MVT_BOOL, 1));
143		BOOL outValue, inValue = TRUE;
144		LLTemplateMessageBuilder* builder = defaultBuilder(messageTemplate);
145		builder->addBOOL(_PREHASH_Test0, inValue);
146		LLTemplateMessageReader* reader = setReader(messageTemplate, builder);
147		reader->getBOOL(_PREHASH_Test0, _PREHASH_Test0, outValue);
148		ensure_equals("Ensure BOOL", inValue, outValue);
149		delete reader;
150	}
151
152	template<> template<>
153	void LLTemplateMessageBuilderTestObject::test<3>()
154		 // U8
155	{
156		LLMessageTemplate messageTemplate = defaultTemplate();
157		messageTemplate.addBlock(defaultBlock(MVT_U8, 1));
158		U8 outValue, inValue = 2;
159		LLTemplateMessageBuilder* builder = defaultBuilder(messageTemplate);
160		builder->addU8(_PREHASH_Test0, inValue);
161		LLTemplateMessageReader* reader = setReader(messageTemplate, builder);
162		reader->getU8(_PREHASH_Test0, _PREHASH_Test0, outValue);
163		ensure_equals("Ensure U8", inValue, outValue);
164		delete reader;
165	}
166
167	template<> template<>
168	void LLTemplateMessageBuilderTestObject::test<4>()
169		 // S16
170	{
171		LLMessageTemplate messageTemplate = defaultTemplate();
172		messageTemplate.addBlock(defaultBlock(MVT_S16, 2));
173		S16 outValue, inValue = 90;
174		LLTemplateMessageBuilder* builder = defaultBuilder(messageTemplate);
175		builder->addS16(_PREHASH_Test0, inValue);
176		LLTemplateMessageReader* reader = setReader(messageTemplate, builder);
177		reader->getS16(_PREHASH_Test0, _PREHASH_Test0, outValue);
178		ensure_equals("Ensure S16", inValue, outValue);
179		delete reader;
180	}
181
182	template<> template<>
183	void LLTemplateMessageBuilderTestObject::test<5>()
184		 // U16
185	{
186		LLMessageTemplate messageTemplate = defaultTemplate();
187		messageTemplate.addBlock(defaultBlock(MVT_U16, 2));
188		U16 outValue, inValue = 3;
189		LLTemplateMessageBuilder* builder = defaultBuilder(messageTemplate);
190		builder->addU16(_PREHASH_Test0, inValue);
191		LLTemplateMessageReader* reader = setReader(messageTemplate, builder);
192		reader->getU16(_PREHASH_Test0, _PREHASH_Test0, outValue);
193		ensure_equals("Ensure U16", inValue, outValue);
194		delete reader;
195	}
196
197	template<> template<>
198	void LLTemplateMessageBuilderTestObject::test<6>()
199		 // S32
200	{
201		LLMessageTemplate messageTemplate = defaultTemplate();
202		messageTemplate.addBlock(defaultBlock(MVT_S32, 4));
203		S32 outValue, inValue = 44;
204		LLTemplateMessageBuilder* builder = defaultBuilder(messageTemplate);
205		builder->addS32(_PREHASH_Test0, inValue);
206		LLTemplateMessageReader* reader = setReader(messageTemplate, builder);
207		reader->getS32(_PREHASH_Test0, _PREHASH_Test0, outValue);
208		ensure_equals("Ensure S32", inValue, outValue);
209		delete reader;
210	}
211
212	template<> template<>
213	void LLTemplateMessageBuilderTestObject::test<7>()
214		 // F32
215	{
216		LLMessageTemplate messageTemplate = defaultTemplate();
217		messageTemplate.addBlock(defaultBlock(MVT_F32, 4));
218		F32 outValue, inValue = 121.44f;
219		LLTemplateMessageBuilder* builder = defaultBuilder(messageTemplate);
220		builder->addF32(_PREHASH_Test0, inValue);
221		LLTemplateMessageReader* reader = setReader(messageTemplate, builder);
222		reader->getF32(_PREHASH_Test0, _PREHASH_Test0, outValue);
223		ensure_equals("Ensure F32", inValue, outValue);
224		delete reader;
225	}
226
227	template<> template<>
228	void LLTemplateMessageBuilderTestObject::test<8>()
229		 // U32
230	{
231		LLMessageTemplate messageTemplate = defaultTemplate();
232		messageTemplate.addBlock(defaultBlock(MVT_U32, 4));
233		U32 outValue, inValue = 88;
234		LLTemplateMessageBuilder* builder = defaultBuilder(messageTemplate);
235		builder->addU32(_PREHASH_Test0, inValue);
236		LLTemplateMessageReader* reader = setReader(messageTemplate, builder);
237		reader->getU32(_PREHASH_Test0, _PREHASH_Test0, outValue);
238		ensure_equals("Ensure U32", inValue, outValue);
239		delete reader;
240	}
241
242	template<> template<>
243	void LLTemplateMessageBuilderTestObject::test<9>()
244		 // U64
245	{
246		LLMessageTemplate messageTemplate = defaultTemplate();
247		messageTemplate.addBlock(defaultBlock(MVT_U64, 8));
248		U64 outValue, inValue = 121;
249		LLTemplateMessageBuilder* builder = defaultBuilder(messageTemplate);
250		builder->addU64(_PREHASH_Test0, inValue);
251		LLTemplateMessageReader* reader = setReader(messageTemplate, builder);
252		reader->getU64(_PREHASH_Test0, _PREHASH_Test0, outValue);
253		ensure_equals("Ensure U64", inValue, outValue);
254		delete reader;
255	}
256
257	template<> template<>
258	void LLTemplateMessageBuilderTestObject::test<10>()
259		 // F64
260	{
261		LLMessageTemplate messageTemplate = defaultTemplate();
262		messageTemplate.addBlock(defaultBlock(MVT_F64, 8));
263		F64 outValue, inValue = 3232143.33;
264		LLTemplateMessageBuilder* builder = defaultBuilder(messageTemplate);
265		builder->addF64(_PREHASH_Test0, inValue);
266		LLTemplateMessageReader* reader = setReader(messageTemplate, builder);
267		reader->getF64(_PREHASH_Test0, _PREHASH_Test0, outValue);
268		ensure_equals("Ensure F64", inValue, outValue);
269		delete reader;
270	}
271
272	template<> template<>
273	void LLTemplateMessageBuilderTestObject::test<11>()
274		 // Vector3
275	{
276		LLMessageTemplate messageTemplate = defaultTemplate();
277		messageTemplate.addBlock(defaultBlock(MVT_LLVector3, 12));
278		LLVector3 outValue, inValue = LLVector3(1,2,3);
279		LLTemplateMessageBuilder* builder = defaultBuilder(messageTemplate);
280		builder->addVector3(_PREHASH_Test0, inValue);
281		LLTemplateMessageReader* reader = setReader(messageTemplate, builder);
282		reader->getVector3(_PREHASH_Test0, _PREHASH_Test0, outValue);
283		ensure_equals("Ensure LLVector3", inValue, outValue);
284		delete reader;
285	}
286
287	template<> template<>
288	void LLTemplateMessageBuilderTestObject::test<12>()
289		 // Vector4
290	{
291		LLMessageTemplate messageTemplate = defaultTemplate();
292		messageTemplate.addBlock(defaultBlock(MVT_LLVector4, 16));
293		LLVector4 outValue, inValue = LLVector4(1,2,3,4);
294		LLTemplateMessageBuilder* builder = defaultBuilder(messageTemplate);
295		builder->addVector4(_PREHASH_Test0, inValue);
296		LLTemplateMessageReader* reader = setReader(messageTemplate, builder);
297		reader->getVector4(_PREHASH_Test0, _PREHASH_Test0, outValue);
298		ensure_equals("Ensure LLVector4", inValue, outValue);
299		delete reader;
300	}
301
302	template<> template<>
303	void LLTemplateMessageBuilderTestObject::test<13>()
304		 // Vector3d
305	{
306		LLMessageTemplate messageTemplate = defaultTemplate();
307		messageTemplate.addBlock(defaultBlock(MVT_LLVector3d, 24));
308		LLVector3d outValue, inValue = LLVector3d(1,2,3);
309		LLTemplateMessageBuilder* builder = defaultBuilder(messageTemplate);
310		builder->addVector3d(_PREHASH_Test0, inValue);
311		LLTemplateMessageReader* reader = setReader(messageTemplate, builder);
312		reader->getVector3d(_PREHASH_Test0, _PREHASH_Test0, outValue);
313		ensure_equals("Ensure LLVector3d", inValue, outValue);
314		delete reader;
315	}
316
317	template<> template<>
318	void LLTemplateMessageBuilderTestObject::test<14>()
319		 // Quaternion
320	{
321		LLMessageTemplate messageTemplate = defaultTemplate();
322		messageTemplate.addBlock(defaultBlock(MVT_LLQuaternion, 12));
323		LLQuaternion outValue, inValue = LLQuaternion(1,2,3,0);
324		LLTemplateMessageBuilder* builder = defaultBuilder(messageTemplate);
325		builder->addQuat(_PREHASH_Test0, inValue);
326		LLTemplateMessageReader* reader = setReader(messageTemplate, builder);
327		reader->getQuat(_PREHASH_Test0, _PREHASH_Test0, outValue);
328		ensure_equals("Ensure LLQuaternion", inValue, outValue);
329		delete reader;
330	}
331
332	template<> template<>
333	void LLTemplateMessageBuilderTestObject::test<15>()
334		 // UUID
335	{
336		LLMessageTemplate messageTemplate = defaultTemplate();
337		messageTemplate.addBlock(defaultBlock(MVT_LLUUID, 16));
338		LLUUID outValue, inValue;
339		inValue.generate();
340		LLTemplateMessageBuilder* builder = defaultBuilder(messageTemplate);
341		builder->addUUID(_PREHASH_Test0, inValue);
342		LLTemplateMessageReader* reader = setReader(messageTemplate, builder);
343		reader->getUUID(_PREHASH_Test0, _PREHASH_Test0, outValue);
344		ensure_equals("Ensure UUID", inValue, outValue);
345		delete reader;
346	}
347
348	template<> template<>
349	void LLTemplateMessageBuilderTestObject::test<16>()
350		 // IPAddr
351	{
352		LLMessageTemplate messageTemplate = defaultTemplate();
353		messageTemplate.addBlock(defaultBlock(MVT_IP_ADDR, 4));
354		U32 outValue, inValue = 12344556;
355		LLTemplateMessageBuilder* builder = defaultBuilder(messageTemplate);
356		builder->addIPAddr(_PREHASH_Test0, inValue);
357		LLTemplateMessageReader* reader = setReader(messageTemplate, builder);
358		reader->getIPAddr(_PREHASH_Test0, _PREHASH_Test0, outValue);
359		ensure_equals("Ensure IPAddr", inValue, outValue);
360		delete reader;
361	}
362
363	 template<> template<>
364	void LLTemplateMessageBuilderTestObject::test<17>()
365		 // IPPort
366	{
367		LLMessageTemplate messageTemplate = defaultTemplate();
368		messageTemplate.addBlock(defaultBlock(MVT_IP_PORT, 2));
369		U16 outValue, inValue = 80;
370		LLTemplateMessageBuilder* builder = defaultBuilder(messageTemplate);
371		builder->addIPPort(_PREHASH_Test0, inValue);
372		LLTemplateMessageReader* reader = setReader(messageTemplate, builder);
373		reader->getIPPort(_PREHASH_Test0, _PREHASH_Test0, outValue);
374		ensure_equals("Ensure IPPort", inValue, outValue);
375		delete reader;
376	}
377
378	template<> template<>
379	void LLTemplateMessageBuilderTestObject::test<18>()
380		// String
381	{
382		LLMessageTemplate messageTemplate = defaultTemplate();
383		messageTemplate.addBlock(defaultBlock(MVT_VARIABLE, 1));
384		std::string outValue, inValue = "testing";
385		LLTemplateMessageBuilder* builder = defaultBuilder(messageTemplate);
386		builder->addString(_PREHASH_Test0, inValue.c_str());
387		LLTemplateMessageReader* reader = setReader(messageTemplate, builder);
388		char buffer[MAX_STRING];
389		reader->getString(_PREHASH_Test0, _PREHASH_Test0, MAX_STRING, buffer);
390		outValue = buffer;
391		ensure_equals("Ensure String", inValue, outValue);
392		delete reader;
393	}
394
395	template<> template<>
396	void LLTemplateMessageBuilderTestObject::test<19>()
397		// block name !-> binary order
398	{
399		U8 buffer1[MAX_BUFFER_SIZE];
400		memset(buffer1, 0, MAX_BUFFER_SIZE);
401		U8 buffer2[MAX_BUFFER_SIZE];
402		memset(buffer2, 0, MAX_BUFFER_SIZE);
403		U32 bufferSize1, bufferSize2;
404
405		// build template: Test0 before Test1
406		LLMessageTemplate messageTemplate = defaultTemplate();
407		messageTemplate.addBlock(createBlock(const_cast<char*>(_PREHASH_Test0), MVT_U32, 4, MBT_SINGLE));
408		messageTemplate.addBlock(createBlock(const_cast<char*>(_PREHASH_Test1), MVT_U32, 4, MBT_SINGLE));
409
410		// build message: 1st declared block var == 0xaaaa, 2nd declared block var == 0xbbbb
411		LLTemplateMessageBuilder* builder = defaultBuilder(messageTemplate, const_cast<char*>(_PREHASH_Test0));
412		builder->addU32(_PREHASH_Test0, 0xaaaa);
413		builder->nextBlock(_PREHASH_Test1);
414		builder->addU32(_PREHASH_Test0, 0xbbbb);
415		bufferSize1 = builder->buildMessage(buffer1, MAX_BUFFER_SIZE, 0);
416		delete builder;
417
418		// build template: Test1 before Test0
419		messageTemplate = defaultTemplate();
420		messageTemplate.addBlock(createBlock(const_cast<char*>(_PREHASH_Test1), MVT_U32, 4, MBT_SINGLE));
421		messageTemplate.addBlock(createBlock(const_cast<char*>(_PREHASH_Test0), MVT_U32, 4, MBT_SINGLE));
422
423		// build message: 1st declared block var == 0xaaaa, 2nd declared block var == 0xbbbb
424		builder = defaultBuilder(messageTemplate, const_cast<char*>(_PREHASH_Test1));
425		builder->addU32(_PREHASH_Test0, 0xaaaa);
426		builder->nextBlock(_PREHASH_Test0);
427		builder->addU32(_PREHASH_Test0, 0xbbbb);
428		bufferSize2 = builder->buildMessage(buffer2, MAX_BUFFER_SIZE, 0);
429		delete builder;
430
431		ensure_equals("Ensure Buffer Sizes Equal", bufferSize1, bufferSize2);
432		ensure_equals("Ensure Buffer Contents Equal", memcmp(buffer1, buffer2, bufferSize1), 0);
433	}
434
435	template<> template<>
436	void LLTemplateMessageBuilderTestObject::test<20>()
437		// block build order !-> binary order
438	{
439		U8 buffer1[MAX_BUFFER_SIZE];
440		memset(buffer1, 0, MAX_BUFFER_SIZE);
441		U8 buffer2[MAX_BUFFER_SIZE];
442		memset(buffer2, 0, MAX_BUFFER_SIZE);
443		U32 bufferSize1, bufferSize2;
444
445		// build template: Test0 before Test1
446		LLMessageTemplate messageTemplate = defaultTemplate();
447		messageTemplate.addBlock(createBlock(const_cast<char*>(_PREHASH_Test0), MVT_U32, 4, MBT_SINGLE));
448		messageTemplate.addBlock(createBlock(const_cast<char*>(_PREHASH_Test1), MVT_U32, 4, MBT_SINGLE));
449
450		// build message: 1st declared block var == 0xaaaa, 2nd declared block var == 0xbbbb
451		LLTemplateMessageBuilder* builder = defaultBuilder(messageTemplate, const_cast<char*>(_PREHASH_Test0));
452		builder->addU32(_PREHASH_Test0, 0xaaaa);
453		builder->nextBlock(_PREHASH_Test1);
454		builder->addU32(_PREHASH_Test0, 0xbbbb);
455		bufferSize1 = builder->buildMessage(buffer1, MAX_BUFFER_SIZE, 0);
456		delete builder;
457
458		// build message: 1st declared block var == 0xaaaa, 2nd declared block var == 0xbbbb
459		builder = defaultBuilder(messageTemplate, const_cast<char*>(_PREHASH_Test1));
460		builder->addU32(_PREHASH_Test0, 0xbbbb);
461		builder->nextBlock(_PREHASH_Test0);
462		builder->addU32(_PREHASH_Test0, 0xaaaa);
463		bufferSize2 = builder->buildMessage(buffer2, MAX_BUFFER_SIZE, 0);
464		delete builder;
465
466		ensure_equals("Ensure Buffer Sizes Equal", bufferSize1, bufferSize2);
467		ensure_equals("Ensure Buffer Contents Equal", memcmp(buffer1, buffer2, bufferSize1), 0);
468	}
469
470	template<> template<>
471	void LLTemplateMessageBuilderTestObject::test<21>()
472		// block appended in declaration -> data appended in binary
473	{
474		U8 buffer1[MAX_BUFFER_SIZE];
475		memset(buffer1, 0, MAX_BUFFER_SIZE);
476		U8 buffer2[MAX_BUFFER_SIZE];
477		memset(buffer2, 0, MAX_BUFFER_SIZE);
478		U32 bufferSize1, bufferSize2;
479
480		// Build template: Test0 only
481		LLMessageTemplate messageTemplate = defaultTemplate();
482		messageTemplate.addBlock(createBlock(const_cast<char*>(_PREHASH_Test0), MVT_U32, 4, MBT_SINGLE));
483
484		// Build message
485		LLTemplateMessageBuilder* builder = defaultBuilder(messageTemplate, const_cast<char*>(_PREHASH_Test0));
486		builder->addU32(_PREHASH_Test0, 0xaaaa);
487		bufferSize1 = builder->buildMessage(buffer1, MAX_BUFFER_SIZE, 0);
488		delete builder;
489
490		// Build template: Test0 before Test1
491		messageTemplate = defaultTemplate();
492		messageTemplate.addBlock(createBlock(const_cast<char*>(_PREHASH_Test0), MVT_U32, 4, MBT_SINGLE));
493		messageTemplate.addBlock(createBlock(const_cast<char*>(_PREHASH_Test1), MVT_U32, 4, MBT_SINGLE));
494
495		// Build message
496		builder = defaultBuilder(messageTemplate, const_cast<char*>(_PREHASH_Test0));
497		builder->addU32(_PREHASH_Test0, 0xaaaa);
498		builder->nextBlock(_PREHASH_Test1);
499		builder->addU32(_PREHASH_Test0, 0xbbbb);
500		bufferSize2 = builder->buildMessage(buffer2, MAX_BUFFER_SIZE, 0);
501		delete builder;
502
503		ensure_not_equals("Ensure Buffer Sizes Not Equal", bufferSize1, bufferSize2);
504		ensure_equals("Ensure Buffer Prefix Equal", memcmp(buffer1, buffer2, bufferSize1), 0);
505		ensure_not_equals("Ensure Buffer Contents Not Equal", memcmp(buffer1, buffer2, bufferSize2), 0);
506	}
507
508	template<> template<>
509	void LLTemplateMessageBuilderTestObject::test<22>()
510		// repeated penultimate block (crashes when data in LLDynamicArrayIndexed)
511	{
512		U32 inTest00 = 0, inTest01 = 1, inTest1 = 2;
513		U32 outTest00, outTest01, outTest1;
514		LLMessageTemplate messageTemplate = defaultTemplate();
515		messageTemplate.addBlock(createBlock(const_cast<char*>(_PREHASH_Test0), MVT_U32, 4));
516		messageTemplate.addBlock(createBlock(const_cast<char*>(_PREHASH_Test1), MVT_U32, 4));
517		LLTemplateMessageBuilder* builder = defaultBuilder(messageTemplate);
518		builder->addU32(_PREHASH_Test0, inTest00);
519		builder->nextBlock(_PREHASH_Test0);
520		builder->addU32(_PREHASH_Test0, inTest01);
521		builder->nextBlock(_PREHASH_Test1);
522		builder->addU32(_PREHASH_Test0, inTest1);
523		LLTemplateMessageReader* reader = setReader(messageTemplate, builder);
524		reader->getU32(_PREHASH_Test0, _PREHASH_Test0, outTest00, 0);
525		reader->getU32(_PREHASH_Test0, _PREHASH_Test0, outTest01, 1);
526		reader->getU32(_PREHASH_Test1, _PREHASH_Test0, outTest1);
527		ensure_equals("Ensure Test0[0]", inTest00, outTest00);
528		ensure_equals("Ensure Test0[1]", inTest01, outTest01);
529		ensure_equals("Ensure Test1", inTest1, outTest1);
530		delete reader;
531	}
532
533	template<> template<>
534	void LLTemplateMessageBuilderTestObject::test<23>()
535		// variable repeated block name never accessed
536	{
537		U32 inTest = 1, outTest;
538		LLMessageTemplate messageTemplate = defaultTemplate();
539		messageTemplate.addBlock(
540			createBlock(const_cast<char*>(_PREHASH_Test0), MVT_U32, 4, MBT_SINGLE));
541		messageTemplate.addBlock(createBlock(const_cast<char*>(_PREHASH_Test1), MVT_U32, 4));
542
543		LLTemplateMessageBuilder* builder = defaultBuilder(messageTemplate);
544		builder->addU32(_PREHASH_Test0, inTest);
545
546		LLTemplateMessageReader* reader = setReader(messageTemplate, builder);
547		reader->getU32(_PREHASH_Test0, _PREHASH_Test0, outTest);
548		S32 blockCount = reader->getNumberOfBlocks(const_cast<char*>(_PREHASH_Test1));
549		ensure_equals("Ensure block count", blockCount, 0);
550		ensure_equals("Ensure Test0", inTest, outTest);
551		delete reader;
552	}
553
554	template<> template<>
555	void LLTemplateMessageBuilderTestObject::test<24>()
556		// forwarding message
557	{
558		// build template
559		LLMessageTemplate messageTemplate = defaultTemplate();
560		messageTemplate.addBlock(createBlock(const_cast<char*>(_PREHASH_Test0), MVT_U32, 4));
561
562		// build message
563		LLTemplateMessageBuilder* builder = defaultBuilder(messageTemplate);
564		builder->addU32(_PREHASH_Test0, 42);
565
566		// read message
567		LLTemplateMessageReader* reader = setReader(messageTemplate, builder);
568
569		// forward message
570		builder = defaultBuilder(messageTemplate);
571		builder->newMessage(_PREHASH_TestMessage);
572		reader->copyToBuilder(*builder);
573		U8 buffer[MAX_BUFFER_SIZE];
574		builder->buildMessage(buffer, MAX_BUFFER_SIZE, 0);
575
576		delete builder;
577		delete reader;
578	}
579
580	template<> template<>
581	void LLTemplateMessageBuilderTestObject::test<25>()
582		// non-zero offset with undefined
583	{
584		LLMessageTemplate messageTemplate = defaultTemplate();
585		messageTemplate.addBlock(defaultBlock());
586		LLTemplateMessageBuilder* builder = defaultBuilder(messageTemplate);
587		LLTemplateMessageReader* reader = setReader(
588			messageTemplate, builder, 10);
589		delete reader;
590	}
591
592	template<> template<>
593	void LLTemplateMessageBuilderTestObject::test<26>()
594		 // non-zero offset with BOOL
595	{
596		LLMessageTemplate messageTemplate = defaultTemplate();
597		messageTemplate.addBlock(defaultBlock(MVT_BOOL, 1));
598		BOOL outValue, inValue = TRUE;
599		LLTemplateMessageBuilder* builder = defaultBuilder(messageTemplate);
600		builder->addBOOL(_PREHASH_Test0, inValue);
601		LLTemplateMessageReader* reader = setReader(
602			messageTemplate, builder, 1);
603		reader->getBOOL(_PREHASH_Test0, _PREHASH_Test0, outValue);
604		ensure_equals("Ensure BOOL", inValue, outValue);
605		delete reader;
606	}
607
608	template<> template<>
609	void LLTemplateMessageBuilderTestObject::test<27>()
610		 // non-zero offset with U8
611	{
612		LLMessageTemplate messageTemplate = defaultTemplate();
613		messageTemplate.addBlock(defaultBlock(MVT_U8, 1));
614		U8 outValue, inValue = 2;
615		LLTemplateMessageBuilder* builder = defaultBuilder(messageTemplate);
616		builder->addU8(_PREHASH_Test0, inValue);
617		LLTemplateMessageReader* reader = setReader(
618			messageTemplate, builder, 255);
619		reader->getU8(_PREHASH_Test0, _PREHASH_Test0, outValue);
620		ensure_equals("Ensure U8", inValue, outValue);
621		delete reader;
622	}
623
624	template<> template<>
625	void LLTemplateMessageBuilderTestObject::test<28>()
626		 // non-zero offset with S16
627	{
628		LLMessageTemplate messageTemplate = defaultTemplate();
629		messageTemplate.addBlock(defaultBlock(MVT_S16, 2));
630		S16 outValue, inValue = 90;
631		LLTemplateMessageBuilder* builder = defaultBuilder(messageTemplate);
632		builder->addS16(_PREHASH_Test0, inValue);
633		LLTemplateMessageReader* reader = setReader(
634			messageTemplate, builder, 2);
635		reader->getS16(_PREHASH_Test0, _PREHASH_Test0, outValue);
636		ensure_equals("Ensure S16", inValue, outValue);
637		delete reader;
638	}
639
640	template<> template<>
641	void LLTemplateMessageBuilderTestObject::test<29>()
642		 // non-zero offset with U16
643	{
644		LLMessageTemplate messageTemplate = defaultTemplate();
645		messageTemplate.addBlock(defaultBlock(MVT_U16, 2));
646		U16 outValue, inValue = 3;
647		LLTemplateMessageBuilder* builder = defaultBuilder(messageTemplate);
648		builder->addU16(_PREHASH_Test0, inValue);
649		LLTemplateMessageReader* reader = setReader(
650			messageTemplate, builder, 4);
651		reader->getU16(_PREHASH_Test0, _PREHASH_Test0, outValue);
652		ensure_equals("Ensure U16", inValue, outValue);
653		delete reader;
654	}
655
656	template<> template<>
657	void LLTemplateMessageBuilderTestObject::test<30>()
658		 // non-zero offset with S32
659	{
660		LLMessageTemplate messageTemplate = defaultTemplate();
661		messageTemplate.addBlock(defaultBlock(MVT_S32, 4));
662		S32 outValue, inValue = 44;
663		LLTemplateMessageBuilder* builder = defaultBuilder(messageTemplate);
664		builder->addS32(_PREHASH_Test0, inValue);
665		LLTemplateMessageReader* reader = setReader(
666			messageTemplate, builder, 4);
667		reader->getS32(_PREHASH_Test0, _PREHASH_Test0, outValue);
668		ensure_equals("Ensure S32", inValue, outValue);
669		delete reader;
670	}
671
672	template<> template<>
673	void LLTemplateMessageBuilderTestObject::test<31>()
674		 // non-zero offset with F32
675	{
676		LLMessageTemplate messageTemplate = defaultTemplate();
677		messageTemplate.addBlock(defaultBlock(MVT_F32, 4));
678		F32 outValue, inValue = 121.44f;
679		LLTemplateMessageBuilder* builder = defaultBuilder(messageTemplate);
680		builder->addF32(_PREHASH_Test0, inValue);
681		LLTemplateMessageReader* reader = setReader(
682			messageTemplate, builder, 16);
683		reader->getF32(_PREHASH_Test0, _PREHASH_Test0, outValue);
684		ensure_equals("Ensure F32", inValue, outValue);
685		delete reader;
686	}
687
688	template<> template<>
689	void LLTemplateMessageBuilderTestObject::test<32>()
690		 // non-zero offset with U32
691	{
692		LLMessageTemplate messageTemplate = defaultTemplate();
693		messageTemplate.addBlock(defaultBlock(MVT_U32, 4));
694		U32 outValue, inValue = 88;
695		LLTemplateMessageBuilder* builder = defaultBuilder(messageTemplate);
696		builder->addU32(_PREHASH_Test0, inValue);
697		LLTemplateMessageReader* reader = setReader(
698			messageTemplate, builder, 127);
699		reader->getU32(_PREHASH_Test0, _PREHASH_Test0, outValue);
700		ensure_equals("Ensure U32", inValue, outValue);
701		delete reader;
702	}
703
704	template<> template<>
705	void LLTemplateMessageBuilderTestObject::test<33>()
706		 // non-zero offset with U64
707	{
708		LLMessageTemplate messageTemplate = defaultTemplate();
709		messageTemplate.addBlock(defaultBlock(MVT_U64, 8));
710		U64 outValue, inValue = 121;
711		LLTemplateMessageBuilder* builder = defaultBuilder(messageTemplate);
712		builder->addU64(_PREHASH_Test0, inValue);
713		LLTemplateMessageReader* reader = setReader(
714			messageTemplate, builder, 32);
715		reader->getU64(_PREHASH_Test0, _PREHASH_Test0, outValue);
716		ensure_equals("Ensure U64", inValue, outValue);
717		delete reader;
718	}
719
720	template<> template<>
721	void LLTemplateMessageBuilderTestObject::test<34>()
722		 // non-zero offset with F64
723	{
724		LLMessageTemplate messageTemplate = defaultTemplate();
725		messageTemplate.addBlock(defaultBlock(MVT_F64, 8));
726		F64 outValue, inValue = 3232143.33;
727		LLTemplateMessageBuilder* builder = defaultBuilder(messageTemplate);
728		builder->addF64(_PREHASH_Test0, inValue);
729		LLTemplateMessageReader* reader = setReader(
730			messageTemplate, builder, 128);
731		reader->getF64(_PREHASH_Test0, _PREHASH_Test0, outValue);
732		ensure_equals("Ensure F64", inValue, outValue);
733		delete reader;
734	}
735
736	template<> template<>
737	void LLTemplateMessageBuilderTestObject::test<35>()
738		 // non-zero offset with Vector3
739	{
740		LLMessageTemplate messageTemplate = defaultTemplate();
741		messageTemplate.addBlock(defaultBlock(MVT_LLVector3, 12));
742		LLVector3 outValue, inValue = LLVector3(1,2,3);
743		LLTemplateMessageBuilder* builder = defaultBuilder(messageTemplate);
744		builder->addVector3(_PREHASH_Test0, inValue);
745		LLTemplateMessageReader* reader = setReader(
746			messageTemplate, builder, 63);
747		reader->getVector3(_PREHASH_Test0, _PREHASH_Test0, outValue);
748		ensure_equals("Ensure LLVector3", inValue, outValue);
749		delete reader;
750	}
751
752	template<> template<>
753	void LLTemplateMessageBuilderTestObject::test<36>()
754		 // non-zero offset with Vector4
755	{
756		LLMessageTemplate messageTemplate = defaultTemplate();
757		messageTemplate.addBlock(defaultBlock(MVT_LLVector4, 16));
758		LLVector4 outValue, inValue = LLVector4(1,2,3,4);
759		LLTemplateMessageBuilder* builder = defaultBuilder(messageTemplate);
760		builder->addVector4(_PREHASH_Test0, inValue);
761		LLTemplateMessageReader* reader = setReader(
762			messageTemplate, builder, 64);
763		reader->getVector4(_PREHASH_Test0, _PREHASH_Test0, outValue);
764		ensure_equals("Ensure LLVector4", inValue, outValue);
765		delete reader;
766	}
767
768	template<> template<>
769	void LLTemplateMessageBuilderTestObject::test<37>()
770		 // non-zero offset with Vector3d
771	{
772		LLMessageTemplate messageTemplate = defaultTemplate();
773		messageTemplate.addBlock(defaultBlock(MVT_LLVector3d, 24));
774		LLVector3d outValue, inValue = LLVector3d(1,2,3);
775		LLTemplateMessageBuilder* builder = defaultBuilder(messageTemplate);
776		builder->addVector3d(_PREHASH_Test0, inValue);
777		LLTemplateMessageReader* reader = setReader(
778			messageTemplate, builder, 64);
779		reader->getVector3d(_PREHASH_Test0, _PREHASH_Test0, outValue);
780		ensure_equals("Ensure LLVector3d", inValue, outValue);
781		delete reader;
782	}
783
784	template<> template<>
785	void LLTemplateMessageBuilderTestObject::test<38>()
786		 // non-zero offset with Quaternion
787	{
788		LLMessageTemplate messageTemplate = defaultTemplate();
789		messageTemplate.addBlock(defaultBlock(MVT_LLQuaternion, 12));
790		LLQuaternion outValue, inValue = LLQuaternion(1,2,3,0);
791		LLTemplateMessageBuilder* builder = defaultBuilder(messageTemplate);
792		builder->addQuat(_PREHASH_Test0, inValue);
793		LLTemplateMessageReader* reader = setReader(
794			messageTemplate, builder, 12);
795		reader->getQuat(_PREHASH_Test0, _PREHASH_Test0, outValue);
796		ensure_equals("Ensure LLQuaternion", inValue, outValue);
797		delete reader;
798	}
799
800	template<> template<>
801	void LLTemplateMessageBuilderTestObject::test<39>()
802		 // non-zero offset with UUID
803	{
804		LLMessageTemplate messageTemplate = defaultTemplate();
805		messageTemplate.addBlock(defaultBlock(MVT_LLUUID, 16));
806		LLUUID outValue, inValue;
807		inValue.generate();
808		LLTemplateMessageBuilder* builder = defaultBuilder(messageTemplate);
809		builder->addUUID(_PREHASH_Test0, inValue);
810		LLTemplateMessageReader* reader = setReader(
811			messageTemplate, builder, 31);
812		reader->getUUID(_PREHASH_Test0, _PREHASH_Test0, outValue);
813		ensure_equals("Ensure UUID", inValue, outValue);
814		delete reader;
815	}
816
817	template<> template<>
818	void LLTemplateMessageBuilderTestObject::test<40>()
819		 // non-zero offset with IPAddr
820	{
821		LLMessageTemplate messageTemplate = defaultTemplate();
822		messageTemplate.addBlock(defaultBlock(MVT_IP_ADDR, 4));
823		U32 outValue, inValue = 12344556;
824		LLTemplateMessageBuilder* builder = defaultBuilder(messageTemplate);
825		builder->addIPAddr(_PREHASH_Test0, inValue);
826		LLTemplateMessageReader* reader = setReader(
827			messageTemplate, builder, 32);
828		reader->getIPAddr(_PREHASH_Test0, _PREHASH_Test0, outValue);
829		ensure_equals("Ensure IPAddr", inValue, outValue);
830		delete reader;
831	}
832
833	 template<> template<>
834	void LLTemplateMessageBuilderTestObject::test<41>()
835		 // non-zero offset with IPPort
836	{
837		LLMessageTemplate messageTemplate = defaultTemplate();
838		messageTemplate.addBlock(defaultBlock(MVT_IP_PORT, 2));
839		U16 outValue, inValue = 80;
840		LLTemplateMessageBuilder* builder = defaultBuilder(messageTemplate);
841		builder->addIPPort(_PREHASH_Test0, inValue);
842		LLTemplateMessageReader* reader = setReader(
843			messageTemplate, builder, 6);
844		reader->getIPPort(_PREHASH_Test0, _PREHASH_Test0, outValue);
845		ensure_equals("Ensure IPPort", inValue, outValue);
846		delete reader;
847	}
848
849	template<> template<>
850	void LLTemplateMessageBuilderTestObject::test<42>()
851		// non-zero offset with String
852	{
853		LLMessageTemplate messageTemplate = defaultTemplate();
854		messageTemplate.addBlock(defaultBlock(MVT_VARIABLE, 1));
855		std::string outValue, inValue = "testing";
856		LLTemplateMessageBuilder* builder = defaultBuilder(messageTemplate);
857		builder->addString(_PREHASH_Test0, inValue.c_str());
858		LLTemplateMessageReader* reader = setReader(
859			messageTemplate, builder, 255);
860		char buffer[MAX_STRING];
861		reader->getString(_PREHASH_Test0, _PREHASH_Test0, MAX_STRING, buffer);
862		outValue = buffer;
863		ensure_equals("Ensure String", inValue, outValue);
864		delete reader;
865	}
866
867	template<> template<>
868	void LLTemplateMessageBuilderTestObject::test<43>()
869		// read past end of message -> default values (forward compatibility)
870	{
871		// build message with single block
872		LLMessageTemplate messageTemplate = defaultTemplate();
873		messageTemplate.addBlock(defaultBlock(MVT_U32, 4, MBT_SINGLE));
874		U32 outValue, outValue2, inValue = 0xbbbbbbbb;
875		LLTemplateMessageBuilder* builder = defaultBuilder(messageTemplate);
876		builder->addU32(_PREHASH_Test0, inValue);
877		const U32 bufferSize = 1024;
878		U8 buffer[bufferSize];
879		memset(buffer, 0xaa, bufferSize);
880		memset(buffer, 0, LL_PACKET_ID_SIZE);
881		U32 builtSize = builder->buildMessage(buffer, bufferSize, 0);
882		delete builder;
883
884		// add block to reader template
885		messageTemplate.addBlock(createBlock(const_cast<char*>(_PREHASH_Test1), MVT_U32, 4, MBT_SINGLE));
886
887		// read message value and default value
888		numberMap[1] = &messageTemplate;
889		LLTemplateMessageReader* reader = 
890			new LLTemplateMessageReader(numberMap);
891		reader->validateMessage(buffer, builtSize, LLHost());
892		reader->readMessage(buffer, LLHost());
893		reader->getU32(_PREHASH_Test0, _PREHASH_Test0, outValue);
894		reader->getU32(_PREHASH_Test1, _PREHASH_Test0, outValue2);
895		ensure_equals("Ensure present value ", outValue, inValue);
896		ensure_equals("Ensure default value ", outValue2, 0);
897		delete reader;
898	}
899
900	template<> template<>
901	void LLTemplateMessageBuilderTestObject::test<44>()
902		// read variable block past end of message -> 0 repeats
903	{
904		// build message with single block
905		LLMessageTemplate messageTemplate = defaultTemplate();
906		messageTemplate.addBlock(defaultBlock(MVT_U32, 4, MBT_SINGLE));
907		U32 outValue, outValue2, inValue = 0xbbbbbbbb;
908		LLTemplateMessageBuilder* builder = defaultBuilder(messageTemplate);
909		builder->addU32(_PREHASH_Test0, inValue);
910		const U32 bufferSize = 1024;
911		U8 buffer[bufferSize];
912		memset(buffer, 0xaa, bufferSize);
913		memset(buffer, 0, LL_PACKET_ID_SIZE);
914		U32 builtSize = builder->buildMessage(buffer, bufferSize, 0);
915		delete builder;
916
917		// add variable block to reader template
918		messageTemplate.addBlock(createBlock(const_cast<char*>(_PREHASH_Test1), MVT_U32, 4));
919
920		// read message value and check block repeat count
921		numberMap[1] = &messageTemplate;
922		LLTemplateMessageReader* reader = 
923			new LLTemplateMessageReader(numberMap);
924		reader->validateMessage(buffer, builtSize, LLHost());
925		reader->readMessage(buffer, LLHost());
926		reader->getU32(_PREHASH_Test0, _PREHASH_Test0, outValue);
927		outValue2 = reader->getNumberOfBlocks(_PREHASH_Test1);
928		ensure_equals("Ensure present value ", outValue, inValue);
929		ensure_equals("Ensure 0 repeats ", outValue2, 0);
930		delete reader;
931	}
932
933	template<> template<>
934	void LLTemplateMessageBuilderTestObject::test<45>()
935		// read variable length data past end of message -> 0 length
936	{
937		// build message with single block
938		LLMessageTemplate messageTemplate = defaultTemplate();
939		messageTemplate.addBlock(defaultBlock(MVT_U32, 4, MBT_SINGLE));
940		U32 outValue, outValue2, inValue = 0xbbbbbbbb;
941		LLTemplateMessageBuilder* builder = defaultBuilder(messageTemplate);
942		builder->addU32(_PREHASH_Test0, inValue);
943		const U32 bufferSize = 1024;
944		U8 buffer[bufferSize];
945		memset(buffer, 0xaa, bufferSize);
946		memset(buffer, 0, LL_PACKET_ID_SIZE);
947		U32 builtSize = builder->buildMessage(buffer, bufferSize, 0);
948		delete builder;
949
950		// add variable block to reader template
951		messageTemplate.addBlock(createBlock(const_cast<char*>(_PREHASH_Test1), MVT_VARIABLE, 4,
952											 MBT_SINGLE));
953
954		// read message value and default string
955		numberMap[1] = &messageTemplate;
956		LLTemplateMessageReader* reader = 
957			new LLTemplateMessageReader(numberMap);
958		reader->validateMessage(buffer, builtSize, LLHost());
959		reader->readMessage(buffer, LLHost());
960		reader->getU32(_PREHASH_Test0, _PREHASH_Test0, outValue);
961		char outBuffer[bufferSize];
962		memset(buffer, 0xcc, bufferSize);
963		reader->getString(_PREHASH_Test1, _PREHASH_Test0, bufferSize, 
964						  outBuffer);
965		outValue2 = reader->getNumberOfBlocks(_PREHASH_Test1);
966		ensure_equals("Ensure present value ", outValue, inValue);
967		ensure_equals("Ensure unchanged buffer ", strlen(outBuffer), 0);
968		delete reader;
969	}
970}
971