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