diff options
author | Alex Ames <amablue@google.com> | 2015-02-13 15:58:29 -0800 |
---|---|---|
committer | Alex Ames <amablue@google.com> | 2015-02-17 14:10:18 -0800 |
commit | d575321eba7f83f40de5fb23685ed3cdb47bc9cc (patch) | |
tree | c5c28db4f838a3e5d9cd5dece77acda7fe197296 /include | |
parent | 620fe1c5cf23f5dd4e9d734e1029c6c772f0f811 (diff) | |
download | flatbuffers-d575321eba7f83f40de5fb23685ed3cdb47bc9cc.tar.gz flatbuffers-d575321eba7f83f40de5fb23685ed3cdb47bc9cc.tar.bz2 flatbuffers-d575321eba7f83f40de5fb23685ed3cdb47bc9cc.zip |
Added the hash attribute to ints and longs.
FlatBuffer schema files can now optionally specify a hash attribute that
will allow someone writing json files to enter a string to be hashed
rather than a specific value. The hashing algorithm to use is specified
by the schema.
Currently the only algorithms are fnv1 and fnv1a. There are 32 bit and
64 variatns for each. Additionally, a hashing command line tool was
added so that you can see what a string will hash to without needing to
inspect the flatbuffer binary blob.
Change-Id: I0cb359d0e2dc7d2dc1874b446dc19a17cc77109d
Diffstat (limited to 'include')
-rw-r--r-- | include/flatbuffers/hash.h | 105 | ||||
-rw-r--r-- | include/flatbuffers/idl.h | 3 |
2 files changed, 108 insertions, 0 deletions
diff --git a/include/flatbuffers/hash.h b/include/flatbuffers/hash.h new file mode 100644 index 00000000..134d1751 --- /dev/null +++ b/include/flatbuffers/hash.h @@ -0,0 +1,105 @@ +/* + * Copyright 2015 Google Inc. All rights reserved. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#ifndef FLATBUFFERS_HASH_H_ +#define FLATBUFFERS_HASH_H_ + +#include <cstdint> +#include <cstring> + +namespace flatbuffers { + +template <typename T> +struct FnvTraits { + static const T kFnvPrime; + static const T kOffsetBasis; +}; + +template <> +struct FnvTraits<uint32_t> { + static const uint32_t kFnvPrime = 0x01000193; + static const uint32_t kOffsetBasis = 0x811C9DC5; +}; + +template <> +struct FnvTraits<uint64_t> { + static const uint64_t kFnvPrime = 0x00000100000001b3; + static const uint64_t kOffsetBasis = 0xcbf29ce484222645; +}; + +template <typename T> +T HashFnv1(const char *input) { + T hash = FnvTraits<T>::kOffsetBasis; + for (const char *c = input; *c; ++c) { + hash *= FnvTraits<T>::kFnvPrime; + hash ^= static_cast<unsigned char>(*c); + } + return hash; +} + +template <typename T> +T HashFnv1a(const char *input) { + T hash = FnvTraits<T>::kOffsetBasis; + for (const char *c = input; *c; ++c) { + hash ^= static_cast<unsigned char>(*c); + hash *= FnvTraits<T>::kFnvPrime; + } + return hash; +} + +template <typename T> +struct NamedHashFunction { + const char *name; + + typedef T (*HashFunction)(const char*); + HashFunction function; +}; + +const NamedHashFunction<uint32_t> kHashFunctions32[] = { + { "fnv1_32", HashFnv1<uint32_t> }, + { "fnv1a_32", HashFnv1a<uint32_t> }, +}; + +const NamedHashFunction<uint64_t> kHashFunctions64[] = { + { "fnv1_64", HashFnv1<uint64_t> }, + { "fnv1a_64", HashFnv1a<uint64_t> }, +}; + +inline NamedHashFunction<uint32_t>::HashFunction FindHashFunction32( + const char *name) { + std::size_t size = sizeof(kHashFunctions32) / sizeof(kHashFunctions32[0]); + for (std::size_t i = 0; i < size; ++i) { + if (std::strcmp(name, kHashFunctions32[i].name) == 0) { + return kHashFunctions32[i].function; + } + } + return nullptr; +} + +inline NamedHashFunction<uint64_t>::HashFunction FindHashFunction64( + const char *name) { + std::size_t size = sizeof(kHashFunctions64) / sizeof(kHashFunctions64[0]); + for (std::size_t i = 0; i < size; ++i) { + if (std::strcmp(name, kHashFunctions64[i].name) == 0) { + return kHashFunctions64[i].function; + } + } + return nullptr; +} + +} // namespace flatbuffers + +#endif // FLATBUFFERS_HASH_H_ diff --git a/include/flatbuffers/idl.h b/include/flatbuffers/idl.h index 4ed789e3..6437362e 100644 --- a/include/flatbuffers/idl.h +++ b/include/flatbuffers/idl.h @@ -24,6 +24,7 @@ #include <functional> #include "flatbuffers/flatbuffers.h" +#include "flatbuffers/hash.h" // This file defines the data types representing a parsed IDL (Interface // Definition Language) / schema file. @@ -280,6 +281,7 @@ class Parser { known_attributes_.insert("deprecated"); known_attributes_.insert("required"); known_attributes_.insert("key"); + known_attributes_.insert("hash"); known_attributes_.insert("id"); known_attributes_.insert("force_align"); known_attributes_.insert("bit_flags"); @@ -334,6 +336,7 @@ class Parser { uoffset_t ParseVector(const Type &type); void ParseMetaData(Definition &def); bool TryTypedValue(int dtoken, bool check, Value &e, BaseType req); + void ParseHash(Value &e, FieldDef* field); void ParseSingleValue(Value &e); int64_t ParseIntegerFromString(Type &type); StructDef *LookupCreateStruct(const std::string &name); |