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 deInt8 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