PageRenderTime 122ms CodeModel.GetById 23ms app.highlight 93ms RepoModel.GetById 1ms app.codeStats 0ms

/indra/llcommon/tests/commonmisc_test.cpp

https://bitbucket.org/lindenlab/viewer-beta/
C++ | 671 lines | 614 code | 21 blank | 36 comment | 6 complexity | 449cf17900de7adc1533c0fbee2845f2 MD5 | raw file
  1/** 
  2 * @file common.cpp
  3 * @author Phoenix
  4 * @date 2005-10-12
  5 * @brief Common templates for test framework
  6 *
  7 * $LicenseInfo:firstyear=2005&license=viewerlgpl$
  8 * Second Life Viewer Source Code
  9 * Copyright (C) 2010, Linden Research, Inc.
 10 * 
 11 * This library is free software; you can redistribute it and/or
 12 * modify it under the terms of the GNU Lesser General Public
 13 * License as published by the Free Software Foundation;
 14 * version 2.1 of the License only.
 15 * 
 16 * This library is distributed in the hope that it will be useful,
 17 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 18 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
 19 * Lesser General Public License for more details.
 20 * 
 21 * You should have received a copy of the GNU Lesser General Public
 22 * License along with this library; if not, write to the Free Software
 23 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA
 24 * 
 25 * Linden Research, Inc., 945 Battery Street, San Francisco, CA  94111  USA
 26 * $/LicenseInfo$
 27 */
 28
 29/** 
 30 * 
 31 * THOROUGH_DESCRIPTION of common.cpp
 32 *
 33 */
 34
 35#include <algorithm>
 36#include <iomanip>
 37#include <iterator>
 38
 39#include "linden_common.h"
 40
 41#include "../llmemorystream.h"
 42#include "../llsd.h"
 43#include "../llsdserialize.h"
 44#include "../u64.h"
 45#include "../llhash.h"
 46
 47#include "../test/lltut.h"
 48
 49
 50#if LL_WINDOWS
 51// disable overflow warnings
 52#pragma warning(disable: 4307)
 53#endif
 54
 55namespace tut
 56{
 57	struct sd_data
 58	{
 59	};
 60	typedef test_group<sd_data> sd_test;
 61	typedef sd_test::object sd_object;
 62	tut::sd_test sd("LLSD");
 63
 64	template<> template<>
 65	void sd_object::test<1>()
 66	{
 67		std::ostringstream resp;
 68		resp << "{'connect':true,  'position':[r128,r128,r128], 'look_at':[r0,r1,r0], 'agent_access':'M', 'region_x':i8192, 'region_y':i8192}";
 69		std::string str = resp.str();
 70		LLMemoryStream mstr((U8*)str.c_str(), str.size());
 71		LLSD response;
 72		S32 count = LLSDSerialize::fromNotation(response, mstr, str.size());
 73		ensure("stream parsed", response.isDefined());
 74		ensure_equals("stream parse count", count, 13);
 75		ensure_equals("sd type", response.type(), LLSD::TypeMap);
 76		ensure_equals("map element count", response.size(), 6);
 77		ensure_equals("value connect", response["connect"].asBoolean(), true);
 78		ensure_equals("value region_x", response["region_x"].asInteger(),8192);
 79		ensure_equals("value region_y", response["region_y"].asInteger(),8192);
 80	}
 81
 82	template<> template<>
 83	void sd_object::test<2>()
 84	{
 85		const std::string decoded("random");
 86		//const std::string encoded("cmFuZG9t\n");
 87		const std::string streamed("b(6)\"random\"");
 88		typedef std::vector<U8> buf_t;
 89		buf_t buf;
 90		std::copy(
 91			decoded.begin(),
 92			decoded.end(),
 93			std::back_insert_iterator<buf_t>(buf));
 94		LLSD sd;
 95		sd = buf;
 96		std::stringstream str;
 97		S32 count = LLSDSerialize::toNotation(sd, str);
 98		ensure_equals("output count", count, 1);
 99		std::string actual(str.str());
100		ensure_equals("formatted binary encoding", actual, streamed);
101		sd.clear();
102		LLSDSerialize::fromNotation(sd, str, str.str().size());
103		std::vector<U8> after;
104		after = sd.asBinary();
105		ensure_equals("binary decoded size", after.size(), decoded.size());
106		ensure("binary decoding", (0 == memcmp(
107									   &after[0],
108									   decoded.c_str(),
109									   decoded.size())));
110	}
111
112	template<> template<>
113	void sd_object::test<3>()
114	{
115		for(S32 i = 0; i < 100; ++i)
116		{
117			// gen up a starting point
118			typedef std::vector<U8> buf_t;
119			buf_t source;
120			srand(i);		/* Flawfinder: ignore */
121			S32 size = rand() % 1000 + 10;
122			std::generate_n(
123				std::back_insert_iterator<buf_t>(source),
124				size,
125				rand);
126			LLSD sd(source);
127			std::stringstream str;
128			S32 count = LLSDSerialize::toNotation(sd, str);
129			sd.clear();
130			ensure_equals("format count", count, 1);
131			LLSD sd2;
132			count = LLSDSerialize::fromNotation(sd2, str, str.str().size());
133			ensure_equals("parse count", count, 1);
134			buf_t dest = sd2.asBinary();
135			str.str("");
136			str << "binary encoding size " << i;
137			ensure_equals(str.str().c_str(), dest.size(), source.size());
138			str.str("");
139			str << "binary encoding " << i;
140			ensure(str.str().c_str(), (source == dest));
141		}
142	}
143
144	template<> template<>
145	void sd_object::test<4>()
146	{
147		std::ostringstream ostr;
148		ostr << "{'task_id':u1fd77b79-a8e7-25a5-9454-02a4d948ba1c}\n"
149			 << "{\n\tname\tObject|\n}\n";
150		std::string expected = ostr.str();
151		std::stringstream serialized;
152		serialized << "'" << LLSDNotationFormatter::escapeString(expected)
153			   << "'";
154		LLSD sd;
155		S32 count = LLSDSerialize::fromNotation(
156			sd,
157			serialized,
158			serialized.str().size());
159		ensure_equals("parse count", count, 1);
160		ensure_equals("String streaming", sd.asString(), expected);
161	}
162
163	template<> template<>
164	void sd_object::test<5>()
165	{
166		for(S32 i = 0; i < 100; ++i)
167		{
168			// gen up a starting point
169			typedef std::vector<U8> buf_t;
170			buf_t source;
171			srand(666 + i);		/* Flawfinder: ignore */
172			S32 size = rand() % 1000 + 10;
173			std::generate_n(
174				std::back_insert_iterator<buf_t>(source),
175				size,
176				rand);
177			std::stringstream str;
178			str << "b(" << size << ")\"";
179			str.write((const char*)&source[0], size);
180			str << "\"";
181			LLSD sd;
182			S32 count = LLSDSerialize::fromNotation(sd, str, str.str().size());
183			ensure_equals("binary parse", count, 1);
184			buf_t actual = sd.asBinary();
185			ensure_equals("binary size", actual.size(), (size_t)size);
186			ensure("binary data", (0 == memcmp(&source[0], &actual[0], size)));
187		}
188	}
189
190	template<> template<>
191	void sd_object::test<6>()
192	{
193		std::string expected("'{\"task_id\":u1fd77b79-a8e7-25a5-9454-02a4d948ba1c}'\t\n\t\t");
194		std::stringstream str;
195		str << "s(" << expected.size() << ")'";
196		str.write(expected.c_str(), expected.size());
197		str << "'";
198		LLSD sd;
199		S32 count = LLSDSerialize::fromNotation(sd, str, str.str().size());
200		ensure_equals("parse count", count, 1);
201		std::string actual = sd.asString();
202		ensure_equals("string sizes", actual.size(), expected.size());
203		ensure_equals("string content", actual, expected);
204	}
205
206	template<> template<>
207	void sd_object::test<7>()
208	{
209		std::string msg("come on in");
210		std::stringstream stream;
211		stream << "{'connect':1, 'message':'" << msg << "',"
212			   << " 'position':[r45.65,r100.1,r25.5],"
213			   << " 'look_at':[r0,r1,r0],"
214			   << " 'agent_access':'PG'}";
215		LLSD sd;
216		S32 count = LLSDSerialize::fromNotation(
217			sd,
218			stream,
219			stream.str().size());
220		ensure_equals("parse count", count, 12);
221		ensure_equals("bool value", sd["connect"].asBoolean(), true);
222		ensure_equals("message value", sd["message"].asString(), msg);
223		ensure_equals("pos x", sd["position"][0].asReal(), 45.65);
224		ensure_equals("pos y", sd["position"][1].asReal(), 100.1);
225		ensure_equals("pos z", sd["position"][2].asReal(), 25.5);
226		ensure_equals("look x", sd["look_at"][0].asReal(), 0.0);
227		ensure_equals("look y", sd["look_at"][1].asReal(), 1.0);
228		ensure_equals("look z", sd["look_at"][2].asReal(), 0.0);
229	}
230
231	template<> template<>
232	void sd_object::test<8>()
233	{
234		std::stringstream resp;
235		resp << "{'label':'short string test', 'singlechar':'a', 'empty':'', 'endoftest':'end' }";
236		LLSD response;
237		S32 count = LLSDSerialize::fromNotation(
238			response,
239			resp,
240			resp.str().size());
241		ensure_equals("parse count", count, 5);
242		ensure_equals("sd type", response.type(), LLSD::TypeMap);
243		ensure_equals("map element count", response.size(), 4);
244		ensure_equals("singlechar", response["singlechar"].asString(), "a");
245		ensure_equals("empty", response["empty"].asString(), "");
246	}
247
248	template<> template<>
249	void sd_object::test<9>()
250	{
251		std::ostringstream resp;
252		resp << "{'label':'short binary test', 'singlebinary':b(1)\"A\", 'singlerawstring':s(1)\"A\", 'endoftest':'end' }";
253		std::string str = resp.str();
254		LLSD sd;
255		LLMemoryStream mstr((U8*)str.c_str(), str.size());
256		S32 count = LLSDSerialize::fromNotation(sd, mstr, str.size());
257		ensure_equals("parse count", count, 5);
258		ensure("sd created", sd.isDefined());
259		ensure_equals("sd type", sd.type(), LLSD::TypeMap);
260		ensure_equals("map element count", sd.size(), 4);
261		ensure_equals(
262			"label",
263			sd["label"].asString(),
264			"short binary test");
265		std::vector<U8> bin =  sd["singlebinary"].asBinary();
266		std::vector<U8> expected;
267		expected.resize(1);
268		expected[0] = 'A';
269		ensure("single binary", (0 == memcmp(&bin[0], &expected[0], 1)));
270		ensure_equals(
271			"single string",
272			sd["singlerawstring"].asString(),
273			std::string("A"));
274		ensure_equals("end", sd["endoftest"].asString(), "end");
275	}
276
277	template<> template<>
278	void sd_object::test<10>()
279	{
280
281		std::string message("parcel '' is naughty.");
282		std::stringstream str;
283		str << "{'message':'" << LLSDNotationFormatter::escapeString(message)
284			<< "'}";
285		std::string expected_str("{'message':'parcel \\'\\' is naughty.'}");
286		std::string actual_str = str.str();
287		ensure_equals("stream contents", actual_str, expected_str);
288		LLSD sd;
289		S32 count = LLSDSerialize::fromNotation(sd, str, actual_str.size());
290		ensure_equals("parse count", count, 2);
291		ensure("valid parse", sd.isDefined());
292		std::string actual = sd["message"].asString();
293		ensure_equals("message contents", actual, message);
294	}
295
296	template<> template<>
297	void sd_object::test<11>()
298	{
299		std::string expected("\"\"\"\"''''''\"");
300		std::stringstream str;
301		str << "'" << LLSDNotationFormatter::escapeString(expected) << "'";
302		LLSD sd;
303		S32 count = LLSDSerialize::fromNotation(sd, str, str.str().size());
304		ensure_equals("parse count", count, 1);
305		ensure_equals("string value", sd.asString(), expected);
306	}
307
308	template<> template<>
309	void sd_object::test<12>()
310	{
311		std::string expected("mytest\\");
312		std::stringstream str;
313		str << "'" << LLSDNotationFormatter::escapeString(expected) << "'";
314		LLSD sd;
315		S32 count = LLSDSerialize::fromNotation(sd, str, str.str().size());
316		ensure_equals("parse count", count, 1);
317		ensure_equals("string value", sd.asString(), expected);
318	}
319
320	template<> template<>
321	void sd_object::test<13>()
322	{
323		for(S32 i = 0; i < 1000; ++i)
324		{
325			// gen up a starting point
326			std::string expected;
327			srand(1337 + i);		/* Flawfinder: ignore */
328			S32 size = rand() % 30 + 5;
329			std::generate_n(
330				std::back_insert_iterator<std::string>(expected),
331				size,
332				rand);
333			std::stringstream str;
334			str << "'" << LLSDNotationFormatter::escapeString(expected) << "'";
335			LLSD sd;
336			S32 count = LLSDSerialize::fromNotation(sd, str, expected.size());
337			ensure_equals("parse count", count, 1);
338			std::string actual = sd.asString();
339/*
340			if(actual != expected)
341			{
342				llwarns << "iteration " << i << llendl;
343				std::ostringstream e_str;
344				std::string::iterator iter = expected.begin();
345				std::string::iterator end = expected.end();
346				for(; iter != end; ++iter)
347				{
348					e_str << (S32)((U8)(*iter)) << " ";
349				}
350				e_str << std::endl;
351				llsd_serialize_string(e_str, expected);
352				llwarns << "expected size: " << expected.size() << llendl;
353				llwarns << "expected:      " << e_str.str() << llendl;
354
355				std::ostringstream a_str;
356				iter = actual.begin();
357				end = actual.end();
358				for(; iter != end; ++iter)
359				{
360					a_str << (S32)((U8)(*iter)) << " ";
361				}
362				a_str << std::endl;
363				llsd_serialize_string(a_str, actual);
364				llwarns << "actual size:   " << actual.size() << llendl;
365				llwarns << "actual:      " << a_str.str() << llendl;
366			}
367*/
368			ensure_equals("string value", actual, expected);
369		}
370	}
371
372	template<> template<>
373	void sd_object::test<14>()
374	{
375//#if LL_WINDOWS && _MSC_VER >= 1400
376//        skip_fail("Fails on VS2005 due to broken LLSDSerialize::fromNotation() parser.");
377//#endif
378		std::string param = "[{'version':i1},{'data':{'binary_bucket':b(0)\"\"},'from_id':u3c115e51-04f4-523c-9fa6-98aff1034730,'from_name':'Phoenix Linden','id':u004e45e5-5576-277a-fba7-859d6a4cb5c8,'message':'hey','offline':i0,'timestamp':i0,'to_id':u3c5f1bb4-5182-7546-6401-1d329b4ff2f8,'type':i0},{'agent_id':u3c115e51-04f4-523c-9fa6-98aff1034730,'god_level':i0,'limited_to_estate':i1}]";
379		std::istringstream istr;
380		istr.str(param);
381		LLSD param_sd;
382		LLSDSerialize::fromNotation(param_sd, istr, param.size());
383		ensure_equals("parsed type", param_sd.type(), LLSD::TypeArray);
384		LLSD version_sd = param_sd[0];
385		ensure_equals("version type", version_sd.type(), LLSD::TypeMap);
386		ensure("has version", version_sd.has("version"));
387		ensure_equals("version number", version_sd["version"].asInteger(), 1);
388		LLSD src_sd = param_sd[1];
389		ensure_equals("src type", src_sd.type(), LLSD::TypeMap);
390		LLSD dst_sd = param_sd[2];
391		ensure_equals("dst type", dst_sd.type(), LLSD::TypeMap);
392	}
393
394	template<> template<>
395	void sd_object::test<15>()
396	{
397		std::string val = "[{'failures':!,'successfuls':[u3c115e51-04f4-523c-9fa6-98aff1034730]}]";
398		std::istringstream istr;
399		istr.str(val);
400		LLSD sd;
401		LLSDSerialize::fromNotation(sd, istr, val.size());
402		ensure_equals("parsed type", sd.type(), LLSD::TypeArray);
403		ensure_equals("parsed size", sd.size(), 1);
404		LLSD failures = sd[0]["failures"];
405		ensure("no failures.", failures.isUndefined());
406		LLSD success = sd[0]["successfuls"];
407		ensure_equals("success type", success.type(), LLSD::TypeArray);
408		ensure_equals("success size", success.size(), 1);
409		ensure_equals("success instance type", success[0].type(), LLSD::TypeUUID);
410	}
411
412	template<> template<>
413	void sd_object::test<16>()
414	{
415		std::string val = "[f,t,0,1,{'foo':t,'bar':f}]";
416		std::istringstream istr;
417		istr.str(val);
418		LLSD sd;
419		LLSDSerialize::fromNotation(sd, istr, val.size());
420		ensure_equals("parsed type", sd.type(), LLSD::TypeArray);
421		ensure_equals("parsed size", sd.size(), 5);
422		ensure_equals("element 0 false", sd[0].asBoolean(), false);
423		ensure_equals("element 1 true", sd[1].asBoolean(), true);
424		ensure_equals("element 2 false", sd[2].asBoolean(), false);
425		ensure_equals("element 3 true", sd[3].asBoolean(), true);
426		LLSD map = sd[4];
427		ensure_equals("element 4 type", map.type(), LLSD::TypeMap);
428		ensure_equals("map foo type", map["foo"].type(), LLSD::TypeBoolean);
429		ensure_equals("map foo value", map["foo"].asBoolean(), true);
430		ensure_equals("map bar type", map["bar"].type(), LLSD::TypeBoolean);
431		ensure_equals("map bar value", map["bar"].asBoolean(), false);
432	}
433
434/*
435	template<> template<>
436	void sd_object::test<16>()
437	{
438	}
439*/
440}
441
442#if 0
443'{\'task_id\':u1fd77b79-a8e7-25a5-9454-02a4d948ba1c}\n{\n\tname\tObject|\n\tpermissions 0\n\t{\n\t\tbase_mask\t7fffffff\n\t\towner_mask\t7fffffff\n\t\tgroup_mask\t00000000\n\t\teveryone_mask\t00000000\n\t\tnext_owner_mask\t00082000\n\t\tcreator_id\t3c115e51-04f4-523c-9fa6-98aff1034730\n\t\towner_id\t3c115e51-04f4-523c-9fa6-98aff1034730\n\t\tlast_owner_id\t00000000-0000-0000-0000-000000000000\n\t\tgroup_id\t00000000-0000-0000-0000-000000000000\n\t}\n\tlocal_id\t10284\n\ttotal_crc\t35\n\ttype\t1\n\ttask_valid\t2\n\ttravel_access\t21\n\tdisplayopts\t2\n\tdisplaytype\tv\n\tpos\t0\t0\t0\n\toldpos\t0\t0\t0\n\trotation\t4.371139183945160766597837e-08\t1\t4.371139183945160766597837e-08\t0\n\tvelocity\t0\t0\t0\n\tangvel\t0\t0\t0\n\tscale\t0.2816932\t0.2816932\t0.2816932\n\tsit_offset\t0\t0\t0\n\tcamera_eye_offset\t0\t0\t0\n\tcamera_at_offset\t0\t0\t0\n\tsit_quat\t0\t0\t0\t1\n\tsit_hint\t0\n\tstate\t80\n\tmaterial\t3\n\tsoundid\t00000000-0000-0000-0000-000000000000\n\tsoundgain\t0\n\tsoundradius\t0\n\tsoundflags\t0\n\ttextcolor\t0 0 0 1\n\tselected\t0\n\tselector\t00000000-0000-0000-0000-000000000000\n\tusephysics\t0\n\trotate_x\t1\n\trotate_y\t1\n\trotate_z\t1\n\tphantom\t0\n\tremote_script_access_pin\t0\n\tvolume_detect\t0\n\tblock_grabs\t0\n\tdie_at_edge\t0\n\treturn_at_edge\t0\n\ttemporary\t0\n\tsandbox\t0\n\tsandboxhome\t0\t0\t0\n\tshape 0\n\t{\n\t\tpath 0\n\t\t{\n\t\t\tcurve\t16\n\t\t\tbegin\t0\n\t\t\tend\t1\n\t\t\tscale_x\t1\n\t\t\tscale_y\t1\n\t\t\tshear_x\t0\n\t\t\tshear_y\t0\n\t\t\ttwist\t0\n\t\t\ttwist_begin\t0\n\t\t\tradius_offset\t0\n\t\t\ttaper_x\t0\n\t\t\ttaper_y\t0\n\t\t\trevolutions\t1\n\t\t\tskew\t0\n\t\t}\n\t\tprofile 0\n\t\t{\n\t\t\tcurve\t1\n\t\t\tbegin\t0\n\t\t\tend\t1\n\t\t\thollow\t0\n\t\t}\n\t}\n\tfaces\t6\n\t{\n\t\timageid\t89556747-24cb-43ed-920b-47caed15465f\n\t\tcolors\t1 1 1 1\n\t\tscales\t0.56\n\t\tscalet\t0.56\n\t\toffsets\t0\n\t\toffsett\t0\n\t\timagerot\t0\n\t\tbump\t0\n\t\tfullbright\t0\n\t\tmedia_flags\t0\n\t}\n\t{\n\t\timageid\t89556747-24cb-43ed-920b-47caed15465f\n\t\tcolors\t1 1 1 1\n\t\tscales\t0.56\n\t\tscalet\t0.56\n\t\toffsets\t0\n\t\toffsett\t0\n\t\timagerot\t0\n\t\tbump\t0\n\t\tfullbright\t0\n\t\tmedia_flags\t0\n\t}\n\t{\n\t\timageid\t89556747-24cb-43ed-920b-47caed15465f\n\t\tcolors\t1 1 1 1\n\t\tscales\t0.56\n\t\tscalet\t0.56\n\t\toffsets\t0\n\t\toffsett\t0\n\t\timagerot\t0\n\t\tbump\t0\n\t\tfullbright\t0\n\t\tmedia_flags\t0\n\t}\n\t{\n\t\timageid\t89556747-24cb-43ed-920b-47caed15465f\n\t\tcolors\t1 1 1 1\n\t\tscales\t0.56\n\t\tscalet\t0.56\n\t\toffsets\t0\n\t\toffsett\t0\n\t\timagerot\t0\n\t\tbump\t0\n\t\tfullbright\t0\n\t\tmedia_flags\t0\n\t}\n\t{\n\t\timageid\t89556747-24cb-43ed-920b-47caed15465f\n\t\tcolors\t1 1 1 1\n\t\tscales\t0.56\n\t\tscalet\t0.56\n\t\toffsets\t0\n\t\toffsett\t0\n\t\timagerot\t0\n\t\tbump\t0\n\t\tfullbright\t0\n\t\tmedia_flags\t0\n\t}\n\t{\n\t\timageid\t89556747-24cb-43ed-920b-47caed15465f\n\t\tcolors\t1 1 1 1\n\t\tscales\t0.56\n\t\tscalet\t0.56\n\t\toffsets\t0\n\t\toffsett\t0\n\t\timagerot\t0\n\t\tbump\t0\n\t\tfullbright\t0\n\t\tmedia_flags\t0\n\t}\n\tps_next_crc\t1\n\tgpw_bias\t1\n\tip\t0\n\tcomplete\tTRUE\n\tdelay\t50000\n\tnextstart\t1132625972249870\n\tbirthtime\t1132625953120694\n\treztime\t1132625953120694\n\tparceltime\t1132625953120694\n\ttax_rate\t1.01615\n\tnamevalue\tAttachmentOrientation VEC3 RW DS -3.141593, 0.000000, -3.141593\n\tnamevalue\tAttachmentOffset VEC3 RW DS 0.000000, 0.000000, 0.000000\n\tnamevalue\tAttachPt U32 RW S 5\n\tnamevalue\tAttachItemID STRING RW SV 1f9975c0-2951-1b93-dd83-46e2b932fcc8\n\tscratchpad\t0\n\t{\n\t\n\t}\n\tsale_info\t0\n\t{\n\t\tsale_type\tnot\n\t\tsale_price\t10\n\t}\n\torig_asset_id\t52019cdd-b464-ba19-e66d-3da751fef9da\n\torig_item_id\t1f9975c0-2951-1b93-dd83-46e2b932fcc8\n\tcorrect_family_id\t00000000-0000-0000-0000-000000000000\n\thas_rezzed\t0\n\tpre_link_base_mask\t7fffffff\n\tdefault_pay_price\t-2\t1\t5\t10\t20\n}\n'
444#endif
445
446namespace tut
447{
448	struct mem_data
449	{
450	};
451	typedef test_group<mem_data> mem_test;
452	typedef mem_test::object mem_object;
453	tut::mem_test mem_stream("LLMemoryStream");
454
455	template<> template<>
456	void mem_object::test<1>()
457	{
458		const char HELLO_WORLD[] = "hello world";
459		LLMemoryStream mem((U8*)&HELLO_WORLD[0], strlen(HELLO_WORLD));		/* Flawfinder: ignore */
460		std::string hello;
461		std::string world;
462		mem >> hello >> world;
463		ensure_equals("first word", hello, std::string("hello"));
464		ensure_equals("second word", world, std::string("world"));
465	}
466}
467
468namespace tut
469{
470	struct U64_data
471	{
472	};
473	typedef test_group<U64_data> U64_test;
474	typedef U64_test::object U64_object;
475	tut::U64_test U64_testcase("U64_conversion");
476
477	// U64_to_str
478	template<> template<>
479	void U64_object::test<1>()
480	{
481		U64 val;
482		std::string val_str;
483		char result[256];
484		std::string result_str;
485
486		val = U64L(18446744073709551610); // slightly less than MAX_U64
487		val_str = "18446744073709551610";
488
489		U64_to_str(val, result, sizeof(result));
490		result_str = (const char*) result;
491		ensure_equals("U64_to_str converted 1.1", val_str, result_str);
492
493		val = 0;
494		val_str = "0";
495		U64_to_str(val, result, sizeof(result));
496		result_str = (const char*) result;
497		ensure_equals("U64_to_str converted 1.2", val_str, result_str);
498
499		val = U64L(18446744073709551615); // 0xFFFFFFFFFFFFFFFF
500		val_str = "18446744073709551615";
501		U64_to_str(val, result, sizeof(result));
502		result_str = (const char*) result;
503		ensure_equals("U64_to_str converted 1.3", val_str, result_str);
504
505		// overflow - will result in warning at compile time
506		val = U64L(18446744073709551615) + 1; // overflow 0xFFFFFFFFFFFFFFFF + 1 == 0
507		val_str = "0";
508		U64_to_str(val, result, sizeof(result));
509		result_str = (const char*) result;
510		ensure_equals("U64_to_str converted 1.4", val_str, result_str);
511
512		val = U64L(-1); // 0xFFFFFFFFFFFFFFFF == 18446744073709551615
513		val_str = "18446744073709551615";
514		U64_to_str(val, result, sizeof(result));
515		result_str = (const char*) result;
516		ensure_equals("U64_to_str converted 1.5", val_str, result_str);
517
518		val = U64L(10000000000000000000); // testing preserving of 0s
519		val_str = "10000000000000000000";
520		U64_to_str(val, result, sizeof(result));
521		result_str = (const char*) result;
522		ensure_equals("U64_to_str converted 1.6", val_str, result_str);
523
524		val = 1; // testing no leading 0s
525		val_str = "1";
526		U64_to_str(val, result, sizeof(result));
527		result_str = (const char*) result;
528		ensure_equals("U64_to_str converted 1.7", val_str, result_str);
529
530		val = U64L(18446744073709551615); // testing exact sized buffer for result
531		val_str = "18446744073709551615";
532		memset(result, 'A', sizeof(result)); // initialize buffer with all 'A'
533		U64_to_str(val, result, sizeof("18446744073709551615")); //pass in the exact size
534		result_str = (const char*) result;
535		ensure_equals("U64_to_str converted 1.8", val_str, result_str);
536
537		val = U64L(18446744073709551615); // testing smaller sized buffer for result
538		val_str = "1844";
539		memset(result, 'A', sizeof(result)); // initialize buffer with all 'A'
540		U64_to_str(val, result, 5); //pass in a size of 5. should only copy first 4 integers and add a null terminator
541		result_str = (const char*) result;
542		ensure_equals("U64_to_str converted 1.9", val_str, result_str);
543	}
544
545	// str_to_U64
546	template<> template<>
547	void U64_object::test<2>()
548	{
549		U64 val;
550		U64 result;
551
552		val = U64L(18446744073709551610); // slightly less than MAX_U64
553		result = str_to_U64("18446744073709551610");
554		ensure_equals("str_to_U64 converted 2.1", val, result);
555
556		val = U64L(0); // empty string
557		result = str_to_U64(LLStringUtil::null);
558		ensure_equals("str_to_U64 converted 2.2", val, result);
559
560		val = U64L(0); // 0
561		result = str_to_U64("0");
562		ensure_equals("str_to_U64 converted 2.3", val, result);
563
564		val = U64L(18446744073709551615); // 0xFFFFFFFFFFFFFFFF
565		result = str_to_U64("18446744073709551615");
566		ensure_equals("str_to_U64 converted 2.4", val, result);
567
568		// overflow - will result in warning at compile time
569		val = U64L(18446744073709551615) + 1; // overflow 0xFFFFFFFFFFFFFFFF + 1 == 0
570		result = str_to_U64("18446744073709551616");
571		ensure_equals("str_to_U64 converted 2.5", val, result);
572
573		val = U64L(1234); // process till first non-integral character
574		result = str_to_U64("1234A5678");
575		ensure_equals("str_to_U64 converted 2.6", val, result);
576
577		val = U64L(5678); // skip all non-integral characters
578		result = str_to_U64("ABCD5678");
579		ensure_equals("str_to_U64 converted 2.7", val, result);
580
581		// should it skip negative sign and process 
582		// rest of string or return 0
583		val = U64L(1234); // skip initial negative sign 
584		result = str_to_U64("-1234");
585		ensure_equals("str_to_U64 converted 2.8", val, result);
586
587		val = U64L(5678); // stop at negative sign in the middle
588		result = str_to_U64("5678-1234");
589		ensure_equals("str_to_U64 converted 2.9", val, result);
590
591		val = U64L(0); // no integers
592		result = str_to_U64("AaCD");
593		ensure_equals("str_to_U64 converted 2.10", val, result);
594	}
595
596	// U64_to_F64
597	template<> template<>
598	void U64_object::test<3>()
599	{
600		F64 val;
601		F64 result;
602
603		result = 18446744073709551610.0;
604		val = U64_to_F64(U64L(18446744073709551610));
605		ensure_equals("U64_to_F64 converted 3.1", val, result);
606
607		result = 18446744073709551615.0; // 0xFFFFFFFFFFFFFFFF
608		val = U64_to_F64(U64L(18446744073709551615));
609		ensure_equals("U64_to_F64 converted 3.2", val, result);
610
611		result = 0.0; // overflow 0xFFFFFFFFFFFFFFFF + 1 == 0
612		// overflow - will result in warning at compile time
613		val = U64_to_F64(U64L(18446744073709551615)+1);
614		ensure_equals("U64_to_F64 converted 3.3", val, result);
615
616		result = 0.0; // 0
617		val = U64_to_F64(U64L(0));
618		ensure_equals("U64_to_F64 converted 3.4", val, result);
619
620		result = 1.0; // odd
621		val = U64_to_F64(U64L(1));
622		ensure_equals("U64_to_F64 converted 3.5", val, result);
623
624		result = 2.0; // even
625		val = U64_to_F64(U64L(2));
626		ensure_equals("U64_to_F64 converted 3.6", val, result);
627
628		result = U64L(0x7FFFFFFFFFFFFFFF) * 1.0L; // 0x7FFFFFFFFFFFFFFF
629		val = U64_to_F64(U64L(0x7FFFFFFFFFFFFFFF));
630		ensure_equals("U64_to_F64 converted 3.7", val, result);
631	}
632
633	// llstrtou64 
634	// seems to be deprecated - could not find it being used 
635	// anywhere in the tarball - skipping unit tests for now
636}
637
638
639namespace tut
640{
641	struct hash_data
642	{
643	};
644	typedef test_group<hash_data> hash_test;
645	typedef hash_test::object hash_object;
646	tut::hash_test hash_tester("LLHash");
647
648	template<> template<>
649	void hash_object::test<1>()
650	{
651		const char * str1 = "test string one";
652		const char * same_as_str1 = "test string one";
653
654		size_t hash1 = llhash(str1);
655		size_t same_as_hash1 = llhash(same_as_str1);
656
657
658		ensure("Hashes from identical strings should be equal", hash1 == same_as_hash1);
659		
660		char str[100];
661		strcpy( str, "Another test" );
662
663		size_t hash2 = llhash(str);
664		
665		strcpy( str, "Different string, same pointer" );
666
667		size_t hash3 = llhash(str);
668
669		ensure("Hashes from same pointer but different string should not be equal", hash2 != hash3);
670	}
671}