Moving hash and file_io to core

Change-Id: I1e6eece53fadf62a8919aa41e04deee3dac2ce60
This commit is contained in:
Jaroslaw Chodor
2019-10-16 22:21:04 +02:00
committed by sys_ocldev
parent 239fe2a0fe
commit 90e5cf164c
59 changed files with 80 additions and 78 deletions

View File

@@ -12,6 +12,9 @@ set(NEO_CORE_HELPERS
${CMAKE_CURRENT_SOURCE_DIR}/debug_helpers.h
${CMAKE_CURRENT_SOURCE_DIR}/deferred_deleter_helper.h
${CMAKE_CURRENT_SOURCE_DIR}/extendable_enum.h
${CMAKE_CURRENT_SOURCE_DIR}/file_io.cpp
${CMAKE_CURRENT_SOURCE_DIR}/file_io.h
${CMAKE_CURRENT_SOURCE_DIR}/hash.h
${CMAKE_CURRENT_SOURCE_DIR}/interlocked_max.h
${CMAKE_CURRENT_SOURCE_DIR}/non_copyable_or_moveable.h
${CMAKE_CURRENT_SOURCE_DIR}/pipeline_select_args.h
@@ -20,6 +23,7 @@ set(NEO_CORE_HELPERS
${CMAKE_CURRENT_SOURCE_DIR}/preamble_base.inl
${CMAKE_CURRENT_SOURCE_DIR}/preamble_bdw_plus.inl
${CMAKE_CURRENT_SOURCE_DIR}/register_offsets.h
${CMAKE_CURRENT_SOURCE_DIR}/stdio.h
${CMAKE_CURRENT_SOURCE_DIR}/string.h
${CMAKE_CURRENT_SOURCE_DIR}/vec.h
)

98
core/helpers/file_io.cpp Normal file
View File

@@ -0,0 +1,98 @@
/*
* Copyright (C) 2017-2019 Intel Corporation
*
* SPDX-License-Identifier: MIT
*
*/
#include "file_io.h"
#include "core/helpers/debug_helpers.h"
#include "core/helpers/stdio.h"
#include <cstring>
#include <new>
std::unique_ptr<char[]> loadDataFromFile(
const char *filename,
size_t &retSize) {
FILE *fp = nullptr;
size_t nsize = 0;
std::unique_ptr<char[]> ret;
DEBUG_BREAK_IF(nullptr == filename);
// Open the file
fopen_s(&fp, filename, "rb");
if (fp) {
// Allocate a buffer for the file contents
fseek(fp, 0, SEEK_END);
nsize = (size_t)ftell(fp);
fseek(fp, 0, SEEK_SET);
ret.reset(new (std::nothrow) char[nsize + 1]);
if (ret) {
// we initialize to all zeroes before reading in data
memset(ret.get(), 0x00, nsize + 1);
auto read = fread(ret.get(), sizeof(unsigned char), nsize, fp);
DEBUG_BREAK_IF(read != nsize);
((void)(read));
} else {
nsize = 0;
}
fclose(fp);
}
retSize = nsize;
return ret;
}
size_t writeDataToFile(
const char *filename,
const void *pData,
size_t dataSize) {
FILE *fp = nullptr;
size_t nsize = 0;
DEBUG_BREAK_IF(nullptr == pData);
DEBUG_BREAK_IF(nullptr == filename);
fopen_s(&fp, filename, "wb");
if (fp) {
nsize = fwrite(pData, sizeof(unsigned char), dataSize, fp);
fclose(fp);
}
return nsize;
}
bool fileExists(const std::string &fileName) {
FILE *pFile = nullptr;
DEBUG_BREAK_IF(fileName.empty());
DEBUG_BREAK_IF(fileName == "");
fopen_s(&pFile, fileName.c_str(), "rb");
if (pFile) {
fclose(pFile);
}
return pFile != nullptr;
}
bool fileExistsHasSize(const std::string &fileName) {
FILE *pFile = nullptr;
size_t nsize = 0;
DEBUG_BREAK_IF(fileName.empty());
DEBUG_BREAK_IF(fileName == "");
fopen_s(&pFile, fileName.c_str(), "rb");
if (pFile) {
fseek(pFile, 0, SEEK_END);
nsize = (size_t)ftell(pFile);
fclose(pFile);
}
return pFile != nullptr && nsize > 0;
}

24
core/helpers/file_io.h Normal file
View File

@@ -0,0 +1,24 @@
/*
* Copyright (C) 2017-2019 Intel Corporation
*
* SPDX-License-Identifier: MIT
*
*/
#pragma once
#include <cstdint>
#include <memory>
#include <string>
std::unique_ptr<char[]> loadDataFromFile(
const char *filename,
size_t &retSize);
size_t writeDataToFile(
const char *filename,
const void *pData,
size_t dataSize);
bool fileExists(const std::string &fileName);
bool fileExistsHasSize(const std::string &fileName);

117
core/helpers/hash.h Normal file
View File

@@ -0,0 +1,117 @@
/*
* Copyright (C) 2017-2019 Intel Corporation
*
* SPDX-License-Identifier: MIT
*
*/
#pragma once
#include "common/compiler_support.h"
#include "core/helpers/aligned_memory.h"
#include <cstdint>
namespace NEO {
// clang-format off
#define HASH_JENKINS_MIX(a,b,c) \
{ \
a -= b; a -= c; a ^= (c>>13); \
b -= c; b -= a; b ^= (a<<8); \
c -= a; c -= b; c ^= (b>>13); \
a -= b; a -= c; a ^= (c>>12); \
b -= c; b -= a; b ^= (a<<16); \
c -= a; c -= b; c ^= (b>>5); \
a -= b; a -= c; a ^= (c>>3); \
b -= c; b -= a; b ^= (a<<10); \
c -= a; c -= b; c ^= (b>>15); \
}
// clang-format on
class Hash {
public:
Hash() {
reset();
};
uint32_t getValue(const char *data, size_t size) {
uint32_t value = 0;
switch (size) {
case 3:
value = static_cast<uint32_t>(*reinterpret_cast<const unsigned char *>(data++));
value <<= 8;
CPP_ATTRIBUTE_FALLTHROUGH;
case 2:
value |= static_cast<uint32_t>(*reinterpret_cast<const unsigned char *>(data++));
value <<= 8;
CPP_ATTRIBUTE_FALLTHROUGH;
case 1:
value |= static_cast<uint32_t>(*reinterpret_cast<const unsigned char *>(data++));
value <<= 8;
}
return value;
}
void update(const char *buff, size_t size) {
if (buff == nullptr)
return;
if ((reinterpret_cast<uintptr_t>(buff) & 0x3) != 0) {
const unsigned char *tmp = (const unsigned char *)buff;
while (size >= sizeof(uint32_t)) {
uint32_t value = (uint32_t)tmp[0] + (((uint32_t)tmp[1]) << 8) + ((uint32_t)tmp[2] << 16) + ((uint32_t)tmp[3] << 24);
a ^= value;
HASH_JENKINS_MIX(a, hi, lo);
size -= sizeof(uint32_t);
tmp += sizeof(uint32_t);
}
if (size > 0) {
uint32_t value = getValue((char *)tmp, size);
a ^= value;
HASH_JENKINS_MIX(a, hi, lo);
}
} else {
const uint32_t *tmp = reinterpret_cast<const uint32_t *>(buff);
while (size >= sizeof(*tmp)) {
a ^= *(tmp++);
HASH_JENKINS_MIX(a, hi, lo);
size -= sizeof(*tmp);
}
if (size > 0) {
uint32_t value = getValue((char *)tmp, size);
a ^= value;
HASH_JENKINS_MIX(a, hi, lo);
}
}
}
uint64_t finish() {
return (((uint64_t)hi) << 32) | lo;
}
void reset() {
a = 0x428a2f98;
hi = 0x71374491;
lo = 0xb5c0fbcf;
}
static uint64_t hash(const char *buff, size_t size) {
Hash hash;
hash.update(buff, size);
return hash.finish();
}
protected:
uint32_t a, hi, lo;
};
template <typename T>
uint32_t hashPtrToU32(const T *src) {
auto asInt = reinterpret_cast<uintptr_t>(src);
constexpr auto m = sizeof(uintptr_t) / 8;
asInt = asInt ^ ((asInt & ~(m - 1)) >> (m * 32));
return static_cast<uint32_t>(asInt);
}
} // namespace NEO

31
core/helpers/stdio.h Normal file
View File

@@ -0,0 +1,31 @@
/*
* Copyright (C) 2017-2019 Intel Corporation
*
* SPDX-License-Identifier: MIT
*
*/
#pragma once
#ifndef _WIN32
#ifndef __STDC_LIB_EXT1__
#if __STDC_WANT_LIB_EXT1__ != 1
#include <cstdio>
#include <errno.h>
inline int fopen_s(FILE **pFile, const char *filename, const char *mode) {
if ((pFile == nullptr) || (filename == nullptr) || (mode == nullptr)) {
return -EINVAL;
}
*pFile = fopen(filename, mode);
if (*pFile == nullptr) {
return -errno;
}
return 0;
}
#endif
#endif
#endif

View File

@@ -7,8 +7,12 @@
set(NEO_CORE_HELPERS_TESTS
${CMAKE_CURRENT_SOURCE_DIR}/CMakeLists.txt
${CMAKE_CURRENT_SOURCE_DIR}/debug_manager_state_restore.h
${CMAKE_CURRENT_SOURCE_DIR}/file_io_tests.cpp
${CMAKE_CURRENT_SOURCE_DIR}/hash_tests.cpp
${CMAKE_CURRENT_SOURCE_DIR}/memory_leak_listener.h
${CMAKE_CURRENT_SOURCE_DIR}/memory_management.h
${CMAKE_CURRENT_SOURCE_DIR}/string_tests.cpp
${CMAKE_CURRENT_SOURCE_DIR}/string_to_hash_tests.cpp
)
set_property(GLOBAL PROPERTY NEO_CORE_HELPERS_TESTS ${NEO_CORE_HELPERS_TESTS})

View File

@@ -0,0 +1,42 @@
/*
* Copyright (C) 2017-2019 Intel Corporation
*
* SPDX-License-Identifier: MIT
*
*/
#include "core/helpers/file_io.h"
#include "core/helpers/stdio.h"
#include "gtest/gtest.h"
#include <cstdio>
TEST(FileIO, existsHasSize) {
std::string fileName("fileIO.bin");
std::remove(fileName.c_str());
ASSERT_FALSE(fileExists(fileName.c_str()));
FILE *fp = nullptr;
fopen_s(&fp, fileName.c_str(), "wb");
ASSERT_NE(nullptr, fp);
fprintf(fp, "TEST");
fclose(fp);
EXPECT_TRUE(fileExists(fileName.c_str()));
EXPECT_TRUE(fileExistsHasSize(fileName.c_str()));
}
TEST(FileIO, existsSizeZero) {
std::string fileName("fileIO.bin");
std::remove(fileName.c_str());
ASSERT_FALSE(fileExists(fileName.c_str()));
FILE *fp = nullptr;
fopen_s(&fp, fileName.c_str(), "wb");
ASSERT_NE(nullptr, fp);
fclose(fp);
EXPECT_TRUE(fileExists(fileName.c_str()));
EXPECT_FALSE(fileExistsHasSize(fileName.c_str()));
}

View File

@@ -0,0 +1,36 @@
/*
* Copyright (C) 2018-2019 Intel Corporation
*
* SPDX-License-Identifier: MIT
*
*/
#include "core/helpers/hash.h"
#include "gtest/gtest.h"
using namespace NEO;
TEST(HashTests, givenSamePointersWhenHashIsCalculatedThenSame32BitValuesAreGenerated) {
uintptr_t ptr1UI = 1;
uintptr_t ptr2UI = 1;
void *ptr1 = reinterpret_cast<void *>(ptr1UI);
void *ptr2 = reinterpret_cast<void *>(ptr2UI);
uint32_t hash1 = hashPtrToU32(ptr1);
uint32_t hash2 = hashPtrToU32(ptr2);
EXPECT_EQ(hash1, hash2);
}
TEST(HashTests, givenDifferentPointersWhenHashIsCalculatedThenUnique32BitValuesAreGenerated) {
uintptr_t ptr1UI = 1;
uintptr_t ptr2UI = ptr1UI | (ptr1UI << ((sizeof(uintptr_t) / 2) * 8));
void *ptr1 = reinterpret_cast<void *>(ptr1UI);
void *ptr2 = reinterpret_cast<void *>(ptr2UI);
uint32_t hash1 = hashPtrToU32(ptr1);
uint32_t hash2 = hashPtrToU32(ptr2);
EXPECT_NE(hash1, hash2);
}

View File

@@ -0,0 +1,150 @@
/*
* Copyright (C) 2017-2019 Intel Corporation
*
* SPDX-License-Identifier: MIT
*
*/
#include "core/helpers/hash.h"
#include "core/helpers/string.h"
#include "gtest/gtest.h"
#if defined(__linux__)
TEST(StringHelpers, strncpy) {
char dst[1024] = "";
char src[1024] = "HelloWorld";
//preconditions
ASSERT_EQ(sizeof(dst), sizeof(src));
//String must be smaller than array capacity
ASSERT_LT(strlen(src), sizeof(src));
auto ret = strncpy_s(nullptr, 1024, src, 1024);
EXPECT_EQ(ret, -EINVAL);
ret = strncpy_s(dst, 1024, nullptr, 1024);
EXPECT_EQ(ret, -EINVAL);
ret = strncpy_s(dst, 512, src, 1024);
EXPECT_EQ(ret, -ERANGE);
memset(dst, 0, sizeof(dst));
ret = strncpy_s(dst, 1024, src, strlen(src) / 2);
EXPECT_EQ(ret, 0);
EXPECT_EQ(0, memcmp(dst, src, strlen(src) / 2));
for (size_t i = strlen(src) / 2; i < sizeof(dst); i++)
EXPECT_EQ(0, dst[i]);
memset(dst, 0, sizeof(dst));
ret = strncpy_s(dst, strlen(src) / 2, src, strlen(src) / 2);
EXPECT_EQ(ret, 0);
EXPECT_EQ(0, memcmp(dst, src, strlen(src) / 2));
for (size_t i = strlen(src) / 2; i < sizeof(dst); i++)
EXPECT_EQ(0, dst[i]);
strncpy_s(dst, 1024, src, 1024);
EXPECT_EQ(0, memcmp(dst, src, strlen(src)));
for (size_t i = strlen(src); i < sizeof(dst); i++)
EXPECT_EQ(0, dst[i]);
}
TEST(StringHelpers, memmove) {
char dst[1024] = "";
char src[1024] = "HelloWorld";
ASSERT_EQ(sizeof(dst), sizeof(src));
auto ret = memmove_s(nullptr, sizeof(dst), src, sizeof(src));
EXPECT_EQ(ret, -EINVAL);
ret = memmove_s(dst, sizeof(dst), nullptr, sizeof(src));
EXPECT_EQ(ret, -EINVAL);
ret = memmove_s(dst, sizeof(src) / 2, src, sizeof(src));
EXPECT_EQ(ret, -ERANGE);
memset(dst, 0, sizeof(dst));
ret = memmove_s(dst, sizeof(dst), src, sizeof(src));
EXPECT_EQ(ret, 0);
EXPECT_EQ(0, memcmp(dst, src, sizeof(dst)));
}
TEST(StringHelpers, strcpy) {
char dst[1024] = "";
char src[1024] = "HelloWorld";
ASSERT_EQ(sizeof(dst), sizeof(src));
auto ret = strcpy_s(nullptr, 0, src);
EXPECT_EQ(ret, -EINVAL);
ret = strcpy_s(nullptr, sizeof(dst), src);
EXPECT_EQ(ret, -EINVAL);
ret = strcpy_s(nullptr, 0, nullptr);
EXPECT_EQ(ret, -EINVAL);
ret = strcpy_s(nullptr, sizeof(dst), nullptr);
EXPECT_EQ(ret, -EINVAL);
ret = strcpy_s(dst, 0, nullptr);
EXPECT_EQ(ret, -EINVAL);
ret = strcpy_s(dst, strlen(src) / 2, src);
EXPECT_EQ(ret, -ERANGE);
ret = strcpy_s(dst, strlen(src), src);
EXPECT_EQ(ret, -ERANGE);
char pattern = 0x5a;
memset(dst, pattern, sizeof(dst));
ret = strcpy_s(dst, sizeof(dst), src);
EXPECT_EQ(ret, 0);
EXPECT_EQ(0, memcmp(dst, src, strlen(src)));
EXPECT_EQ(0, dst[strlen(src)]);
for (size_t i = strlen(src) + 1; i < sizeof(dst); i++)
EXPECT_EQ(pattern, dst[i]);
}
TEST(StringHelpers, strnlen) {
char src[1024] = "HelloWorld";
auto ret = strnlen_s(nullptr, sizeof(src));
EXPECT_EQ(ret, 0u);
ret = strnlen_s(src, 0);
EXPECT_EQ(ret, 0u);
ret = strnlen_s(src, sizeof(src));
EXPECT_EQ(ret, strlen(src));
}
TEST(StringHelpers, memcpy) {
char dst[1024] = "";
char src[1024] = "HelloWorld";
//preconditions
ASSERT_EQ(sizeof(dst), sizeof(src));
//String must be smaller than array capacity
ASSERT_LT(strlen(src), sizeof(src));
auto ret = memcpy_s(nullptr, sizeof(dst), src, sizeof(src));
EXPECT_EQ(ret, -EINVAL);
ret = memcpy_s(dst, sizeof(dst), nullptr, sizeof(src));
EXPECT_EQ(ret, -EINVAL);
ret = memcpy_s(dst, sizeof(dst) / 2, src, sizeof(src));
EXPECT_EQ(ret, -ERANGE);
memset(dst, 0, sizeof(dst));
ret = memcpy_s(dst, sizeof(dst), src, strlen(src) / 2);
EXPECT_EQ(ret, 0);
EXPECT_EQ(0, memcmp(dst, src, strlen(src) / 2));
for (size_t i = strlen(src) / 2; i < sizeof(dst); i++)
EXPECT_EQ(0, dst[i]);
}
#endif

View File

@@ -0,0 +1,238 @@
/*
* Copyright (C) 2017-2019 Intel Corporation
*
* SPDX-License-Identifier: MIT
*
*/
#include "core/helpers/hash.h"
#include "runtime/helpers/string_helpers.h"
#include "gtest/gtest.h"
using NEO::Hash;
TEST(CreateCombinedStrings, singleString) {
std::string dstString;
size_t dstStringSizeInBytes = 0;
const char srcString[] = "HelloWorld";
const char *pSrcString = srcString;
auto srcStrings = &pSrcString;
size_t lengths = strlen(srcString);
auto retVal = createCombinedString(
dstString,
dstStringSizeInBytes,
1,
srcStrings,
&lengths);
EXPECT_EQ(CL_SUCCESS, retVal);
EXPECT_EQ(lengths + 1, dstStringSizeInBytes);
EXPECT_EQ(0, strcmp(srcString, dstString.c_str()));
}
TEST(CreateCombinedStrings, SingleStringWithNullLengthNoCrash) {
std::string dstString;
size_t dstStringSizeInBytes = 0;
const char srcString[] = "HelloWorld";
const char *pSrcString = srcString;
auto srcStrings = &pSrcString;
auto retVal = createCombinedString(
dstString,
dstStringSizeInBytes,
1,
srcStrings,
nullptr);
EXPECT_EQ(CL_SUCCESS, retVal);
EXPECT_EQ(0, strcmp(srcString, dstString.c_str()));
}
TEST(CreateCombinedStrings, SingleStringWithZeroLengthNoCrash) {
std::string dstString;
size_t dstStringSizeInBytes = 0;
const char srcString[] = "HelloWorld";
const char *pSrcString = srcString;
auto srcStrings = &pSrcString;
size_t lengths = 0;
auto retVal = createCombinedString(
dstString,
dstStringSizeInBytes,
1,
srcStrings,
&lengths);
EXPECT_EQ(CL_SUCCESS, retVal);
EXPECT_EQ(0, strcmp(srcString, dstString.c_str()));
}
TEST(CreateCombinedStrings, multiString) {
std::string dstString;
size_t dstStringSizeInBytes = 0;
const char *srcString[] = {"HelloWorld", "dlroWolleH"};
std::string combined(srcString[0]);
combined += srcString[1];
auto srcStrings = &srcString[0];
size_t lengths[2] = {strlen(srcString[0]), strlen(srcString[1])};
auto retVal = createCombinedString(
dstString,
dstStringSizeInBytes,
2,
srcStrings,
lengths);
EXPECT_EQ(CL_SUCCESS, retVal);
EXPECT_EQ(0, strcmp(combined.c_str(), dstString.c_str()));
}
TEST(CreateCombinedStrings, multiStringWithNullLengthNoCrash) {
std::string dstString;
size_t dstStringSizeInBytes = 0;
const char *srcString[] = {"HelloWorld", "dlroWolleH"};
std::string combined(srcString[0]);
combined += srcString[1];
auto srcStrings = &srcString[0];
auto retVal = createCombinedString(
dstString,
dstStringSizeInBytes,
2,
srcStrings,
nullptr);
EXPECT_EQ(CL_SUCCESS, retVal);
EXPECT_EQ(0, strcmp(combined.c_str(), dstString.c_str()));
}
TEST(CreateCombinedStrings, multiStringWithZeroLengthNoCrash) {
std::string dstString;
size_t dstStringSizeInBytes = 0;
const char *srcString[] = {"HelloWorld", "dlroWolleH"};
std::string combined(srcString[0]);
combined += srcString[1];
auto srcStrings = &srcString[0];
size_t lengths[2] = {0, strlen(srcString[1])};
auto retVal = createCombinedString(
dstString,
dstStringSizeInBytes,
2,
srcStrings,
lengths);
EXPECT_EQ(CL_SUCCESS, retVal);
EXPECT_EQ(0, strcmp(combined.c_str(), dstString.c_str()));
}
TEST(CreateCombinedStrings, GivenMultipleStringWhichOneContainsAndErrorAndSizeThatForcesDriverToOmitTheErorrThenProgramSourceDoesntContainErrorString) {
std::string dstString;
size_t dstStringSizeInBytes = 0;
const char *srcString[] = {"HelloWorld", "dlroWolleHBABA"};
const char *expString[] = {"HelloWorld", "dlroWolleH"};
size_t lengths[2] = {0, strlen(expString[1])};
std::string combined(expString[0]);
combined += expString[1];
auto retVal = createCombinedString(
dstString,
dstStringSizeInBytes,
2,
srcString,
lengths);
EXPECT_EQ(CL_SUCCESS, retVal);
EXPECT_EQ(0, strcmp(combined.c_str(), dstString.c_str()));
}
TEST(CreateCombinedStrings, negativeScenarios) {
std::string dstString;
size_t dstStringSizeInBytes = 0;
const char *srcString[] = {"HelloWorld", "dlroWolleH"};
std::string combined(srcString[0]);
combined += srcString[1];
const char *srcStrings[2] = {srcString[0], srcString[1]};
size_t lengths[2] = {0, strlen(srcString[1])};
auto retVal = createCombinedString(
dstString,
dstStringSizeInBytes,
0,
srcStrings,
lengths);
EXPECT_EQ(CL_INVALID_VALUE, retVal);
retVal = createCombinedString(
dstString,
dstStringSizeInBytes,
1,
nullptr,
lengths);
EXPECT_EQ(CL_INVALID_VALUE, retVal);
srcStrings[0] = nullptr;
retVal = createCombinedString(
dstString,
dstStringSizeInBytes,
2,
srcStrings,
lengths);
EXPECT_EQ(CL_INVALID_VALUE, retVal);
}
TEST(CreateCombinedStrings, GivenMultipleStringThatCountIsHigherThenMaximalStackSizeSizesWhenAskedForCombinedThenProperStringIsRetruned) {
std::string dstString;
size_t dstStringSizeInBytes = 0;
const char *defaultString = "hello";
const char *srcString[maximalStackSizeSizes + 2];
std::string combinedString;
for (int i = 0; i < maximalStackSizeSizes + 2; i++) {
srcString[i] = defaultString;
combinedString += defaultString;
}
auto retVal = createCombinedString(
dstString,
dstStringSizeInBytes,
maximalStackSizeSizes + 2,
srcString,
nullptr);
EXPECT_EQ(CL_SUCCESS, retVal);
EXPECT_EQ(0, strcmp(combinedString.c_str(), dstString.c_str()));
}
TEST(CreateHash, HashBuffers) {
char pBuffer[128];
memset(pBuffer, 0x23, sizeof(pBuffer));
// make sure we can get a hash and make sure we can get the same hash
auto hash1 = Hash::hash(pBuffer, sizeof(pBuffer));
auto hash2 = Hash::hash(pBuffer, sizeof(pBuffer));
EXPECT_NE(0u, hash1);
EXPECT_NE(0u, hash2);
EXPECT_EQ(hash1, hash2);
// make sure that we get a different hash for different length/data
auto hash3 = Hash::hash(pBuffer, sizeof(pBuffer) - 1);
EXPECT_NE(0u, hash3);
EXPECT_NE(hash2, hash3);
}
TEST(CreateHash, unalignedLengths) {
char pBuffer[] = {
0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55};
// Use unaligned lengths. Wiggle the byte after the length
// Shouldn't affect hash.
for (auto length = 1u; length < sizeof(pBuffer); length++) {
auto hash1 = Hash::hash(pBuffer, length);
pBuffer[length]++;
EXPECT_EQ(hash1, Hash::hash(pBuffer, length));
}
}