1 /* 2 * Copyright 2015 Google Inc. All rights reserved. 3 * 4 * Licensed under the Apache License, Version 2.0 (the "License"); 5 * you may not use this file except in compliance with the License. 6 * You may obtain a copy of the License at 7 * 8 * http://www.apache.org/licenses/LICENSE-2.0 9 * 10 * Unless required by applicable law or agreed to in writing, software 11 * distributed under the License is distributed on an "AS IS" BASIS, 12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 * See the License for the specific language governing permissions and 14 * limitations under the License. 15 */ 16 17 #ifndef FLATBUFFERS_HASH_H_ 18 #define FLATBUFFERS_HASH_H_ 19 20 #include <cstdint> 21 #include <cstring> 22 23 #include "flatbuffers/flatbuffers.h" 24 25 namespace flatbuffers { 26 27 template <typename T> 28 struct FnvTraits { 29 static const T kFnvPrime; 30 static const T kOffsetBasis; 31 }; 32 33 template <> 34 struct FnvTraits<uint32_t> { 35 static const uint32_t kFnvPrime = 0x01000193; 36 static const uint32_t kOffsetBasis = 0x811C9DC5; 37 }; 38 39 template <> 40 struct FnvTraits<uint64_t> { 41 static const uint64_t kFnvPrime = 0x00000100000001b3ULL; 42 static const uint64_t kOffsetBasis = 0xcbf29ce484222645ULL; 43 }; 44 45 template <typename T> 46 T HashFnv1(const char *input) { 47 T hash = FnvTraits<T>::kOffsetBasis; 48 for (const char *c = input; *c; ++c) { 49 hash *= FnvTraits<T>::kFnvPrime; 50 hash ^= static_cast<unsigned char>(*c); 51 } 52 return hash; 53 } 54 55 template <typename T> 56 T HashFnv1a(const char *input) { 57 T hash = FnvTraits<T>::kOffsetBasis; 58 for (const char *c = input; *c; ++c) { 59 hash ^= static_cast<unsigned char>(*c); 60 hash *= FnvTraits<T>::kFnvPrime; 61 } 62 return hash; 63 } 64 65 template <typename T> 66 struct NamedHashFunction { 67 const char *name; 68 69 typedef T (*HashFunction)(const char*); 70 HashFunction function; 71 }; 72 73 const NamedHashFunction<uint32_t> kHashFunctions32[] = { 74 { "fnv1_32", HashFnv1<uint32_t> }, 75 { "fnv1a_32", HashFnv1a<uint32_t> }, 76 }; 77 78 const NamedHashFunction<uint64_t> kHashFunctions64[] = { 79 { "fnv1_64", HashFnv1<uint64_t> }, 80 { "fnv1a_64", HashFnv1a<uint64_t> }, 81 }; 82 83 inline NamedHashFunction<uint32_t>::HashFunction FindHashFunction32( 84 const char *name) { 85 std::size_t size = sizeof(kHashFunctions32) / sizeof(kHashFunctions32[0]); 86 for (std::size_t i = 0; i < size; ++i) { 87 if (std::strcmp(name, kHashFunctions32[i].name) == 0) { 88 return kHashFunctions32[i].function; 89 } 90 } 91 return nullptr; 92 } 93 94 inline NamedHashFunction<uint64_t>::HashFunction FindHashFunction64( 95 const char *name) { 96 std::size_t size = sizeof(kHashFunctions64) / sizeof(kHashFunctions64[0]); 97 for (std::size_t i = 0; i < size; ++i) { 98 if (std::strcmp(name, kHashFunctions64[i].name) == 0) { 99 return kHashFunctions64[i].function; 100 } 101 } 102 return nullptr; 103 } 104 105 } // namespace flatbuffers 106 107 #endif // FLATBUFFERS_HASH_H_ 108