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 
32 namespace tcu
33 {
34 
35 namespace
36 {
37 
advanceCrc32(deUint32 oldCrc,size_t len,const deUint8 * data)38 deUint32 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 
SeedBuilder(void)62 SeedBuilder::SeedBuilder (void)
63 	: m_hash (0xccf139d7u)
64 {
65 }
66 
feed(size_t size,const void * ptr)67 void SeedBuilder::feed (size_t size, const void* ptr)
68 {
69 	m_hash = advanceCrc32(m_hash, size, (const deUint8*)ptr);
70 }
71 
operator <<(SeedBuilder & builder,bool value)72 SeedBuilder& 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 
operator <<(SeedBuilder & builder,deInt8 value)80 SeedBuilder& operator<< (SeedBuilder& builder, deInt8 value)
81 {
82 	const deInt8 val = value ^ 75;
83 
84 	builder.feed(sizeof(val), &val);
85 	return builder;
86 }
87 
operator <<(SeedBuilder & builder,deUint8 value)88 SeedBuilder& operator<< (SeedBuilder& builder, deUint8 value)
89 {
90 	const deUint8 val = value ^ 140u;
91 
92 	builder.feed(sizeof(val), &val);
93 	return builder;
94 }
95 
operator <<(SeedBuilder & builder,deInt16 value)96 SeedBuilder& 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 
operator <<(SeedBuilder & builder,deUint16 value)109 SeedBuilder& 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 
operator <<(SeedBuilder & builder,deInt32 value)122 SeedBuilder& 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 
operator <<(SeedBuilder & builder,deUint32 value)137 SeedBuilder& 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 
operator <<(SeedBuilder & builder,deInt64 value)152 SeedBuilder& 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 
operator <<(SeedBuilder & builder,deUint64 value)172 SeedBuilder& 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 
operator <<(SeedBuilder & builder,float value)192 SeedBuilder& 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 
operator <<(SeedBuilder & builder,double value)213 SeedBuilder& 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 
operator <<(SeedBuilder & builder,const std::string & value)237 SeedBuilder& operator<< (SeedBuilder& builder, const std::string& value)
238 {
239 	builder.feed(value.length(), value.c_str());
240 	return builder;
241 }
242 
243 } // tcu
244