1/*-------------------------------------------------------------------------
2 * drawElements Quality Program Tester Core
3 * ----------------------------------------
4 *
5 * Copyright 2014 The Android Open Source Project
6 *
7 * Licensed under the Apache License, Version 2.0 (the "License");
8 * you may not use this file except in compliance with the License.
9 * You may obtain a copy of the License at
10 *
11 *      http://www.apache.org/licenses/LICENSE-2.0
12 *
13 * Unless required by applicable law or agreed to in writing, software
14 * distributed under the License is distributed on an "AS IS" BASIS,
15 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
16 * See the License for the specific language governing permissions and
17 * limitations under the License.
18 *
19 *//*!
20 * \file
21 * \brief Utility class to build seeds from different data types.
22 *
23 * Values are first XORed with type specifig mask, which makes sure that
24 * two values with different types, but same bit presentation produce
25 * different results. Then values are passed through 32 bit crc.
26 *//*--------------------------------------------------------------------*/
27
28#include "tcuSeedBuilder.hpp"
29
30#include "deMemory.h"
31
32namespace tcu
33{
34
35namespace
36{
37
38deUint32 advanceCrc32 (deUint32 oldCrc, size_t len, const deUint8* data)
39{
40	const deUint32	generator	= 0x04C11DB7u;
41	deUint32		crc			= oldCrc;
42
43	for (size_t i = 0; i < len; i++)
44	{
45		const deUint32 current = static_cast<deUint32>(data[i]);
46		crc = crc ^ current;
47
48		for (size_t bitNdx = 0; bitNdx < 8; bitNdx++)
49		{
50			if (crc & 1u)
51				crc = (crc >> 1u) ^ generator;
52			else
53				crc = (crc >> 1u);
54		}
55	}
56
57	return crc;
58}
59
60} // anonymous
61
62SeedBuilder::SeedBuilder (void)
63	: m_hash (0xccf139d7u)
64{
65}
66
67void SeedBuilder::feed (size_t size, const void* ptr)
68{
69	m_hash = advanceCrc32(m_hash, size, (const deUint8*)ptr);
70}
71
72SeedBuilder& operator<< (SeedBuilder& builder, bool value)
73{
74	const deUint8 val = (value ? 54: 7);
75
76	builder.feed(sizeof(val), &val);
77	return builder;
78}
79
80SeedBuilder& operator<< (SeedBuilder& builder, deInt8 value)
81{
82	const deInt8 val = value ^ 75;
83
84	builder.feed(sizeof(val), &val);
85	return builder;
86}
87
88SeedBuilder& operator<< (SeedBuilder& builder, deUint8 value)
89{
90	const deInt8 val = value ^ 140u;
91
92	builder.feed(sizeof(val), &val);
93	return builder;
94}
95
96SeedBuilder& operator<< (SeedBuilder& builder, deInt16 value)
97{
98	const deInt16	val		= value ^ 555;
99	const deUint8	data[]	=
100	{
101		(deUint8)(((deUint16)val) & 0xFFu),
102		(deUint8)(((deUint16)val) >> 8),
103	};
104
105	builder.feed(sizeof(data), data);
106	return builder;
107}
108
109SeedBuilder& operator<< (SeedBuilder& builder, deUint16 value)
110{
111	const deUint16	val		= value ^ 37323u;
112	const deUint8	data[]	=
113	{
114		(deUint8)(val & 0xFFu),
115		(deUint8)(val >> 8),
116	};
117
118	builder.feed(sizeof(data), data);
119	return builder;
120}
121
122SeedBuilder& operator<< (SeedBuilder& builder, deInt32 value)
123{
124	const deInt32	val		= value ^ 53054741;
125	const deUint8	data[]	=
126	{
127		(deUint8)(((deUint32)val) & 0xFFu),
128		(deUint8)((((deUint32)val) >> 8) & 0xFFu),
129		(deUint8)((((deUint32)val) >> 16) & 0xFFu),
130		(deUint8)((((deUint32)val) >> 24) & 0xFFu),
131	};
132
133	builder.feed(sizeof(data), data);
134	return builder;
135}
136
137SeedBuilder& operator<< (SeedBuilder& builder, deUint32 value)
138{
139	const deUint32	val		= value ^ 1977303630u;
140	const deUint8	data[]	=
141	{
142		(deUint8)(val & 0xFFu),
143		(deUint8)((val >> 8) & 0xFFu),
144		(deUint8)((val >> 16) & 0xFFu),
145		(deUint8)((val >> 24) & 0xFFu),
146	};
147
148	builder.feed(sizeof(data), data);
149	return builder;
150}
151
152SeedBuilder& operator<< (SeedBuilder& builder, deInt64 value)
153{
154	const deInt64	val		= value ^ 772935234179004386ll;
155	const deUint8	data[]	=
156	{
157		(deUint8)(((deUint64)val) & 0xFFu),
158		(deUint8)((((deUint64)val) >> 8) & 0xFFu),
159		(deUint8)((((deUint64)val) >> 16) & 0xFFu),
160		(deUint8)((((deUint64)val) >> 24) & 0xFFu),
161
162		(deUint8)((((deUint64)val) >> 32) & 0xFFu),
163		(deUint8)((((deUint64)val) >> 40) & 0xFFu),
164		(deUint8)((((deUint64)val) >> 48) & 0xFFu),
165		(deUint8)((((deUint64)val) >> 56) & 0xFFu),
166	};
167
168	builder.feed(sizeof(data), data);
169	return builder;
170}
171
172SeedBuilder& operator<< (SeedBuilder& builder, deUint64 value)
173{
174	const deUint64	val		= value ^ 4664937258000467599ull;
175	const deUint8	data[]	=
176	{
177		(deUint8)(val & 0xFFu),
178		(deUint8)((val >> 8) & 0xFFu),
179		(deUint8)((val >> 16) & 0xFFu),
180		(deUint8)((val >> 24) & 0xFFu),
181
182		(deUint8)((val >> 32) & 0xFFu),
183		(deUint8)((val >> 40) & 0xFFu),
184		(deUint8)((val >> 48) & 0xFFu),
185		(deUint8)((val >> 56) & 0xFFu),
186	};
187
188	builder.feed(sizeof(data), data);
189	return builder;
190}
191
192SeedBuilder& operator<< (SeedBuilder& builder, float value)
193{
194	// \note Assume that float has same endianess as uint32.
195	deUint32 val;
196
197	deMemcpy(&val, &value, sizeof(deUint32));
198
199	{
200		const deUint8	data[]	=
201		{
202			(deUint8)(val & 0xFFu),
203			(deUint8)((val >> 8) & 0xFFu),
204			(deUint8)((val >> 16) & 0xFFu),
205			(deUint8)((val >> 24) & 0xFFu),
206		};
207
208		builder.feed(sizeof(data), data);
209		return builder;
210	}
211}
212
213SeedBuilder& operator<< (SeedBuilder& builder, double value)
214{
215	// \note Assume that double has same endianess as uint64.
216	deUint64 val;
217
218	deMemcpy(&val, &value, sizeof(deUint64));
219
220	const deUint8	data[]	=
221	{
222		(deUint8)(val & 0xFFu),
223		(deUint8)((val >> 8) & 0xFFu),
224		(deUint8)((val >> 16) & 0xFFu),
225		(deUint8)((val >> 24) & 0xFFu),
226
227		(deUint8)((val >> 32) & 0xFFu),
228		(deUint8)((val >> 40) & 0xFFu),
229		(deUint8)((val >> 48) & 0xFFu),
230		(deUint8)((val >> 56) & 0xFFu),
231	};
232
233	builder.feed(sizeof(data), data);
234	return builder;
235}
236
237SeedBuilder& operator<< (SeedBuilder& builder, const std::string& value)
238{
239	builder.feed(value.length(), value.c_str());
240	return builder;
241}
242
243} // tcu
244