Home | History | Annotate | Download | only in common
      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 
     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 
     62 SeedBuilder::SeedBuilder (void)
     63 	: m_hash (0xccf139d7u)
     64 {
     65 }
     66 
     67 void SeedBuilder::feed (size_t size, const void* ptr)
     68 {
     69 	m_hash = advanceCrc32(m_hash, size, (const deUint8*)ptr);
     70 }
     71 
     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 
     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 
     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 
     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 
    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 
    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 
    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 
    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 
    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 
    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 
    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 
    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