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(uint32_t oldCrc,size_t len,const uint8_t * data)38 uint32_t advanceCrc32(uint32_t oldCrc, size_t len, const uint8_t *data)
39 {
40 const uint32_t generator = 0x04C11DB7u;
41 uint32_t crc = oldCrc;
42
43 for (size_t i = 0; i < len; i++)
44 {
45 const uint32_t current = static_cast<uint32_t>(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 } // namespace
61
SeedBuilder(void)62 SeedBuilder::SeedBuilder(void) : m_hash(0xccf139d7u)
63 {
64 }
65
feed(size_t size,const void * ptr)66 void SeedBuilder::feed(size_t size, const void *ptr)
67 {
68 m_hash = advanceCrc32(m_hash, size, (const uint8_t *)ptr);
69 }
70
operator <<(SeedBuilder & builder,bool value)71 SeedBuilder &operator<<(SeedBuilder &builder, bool value)
72 {
73 const uint8_t val = (value ? 54 : 7);
74
75 builder.feed(sizeof(val), &val);
76 return builder;
77 }
78
operator <<(SeedBuilder & builder,int8_t value)79 SeedBuilder &operator<<(SeedBuilder &builder, int8_t value)
80 {
81 const int8_t val = value ^ 75;
82
83 builder.feed(sizeof(val), &val);
84 return builder;
85 }
86
operator <<(SeedBuilder & builder,uint8_t value)87 SeedBuilder &operator<<(SeedBuilder &builder, uint8_t value)
88 {
89 const uint8_t val = value ^ 140u;
90
91 builder.feed(sizeof(val), &val);
92 return builder;
93 }
94
operator <<(SeedBuilder & builder,int16_t value)95 SeedBuilder &operator<<(SeedBuilder &builder, int16_t value)
96 {
97 const int16_t val = value ^ 555;
98 const uint8_t data[] = {
99 (uint8_t)(((uint16_t)val) & 0xFFu),
100 (uint8_t)(((uint16_t)val) >> 8),
101 };
102
103 builder.feed(sizeof(data), data);
104 return builder;
105 }
106
operator <<(SeedBuilder & builder,uint16_t value)107 SeedBuilder &operator<<(SeedBuilder &builder, uint16_t value)
108 {
109 const uint16_t val = value ^ 37323u;
110 const uint8_t data[] = {
111 (uint8_t)(val & 0xFFu),
112 (uint8_t)(val >> 8),
113 };
114
115 builder.feed(sizeof(data), data);
116 return builder;
117 }
118
operator <<(SeedBuilder & builder,int32_t value)119 SeedBuilder &operator<<(SeedBuilder &builder, int32_t value)
120 {
121 const int32_t val = value ^ 53054741;
122 const uint8_t data[] = {
123 (uint8_t)(((uint32_t)val) & 0xFFu),
124 (uint8_t)((((uint32_t)val) >> 8) & 0xFFu),
125 (uint8_t)((((uint32_t)val) >> 16) & 0xFFu),
126 (uint8_t)((((uint32_t)val) >> 24) & 0xFFu),
127 };
128
129 builder.feed(sizeof(data), data);
130 return builder;
131 }
132
operator <<(SeedBuilder & builder,uint32_t value)133 SeedBuilder &operator<<(SeedBuilder &builder, uint32_t value)
134 {
135 const uint32_t val = value ^ 1977303630u;
136 const uint8_t data[] = {
137 (uint8_t)(val & 0xFFu),
138 (uint8_t)((val >> 8) & 0xFFu),
139 (uint8_t)((val >> 16) & 0xFFu),
140 (uint8_t)((val >> 24) & 0xFFu),
141 };
142
143 builder.feed(sizeof(data), data);
144 return builder;
145 }
146
operator <<(SeedBuilder & builder,int64_t value)147 SeedBuilder &operator<<(SeedBuilder &builder, int64_t value)
148 {
149 const int64_t val = value ^ 772935234179004386ll;
150 const uint8_t data[] = {
151 (uint8_t)(((uint64_t)val) & 0xFFu), (uint8_t)((((uint64_t)val) >> 8) & 0xFFu),
152 (uint8_t)((((uint64_t)val) >> 16) & 0xFFu), (uint8_t)((((uint64_t)val) >> 24) & 0xFFu),
153
154 (uint8_t)((((uint64_t)val) >> 32) & 0xFFu), (uint8_t)((((uint64_t)val) >> 40) & 0xFFu),
155 (uint8_t)((((uint64_t)val) >> 48) & 0xFFu), (uint8_t)((((uint64_t)val) >> 56) & 0xFFu),
156 };
157
158 builder.feed(sizeof(data), data);
159 return builder;
160 }
161
operator <<(SeedBuilder & builder,uint64_t value)162 SeedBuilder &operator<<(SeedBuilder &builder, uint64_t value)
163 {
164 const uint64_t val = value ^ 4664937258000467599ull;
165 const uint8_t data[] = {
166 (uint8_t)(val & 0xFFu), (uint8_t)((val >> 8) & 0xFFu),
167 (uint8_t)((val >> 16) & 0xFFu), (uint8_t)((val >> 24) & 0xFFu),
168
169 (uint8_t)((val >> 32) & 0xFFu), (uint8_t)((val >> 40) & 0xFFu),
170 (uint8_t)((val >> 48) & 0xFFu), (uint8_t)((val >> 56) & 0xFFu),
171 };
172
173 builder.feed(sizeof(data), data);
174 return builder;
175 }
176
operator <<(SeedBuilder & builder,float value)177 SeedBuilder &operator<<(SeedBuilder &builder, float value)
178 {
179 // \note Assume that float has same endianess as uint32.
180 uint32_t val;
181
182 deMemcpy(&val, &value, sizeof(uint32_t));
183
184 {
185 const uint8_t data[] = {
186 (uint8_t)(val & 0xFFu),
187 (uint8_t)((val >> 8) & 0xFFu),
188 (uint8_t)((val >> 16) & 0xFFu),
189 (uint8_t)((val >> 24) & 0xFFu),
190 };
191
192 builder.feed(sizeof(data), data);
193 return builder;
194 }
195 }
196
operator <<(SeedBuilder & builder,double value)197 SeedBuilder &operator<<(SeedBuilder &builder, double value)
198 {
199 // \note Assume that double has same endianess as uint64.
200 uint64_t val;
201
202 deMemcpy(&val, &value, sizeof(uint64_t));
203
204 const uint8_t data[] = {
205 (uint8_t)(val & 0xFFu), (uint8_t)((val >> 8) & 0xFFu),
206 (uint8_t)((val >> 16) & 0xFFu), (uint8_t)((val >> 24) & 0xFFu),
207
208 (uint8_t)((val >> 32) & 0xFFu), (uint8_t)((val >> 40) & 0xFFu),
209 (uint8_t)((val >> 48) & 0xFFu), (uint8_t)((val >> 56) & 0xFFu),
210 };
211
212 builder.feed(sizeof(data), data);
213 return builder;
214 }
215
operator <<(SeedBuilder & builder,const std::string & value)216 SeedBuilder &operator<<(SeedBuilder &builder, const std::string &value)
217 {
218 builder.feed(value.length(), value.c_str());
219 return builder;
220 }
221
222 } // namespace tcu
223