mirror of
https://github.com/google/flatbuffers.git
synced 2026-06-04 12:43:24 +00:00
Merge "Added the hash attribute to ints and longs." into ub-games-master
This commit is contained in:
102
src/flathash.cpp
Normal file
102
src/flathash.cpp
Normal file
@@ -0,0 +1,102 @@
|
||||
/*
|
||||
* 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.
|
||||
*/
|
||||
|
||||
#include <iostream>
|
||||
#include <sstream>
|
||||
#include <string>
|
||||
#include "flatbuffers/hash.h"
|
||||
|
||||
enum OutputFormat {
|
||||
kDecimal,
|
||||
kHexadecimal,
|
||||
kHexadecimal0x,
|
||||
};
|
||||
|
||||
int main(int argc, char* argv[]) {
|
||||
const char* name = argv[0];
|
||||
if (argc <= 1) {
|
||||
printf("%s HASH [OPTION]... STRING... [-- STRING...]\n", name);
|
||||
printf("Available hashing algorithms:\n 32 bit:\n");
|
||||
size_t size = sizeof(flatbuffers::kHashFunctions32) /
|
||||
sizeof(flatbuffers::kHashFunctions32[0]);
|
||||
for (size_t i = 0; i < size; ++i) {
|
||||
printf(" * %s\n", flatbuffers::kHashFunctions32[i].name);
|
||||
}
|
||||
printf(" 64 bit:\n");
|
||||
size = sizeof(flatbuffers::kHashFunctions64) /
|
||||
sizeof(flatbuffers::kHashFunctions64[0]);
|
||||
for (size_t i = 0; i < size; ++i) {
|
||||
printf(" * %s\n", flatbuffers::kHashFunctions64[i].name);
|
||||
}
|
||||
printf(
|
||||
" -d Output hash in decimal.\n"
|
||||
" -x Output hash in hexadecimal.\n"
|
||||
" -0x Output hash in hexadecimal and prefix with 0x.\n"
|
||||
" -c Append the string to the output in a c-style comment.\n");
|
||||
return 0;
|
||||
}
|
||||
|
||||
const char* hash_algorithm = argv[1];
|
||||
|
||||
flatbuffers::NamedHashFunction<uint32_t>::HashFunction hash_function32 =
|
||||
flatbuffers::FindHashFunction32(hash_algorithm);
|
||||
flatbuffers::NamedHashFunction<uint64_t>::HashFunction hash_function64 =
|
||||
flatbuffers::FindHashFunction64(hash_algorithm);
|
||||
|
||||
if (!hash_function32 && !hash_function64) {
|
||||
printf("\"%s\" is not a known hash algorithm.\n", hash_algorithm);
|
||||
return 0;
|
||||
}
|
||||
|
||||
OutputFormat output_format = kHexadecimal;
|
||||
bool annotate = false;
|
||||
bool escape_dash = false;
|
||||
for (int i = 2; i < argc; i++) {
|
||||
const char* arg = argv[i];
|
||||
if (!escape_dash && arg[0] == '-') {
|
||||
std::string opt = arg;
|
||||
if (opt == "-d") output_format = kDecimal;
|
||||
else if (opt == "-x") output_format = kHexadecimal;
|
||||
else if (opt == "-0x") output_format = kHexadecimal0x;
|
||||
else if (opt == "-c") annotate = true;
|
||||
else if (opt == "--") escape_dash = true;
|
||||
else printf("Unrecognized argument: \"%s\"\n", arg);
|
||||
} else {
|
||||
std::stringstream ss;
|
||||
if (output_format == kDecimal) {
|
||||
ss << std::dec;
|
||||
} else if (output_format == kHexadecimal) {
|
||||
ss << std::hex;
|
||||
} else if (output_format == kHexadecimal0x) {
|
||||
ss << std::hex;
|
||||
ss << "0x";
|
||||
}
|
||||
if (hash_function32)
|
||||
ss << hash_function32(arg);
|
||||
else if (hash_function64)
|
||||
ss << hash_function64(arg);
|
||||
|
||||
if (annotate)
|
||||
ss << " /* \"" << arg << "\" */";
|
||||
|
||||
ss << "\n";
|
||||
|
||||
std::cout << ss.str();
|
||||
}
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
@@ -18,6 +18,7 @@
|
||||
#include <list>
|
||||
|
||||
#include "flatbuffers/flatbuffers.h"
|
||||
#include "flatbuffers/hash.h"
|
||||
#include "flatbuffers/idl.h"
|
||||
#include "flatbuffers/util.h"
|
||||
|
||||
@@ -392,6 +393,27 @@ void Parser::ParseField(StructDef &struct_def) {
|
||||
field.doc_comment = dc;
|
||||
ParseMetaData(field);
|
||||
field.deprecated = field.attributes.Lookup("deprecated") != nullptr;
|
||||
auto hash_name = field.attributes.Lookup("hash");
|
||||
if (hash_name) {
|
||||
switch (type.base_type) {
|
||||
case BASE_TYPE_INT:
|
||||
case BASE_TYPE_UINT: {
|
||||
if (FindHashFunction32(hash_name->constant.c_str()) == nullptr)
|
||||
Error("Unknown hashing algorithm for 32 bit types: " +
|
||||
hash_name->constant);
|
||||
break;
|
||||
}
|
||||
case BASE_TYPE_LONG:
|
||||
case BASE_TYPE_ULONG: {
|
||||
if (FindHashFunction64(hash_name->constant.c_str()) == nullptr)
|
||||
Error("Unknown hashing algorithm for 64 bit types: " +
|
||||
hash_name->constant);
|
||||
break;
|
||||
}
|
||||
default:
|
||||
Error("only int, uint, long and ulong data types support hashing.");
|
||||
}
|
||||
}
|
||||
if (field.deprecated && struct_def.fixed)
|
||||
Error("can't deprecate fields in a struct");
|
||||
field.required = field.attributes.Lookup("required") != nullptr;
|
||||
@@ -465,6 +487,18 @@ void Parser::ParseAnyValue(Value &val, FieldDef *field) {
|
||||
val.constant = NumToString(ParseVector(val.type.VectorType()));
|
||||
break;
|
||||
}
|
||||
case BASE_TYPE_INT:
|
||||
case BASE_TYPE_UINT:
|
||||
case BASE_TYPE_LONG:
|
||||
case BASE_TYPE_ULONG: {
|
||||
if (field && field->attributes.Lookup("hash") &&
|
||||
(token_ == kTokenIdentifier || token_ == kTokenStringConstant)) {
|
||||
ParseHash(val, field);
|
||||
} else {
|
||||
ParseSingleValue(val);
|
||||
}
|
||||
break;
|
||||
}
|
||||
default:
|
||||
ParseSingleValue(val);
|
||||
break;
|
||||
@@ -583,7 +617,7 @@ uoffset_t Parser::ParseVector(const Type &type) {
|
||||
if ((!strict_json_ || !count) && IsNext(']')) break;
|
||||
Value val;
|
||||
val.type = type;
|
||||
ParseAnyValue(val, NULL);
|
||||
ParseAnyValue(val, nullptr);
|
||||
field_stack_.push_back(std::make_pair(val, nullptr));
|
||||
count++;
|
||||
if (IsNext(']')) break;
|
||||
@@ -689,6 +723,31 @@ int64_t Parser::ParseIntegerFromString(Type &type) {
|
||||
return result;
|
||||
}
|
||||
|
||||
|
||||
void Parser::ParseHash(Value &e, FieldDef* field) {
|
||||
assert(field);
|
||||
Value *hash_name = field->attributes.Lookup("hash");
|
||||
switch (e.type.base_type) {
|
||||
case BASE_TYPE_INT:
|
||||
case BASE_TYPE_UINT: {
|
||||
auto hash = FindHashFunction32(hash_name->constant.c_str());
|
||||
uint32_t hashed_value = hash(attribute_.c_str());
|
||||
e.constant = NumToString(hashed_value);
|
||||
break;
|
||||
}
|
||||
case BASE_TYPE_LONG:
|
||||
case BASE_TYPE_ULONG: {
|
||||
auto hash = FindHashFunction64(hash_name->constant.c_str());
|
||||
uint64_t hashed_value = hash(attribute_.c_str());
|
||||
e.constant = NumToString(hashed_value);
|
||||
break;
|
||||
}
|
||||
default:
|
||||
assert(0);
|
||||
}
|
||||
Next();
|
||||
}
|
||||
|
||||
void Parser::ParseSingleValue(Value &e) {
|
||||
// First check if this could be a string/identifier enum value:
|
||||
if (e.type.base_type != BASE_TYPE_STRING &&
|
||||
|
||||
Reference in New Issue
Block a user