mirror of
https://github.com/google/flatbuffers.git
synced 2026-07-01 06:21:38 +00:00
Merge remote-tracking branch 'refs/remotes/google/master' into key
# Conflicts: # src/idl_gen_general.cpp
This commit is contained in:
57
CMake/PackageDebian.cmake
Normal file
57
CMake/PackageDebian.cmake
Normal file
@@ -0,0 +1,57 @@
|
|||||||
|
# ------------------- Debianization ---------------------
|
||||||
|
if (UNIX)
|
||||||
|
|
||||||
|
# Set build environment
|
||||||
|
SET(CPACK_GENERATOR "TGZ;DEB")
|
||||||
|
SET(CPACK_SOURCE_TGZ "ON")
|
||||||
|
|
||||||
|
# Common package information
|
||||||
|
SET(CPACK_PACKAGE_DESCRIPTION_SUMMARY
|
||||||
|
"FlatBuffers is an efficient cross platform serialization library for C++, with support for Java, C# and Go. It was created at Google specifically for game development and other performance-critical applications.")
|
||||||
|
SET(CPACK_DEBIAN_PACKAGE_HOMEPAGE "https://github.com/google/flatbuffers")
|
||||||
|
SET(CPACK_DEBIAN_PACKAGE_MAINTAINER "Vitaly Isaev <vitalyisaev2@gmail.com>")
|
||||||
|
|
||||||
|
# Derive package version from git
|
||||||
|
EXECUTE_PROCESS(
|
||||||
|
COMMAND date +%Y%m%d
|
||||||
|
OUTPUT_VARIABLE DATE
|
||||||
|
OUTPUT_STRIP_TRAILING_WHITESPACE
|
||||||
|
)
|
||||||
|
EXECUTE_PROCESS(
|
||||||
|
COMMAND git describe
|
||||||
|
WORKING_DIRECTORY ${CMAKE_SOURCE_DIR}
|
||||||
|
OUTPUT_VARIABLE GIT_DESCRIBE_DIRTY
|
||||||
|
OUTPUT_STRIP_TRAILING_WHITESPACE
|
||||||
|
)
|
||||||
|
string(REGEX REPLACE "^v([0-9]+)\\..*" "\\1" VERSION_MAJOR "${GIT_DESCRIBE_DIRTY}")
|
||||||
|
string(REGEX REPLACE "^v[0-9]+\\.([0-9]+).*" "\\1" VERSION_MINOR "${GIT_DESCRIBE_DIRTY}")
|
||||||
|
string(REGEX REPLACE "^v[0-9]+\\.[0-9]+\\.([0-9]+).*" "\\1" VERSION_PATCH "${GIT_DESCRIBE_DIRTY}")
|
||||||
|
string(REGEX REPLACE "^v[0-9]+\\.[0-9]+\\.[0-9]+\\-([0-9]+).*" "\\1" VERSION_COMMIT "${GIT_DESCRIBE_DIRTY}")
|
||||||
|
SET(CPACK_PACKAGE_VERSION_MAJOR ${VERSION_MAJOR})
|
||||||
|
SET(CPACK_PACKAGE_VERSION_MINOR ${VERSION_MINOR})
|
||||||
|
SET(CPACK_PACKAGE_VERSION_PATCH ${VERSION_PATCH})
|
||||||
|
SET(CPACK_PACKAGE_VERSION "${VERSION_MAJOR}.${VERSION_MINOR}.${VERSION_PATCH}-${VERSION_COMMIT}")
|
||||||
|
SET(CPACK_DEBIAN_PACKAGE_VERSION "${CPACK_PACKAGE_VERSION}")
|
||||||
|
|
||||||
|
# Derive architecture
|
||||||
|
IF(NOT CPACK_DEBIAN_PACKAGE_ARCHITECTURE)
|
||||||
|
FIND_PROGRAM(DPKG_CMD dpkg)
|
||||||
|
IF(NOT DPKG_CMD)
|
||||||
|
MESSAGE(STATUS "Can not find dpkg in your path, default to i386.")
|
||||||
|
SET(CPACK_DEBIAN_PACKAGE_ARCHITECTURE i386)
|
||||||
|
ENDIF(NOT DPKG_CMD)
|
||||||
|
EXECUTE_PROCESS(COMMAND "${DPKG_CMD}" --print-architecture
|
||||||
|
OUTPUT_VARIABLE CPACK_DEBIAN_PACKAGE_ARCHITECTURE
|
||||||
|
OUTPUT_STRIP_TRAILING_WHITESPACE
|
||||||
|
)
|
||||||
|
ENDIF(NOT CPACK_DEBIAN_PACKAGE_ARCHITECTURE)
|
||||||
|
|
||||||
|
# Package name
|
||||||
|
SET(CPACK_DEBIAN_PACKAGE_NAME "flatbuffers")
|
||||||
|
SET(CPACK_RESOURCE_FILE_LICENSE ${CMAKE_SOURCE_DIR}/LICENSE.txt)
|
||||||
|
SET(CPACK_PACKAGE_FILE_NAME
|
||||||
|
"${CPACK_DEBIAN_PACKAGE_NAME}_${CPACK_DEBIAN_PACKAGE_VERSION}_${CPACK_DEBIAN_PACKAGE_ARCHITECTURE}")
|
||||||
|
|
||||||
|
endif(UNIX)
|
||||||
|
|
||||||
|
INCLUDE(CPack)
|
||||||
@@ -44,6 +44,7 @@ set(FlatBuffers_Compiler_SRCS
|
|||||||
src/idl_gen_fbs.cpp
|
src/idl_gen_fbs.cpp
|
||||||
src/idl_gen_grpc.cpp
|
src/idl_gen_grpc.cpp
|
||||||
src/flatc.cpp
|
src/flatc.cpp
|
||||||
|
grpc/src/compiler/schema_interface.h
|
||||||
grpc/src/compiler/cpp_generator.h
|
grpc/src/compiler/cpp_generator.h
|
||||||
grpc/src/compiler/cpp_generator.cc
|
grpc/src/compiler/cpp_generator.cc
|
||||||
)
|
)
|
||||||
@@ -222,3 +223,7 @@ if(FLATBUFFERS_BUILD_TESTS)
|
|||||||
endif()
|
endif()
|
||||||
|
|
||||||
include(CMake/BuildFlatBuffers.cmake)
|
include(CMake/BuildFlatBuffers.cmake)
|
||||||
|
|
||||||
|
if(FLATBUFFERS_PACKAGE_DEBIAN)
|
||||||
|
include(CMake/PackageDebian.cmake)
|
||||||
|
endif()
|
||||||
|
|||||||
@@ -761,7 +761,7 @@ INPUT = "FlatBuffers.md" \
|
|||||||
"WhitePaper.md" \
|
"WhitePaper.md" \
|
||||||
"Internals.md" \
|
"Internals.md" \
|
||||||
"Grammar.md" \
|
"Grammar.md" \
|
||||||
"CONTRIBUTING.md" \
|
"../../CONTRIBUTING.md" \
|
||||||
"Tutorial.md" \
|
"Tutorial.md" \
|
||||||
"GoApi.md" \
|
"GoApi.md" \
|
||||||
"groups" \
|
"groups" \
|
||||||
|
|||||||
@@ -67,7 +67,8 @@ grpc::string FilenameIdentifier(const grpc::string &filename) {
|
|||||||
template<class T, size_t N>
|
template<class T, size_t N>
|
||||||
T *array_end(T (&array)[N]) { return array + N; }
|
T *array_end(T (&array)[N]) { return array + N; }
|
||||||
|
|
||||||
void PrintIncludes(Printer *printer, const std::vector<grpc::string>& headers, const Parameters ¶ms) {
|
void PrintIncludes(grpc_generator::Printer *printer,
|
||||||
|
const std::vector<grpc::string>& headers, const Parameters ¶ms) {
|
||||||
std::map<grpc::string, grpc::string> vars;
|
std::map<grpc::string, grpc::string> vars;
|
||||||
|
|
||||||
vars["l"] = params.use_system_headers ? '<' : '"';
|
vars["l"] = params.use_system_headers ? '<' : '"';
|
||||||
@@ -86,7 +87,7 @@ void PrintIncludes(Printer *printer, const std::vector<grpc::string>& headers, c
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
grpc::string GetHeaderPrologue(File *file, const Parameters & /*params*/) {
|
grpc::string GetHeaderPrologue(grpc_generator::File *file, const Parameters & /*params*/) {
|
||||||
grpc::string output;
|
grpc::string output;
|
||||||
{
|
{
|
||||||
// Scope the output stream so it closes and finalizes output to the string.
|
// Scope the output stream so it closes and finalizes output to the string.
|
||||||
@@ -111,7 +112,7 @@ grpc::string GetHeaderPrologue(File *file, const Parameters & /*params*/) {
|
|||||||
return output;
|
return output;
|
||||||
}
|
}
|
||||||
|
|
||||||
grpc::string GetHeaderIncludes(File *file,
|
grpc::string GetHeaderIncludes(grpc_generator::File *file,
|
||||||
const Parameters ¶ms) {
|
const Parameters ¶ms) {
|
||||||
grpc::string output;
|
grpc::string output;
|
||||||
{
|
{
|
||||||
@@ -154,7 +155,7 @@ grpc::string GetHeaderIncludes(File *file,
|
|||||||
}
|
}
|
||||||
|
|
||||||
void PrintHeaderClientMethodInterfaces(
|
void PrintHeaderClientMethodInterfaces(
|
||||||
Printer *printer, const Method *method,
|
grpc_generator::Printer *printer, const grpc_generator::Method *method,
|
||||||
std::map<grpc::string, grpc::string> *vars, bool is_public) {
|
std::map<grpc::string, grpc::string> *vars, bool is_public) {
|
||||||
(*vars)["Method"] = method->name();
|
(*vars)["Method"] = method->name();
|
||||||
(*vars)["Request"] = method->input_type_name();
|
(*vars)["Request"] = method->input_type_name();
|
||||||
@@ -303,8 +304,8 @@ void PrintHeaderClientMethodInterfaces(
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void PrintHeaderClientMethod(Printer *printer,
|
void PrintHeaderClientMethod(grpc_generator::Printer *printer,
|
||||||
const Method *method,
|
const grpc_generator::Method *method,
|
||||||
std::map<grpc::string, grpc::string> *vars,
|
std::map<grpc::string, grpc::string> *vars,
|
||||||
bool is_public) {
|
bool is_public) {
|
||||||
(*vars)["Method"] = method->name();
|
(*vars)["Method"] = method->name();
|
||||||
@@ -445,13 +446,13 @@ void PrintHeaderClientMethod(Printer *printer,
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void PrintHeaderClientMethodData(Printer *printer, const Method *method,
|
void PrintHeaderClientMethodData(grpc_generator::Printer *printer, const grpc_generator::Method *method,
|
||||||
std::map<grpc::string, grpc::string> *vars) {
|
std::map<grpc::string, grpc::string> *vars) {
|
||||||
(*vars)["Method"] = method->name();
|
(*vars)["Method"] = method->name();
|
||||||
printer->Print(*vars, "const ::grpc::RpcMethod rpcmethod_$Method$_;\n");
|
printer->Print(*vars, "const ::grpc::RpcMethod rpcmethod_$Method$_;\n");
|
||||||
}
|
}
|
||||||
|
|
||||||
void PrintHeaderServerMethodSync(Printer *printer, const Method *method,
|
void PrintHeaderServerMethodSync(grpc_generator::Printer *printer, const grpc_generator::Method *method,
|
||||||
std::map<grpc::string, grpc::string> *vars) {
|
std::map<grpc::string, grpc::string> *vars) {
|
||||||
(*vars)["Method"] = method->name();
|
(*vars)["Method"] = method->name();
|
||||||
(*vars)["Request"] = method->input_type_name();
|
(*vars)["Request"] = method->input_type_name();
|
||||||
@@ -483,8 +484,8 @@ void PrintHeaderServerMethodSync(Printer *printer, const Method *method,
|
|||||||
}
|
}
|
||||||
|
|
||||||
void PrintHeaderServerMethodAsync(
|
void PrintHeaderServerMethodAsync(
|
||||||
Printer *printer,
|
grpc_generator::Printer *printer,
|
||||||
const Method *method,
|
const grpc_generator::Method *method,
|
||||||
std::map<grpc::string, grpc::string> *vars) {
|
std::map<grpc::string, grpc::string> *vars) {
|
||||||
(*vars)["Method"] = method->name();
|
(*vars)["Method"] = method->name();
|
||||||
(*vars)["Request"] = method->input_type_name();
|
(*vars)["Request"] = method->input_type_name();
|
||||||
@@ -599,8 +600,8 @@ void PrintHeaderServerMethodAsync(
|
|||||||
}
|
}
|
||||||
|
|
||||||
void PrintHeaderServerMethodGeneric(
|
void PrintHeaderServerMethodGeneric(
|
||||||
Printer *printer,
|
grpc_generator::Printer *printer,
|
||||||
const Method *method,
|
const grpc_generator::Method *method,
|
||||||
std::map<grpc::string, grpc::string> *vars) {
|
std::map<grpc::string, grpc::string> *vars) {
|
||||||
(*vars)["Method"] = method->name();
|
(*vars)["Method"] = method->name();
|
||||||
(*vars)["Request"] = method->input_type_name();
|
(*vars)["Request"] = method->input_type_name();
|
||||||
@@ -669,8 +670,8 @@ void PrintHeaderServerMethodGeneric(
|
|||||||
printer->Print(*vars, "};\n");
|
printer->Print(*vars, "};\n");
|
||||||
}
|
}
|
||||||
|
|
||||||
void PrintHeaderService(Printer *printer,
|
void PrintHeaderService(grpc_generator::Printer *printer,
|
||||||
const Service *service,
|
const grpc_generator::Service *service,
|
||||||
std::map<grpc::string, grpc::string> *vars) {
|
std::map<grpc::string, grpc::string> *vars) {
|
||||||
(*vars)["Service"] = service->name();
|
(*vars)["Service"] = service->name();
|
||||||
|
|
||||||
@@ -764,7 +765,7 @@ void PrintHeaderService(Printer *printer,
|
|||||||
printer->Print("};\n");
|
printer->Print("};\n");
|
||||||
}
|
}
|
||||||
|
|
||||||
grpc::string GetHeaderServices(File *file,
|
grpc::string GetHeaderServices(grpc_generator::File *file,
|
||||||
const Parameters ¶ms) {
|
const Parameters ¶ms) {
|
||||||
grpc::string output;
|
grpc::string output;
|
||||||
{
|
{
|
||||||
@@ -795,7 +796,7 @@ grpc::string GetHeaderServices(File *file,
|
|||||||
return output;
|
return output;
|
||||||
}
|
}
|
||||||
|
|
||||||
grpc::string GetHeaderEpilogue(File *file, const Parameters & /*params*/) {
|
grpc::string GetHeaderEpilogue(grpc_generator::File *file, const Parameters & /*params*/) {
|
||||||
grpc::string output;
|
grpc::string output;
|
||||||
{
|
{
|
||||||
// Scope the output stream so it closes and finalizes output to the string.
|
// Scope the output stream so it closes and finalizes output to the string.
|
||||||
@@ -821,7 +822,7 @@ grpc::string GetHeaderEpilogue(File *file, const Parameters & /*params*/) {
|
|||||||
return output;
|
return output;
|
||||||
}
|
}
|
||||||
|
|
||||||
grpc::string GetSourcePrologue(File *file, const Parameters & /*params*/) {
|
grpc::string GetSourcePrologue(grpc_generator::File *file, const Parameters & /*params*/) {
|
||||||
grpc::string output;
|
grpc::string output;
|
||||||
{
|
{
|
||||||
// Scope the output stream so it closes and finalizes output to the string.
|
// Scope the output stream so it closes and finalizes output to the string.
|
||||||
@@ -845,7 +846,7 @@ grpc::string GetSourcePrologue(File *file, const Parameters & /*params*/) {
|
|||||||
return output;
|
return output;
|
||||||
}
|
}
|
||||||
|
|
||||||
grpc::string GetSourceIncludes(File *file,
|
grpc::string GetSourceIncludes(grpc_generator::File *file,
|
||||||
const Parameters ¶ms) {
|
const Parameters ¶ms) {
|
||||||
grpc::string output;
|
grpc::string output;
|
||||||
{
|
{
|
||||||
@@ -880,8 +881,8 @@ grpc::string GetSourceIncludes(File *file,
|
|||||||
return output;
|
return output;
|
||||||
}
|
}
|
||||||
|
|
||||||
void PrintSourceClientMethod(Printer *printer,
|
void PrintSourceClientMethod(grpc_generator::Printer *printer,
|
||||||
const Method *method,
|
const grpc_generator::Method *method,
|
||||||
std::map<grpc::string, grpc::string> *vars) {
|
std::map<grpc::string, grpc::string> *vars) {
|
||||||
(*vars)["Method"] = method->name();
|
(*vars)["Method"] = method->name();
|
||||||
(*vars)["Request"] = method->input_type_name();
|
(*vars)["Request"] = method->input_type_name();
|
||||||
@@ -981,8 +982,8 @@ void PrintSourceClientMethod(Printer *printer,
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void PrintSourceServerMethod(Printer *printer,
|
void PrintSourceServerMethod(grpc_generator::Printer *printer,
|
||||||
const Method *method,
|
const grpc_generator::Method *method,
|
||||||
std::map<grpc::string, grpc::string> *vars) {
|
std::map<grpc::string, grpc::string> *vars) {
|
||||||
(*vars)["Method"] = method->name();
|
(*vars)["Method"] = method->name();
|
||||||
(*vars)["Request"] = method->input_type_name();
|
(*vars)["Request"] = method->input_type_name();
|
||||||
@@ -1040,8 +1041,8 @@ void PrintSourceServerMethod(Printer *printer,
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void PrintSourceService(Printer *printer,
|
void PrintSourceService(grpc_generator::Printer *printer,
|
||||||
const Service *service,
|
const grpc_generator::Service *service,
|
||||||
std::map<grpc::string, grpc::string> *vars) {
|
std::map<grpc::string, grpc::string> *vars) {
|
||||||
(*vars)["Service"] = service->name();
|
(*vars)["Service"] = service->name();
|
||||||
|
|
||||||
@@ -1153,7 +1154,7 @@ void PrintSourceService(Printer *printer,
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
grpc::string GetSourceServices(File *file,
|
grpc::string GetSourceServices(grpc_generator::File *file,
|
||||||
const Parameters ¶ms) {
|
const Parameters ¶ms) {
|
||||||
grpc::string output;
|
grpc::string output;
|
||||||
{
|
{
|
||||||
@@ -1182,7 +1183,7 @@ grpc::string GetSourceServices(File *file,
|
|||||||
return output;
|
return output;
|
||||||
}
|
}
|
||||||
|
|
||||||
grpc::string GetSourceEpilogue(File *file, const Parameters & /*params*/) {
|
grpc::string GetSourceEpilogue(grpc_generator::File *file, const Parameters & /*params*/) {
|
||||||
grpc::string temp;
|
grpc::string temp;
|
||||||
|
|
||||||
if (!file->package().empty()) {
|
if (!file->package().empty()) {
|
||||||
|
|||||||
@@ -41,16 +41,7 @@
|
|||||||
#include <memory>
|
#include <memory>
|
||||||
#include <vector>
|
#include <vector>
|
||||||
|
|
||||||
#ifndef GRPC_CUSTOM_STRING
|
#include "src/compiler/schema_interface.h"
|
||||||
#include <string>
|
|
||||||
#define GRPC_CUSTOM_STRING std::string
|
|
||||||
#endif
|
|
||||||
|
|
||||||
namespace grpc {
|
|
||||||
|
|
||||||
typedef GRPC_CUSTOM_STRING string;
|
|
||||||
|
|
||||||
} // namespace grpc
|
|
||||||
|
|
||||||
namespace grpc_cpp_generator {
|
namespace grpc_cpp_generator {
|
||||||
|
|
||||||
@@ -64,83 +55,29 @@ struct Parameters {
|
|||||||
grpc::string grpc_search_path;
|
grpc::string grpc_search_path;
|
||||||
};
|
};
|
||||||
|
|
||||||
// An abstract interface representing a method.
|
|
||||||
struct Method {
|
|
||||||
virtual ~Method() {}
|
|
||||||
|
|
||||||
virtual grpc::string name() const = 0;
|
|
||||||
|
|
||||||
virtual grpc::string input_type_name() const = 0;
|
|
||||||
virtual grpc::string output_type_name() const = 0;
|
|
||||||
|
|
||||||
virtual bool NoStreaming() const = 0;
|
|
||||||
virtual bool ClientOnlyStreaming() const = 0;
|
|
||||||
virtual bool ServerOnlyStreaming() const = 0;
|
|
||||||
virtual bool BidiStreaming() const = 0;
|
|
||||||
};
|
|
||||||
|
|
||||||
// An abstract interface representing a service.
|
|
||||||
struct Service {
|
|
||||||
virtual ~Service() {}
|
|
||||||
|
|
||||||
virtual grpc::string name() const = 0;
|
|
||||||
|
|
||||||
virtual int method_count() const = 0;
|
|
||||||
virtual std::unique_ptr<const Method> method(int i) const = 0;
|
|
||||||
};
|
|
||||||
|
|
||||||
struct Printer {
|
|
||||||
virtual ~Printer() {}
|
|
||||||
|
|
||||||
virtual void Print(const std::map<grpc::string, grpc::string> &vars,
|
|
||||||
const char *template_string) = 0;
|
|
||||||
virtual void Print(const char *string) = 0;
|
|
||||||
virtual void Indent() = 0;
|
|
||||||
virtual void Outdent() = 0;
|
|
||||||
};
|
|
||||||
|
|
||||||
// An interface that allows the source generated to be output using various
|
|
||||||
// libraries/idls/serializers.
|
|
||||||
struct File {
|
|
||||||
virtual ~File() {}
|
|
||||||
|
|
||||||
virtual grpc::string filename() const = 0;
|
|
||||||
virtual grpc::string filename_without_ext() const = 0;
|
|
||||||
virtual grpc::string message_header_ext() const = 0;
|
|
||||||
virtual grpc::string service_header_ext() const = 0;
|
|
||||||
virtual grpc::string package() const = 0;
|
|
||||||
virtual std::vector<grpc::string> package_parts() const = 0;
|
|
||||||
virtual grpc::string additional_headers() const = 0;
|
|
||||||
|
|
||||||
virtual int service_count() const = 0;
|
|
||||||
virtual std::unique_ptr<const Service> service(int i) const = 0;
|
|
||||||
|
|
||||||
virtual std::unique_ptr<Printer> CreatePrinter(grpc::string *str) const = 0;
|
|
||||||
};
|
|
||||||
|
|
||||||
// Return the prologue of the generated header file.
|
// Return the prologue of the generated header file.
|
||||||
grpc::string GetHeaderPrologue(File *file, const Parameters ¶ms);
|
grpc::string GetHeaderPrologue(grpc_generator::File *file, const Parameters ¶ms);
|
||||||
|
|
||||||
// Return the includes needed for generated header file.
|
// Return the includes needed for generated header file.
|
||||||
grpc::string GetHeaderIncludes(File *file, const Parameters ¶ms);
|
grpc::string GetHeaderIncludes(grpc_generator::File *file, const Parameters ¶ms);
|
||||||
|
|
||||||
// Return the includes needed for generated source file.
|
// Return the includes needed for generated source file.
|
||||||
grpc::string GetSourceIncludes(File *file, const Parameters ¶ms);
|
grpc::string GetSourceIncludes(grpc_generator::File *file, const Parameters ¶ms);
|
||||||
|
|
||||||
// Return the epilogue of the generated header file.
|
// Return the epilogue of the generated header file.
|
||||||
grpc::string GetHeaderEpilogue(File *file, const Parameters ¶ms);
|
grpc::string GetHeaderEpilogue(grpc_generator::File *file, const Parameters ¶ms);
|
||||||
|
|
||||||
// Return the prologue of the generated source file.
|
// Return the prologue of the generated source file.
|
||||||
grpc::string GetSourcePrologue(File *file, const Parameters ¶ms);
|
grpc::string GetSourcePrologue(grpc_generator::File *file, const Parameters ¶ms);
|
||||||
|
|
||||||
// Return the services for generated header file.
|
// Return the services for generated header file.
|
||||||
grpc::string GetHeaderServices(File *file, const Parameters ¶ms);
|
grpc::string GetHeaderServices(grpc_generator::File *file, const Parameters ¶ms);
|
||||||
|
|
||||||
// Return the services for generated source file.
|
// Return the services for generated source file.
|
||||||
grpc::string GetSourceServices(File *file, const Parameters ¶ms);
|
grpc::string GetSourceServices(grpc_generator::File *file, const Parameters ¶ms);
|
||||||
|
|
||||||
// Return the epilogue of the generated source file.
|
// Return the epilogue of the generated source file.
|
||||||
grpc::string GetSourceEpilogue(File *file, const Parameters ¶ms);
|
grpc::string GetSourceEpilogue(grpc_generator::File *file, const Parameters ¶ms);
|
||||||
|
|
||||||
} // namespace grpc_cpp_generator
|
} // namespace grpc_cpp_generator
|
||||||
|
|
||||||
|
|||||||
108
grpc/src/compiler/schema_interface.h
Normal file
108
grpc/src/compiler/schema_interface.h
Normal file
@@ -0,0 +1,108 @@
|
|||||||
|
/*
|
||||||
|
*
|
||||||
|
* Copyright 2015, Google Inc.
|
||||||
|
* All rights reserved.
|
||||||
|
*
|
||||||
|
* Redistribution and use in source and binary forms, with or without
|
||||||
|
* modification, are permitted provided that the following conditions are
|
||||||
|
* met:
|
||||||
|
*
|
||||||
|
* * Redistributions of source code must retain the above copyright
|
||||||
|
* notice, this list of conditions and the following disclaimer.
|
||||||
|
* * Redistributions in binary form must reproduce the above
|
||||||
|
* copyright notice, this list of conditions and the following disclaimer
|
||||||
|
* in the documentation and/or other materials provided with the
|
||||||
|
* distribution.
|
||||||
|
* * Neither the name of Google Inc. nor the names of its
|
||||||
|
* contributors may be used to endorse or promote products derived from
|
||||||
|
* this software without specific prior written permission.
|
||||||
|
*
|
||||||
|
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
||||||
|
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
|
||||||
|
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
|
||||||
|
* A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
|
||||||
|
* OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
|
||||||
|
* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
|
||||||
|
* LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
|
||||||
|
* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
|
||||||
|
* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||||
|
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
|
||||||
|
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
|
||||||
|
#ifndef GRPC_INTERNAL_COMPILER_SCHEMA_INTERFACE_H
|
||||||
|
#define GRPC_INTERNAL_COMPILER_SCHEMA_INTERFACE_H
|
||||||
|
|
||||||
|
#include <memory>
|
||||||
|
#include <vector>
|
||||||
|
|
||||||
|
#ifndef GRPC_CUSTOM_STRING
|
||||||
|
#include <string>
|
||||||
|
#define GRPC_CUSTOM_STRING std::string
|
||||||
|
#endif
|
||||||
|
|
||||||
|
namespace grpc {
|
||||||
|
|
||||||
|
typedef GRPC_CUSTOM_STRING string;
|
||||||
|
|
||||||
|
} // namespace grpc
|
||||||
|
|
||||||
|
namespace grpc_generator {
|
||||||
|
|
||||||
|
// An abstract interface representing a method.
|
||||||
|
struct Method {
|
||||||
|
virtual ~Method() {}
|
||||||
|
|
||||||
|
virtual grpc::string name() const = 0;
|
||||||
|
|
||||||
|
virtual grpc::string input_type_name() const = 0;
|
||||||
|
virtual grpc::string output_type_name() const = 0;
|
||||||
|
|
||||||
|
virtual bool NoStreaming() const = 0;
|
||||||
|
virtual bool ClientOnlyStreaming() const = 0;
|
||||||
|
virtual bool ServerOnlyStreaming() const = 0;
|
||||||
|
virtual bool BidiStreaming() const = 0;
|
||||||
|
};
|
||||||
|
|
||||||
|
// An abstract interface representing a service.
|
||||||
|
struct Service {
|
||||||
|
virtual ~Service() {}
|
||||||
|
|
||||||
|
virtual grpc::string name() const = 0;
|
||||||
|
|
||||||
|
virtual int method_count() const = 0;
|
||||||
|
virtual std::unique_ptr<const Method> method(int i) const = 0;
|
||||||
|
};
|
||||||
|
|
||||||
|
struct Printer {
|
||||||
|
virtual ~Printer() {}
|
||||||
|
|
||||||
|
virtual void Print(const std::map<grpc::string, grpc::string> &vars,
|
||||||
|
const char *template_string) = 0;
|
||||||
|
virtual void Print(const char *string) = 0;
|
||||||
|
virtual void Indent() = 0;
|
||||||
|
virtual void Outdent() = 0;
|
||||||
|
};
|
||||||
|
|
||||||
|
// An interface that allows the source generated to be output using various
|
||||||
|
// libraries/idls/serializers.
|
||||||
|
struct File {
|
||||||
|
virtual ~File() {}
|
||||||
|
|
||||||
|
virtual grpc::string filename() const = 0;
|
||||||
|
virtual grpc::string filename_without_ext() const = 0;
|
||||||
|
virtual grpc::string message_header_ext() const = 0;
|
||||||
|
virtual grpc::string service_header_ext() const = 0;
|
||||||
|
virtual grpc::string package() const = 0;
|
||||||
|
virtual std::vector<grpc::string> package_parts() const = 0;
|
||||||
|
virtual grpc::string additional_headers() const = 0;
|
||||||
|
|
||||||
|
virtual int service_count() const = 0;
|
||||||
|
virtual std::unique_ptr<const Service> service(int i) const = 0;
|
||||||
|
|
||||||
|
virtual std::unique_ptr<Printer> CreatePrinter(grpc::string *str) const = 0;
|
||||||
|
};
|
||||||
|
} // namespace grpc_generator
|
||||||
|
|
||||||
|
#endif // GRPC_INTERNAL_COMPILER_SCHEMA_INTERFACE_H
|
||||||
@@ -1436,11 +1436,6 @@ class Struct FLATBUFFERS_FINAL_CLASS {
|
|||||||
return ReadScalar<T>(&data_[o]);
|
return ReadScalar<T>(&data_[o]);
|
||||||
}
|
}
|
||||||
|
|
||||||
template<typename T> T GetPointer(uoffset_t o) const {
|
|
||||||
auto p = &data_[o];
|
|
||||||
return reinterpret_cast<T>(p + ReadScalar<uoffset_t>(p));
|
|
||||||
}
|
|
||||||
|
|
||||||
template<typename T> T GetStruct(uoffset_t o) const {
|
template<typename T> T GetStruct(uoffset_t o) const {
|
||||||
return reinterpret_cast<T>(&data_[o]);
|
return reinterpret_cast<T>(&data_[o]);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -596,7 +596,9 @@ extern void GenComment(const std::vector<std::string> &dc,
|
|||||||
// if it is less than 0, no linefeeds will be generated either.
|
// if it is less than 0, no linefeeds will be generated either.
|
||||||
// See idl_gen_text.cpp.
|
// See idl_gen_text.cpp.
|
||||||
// strict_json adds "quotes" around field names if true.
|
// strict_json adds "quotes" around field names if true.
|
||||||
extern void GenerateText(const Parser &parser,
|
// If the flatbuffer cannot be encoded in JSON (e.g., it contains non-UTF-8
|
||||||
|
// byte arrays in String values), returns false.
|
||||||
|
extern bool GenerateText(const Parser &parser,
|
||||||
const void *flatbuffer,
|
const void *flatbuffer,
|
||||||
std::string *text);
|
std::string *text);
|
||||||
extern bool GenerateTextFile(const Parser &parser,
|
extern bool GenerateTextFile(const Parser &parser,
|
||||||
|
|||||||
@@ -367,6 +367,28 @@ public class FlatBufferBuilder {
|
|||||||
}
|
}
|
||||||
/// @endcond
|
/// @endcond
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Create a new array/vector and return a ByteBuffer to be filled later.
|
||||||
|
* Call {@link #endVector} after this method to get an offset to the beginning
|
||||||
|
* of vector.
|
||||||
|
*
|
||||||
|
* @param elem_size the size of each element in bytes.
|
||||||
|
* @param num_elems number of elements in the vector.
|
||||||
|
* @param alignment byte alignment.
|
||||||
|
* @return ByteBuffer with position and limit set to the space allocated for the array.
|
||||||
|
*/
|
||||||
|
public ByteBuffer createUnintializedVector(int elem_size, int num_elems, int alignment) {
|
||||||
|
int length = elem_size * num_elems;
|
||||||
|
startVector(elem_size, num_elems, alignment);
|
||||||
|
|
||||||
|
bb.position(space -= length);
|
||||||
|
|
||||||
|
// Slice and limit the copy vector to point to the 'array'
|
||||||
|
ByteBuffer copy = bb.slice().order(ByteOrder.LITTLE_ENDIAN);
|
||||||
|
copy.limit(length);
|
||||||
|
return copy;
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Create a vector of tables.
|
* Create a vector of tables.
|
||||||
*
|
*
|
||||||
@@ -438,6 +460,20 @@ public class FlatBufferBuilder {
|
|||||||
return endVector();
|
return endVector();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Create a byte array in the buffer.
|
||||||
|
*
|
||||||
|
* @param arr A source array with data
|
||||||
|
* @return The offset in the buffer where the encoded array starts.
|
||||||
|
*/
|
||||||
|
public int createByteVector(byte[] arr) {
|
||||||
|
int length = arr.length;
|
||||||
|
startVector(1, length, 1);
|
||||||
|
bb.position(space -= length);
|
||||||
|
bb.put(arr);
|
||||||
|
return endVector();
|
||||||
|
}
|
||||||
|
|
||||||
/// @cond FLATBUFFERS_INTERNAL
|
/// @cond FLATBUFFERS_INTERNAL
|
||||||
/**
|
/**
|
||||||
* Should not be accessing the final buffer before it is finished.
|
* Should not be accessing the final buffer before it is finished.
|
||||||
|
|||||||
@@ -37,6 +37,12 @@ public class Table {
|
|||||||
return Charset.forName("UTF-8").newDecoder();
|
return Charset.forName("UTF-8").newDecoder();
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
public final static ThreadLocal<Charset> UTF8_CHARSET = new ThreadLocal<Charset>() {
|
||||||
|
@Override
|
||||||
|
protected Charset initialValue() {
|
||||||
|
return Charset.forName("UTF-8");
|
||||||
|
}
|
||||||
|
};
|
||||||
private final static ThreadLocal<CharBuffer> CHAR_BUFFER = new ThreadLocal<CharBuffer>();
|
private final static ThreadLocal<CharBuffer> CHAR_BUFFER = new ThreadLocal<CharBuffer>();
|
||||||
/** Used to hold the position of the `bb` buffer. */
|
/** Used to hold the position of the `bb` buffer. */
|
||||||
protected int bb_pos;
|
protected int bb_pos;
|
||||||
@@ -204,10 +210,14 @@ public class Table {
|
|||||||
* @param offsets An 'int' indexes of the tables into the bb.
|
* @param offsets An 'int' indexes of the tables into the bb.
|
||||||
* @param bb A {@code ByteBuffer} to get the tables.
|
* @param bb A {@code ByteBuffer} to get the tables.
|
||||||
*/
|
*/
|
||||||
protected void sortTables(int[] offsets, ByteBuffer bb) {
|
protected void sortTables(int[] offsets, final ByteBuffer bb) {
|
||||||
Integer[] off = new Integer[offsets.length];
|
Integer[] off = new Integer[offsets.length];
|
||||||
for (int i = 0; i < offsets.length; i++) off[i] = offsets[i];
|
for (int i = 0; i < offsets.length; i++) off[i] = offsets[i];
|
||||||
Arrays.sort(off, (Integer o1, Integer o2) -> keysCompare(o1, o2, bb));
|
java.util.Arrays.sort(off, new java.util.Comparator<Integer>() {
|
||||||
|
public int compare(Integer o1, Integer o2) {
|
||||||
|
return keysCompare(o1, o2, bb);
|
||||||
|
}
|
||||||
|
});
|
||||||
for (int i = 0; i < offsets.length; i++) offsets[i] = off[i];
|
for (int i = 0; i < offsets.length; i++) offsets[i] = off[i];
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -14,7 +14,20 @@
|
|||||||
* limitations under the License.
|
* limitations under the License.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
//#define UNSAFE_BYTEBUFFER // uncomment this line to use faster ByteBuffer
|
// There are 2 #defines that have an impact on performance of this ByteBuffer implementation
|
||||||
|
//
|
||||||
|
// UNSAFE_BYTEBUFFER
|
||||||
|
// This will use unsafe code to manipulate the underlying byte array. This
|
||||||
|
// can yield a reasonable performance increase.
|
||||||
|
//
|
||||||
|
// BYTEBUFFER_NO_BOUNDS_CHECK
|
||||||
|
// This will disable the bounds check asserts to the byte array. This can
|
||||||
|
// yield a small performance gain in normal code..
|
||||||
|
//
|
||||||
|
// Using UNSAFE_BYTEBUFFER and BYTEBUFFER_NO_BOUNDS_CHECK together can yield a
|
||||||
|
// performance gain of ~15% for some operations, however doing so is potentially
|
||||||
|
// dangerous. Do so at your own risk!
|
||||||
|
//
|
||||||
|
|
||||||
using System;
|
using System;
|
||||||
|
|
||||||
@@ -22,9 +35,6 @@ namespace FlatBuffers
|
|||||||
{
|
{
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Class to mimic Java's ByteBuffer which is used heavily in Flatbuffers.
|
/// Class to mimic Java's ByteBuffer which is used heavily in Flatbuffers.
|
||||||
/// If your execution environment allows unsafe code, you should enable
|
|
||||||
/// unsafe code in your project and #define UNSAFE_BYTEBUFFER to use a
|
|
||||||
/// MUCH faster version of ByteBuffer.
|
|
||||||
/// </summary>
|
/// </summary>
|
||||||
public class ByteBuffer
|
public class ByteBuffer
|
||||||
{
|
{
|
||||||
@@ -126,11 +136,14 @@ namespace FlatBuffers
|
|||||||
}
|
}
|
||||||
#endif // !UNSAFE_BYTEBUFFER
|
#endif // !UNSAFE_BYTEBUFFER
|
||||||
|
|
||||||
|
|
||||||
private void AssertOffsetAndLength(int offset, int length)
|
private void AssertOffsetAndLength(int offset, int length)
|
||||||
{
|
{
|
||||||
|
#if !BYTEBUFFER_NO_BOUNDS_CHECK
|
||||||
if (offset < 0 ||
|
if (offset < 0 ||
|
||||||
offset > _buffer.Length - length)
|
offset > _buffer.Length - length)
|
||||||
throw new ArgumentOutOfRangeException();
|
throw new ArgumentOutOfRangeException();
|
||||||
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
public void PutSbyte(int offset, sbyte value)
|
public void PutSbyte(int offset, sbyte value)
|
||||||
@@ -200,7 +213,6 @@ namespace FlatBuffers
|
|||||||
public unsafe void PutUlong(int offset, ulong value)
|
public unsafe void PutUlong(int offset, ulong value)
|
||||||
{
|
{
|
||||||
AssertOffsetAndLength(offset, sizeof(ulong));
|
AssertOffsetAndLength(offset, sizeof(ulong));
|
||||||
|
|
||||||
fixed (byte* ptr = _buffer)
|
fixed (byte* ptr = _buffer)
|
||||||
{
|
{
|
||||||
*(ulong*)(ptr + offset) = BitConverter.IsLittleEndian
|
*(ulong*)(ptr + offset) = BitConverter.IsLittleEndian
|
||||||
|
|||||||
2
pom.xml
2
pom.xml
@@ -5,7 +5,7 @@
|
|||||||
<modelVersion>4.0.0</modelVersion>
|
<modelVersion>4.0.0</modelVersion>
|
||||||
<groupId>com.google.flatbuffers</groupId>
|
<groupId>com.google.flatbuffers</groupId>
|
||||||
<artifactId>flatbuffers-java</artifactId>
|
<artifactId>flatbuffers-java</artifactId>
|
||||||
<version>1.3.0-SNAPSHOT</version>
|
<version>1.4.0-SNAPSHOT</version>
|
||||||
<packaging>bundle</packaging>
|
<packaging>bundle</packaging>
|
||||||
<name>FlatBuffers Java API</name>
|
<name>FlatBuffers Java API</name>
|
||||||
<description>
|
<description>
|
||||||
|
|||||||
@@ -46,7 +46,10 @@ int main(int /*argc*/, const char * /*argv*/[]) {
|
|||||||
// to ensure it is correct, we now generate text back from the binary,
|
// to ensure it is correct, we now generate text back from the binary,
|
||||||
// and compare the two:
|
// and compare the two:
|
||||||
std::string jsongen;
|
std::string jsongen;
|
||||||
GenerateText(parser, parser.builder_.GetBufferPointer(), &jsongen);
|
if (!GenerateText(parser, parser.builder_.GetBufferPointer(), &jsongen)) {
|
||||||
|
printf("Couldn't serialize parsed data to JSON!\n");
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
|
||||||
if (jsongen != jsonfile) {
|
if (jsongen != jsonfile) {
|
||||||
printf("%s----------------\n%s", jsongen.c_str(), jsonfile.c_str());
|
printf("%s----------------\n%s", jsongen.c_str(), jsonfile.c_str());
|
||||||
|
|||||||
@@ -19,7 +19,7 @@
|
|||||||
#include "flatbuffers/util.h"
|
#include "flatbuffers/util.h"
|
||||||
#include <limits>
|
#include <limits>
|
||||||
|
|
||||||
#define FLATC_VERSION "1.3.0 (" __DATE__ ")"
|
#define FLATC_VERSION "1.4.0 (" __DATE__ ")"
|
||||||
|
|
||||||
static void Error(const std::string &err, bool usage = false,
|
static void Error(const std::string &err, bool usage = false,
|
||||||
bool show_exe_name = true);
|
bool show_exe_name = true);
|
||||||
@@ -243,7 +243,7 @@ int main(int argc, const char *argv[]) {
|
|||||||
goto found;
|
goto found;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
Error("unknown commandline argument" + arg, true);
|
Error("unknown commandline argument: " + arg, true);
|
||||||
found:;
|
found:;
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
|
|||||||
@@ -333,15 +333,15 @@ class CppGenerator : public BaseGenerator {
|
|||||||
return (opts.scoped_enums ? "enum class " : "enum ") + enum_def.name;
|
return (opts.scoped_enums ? "enum class " : "enum ") + enum_def.name;
|
||||||
}
|
}
|
||||||
|
|
||||||
static std::string GenEnumVal(const EnumDef &enum_def,
|
static std::string GenEnumValDecl(const EnumDef &enum_def,
|
||||||
const std::string &enum_val,
|
const std::string &enum_val,
|
||||||
const IDLOptions &opts) {
|
const IDLOptions &opts) {
|
||||||
return opts.prefixed_enums ? enum_def.name + "_" + enum_val : enum_val;
|
return opts.prefixed_enums ? enum_def.name + "_" + enum_val : enum_val;
|
||||||
}
|
}
|
||||||
|
|
||||||
static std::string GetEnumVal(const EnumDef &enum_def,
|
static std::string GetEnumValUse(const EnumDef &enum_def,
|
||||||
const EnumVal &enum_val,
|
const EnumVal &enum_val,
|
||||||
const IDLOptions &opts) {
|
const IDLOptions &opts) {
|
||||||
if (opts.scoped_enums) {
|
if (opts.scoped_enums) {
|
||||||
return enum_def.name + "::" + enum_val.name;
|
return enum_def.name + "::" + enum_val.name;
|
||||||
} else if (opts.prefixed_enums) {
|
} else if (opts.prefixed_enums) {
|
||||||
@@ -396,7 +396,7 @@ class CppGenerator : public BaseGenerator {
|
|||||||
++it) {
|
++it) {
|
||||||
auto &ev = **it;
|
auto &ev = **it;
|
||||||
GenComment(ev.doc_comment, code_ptr, nullptr, " ");
|
GenComment(ev.doc_comment, code_ptr, nullptr, " ");
|
||||||
code += " " + GenEnumVal(enum_def, ev.name, parser_.opts) + " = ";
|
code += " " + GenEnumValDecl(enum_def, ev.name, parser_.opts) + " = ";
|
||||||
code += NumToString(ev.value) + ",\n";
|
code += NumToString(ev.value) + ",\n";
|
||||||
minv = !minv || minv->value > ev.value ? &ev : minv;
|
minv = !minv || minv->value > ev.value ? &ev : minv;
|
||||||
maxv = !maxv || maxv->value < ev.value ? &ev : maxv;
|
maxv = !maxv || maxv->value < ev.value ? &ev : maxv;
|
||||||
@@ -406,15 +406,15 @@ class CppGenerator : public BaseGenerator {
|
|||||||
assert(minv && maxv);
|
assert(minv && maxv);
|
||||||
if (enum_def.attributes.Lookup("bit_flags")) {
|
if (enum_def.attributes.Lookup("bit_flags")) {
|
||||||
if (minv->value != 0) // If the user didn't defined NONE value
|
if (minv->value != 0) // If the user didn't defined NONE value
|
||||||
code += " " + GenEnumVal(enum_def, "NONE", parser_.opts) + " = 0,\n";
|
code += " " + GenEnumValDecl(enum_def, "NONE", parser_.opts) + " = 0,\n";
|
||||||
if (maxv->value != anyv) // If the user didn't defined ANY value
|
if (maxv->value != anyv) // If the user didn't defined ANY value
|
||||||
code += " " + GenEnumVal(enum_def, "ANY", parser_.opts) + " = " +
|
code += " " + GenEnumValDecl(enum_def, "ANY", parser_.opts) + " = " +
|
||||||
NumToString(anyv) + "\n";
|
NumToString(anyv) + "\n";
|
||||||
} else { // MIN & MAX are useless for bit_flags
|
} else { // MIN & MAX are useless for bit_flags
|
||||||
code += " " + GenEnumVal(enum_def, "MIN", parser_.opts) + " = ";
|
code += " " + GenEnumValDecl(enum_def, "MIN", parser_.opts) + " = ";
|
||||||
code += GenEnumVal(enum_def, minv->name, parser_.opts) + ",\n";
|
code += GenEnumValDecl(enum_def, minv->name, parser_.opts) + ",\n";
|
||||||
code += " " + GenEnumVal(enum_def, "MAX", parser_.opts) + " = ";
|
code += " " + GenEnumValDecl(enum_def, "MAX", parser_.opts) + " = ";
|
||||||
code += GenEnumVal(enum_def, maxv->name, parser_.opts) + "\n";
|
code += GenEnumValDecl(enum_def, maxv->name, parser_.opts) + "\n";
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
code += "};\n";
|
code += "};\n";
|
||||||
@@ -429,7 +429,7 @@ class CppGenerator : public BaseGenerator {
|
|||||||
code += " " + enum_def.name + " type;\n\n";
|
code += " " + enum_def.name + " type;\n\n";
|
||||||
code += " flatbuffers::NativeTable *table;\n";
|
code += " flatbuffers::NativeTable *table;\n";
|
||||||
code += " " + enum_def.name + "Union() : type(";
|
code += " " + enum_def.name + "Union() : type(";
|
||||||
code += GenEnumVal(enum_def, "NONE", parser_.opts);
|
code += GetEnumValUse(enum_def, *enum_def.vals.Lookup("NONE"), parser_.opts);
|
||||||
code += "), table(nullptr) {}\n";
|
code += "), table(nullptr) {}\n";
|
||||||
code += " " + enum_def.name + "Union(const ";
|
code += " " + enum_def.name + "Union(const ";
|
||||||
code += enum_def.name + "Union &);\n";
|
code += enum_def.name + "Union &);\n";
|
||||||
@@ -445,7 +445,7 @@ class CppGenerator : public BaseGenerator {
|
|||||||
auto native_name = NativeName(WrapInNameSpace(*ev.struct_def));
|
auto native_name = NativeName(WrapInNameSpace(*ev.struct_def));
|
||||||
code += " " + native_name + " *As";
|
code += " " + native_name + " *As";
|
||||||
code += ev.name + "() { return type == ";
|
code += ev.name + "() { return type == ";
|
||||||
code += GetEnumVal(enum_def, ev, parser_.opts);
|
code += GetEnumValUse(enum_def, ev, parser_.opts);
|
||||||
code += " ? reinterpret_cast<" + native_name;
|
code += " ? reinterpret_cast<" + native_name;
|
||||||
code += " *>(table) : nullptr; }\n";
|
code += " *>(table) : nullptr; }\n";
|
||||||
}
|
}
|
||||||
@@ -478,7 +478,7 @@ class CppGenerator : public BaseGenerator {
|
|||||||
code += "()[static_cast<int>(e)";
|
code += "()[static_cast<int>(e)";
|
||||||
if (enum_def.vals.vec.front()->value) {
|
if (enum_def.vals.vec.front()->value) {
|
||||||
code += " - static_cast<int>(";
|
code += " - static_cast<int>(";
|
||||||
code += GetEnumVal(enum_def, *enum_def.vals.vec.front(), parser_.opts) +
|
code += GetEnumValUse(enum_def, *enum_def.vals.vec.front(), parser_.opts) +
|
||||||
")";
|
")";
|
||||||
}
|
}
|
||||||
code += "]; }\n\n";
|
code += "]; }\n\n";
|
||||||
@@ -500,7 +500,7 @@ class CppGenerator : public BaseGenerator {
|
|||||||
for (auto it = enum_def.vals.vec.begin(); it != enum_def.vals.vec.end();
|
for (auto it = enum_def.vals.vec.begin(); it != enum_def.vals.vec.end();
|
||||||
++it) {
|
++it) {
|
||||||
auto &ev = **it;
|
auto &ev = **it;
|
||||||
code += " case " + GetEnumVal(enum_def, ev, parser_.opts);
|
code += " case " + GetEnumValUse(enum_def, ev, parser_.opts);
|
||||||
if (!ev.value) {
|
if (!ev.value) {
|
||||||
code += ": return true;\n"; // "NONE" enum value.
|
code += ": return true;\n"; // "NONE" enum value.
|
||||||
} else {
|
} else {
|
||||||
@@ -518,7 +518,7 @@ class CppGenerator : public BaseGenerator {
|
|||||||
for (auto it = enum_def.vals.vec.begin(); it != enum_def.vals.vec.end();
|
for (auto it = enum_def.vals.vec.begin(); it != enum_def.vals.vec.end();
|
||||||
++it) {
|
++it) {
|
||||||
auto &ev = **it;
|
auto &ev = **it;
|
||||||
code += " case " + GetEnumVal(enum_def, ev, parser_.opts);
|
code += " case " + GetEnumValUse(enum_def, ev, parser_.opts);
|
||||||
if (!ev.value) {
|
if (!ev.value) {
|
||||||
code += ": return nullptr;\n"; // "NONE" enum value.
|
code += ": return nullptr;\n"; // "NONE" enum value.
|
||||||
} else {
|
} else {
|
||||||
@@ -533,7 +533,7 @@ class CppGenerator : public BaseGenerator {
|
|||||||
for (auto it = enum_def.vals.vec.begin(); it != enum_def.vals.vec.end();
|
for (auto it = enum_def.vals.vec.begin(); it != enum_def.vals.vec.end();
|
||||||
++it) {
|
++it) {
|
||||||
auto &ev = **it;
|
auto &ev = **it;
|
||||||
code += " case " + GetEnumVal(enum_def, ev, parser_.opts);
|
code += " case " + GetEnumValUse(enum_def, ev, parser_.opts);
|
||||||
if (!ev.value) {
|
if (!ev.value) {
|
||||||
code += ": return 0;\n"; // "NONE" enum value.
|
code += ": return 0;\n"; // "NONE" enum value.
|
||||||
} else {
|
} else {
|
||||||
@@ -553,7 +553,7 @@ class CppGenerator : public BaseGenerator {
|
|||||||
++it) {
|
++it) {
|
||||||
auto &ev = **it;
|
auto &ev = **it;
|
||||||
if (ev.value) {
|
if (ev.value) {
|
||||||
code += " case " + GenEnumVal(enum_def, ev.name, parser_.opts);
|
code += " case " + GetEnumValUse(enum_def, ev, parser_.opts);
|
||||||
code += ": delete reinterpret_cast<";
|
code += ": delete reinterpret_cast<";
|
||||||
code += NativeName(WrapInNameSpace(*ev.struct_def));
|
code += NativeName(WrapInNameSpace(*ev.struct_def));
|
||||||
code += " *>(table); break;\n";
|
code += " *>(table); break;\n";
|
||||||
@@ -613,7 +613,7 @@ class CppGenerator : public BaseGenerator {
|
|||||||
if (ev) {
|
if (ev) {
|
||||||
code += WrapInNameSpace(
|
code += WrapInNameSpace(
|
||||||
field.value.type.enum_def->defined_namespace,
|
field.value.type.enum_def->defined_namespace,
|
||||||
GetEnumVal(*field.value.type.enum_def, *ev, parser_.opts));
|
GetEnumValUse(*field.value.type.enum_def, *ev, parser_.opts));
|
||||||
} else {
|
} else {
|
||||||
code += GenUnderlyingCast(field, true, field.value.constant);
|
code += GenUnderlyingCast(field, true, field.value.constant);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -237,7 +237,7 @@ class GeneralGenerator : public BaseGenerator {
|
|||||||
// Save out the generated code for a single class while adding
|
// Save out the generated code for a single class while adding
|
||||||
// declaration boilerplate.
|
// declaration boilerplate.
|
||||||
bool SaveType(const std::string &defname, const Namespace &ns,
|
bool SaveType(const std::string &defname, const Namespace &ns,
|
||||||
const std::string &classcode, bool needs_includes) {
|
const std::string &classcode, bool needs_includes) {
|
||||||
if (!classcode.length()) return true;
|
if (!classcode.length()) return true;
|
||||||
|
|
||||||
std::string code;
|
std::string code;
|
||||||
@@ -684,8 +684,7 @@ std::string GenOffsetGetter(flatbuffers::FieldDef *key_field, const char *num =
|
|||||||
key_offset += num;
|
key_offset += num;
|
||||||
key_offset += (lang_.language == IDLOptions::kCSharp ?
|
key_offset += (lang_.language == IDLOptions::kCSharp ?
|
||||||
".Value, builder.DataBuffer)" : ", _bb)");
|
".Value, builder.DataBuffer)" : ", _bb)");
|
||||||
}
|
} else {
|
||||||
else {
|
|
||||||
key_offset += GenByteBufferLength("bb");
|
key_offset += GenByteBufferLength("bb");
|
||||||
key_offset += " - tableOffset, bb)";
|
key_offset += " - tableOffset, bb)";
|
||||||
}
|
}
|
||||||
@@ -694,23 +693,21 @@ std::string GenOffsetGetter(flatbuffers::FieldDef *key_field, const char *num =
|
|||||||
|
|
||||||
std::string GenLookupKeyGetter(flatbuffers::FieldDef *key_field) {
|
std::string GenLookupKeyGetter(flatbuffers::FieldDef *key_field) {
|
||||||
std::string key_getter = " ";
|
std::string key_getter = " ";
|
||||||
key_getter += "tableOffset = __indirect(vectorLocation + 4 * (start + middle)";
|
key_getter += "int tableOffset = __indirect(vectorLocation + 4 * (start + middle)";
|
||||||
key_getter += ", bb);\n ";
|
key_getter += ", bb);\n ";
|
||||||
if (key_field->value.type.base_type == BASE_TYPE_STRING) {
|
if (key_field->value.type.base_type == BASE_TYPE_STRING) {
|
||||||
key_getter += "comp = " + FunctionStart('C') + "ompareStrings(";
|
key_getter += "int comp = " + FunctionStart('C') + "ompareStrings(";
|
||||||
key_getter += GenOffsetGetter(key_field);
|
key_getter += GenOffsetGetter(key_field);
|
||||||
key_getter += ", byteKey, bb);\n";
|
key_getter += ", byteKey, bb);\n";
|
||||||
}
|
} else {
|
||||||
else {
|
|
||||||
auto get_val = GenGetter(key_field->value.type) +
|
auto get_val = GenGetter(key_field->value.type) +
|
||||||
"(" + GenOffsetGetter(key_field) + ")";
|
"(" + GenOffsetGetter(key_field) + ")";
|
||||||
if (lang_.language == IDLOptions::kCSharp) {
|
if (lang_.language == IDLOptions::kCSharp) {
|
||||||
key_getter += "comp = " + get_val + ".CompareTo(key);\n";
|
key_getter += "int comp = " + get_val + ".CompateTo(key);\n";
|
||||||
}
|
} else {
|
||||||
else {
|
|
||||||
key_getter += GenTypeGet(key_field->value.type) + " val = ";
|
key_getter += GenTypeGet(key_field->value.type) + " val = ";
|
||||||
key_getter += get_val + ";\n";
|
key_getter += get_val + ";\n";
|
||||||
key_getter += " comp = val > key ? 1 : val < key ? -1 : 0;\n";
|
key_getter += " int comp = val > key ? 1 : val < key ? -1 : 0;\n";
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return key_getter;
|
return key_getter;
|
||||||
@@ -1215,8 +1212,7 @@ void GenStruct(StructDef &struct_def, std::string *code_ptr) {
|
|||||||
code += "); }\n";
|
code += "); }\n";
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (struct_def.has_key && (lang_.language == IDLOptions::kJava ||
|
if (struct_def.has_key) {
|
||||||
lang_.language == IDLOptions::kCSharp)) {
|
|
||||||
if (lang_.language == IDLOptions::kJava) {
|
if (lang_.language == IDLOptions::kJava) {
|
||||||
code += "\n @Override\n protected int keysCompare(";
|
code += "\n @Override\n protected int keysCompare(";
|
||||||
code += "Integer o1, Integer o2, ByteBuffer _bb) {";
|
code += "Integer o1, Integer o2, ByteBuffer _bb) {";
|
||||||
@@ -1238,32 +1234,31 @@ void GenStruct(StructDef &struct_def, std::string *code_ptr) {
|
|||||||
code += "ookupByKey(" + GenVectorOffsetType();
|
code += "ookupByKey(" + GenVectorOffsetType();
|
||||||
code += " vectorOffset, " + GenTypeGet(key_field->value.type);
|
code += " vectorOffset, " + GenTypeGet(key_field->value.type);
|
||||||
code += " key, ByteBuffer bb) {\n";
|
code += " key, ByteBuffer bb) {\n";
|
||||||
if (key_field->value.type.base_type == BASE_TYPE_STRING) {
|
code += " byte[] byteKey = ";
|
||||||
code += " byte[] byteKey = ";
|
if (lang_.language == IDLOptions::kJava)
|
||||||
if (lang_.language == IDLOptions::kJava)
|
code += "key.getBytes(Table.UTF8_CHARSET.get());\n";
|
||||||
code += "key.getBytes(java.nio.charset.StandardCharsets.UTF_8);\n";
|
else
|
||||||
else
|
code += "System.Text.Encoding.UTF8.GetBytes(key);\n";
|
||||||
code += "System.Text.Encoding.UTF8.GetBytes(key);\n";
|
|
||||||
}
|
|
||||||
code += " int vectorLocation = " + GenByteBufferLength("bb");
|
code += " int vectorLocation = " + GenByteBufferLength("bb");
|
||||||
code += " - vectorOffset";
|
code += " - vectorOffset";
|
||||||
if (lang_.language == IDLOptions::kCSharp) code += ".Value";
|
if (lang_.language == IDLOptions::kCSharp) code += ".Value";
|
||||||
code += ";\n int span = ";
|
code += ";\n int span = ";
|
||||||
code += "bb." + FunctionStart('G') + "etInt(vectorLocation), ";
|
code += "bb." + FunctionStart('G') + "etInt(vectorLocation);\n";
|
||||||
code += "middle, start = 0, comp, tableOffset; \n";
|
code += " int start = 0;\n";
|
||||||
code += " vectorLocation += 4;\n";
|
code += " vectorLocation += 4;\n";
|
||||||
code += " while (span != 0) {\n";
|
code += " while (span != 0) {\n";
|
||||||
code += " middle = span / 2;\n";
|
code += " int middle = span / 2;\n";
|
||||||
code += GenLookupKeyGetter(key_field);
|
code += GenLookupKeyGetter(key_field);
|
||||||
code += " if (comp > 0) span = middle;\n";
|
code += " if (comp > 0) {\n";
|
||||||
code += " else if (comp < 0) {\n";
|
code += " span = middle;\n";
|
||||||
|
code += " } else if (comp < 0) {\n";
|
||||||
code += " middle++;\n";
|
code += " middle++;\n";
|
||||||
code += " start += middle;\n";
|
code += " start += middle;\n";
|
||||||
code += " span -= middle;\n";
|
code += " span -= middle;\n";
|
||||||
code += " }\n";
|
code += " } else {\n";
|
||||||
code += " else return new " + struct_def.name;
|
code += " return new " + struct_def.name;
|
||||||
code += "().__init(tableOffset, bb);\n";
|
code += "().__init(tableOffset, bb);\n";
|
||||||
code += " }\n";
|
code += " }\n }\n";
|
||||||
code += " return null;\n";
|
code += " return null;\n";
|
||||||
code += " }\n";
|
code += " }\n";
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -288,9 +288,6 @@ static void GetMemberOfVectorOfStruct(const StructDef &struct_def,
|
|||||||
if (!(vectortype.struct_def->fixed)) {
|
if (!(vectortype.struct_def->fixed)) {
|
||||||
code += "\t\tx = rcv._tab.Indirect(x)\n";
|
code += "\t\tx = rcv._tab.Indirect(x)\n";
|
||||||
}
|
}
|
||||||
code += "\t\tif obj == nil {\n";
|
|
||||||
code += "\t\t\tobj = new(" + TypeName(field) + ")\n";
|
|
||||||
code += "\t\t}\n";
|
|
||||||
code += "\t\tobj.Init(rcv._tab.Bytes, x)\n";
|
code += "\t\tobj.Init(rcv._tab.Bytes, x)\n";
|
||||||
code += "\t\treturn true\n\t}\n";
|
code += "\t\treturn true\n\t}\n";
|
||||||
code += "\treturn false\n";
|
code += "\treturn false\n";
|
||||||
|
|||||||
@@ -24,7 +24,7 @@
|
|||||||
|
|
||||||
namespace flatbuffers {
|
namespace flatbuffers {
|
||||||
|
|
||||||
class FlatBufMethod : public grpc_cpp_generator::Method {
|
class FlatBufMethod : public grpc_generator::Method {
|
||||||
public:
|
public:
|
||||||
enum Streaming { kNone, kClient, kServer, kBiDi };
|
enum Streaming { kNone, kClient, kServer, kBiDi };
|
||||||
|
|
||||||
@@ -62,7 +62,7 @@ class FlatBufMethod : public grpc_cpp_generator::Method {
|
|||||||
Streaming streaming_;
|
Streaming streaming_;
|
||||||
};
|
};
|
||||||
|
|
||||||
class FlatBufService : public grpc_cpp_generator::Service {
|
class FlatBufService : public grpc_generator::Service {
|
||||||
public:
|
public:
|
||||||
FlatBufService(const ServiceDef *service) : service_(service) {}
|
FlatBufService(const ServiceDef *service) : service_(service) {}
|
||||||
|
|
||||||
@@ -72,8 +72,8 @@ class FlatBufService : public grpc_cpp_generator::Service {
|
|||||||
return static_cast<int>(service_->calls.vec.size());
|
return static_cast<int>(service_->calls.vec.size());
|
||||||
};
|
};
|
||||||
|
|
||||||
std::unique_ptr<const grpc_cpp_generator::Method> method(int i) const {
|
std::unique_ptr<const grpc_generator::Method> method(int i) const {
|
||||||
return std::unique_ptr<const grpc_cpp_generator::Method>(
|
return std::unique_ptr<const grpc_generator::Method>(
|
||||||
new FlatBufMethod(service_->calls.vec[i]));
|
new FlatBufMethod(service_->calls.vec[i]));
|
||||||
};
|
};
|
||||||
|
|
||||||
@@ -81,7 +81,7 @@ class FlatBufService : public grpc_cpp_generator::Service {
|
|||||||
const ServiceDef *service_;
|
const ServiceDef *service_;
|
||||||
};
|
};
|
||||||
|
|
||||||
class FlatBufPrinter : public grpc_cpp_generator::Printer {
|
class FlatBufPrinter : public grpc_generator::Printer {
|
||||||
public:
|
public:
|
||||||
FlatBufPrinter(std::string *str)
|
FlatBufPrinter(std::string *str)
|
||||||
: str_(str), escape_char_('$'), indent_(0) {}
|
: str_(str), escape_char_('$'), indent_(0) {}
|
||||||
@@ -133,7 +133,7 @@ class FlatBufPrinter : public grpc_cpp_generator::Printer {
|
|||||||
int indent_;
|
int indent_;
|
||||||
};
|
};
|
||||||
|
|
||||||
class FlatBufFile : public grpc_cpp_generator::File {
|
class FlatBufFile : public grpc_generator::File {
|
||||||
public:
|
public:
|
||||||
FlatBufFile(const Parser &parser, const std::string &file_name)
|
FlatBufFile(const Parser &parser, const std::string &file_name)
|
||||||
: parser_(parser), file_name_(file_name) {}
|
: parser_(parser), file_name_(file_name) {}
|
||||||
@@ -163,13 +163,13 @@ class FlatBufFile : public grpc_cpp_generator::File {
|
|||||||
return static_cast<int>(parser_.services_.vec.size());
|
return static_cast<int>(parser_.services_.vec.size());
|
||||||
};
|
};
|
||||||
|
|
||||||
std::unique_ptr<const grpc_cpp_generator::Service> service(int i) const {
|
std::unique_ptr<const grpc_generator::Service> service(int i) const {
|
||||||
return std::unique_ptr<const grpc_cpp_generator::Service> (
|
return std::unique_ptr<const grpc_generator::Service> (
|
||||||
new FlatBufService(parser_.services_.vec[i]));
|
new FlatBufService(parser_.services_.vec[i]));
|
||||||
}
|
}
|
||||||
|
|
||||||
std::unique_ptr<grpc_cpp_generator::Printer> CreatePrinter(std::string *str) const {
|
std::unique_ptr<grpc_generator::Printer> CreatePrinter(std::string *str) const {
|
||||||
return std::unique_ptr<grpc_cpp_generator::Printer>(
|
return std::unique_ptr<grpc_generator::Printer>(
|
||||||
new FlatBufPrinter(str));
|
new FlatBufPrinter(str));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -22,7 +22,7 @@
|
|||||||
|
|
||||||
namespace flatbuffers {
|
namespace flatbuffers {
|
||||||
|
|
||||||
static void GenStruct(const StructDef &struct_def, const Table *table,
|
static bool GenStruct(const StructDef &struct_def, const Table *table,
|
||||||
int indent, const IDLOptions &opts,
|
int indent, const IDLOptions &opts,
|
||||||
std::string *_text);
|
std::string *_text);
|
||||||
|
|
||||||
@@ -48,7 +48,7 @@ void OutputIdentifier(const std::string &name, const IDLOptions &opts,
|
|||||||
// Print (and its template specialization below for pointers) generate text
|
// Print (and its template specialization below for pointers) generate text
|
||||||
// for a single FlatBuffer value into JSON format.
|
// for a single FlatBuffer value into JSON format.
|
||||||
// The general case for scalars:
|
// The general case for scalars:
|
||||||
template<typename T> void Print(T val, Type type, int /*indent*/,
|
template<typename T> bool Print(T val, Type type, int /*indent*/,
|
||||||
StructDef * /*union_sd*/,
|
StructDef * /*union_sd*/,
|
||||||
const IDLOptions &opts,
|
const IDLOptions &opts,
|
||||||
std::string *_text) {
|
std::string *_text) {
|
||||||
@@ -57,7 +57,7 @@ template<typename T> void Print(T val, Type type, int /*indent*/,
|
|||||||
auto enum_val = type.enum_def->ReverseLookup(static_cast<int>(val));
|
auto enum_val = type.enum_def->ReverseLookup(static_cast<int>(val));
|
||||||
if (enum_val) {
|
if (enum_val) {
|
||||||
OutputIdentifier(enum_val->name, opts, _text);
|
OutputIdentifier(enum_val->name, opts, _text);
|
||||||
return;
|
return true;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -66,10 +66,12 @@ template<typename T> void Print(T val, Type type, int /*indent*/,
|
|||||||
} else {
|
} else {
|
||||||
text += NumToString(val);
|
text += NumToString(val);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Print a vector a sequence of JSON values, comma separated, wrapped in "[]".
|
// Print a vector a sequence of JSON values, comma separated, wrapped in "[]".
|
||||||
template<typename T> void PrintVector(const Vector<T> &v, Type type,
|
template<typename T> bool PrintVector(const Vector<T> &v, Type type,
|
||||||
int indent, const IDLOptions &opts,
|
int indent, const IDLOptions &opts,
|
||||||
std::string *_text) {
|
std::string *_text) {
|
||||||
std::string &text = *_text;
|
std::string &text = *_text;
|
||||||
@@ -81,19 +83,25 @@ template<typename T> void PrintVector(const Vector<T> &v, Type type,
|
|||||||
text += NewLine(opts);
|
text += NewLine(opts);
|
||||||
}
|
}
|
||||||
text.append(indent + Indent(opts), ' ');
|
text.append(indent + Indent(opts), ' ');
|
||||||
if (IsStruct(type))
|
if (IsStruct(type)) {
|
||||||
Print(v.GetStructFromOffset(i * type.struct_def->bytesize), type,
|
if (!Print(v.GetStructFromOffset(i * type.struct_def->bytesize), type,
|
||||||
indent + Indent(opts), nullptr, opts, _text);
|
indent + Indent(opts), nullptr, opts, _text)) {
|
||||||
else
|
return false;
|
||||||
Print(v[i], type, indent + Indent(opts), nullptr,
|
}
|
||||||
opts, _text);
|
} else {
|
||||||
|
if (!Print(v[i], type, indent + Indent(opts), nullptr,
|
||||||
|
opts, _text)) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
text += NewLine(opts);
|
text += NewLine(opts);
|
||||||
text.append(indent, ' ');
|
text.append(indent, ' ');
|
||||||
text += "]";
|
text += "]";
|
||||||
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
static void EscapeString(const String &s, std::string *_text, const IDLOptions& opts) {
|
static bool EscapeString(const String &s, std::string *_text, const IDLOptions& opts) {
|
||||||
std::string &text = *_text;
|
std::string &text = *_text;
|
||||||
text += "\"";
|
text += "\"";
|
||||||
for (uoffset_t i = 0; i < s.size(); i++) {
|
for (uoffset_t i = 0; i < s.size(); i++) {
|
||||||
@@ -118,9 +126,19 @@ static void EscapeString(const String &s, std::string *_text, const IDLOptions&
|
|||||||
text += "\\x";
|
text += "\\x";
|
||||||
text += IntToStringHex(static_cast<uint8_t>(c), 2);
|
text += IntToStringHex(static_cast<uint8_t>(c), 2);
|
||||||
} else {
|
} else {
|
||||||
// We previously checked for non-UTF-8 and returned a parse error,
|
// There are two cases here:
|
||||||
// so we shouldn't reach here.
|
//
|
||||||
assert(0);
|
// 1) We reached here by parsing an IDL file. In that case,
|
||||||
|
// we previously checked for non-UTF-8, so we shouldn't reach
|
||||||
|
// here.
|
||||||
|
//
|
||||||
|
// 2) We reached here by someone calling GenerateText()
|
||||||
|
// on a previously-serialized flatbuffer. The data might have
|
||||||
|
// non-UTF-8 Strings, or might be corrupt.
|
||||||
|
//
|
||||||
|
// In both cases, we have to give up and inform the caller
|
||||||
|
// they have no JSON.
|
||||||
|
return false;
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
if (ucc <= 0xFFFF) {
|
if (ucc <= 0xFFFF) {
|
||||||
@@ -145,10 +163,11 @@ static void EscapeString(const String &s, std::string *_text, const IDLOptions&
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
text += "\"";
|
text += "\"";
|
||||||
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Specialization of Print above for pointer types.
|
// Specialization of Print above for pointer types.
|
||||||
template<> void Print<const void *>(const void *val,
|
template<> bool Print<const void *>(const void *val,
|
||||||
Type type, int indent,
|
Type type, int indent,
|
||||||
StructDef *union_sd,
|
StructDef *union_sd,
|
||||||
const IDLOptions &opts,
|
const IDLOptions &opts,
|
||||||
@@ -158,21 +177,27 @@ template<> void Print<const void *>(const void *val,
|
|||||||
// If this assert hits, you have an corrupt buffer, a union type field
|
// If this assert hits, you have an corrupt buffer, a union type field
|
||||||
// was not present or was out of range.
|
// was not present or was out of range.
|
||||||
assert(union_sd);
|
assert(union_sd);
|
||||||
GenStruct(*union_sd,
|
if (!GenStruct(*union_sd,
|
||||||
reinterpret_cast<const Table *>(val),
|
reinterpret_cast<const Table *>(val),
|
||||||
indent,
|
indent,
|
||||||
opts,
|
opts,
|
||||||
_text);
|
_text)) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
break;
|
break;
|
||||||
case BASE_TYPE_STRUCT:
|
case BASE_TYPE_STRUCT:
|
||||||
GenStruct(*type.struct_def,
|
if (!GenStruct(*type.struct_def,
|
||||||
reinterpret_cast<const Table *>(val),
|
reinterpret_cast<const Table *>(val),
|
||||||
indent,
|
indent,
|
||||||
opts,
|
opts,
|
||||||
_text);
|
_text)) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
break;
|
break;
|
||||||
case BASE_TYPE_STRING: {
|
case BASE_TYPE_STRING: {
|
||||||
EscapeString(*reinterpret_cast<const String *>(val), _text, opts);
|
if (!EscapeString(*reinterpret_cast<const String *>(val), _text, opts)) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
case BASE_TYPE_VECTOR:
|
case BASE_TYPE_VECTOR:
|
||||||
@@ -182,31 +207,35 @@ template<> void Print<const void *>(const void *val,
|
|||||||
#define FLATBUFFERS_TD(ENUM, IDLTYPE, CTYPE, JTYPE, GTYPE, NTYPE, \
|
#define FLATBUFFERS_TD(ENUM, IDLTYPE, CTYPE, JTYPE, GTYPE, NTYPE, \
|
||||||
PTYPE) \
|
PTYPE) \
|
||||||
case BASE_TYPE_ ## ENUM: \
|
case BASE_TYPE_ ## ENUM: \
|
||||||
PrintVector<CTYPE>( \
|
if (!PrintVector<CTYPE>( \
|
||||||
*reinterpret_cast<const Vector<CTYPE> *>(val), \
|
*reinterpret_cast<const Vector<CTYPE> *>(val), \
|
||||||
type, indent, opts, _text); break;
|
type, indent, opts, _text)) { \
|
||||||
|
return false; \
|
||||||
|
} \
|
||||||
|
break;
|
||||||
FLATBUFFERS_GEN_TYPES(FLATBUFFERS_TD)
|
FLATBUFFERS_GEN_TYPES(FLATBUFFERS_TD)
|
||||||
#undef FLATBUFFERS_TD
|
#undef FLATBUFFERS_TD
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
default: assert(0);
|
default: assert(0);
|
||||||
}
|
}
|
||||||
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Generate text for a scalar field.
|
// Generate text for a scalar field.
|
||||||
template<typename T> static void GenField(const FieldDef &fd,
|
template<typename T> static bool GenField(const FieldDef &fd,
|
||||||
const Table *table, bool fixed,
|
const Table *table, bool fixed,
|
||||||
const IDLOptions &opts,
|
const IDLOptions &opts,
|
||||||
int indent,
|
int indent,
|
||||||
std::string *_text) {
|
std::string *_text) {
|
||||||
Print(fixed ?
|
return Print(fixed ?
|
||||||
reinterpret_cast<const Struct *>(table)->GetField<T>(fd.value.offset) :
|
reinterpret_cast<const Struct *>(table)->GetField<T>(fd.value.offset) :
|
||||||
table->GetField<T>(fd.value.offset, 0), fd.value.type, indent, nullptr,
|
table->GetField<T>(fd.value.offset, 0), fd.value.type, indent, nullptr,
|
||||||
opts, _text);
|
opts, _text);
|
||||||
}
|
}
|
||||||
|
|
||||||
// Generate text for non-scalar field.
|
// Generate text for non-scalar field.
|
||||||
static void GenFieldOffset(const FieldDef &fd, const Table *table, bool fixed,
|
static bool GenFieldOffset(const FieldDef &fd, const Table *table, bool fixed,
|
||||||
int indent, StructDef *union_sd,
|
int indent, StructDef *union_sd,
|
||||||
const IDLOptions &opts, std::string *_text) {
|
const IDLOptions &opts, std::string *_text) {
|
||||||
const void *val = nullptr;
|
const void *val = nullptr;
|
||||||
@@ -220,12 +249,12 @@ static void GenFieldOffset(const FieldDef &fd, const Table *table, bool fixed,
|
|||||||
? table->GetStruct<const void *>(fd.value.offset)
|
? table->GetStruct<const void *>(fd.value.offset)
|
||||||
: table->GetPointer<const void *>(fd.value.offset);
|
: table->GetPointer<const void *>(fd.value.offset);
|
||||||
}
|
}
|
||||||
Print(val, fd.value.type, indent, union_sd, opts, _text);
|
return Print(val, fd.value.type, indent, union_sd, opts, _text);
|
||||||
}
|
}
|
||||||
|
|
||||||
// Generate text for a struct or table, values separated by commas, indented,
|
// Generate text for a struct or table, values separated by commas, indented,
|
||||||
// and bracketed by "{}"
|
// and bracketed by "{}"
|
||||||
static void GenStruct(const StructDef &struct_def, const Table *table,
|
static bool GenStruct(const StructDef &struct_def, const Table *table,
|
||||||
int indent, const IDLOptions &opts,
|
int indent, const IDLOptions &opts,
|
||||||
std::string *_text) {
|
std::string *_text) {
|
||||||
std::string &text = *_text;
|
std::string &text = *_text;
|
||||||
@@ -253,8 +282,10 @@ static void GenStruct(const StructDef &struct_def, const Table *table,
|
|||||||
#define FLATBUFFERS_TD(ENUM, IDLTYPE, CTYPE, JTYPE, GTYPE, NTYPE, \
|
#define FLATBUFFERS_TD(ENUM, IDLTYPE, CTYPE, JTYPE, GTYPE, NTYPE, \
|
||||||
PTYPE) \
|
PTYPE) \
|
||||||
case BASE_TYPE_ ## ENUM: \
|
case BASE_TYPE_ ## ENUM: \
|
||||||
GenField<CTYPE>(fd, table, struct_def.fixed, \
|
if (!GenField<CTYPE>(fd, table, struct_def.fixed, \
|
||||||
opts, indent + Indent(opts), _text); \
|
opts, indent + Indent(opts), _text)) { \
|
||||||
|
return false; \
|
||||||
|
} \
|
||||||
break;
|
break;
|
||||||
FLATBUFFERS_GEN_TYPES_SCALAR(FLATBUFFERS_TD)
|
FLATBUFFERS_GEN_TYPES_SCALAR(FLATBUFFERS_TD)
|
||||||
#undef FLATBUFFERS_TD
|
#undef FLATBUFFERS_TD
|
||||||
@@ -264,8 +295,10 @@ static void GenStruct(const StructDef &struct_def, const Table *table,
|
|||||||
case BASE_TYPE_ ## ENUM:
|
case BASE_TYPE_ ## ENUM:
|
||||||
FLATBUFFERS_GEN_TYPES_POINTER(FLATBUFFERS_TD)
|
FLATBUFFERS_GEN_TYPES_POINTER(FLATBUFFERS_TD)
|
||||||
#undef FLATBUFFERS_TD
|
#undef FLATBUFFERS_TD
|
||||||
GenFieldOffset(fd, table, struct_def.fixed, indent + Indent(opts),
|
if (!GenFieldOffset(fd, table, struct_def.fixed, indent + Indent(opts),
|
||||||
union_sd, opts, _text);
|
union_sd, opts, _text)) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
if (fd.value.type.base_type == BASE_TYPE_UTYPE) {
|
if (fd.value.type.base_type == BASE_TYPE_UTYPE) {
|
||||||
@@ -284,20 +317,24 @@ static void GenStruct(const StructDef &struct_def, const Table *table,
|
|||||||
text += NewLine(opts);
|
text += NewLine(opts);
|
||||||
text.append(indent, ' ');
|
text.append(indent, ' ');
|
||||||
text += "}";
|
text += "}";
|
||||||
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Generate a text representation of a flatbuffer in JSON format.
|
// Generate a text representation of a flatbuffer in JSON format.
|
||||||
void GenerateText(const Parser &parser, const void *flatbuffer,
|
bool GenerateText(const Parser &parser, const void *flatbuffer,
|
||||||
std::string *_text) {
|
std::string *_text) {
|
||||||
std::string &text = *_text;
|
std::string &text = *_text;
|
||||||
assert(parser.root_struct_def_); // call SetRootType()
|
assert(parser.root_struct_def_); // call SetRootType()
|
||||||
text.reserve(1024); // Reduce amount of inevitable reallocs.
|
text.reserve(1024); // Reduce amount of inevitable reallocs.
|
||||||
GenStruct(*parser.root_struct_def_,
|
if (!GenStruct(*parser.root_struct_def_,
|
||||||
GetRoot<Table>(flatbuffer),
|
GetRoot<Table>(flatbuffer),
|
||||||
0,
|
0,
|
||||||
parser.opts,
|
parser.opts,
|
||||||
_text);
|
_text)) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
text += NewLine(parser.opts);
|
text += NewLine(parser.opts);
|
||||||
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
std::string TextFileName(const std::string &path,
|
std::string TextFileName(const std::string &path,
|
||||||
@@ -310,7 +347,9 @@ bool GenerateTextFile(const Parser &parser,
|
|||||||
const std::string &file_name) {
|
const std::string &file_name) {
|
||||||
if (!parser.builder_.GetSize() || !parser.root_struct_def_) return true;
|
if (!parser.builder_.GetSize() || !parser.root_struct_def_) return true;
|
||||||
std::string text;
|
std::string text;
|
||||||
GenerateText(parser, parser.builder_.GetBufferPointer(), &text);
|
if (!GenerateText(parser, parser.builder_.GetBufferPointer(), &text)) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
return flatbuffers::SaveFile(TextFileName(path, file_name).c_str(),
|
return flatbuffers::SaveFile(TextFileName(path, file_name).c_str(),
|
||||||
text,
|
text,
|
||||||
false);
|
false);
|
||||||
|
|||||||
@@ -40,6 +40,7 @@ namespace FlatBuffers.Test
|
|||||||
Assert.AreEqual((byte)99, buffer[0]);
|
Assert.AreEqual((byte)99, buffer[0]);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#if !BYTEBUFFER_NO_BOUNDS_CHECK
|
||||||
[FlatBuffersTestMethod]
|
[FlatBuffersTestMethod]
|
||||||
public void ByteBuffer_PutByteCannotPutAtOffsetPastLength()
|
public void ByteBuffer_PutByteCannotPutAtOffsetPastLength()
|
||||||
{
|
{
|
||||||
@@ -47,6 +48,7 @@ namespace FlatBuffers.Test
|
|||||||
var uut = new ByteBuffer(buffer);
|
var uut = new ByteBuffer(buffer);
|
||||||
Assert.Throws<ArgumentOutOfRangeException>(() => uut.PutByte(1, 99));
|
Assert.Throws<ArgumentOutOfRangeException>(() => uut.PutByte(1, 99));
|
||||||
}
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
[FlatBuffersTestMethod]
|
[FlatBuffersTestMethod]
|
||||||
public void ByteBuffer_PutShortPopulatesBufferCorrectly()
|
public void ByteBuffer_PutShortPopulatesBufferCorrectly()
|
||||||
@@ -60,6 +62,7 @@ namespace FlatBuffers.Test
|
|||||||
Assert.AreEqual((byte)0, buffer[1]);
|
Assert.AreEqual((byte)0, buffer[1]);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#if !BYTEBUFFER_NO_BOUNDS_CHECK
|
||||||
[FlatBuffersTestMethod]
|
[FlatBuffersTestMethod]
|
||||||
public void ByteBuffer_PutShortCannotPutAtOffsetPastLength()
|
public void ByteBuffer_PutShortCannotPutAtOffsetPastLength()
|
||||||
{
|
{
|
||||||
@@ -67,7 +70,9 @@ namespace FlatBuffers.Test
|
|||||||
var uut = new ByteBuffer(buffer);
|
var uut = new ByteBuffer(buffer);
|
||||||
Assert.Throws<ArgumentOutOfRangeException>(() => uut.PutShort(2, 99));
|
Assert.Throws<ArgumentOutOfRangeException>(() => uut.PutShort(2, 99));
|
||||||
}
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#if !BYTEBUFFER_NO_BOUNDS_CHECK
|
||||||
[FlatBuffersTestMethod]
|
[FlatBuffersTestMethod]
|
||||||
public void ByteBuffer_PutShortChecksLength()
|
public void ByteBuffer_PutShortChecksLength()
|
||||||
{
|
{
|
||||||
@@ -83,6 +88,7 @@ namespace FlatBuffers.Test
|
|||||||
var uut = new ByteBuffer(buffer);
|
var uut = new ByteBuffer(buffer);
|
||||||
Assert.Throws<ArgumentOutOfRangeException>(() => uut.PutShort(1, 99));
|
Assert.Throws<ArgumentOutOfRangeException>(() => uut.PutShort(1, 99));
|
||||||
}
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
[FlatBuffersTestMethod]
|
[FlatBuffersTestMethod]
|
||||||
public void ByteBuffer_PutIntPopulatesBufferCorrectly()
|
public void ByteBuffer_PutIntPopulatesBufferCorrectly()
|
||||||
@@ -98,6 +104,7 @@ namespace FlatBuffers.Test
|
|||||||
Assert.AreEqual(0x0A, buffer[3]);
|
Assert.AreEqual(0x0A, buffer[3]);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#if !BYTEBUFFER_NO_BOUNDS_CHECK
|
||||||
[FlatBuffersTestMethod]
|
[FlatBuffersTestMethod]
|
||||||
public void ByteBuffer_PutIntCannotPutAtOffsetPastLength()
|
public void ByteBuffer_PutIntCannotPutAtOffsetPastLength()
|
||||||
{
|
{
|
||||||
@@ -121,6 +128,7 @@ namespace FlatBuffers.Test
|
|||||||
var uut = new ByteBuffer(buffer);
|
var uut = new ByteBuffer(buffer);
|
||||||
Assert.Throws<ArgumentOutOfRangeException>(() => uut.PutInt(2, 0x0A0B0C0D));
|
Assert.Throws<ArgumentOutOfRangeException>(() => uut.PutInt(2, 0x0A0B0C0D));
|
||||||
}
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
[FlatBuffersTestMethod]
|
[FlatBuffersTestMethod]
|
||||||
public void ByteBuffer_PutLongPopulatesBufferCorrectly()
|
public void ByteBuffer_PutLongPopulatesBufferCorrectly()
|
||||||
@@ -140,6 +148,7 @@ namespace FlatBuffers.Test
|
|||||||
Assert.AreEqual(0x01, buffer[7]);
|
Assert.AreEqual(0x01, buffer[7]);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#if !BYTEBUFFER_NO_BOUNDS_CHECK
|
||||||
[FlatBuffersTestMethod]
|
[FlatBuffersTestMethod]
|
||||||
public void ByteBuffer_PutLongCannotPutAtOffsetPastLength()
|
public void ByteBuffer_PutLongCannotPutAtOffsetPastLength()
|
||||||
{
|
{
|
||||||
@@ -163,6 +172,7 @@ namespace FlatBuffers.Test
|
|||||||
var uut = new ByteBuffer(buffer);
|
var uut = new ByteBuffer(buffer);
|
||||||
Assert.Throws<ArgumentOutOfRangeException>(() => uut.PutLong(2, 0x010203040A0B0C0D));
|
Assert.Throws<ArgumentOutOfRangeException>(() => uut.PutLong(2, 0x010203040A0B0C0D));
|
||||||
}
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
[FlatBuffersTestMethod]
|
[FlatBuffersTestMethod]
|
||||||
public void ByteBuffer_GetByteReturnsCorrectData()
|
public void ByteBuffer_GetByteReturnsCorrectData()
|
||||||
@@ -173,6 +183,7 @@ namespace FlatBuffers.Test
|
|||||||
Assert.AreEqual((byte)99, uut.Get(0));
|
Assert.AreEqual((byte)99, uut.Get(0));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#if !BYTEBUFFER_NO_BOUNDS_CHECK
|
||||||
[FlatBuffersTestMethod]
|
[FlatBuffersTestMethod]
|
||||||
public void ByteBuffer_GetByteChecksOffset()
|
public void ByteBuffer_GetByteChecksOffset()
|
||||||
{
|
{
|
||||||
@@ -180,6 +191,7 @@ namespace FlatBuffers.Test
|
|||||||
var uut = new ByteBuffer(buffer);
|
var uut = new ByteBuffer(buffer);
|
||||||
Assert.Throws<ArgumentOutOfRangeException>(()=>uut.Get(1));
|
Assert.Throws<ArgumentOutOfRangeException>(()=>uut.Get(1));
|
||||||
}
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
[FlatBuffersTestMethod]
|
[FlatBuffersTestMethod]
|
||||||
public void ByteBuffer_GetShortReturnsCorrectData()
|
public void ByteBuffer_GetShortReturnsCorrectData()
|
||||||
@@ -191,6 +203,7 @@ namespace FlatBuffers.Test
|
|||||||
Assert.AreEqual(1, uut.GetShort(0));
|
Assert.AreEqual(1, uut.GetShort(0));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#if !BYTEBUFFER_NO_BOUNDS_CHECK
|
||||||
[FlatBuffersTestMethod]
|
[FlatBuffersTestMethod]
|
||||||
public void ByteBuffer_GetShortChecksOffset()
|
public void ByteBuffer_GetShortChecksOffset()
|
||||||
{
|
{
|
||||||
@@ -206,6 +219,7 @@ namespace FlatBuffers.Test
|
|||||||
var uut = new ByteBuffer(buffer);
|
var uut = new ByteBuffer(buffer);
|
||||||
Assert.Throws<ArgumentOutOfRangeException>(() => uut.GetShort(1));
|
Assert.Throws<ArgumentOutOfRangeException>(() => uut.GetShort(1));
|
||||||
}
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
[FlatBuffersTestMethod]
|
[FlatBuffersTestMethod]
|
||||||
public void ByteBuffer_GetIntReturnsCorrectData()
|
public void ByteBuffer_GetIntReturnsCorrectData()
|
||||||
@@ -219,6 +233,7 @@ namespace FlatBuffers.Test
|
|||||||
Assert.AreEqual(0x0A0B0C0D, uut.GetInt(0));
|
Assert.AreEqual(0x0A0B0C0D, uut.GetInt(0));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#if !BYTEBUFFER_NO_BOUNDS_CHECK
|
||||||
[FlatBuffersTestMethod]
|
[FlatBuffersTestMethod]
|
||||||
public void ByteBuffer_GetIntChecksOffset()
|
public void ByteBuffer_GetIntChecksOffset()
|
||||||
{
|
{
|
||||||
@@ -234,6 +249,7 @@ namespace FlatBuffers.Test
|
|||||||
var uut = new ByteBuffer(buffer);
|
var uut = new ByteBuffer(buffer);
|
||||||
Assert.Throws<ArgumentOutOfRangeException>(() => uut.GetInt(0));
|
Assert.Throws<ArgumentOutOfRangeException>(() => uut.GetInt(0));
|
||||||
}
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
[FlatBuffersTestMethod]
|
[FlatBuffersTestMethod]
|
||||||
public void ByteBuffer_GetLongReturnsCorrectData()
|
public void ByteBuffer_GetLongReturnsCorrectData()
|
||||||
@@ -251,6 +267,7 @@ namespace FlatBuffers.Test
|
|||||||
Assert.AreEqual(0x010203040A0B0C0D, uut.GetLong(0));
|
Assert.AreEqual(0x010203040A0B0C0D, uut.GetLong(0));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#if !BYTEBUFFER_NO_BOUNDS_CHECK
|
||||||
[FlatBuffersTestMethod]
|
[FlatBuffersTestMethod]
|
||||||
public void ByteBuffer_GetLongChecksOffset()
|
public void ByteBuffer_GetLongChecksOffset()
|
||||||
{
|
{
|
||||||
@@ -266,6 +283,7 @@ namespace FlatBuffers.Test
|
|||||||
var uut = new ByteBuffer(buffer);
|
var uut = new ByteBuffer(buffer);
|
||||||
Assert.Throws<ArgumentOutOfRangeException>(() => uut.GetLong(0));
|
Assert.Throws<ArgumentOutOfRangeException>(() => uut.GetLong(0));
|
||||||
}
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
[FlatBuffersTestMethod]
|
[FlatBuffersTestMethod]
|
||||||
public void ByteBuffer_ReverseBytesUshort()
|
public void ByteBuffer_ReverseBytesUshort()
|
||||||
|
|||||||
@@ -185,6 +185,10 @@ class JavaTest {
|
|||||||
|
|
||||||
TestNestedFlatBuffer();
|
TestNestedFlatBuffer();
|
||||||
|
|
||||||
|
TestCreateByteVector();
|
||||||
|
|
||||||
|
TestCreateUninitializedVector();
|
||||||
|
|
||||||
System.out.println("FlatBuffers test: completed successfully");
|
System.out.println("FlatBuffers test: completed successfully");
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -305,6 +309,44 @@ class JavaTest {
|
|||||||
TestEq(nestedMonsterName, nestedMonster.name());
|
TestEq(nestedMonsterName, nestedMonster.name());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static void TestCreateByteVector() {
|
||||||
|
FlatBufferBuilder fbb = new FlatBufferBuilder(16);
|
||||||
|
int str = fbb.createString("MyMonster");
|
||||||
|
byte[] inventory = new byte[] { 0, 1, 2, 3, 4 };
|
||||||
|
int vec = fbb.createByteVector(inventory);
|
||||||
|
Monster.startMonster(fbb);
|
||||||
|
Monster.addInventory(fbb, vec);
|
||||||
|
Monster.addName(fbb, str);
|
||||||
|
int monster1 = Monster.endMonster(fbb);
|
||||||
|
Monster.finishMonsterBuffer(fbb, monster1);
|
||||||
|
Monster monsterObject = Monster.getRootAsMonster(fbb.dataBuffer());
|
||||||
|
|
||||||
|
TestEq(monsterObject.inventory(1), (int)inventory[1]);
|
||||||
|
TestEq(monsterObject.inventoryLength(), inventory.length);
|
||||||
|
TestEq(ByteBuffer.wrap(inventory), monsterObject.inventoryAsByteBuffer());
|
||||||
|
}
|
||||||
|
|
||||||
|
static void TestCreateUninitializedVector() {
|
||||||
|
FlatBufferBuilder fbb = new FlatBufferBuilder(16);
|
||||||
|
int str = fbb.createString("MyMonster");
|
||||||
|
byte[] inventory = new byte[] { 0, 1, 2, 3, 4 };
|
||||||
|
ByteBuffer bb = fbb.createUnintializedVector(1, inventory.length, 1);
|
||||||
|
for (byte i:inventory) {
|
||||||
|
bb.put(i);
|
||||||
|
}
|
||||||
|
int vec = fbb.endVector();
|
||||||
|
Monster.startMonster(fbb);
|
||||||
|
Monster.addInventory(fbb, vec);
|
||||||
|
Monster.addName(fbb, str);
|
||||||
|
int monster1 = Monster.endMonster(fbb);
|
||||||
|
Monster.finishMonsterBuffer(fbb, monster1);
|
||||||
|
Monster monsterObject = Monster.getRootAsMonster(fbb.dataBuffer());
|
||||||
|
|
||||||
|
TestEq(monsterObject.inventory(1), (int)inventory[1]);
|
||||||
|
TestEq(monsterObject.inventoryLength(), inventory.length);
|
||||||
|
TestEq(ByteBuffer.wrap(inventory), monsterObject.inventoryAsByteBuffer());
|
||||||
|
}
|
||||||
|
|
||||||
static <T> void TestEq(T a, T b) {
|
static <T> void TestEq(T a, T b) {
|
||||||
if (!a.equals(b)) {
|
if (!a.equals(b)) {
|
||||||
System.out.println("" + a.getClass().getName() + " " + b.getClass().getName());
|
System.out.println("" + a.getClass().getName() + " " + b.getClass().getName());
|
||||||
|
|||||||
@@ -138,19 +138,22 @@ public sealed class Monster : Table {
|
|||||||
public static Monster LookupByKey(VectorOffset vectorOffset, string key, ByteBuffer bb) {
|
public static Monster LookupByKey(VectorOffset vectorOffset, string key, ByteBuffer bb) {
|
||||||
byte[] byteKey = System.Text.Encoding.UTF8.GetBytes(key);
|
byte[] byteKey = System.Text.Encoding.UTF8.GetBytes(key);
|
||||||
int vectorLocation = bb.Length - vectorOffset.Value;
|
int vectorLocation = bb.Length - vectorOffset.Value;
|
||||||
int span = bb.GetInt(vectorLocation), middle, start = 0, comp, tableOffset;
|
int span = bb.GetInt(vectorLocation);
|
||||||
|
int start = 0;
|
||||||
vectorLocation += 4;
|
vectorLocation += 4;
|
||||||
while (span != 0) {
|
while (span != 0) {
|
||||||
int middle = span / 2;
|
int middle = span / 2;
|
||||||
tableOffset = __indirect(vectorLocation + 4 * (start + middle), bb);
|
int tableOffset = __indirect(vectorLocation + 4 * (start + middle), bb);
|
||||||
comp = CompareStrings(__offset(10, bb.Length - tableOffset, bb), byteKey, bb);
|
int comp = CompareStrings(__offset(10, bb.Length - tableOffset, bb), byteKey, bb);
|
||||||
if (comp > 0) span = middle;
|
if (comp > 0) {
|
||||||
else if (comp < 0) {
|
span = middle;
|
||||||
|
} else if (comp < 0) {
|
||||||
middle++;
|
middle++;
|
||||||
start += middle;
|
start += middle;
|
||||||
span -= middle;
|
span -= middle;
|
||||||
|
} else {
|
||||||
|
return new Monster().__init(tableOffset, bb);
|
||||||
}
|
}
|
||||||
else return new Monster().__init(tableOffset, bb);
|
|
||||||
}
|
}
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -131,9 +131,6 @@ func (rcv *Monster) Test4(obj *Test, j int) bool {
|
|||||||
if o != 0 {
|
if o != 0 {
|
||||||
x := rcv._tab.Vector(o)
|
x := rcv._tab.Vector(o)
|
||||||
x += flatbuffers.UOffsetT(j) * 4
|
x += flatbuffers.UOffsetT(j) * 4
|
||||||
if obj == nil {
|
|
||||||
obj = new(Test)
|
|
||||||
}
|
|
||||||
obj.Init(rcv._tab.Bytes, x)
|
obj.Init(rcv._tab.Bytes, x)
|
||||||
return true
|
return true
|
||||||
}
|
}
|
||||||
@@ -173,9 +170,6 @@ func (rcv *Monster) Testarrayoftables(obj *Monster, j int) bool {
|
|||||||
x := rcv._tab.Vector(o)
|
x := rcv._tab.Vector(o)
|
||||||
x += flatbuffers.UOffsetT(j) * 4
|
x += flatbuffers.UOffsetT(j) * 4
|
||||||
x = rcv._tab.Indirect(x)
|
x = rcv._tab.Indirect(x)
|
||||||
if obj == nil {
|
|
||||||
obj = new(Monster)
|
|
||||||
}
|
|
||||||
obj.Init(rcv._tab.Bytes, x)
|
obj.Init(rcv._tab.Bytes, x)
|
||||||
return true
|
return true
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -140,21 +140,24 @@ public final class Monster extends Table {
|
|||||||
protected int keysCompare(Integer o1, Integer o2, ByteBuffer _bb) { return compareStrings(__offset(10, o1, _bb), __offset(10, o2, _bb), _bb); }
|
protected int keysCompare(Integer o1, Integer o2, ByteBuffer _bb) { return compareStrings(__offset(10, o1, _bb), __offset(10, o2, _bb), _bb); }
|
||||||
|
|
||||||
public static Monster lookupByKey(int vectorOffset, String key, ByteBuffer bb) {
|
public static Monster lookupByKey(int vectorOffset, String key, ByteBuffer bb) {
|
||||||
byte[] byteKey = key.getBytes(StandardCharsets.UTF_8);
|
byte[] byteKey = key.getBytes(Table.UTF8_CHARSET.get());
|
||||||
int vectorLocation = bb.array().length - vectorOffset.Value;
|
int vectorLocation = bb.array().length - vectorOffset;
|
||||||
int span = bb.getInt(vectorLocation), middle, start = 0, comp, tableOffset;
|
int span = bb.getInt(vectorLocation);
|
||||||
|
int start = 0;
|
||||||
vectorLocation += 4;
|
vectorLocation += 4;
|
||||||
while (span != 0) {
|
while (span != 0) {
|
||||||
int middle = span / 2;
|
int middle = span / 2;
|
||||||
tableOffset = __indirect(vectorLocation + 4 * (start + middle), bb);
|
int tableOffset = __indirect(vectorLocation + 4 * (start + middle), bb);
|
||||||
comp = compareStrings(__offset(10, bb.array().length - tableOffset, bb), byteKey, bb);
|
int comp = compareStrings(__offset(10, bb.array().length - tableOffset, bb), byteKey, bb);
|
||||||
if (comp > 0) span = middle;
|
if (comp > 0) {
|
||||||
else if (comp < 0) {
|
span = middle;
|
||||||
|
} else if (comp < 0) {
|
||||||
middle++;
|
middle++;
|
||||||
start += middle;
|
start += middle;
|
||||||
span -= middle;
|
span -= middle;
|
||||||
|
} else {
|
||||||
|
return new Monster().__init(tableOffset, bb);
|
||||||
}
|
}
|
||||||
else return new Monster().__init(tableOffset, bb);
|
|
||||||
}
|
}
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -410,7 +410,8 @@ void ParseAndGenerateTextTest() {
|
|||||||
// to ensure it is correct, we now generate text back from the binary,
|
// to ensure it is correct, we now generate text back from the binary,
|
||||||
// and compare the two:
|
// and compare the two:
|
||||||
std::string jsongen;
|
std::string jsongen;
|
||||||
GenerateText(parser, parser.builder_.GetBufferPointer(), &jsongen);
|
auto result = GenerateText(parser, parser.builder_.GetBufferPointer(), &jsongen);
|
||||||
|
TEST_EQ(result, true);
|
||||||
|
|
||||||
if (jsongen != jsonfile) {
|
if (jsongen != jsonfile) {
|
||||||
printf("%s----------------\n%s", jsongen.c_str(), jsonfile.c_str());
|
printf("%s----------------\n%s", jsongen.c_str(), jsonfile.c_str());
|
||||||
@@ -827,7 +828,8 @@ void FuzzTest2() {
|
|||||||
|
|
||||||
std::string jsongen;
|
std::string jsongen;
|
||||||
parser.opts.indent_step = 0;
|
parser.opts.indent_step = 0;
|
||||||
GenerateText(parser, parser.builder_.GetBufferPointer(), &jsongen);
|
auto result = GenerateText(parser, parser.builder_.GetBufferPointer(), &jsongen);
|
||||||
|
TEST_EQ(result, true);
|
||||||
|
|
||||||
if (jsongen != json) {
|
if (jsongen != json) {
|
||||||
// These strings are larger than a megabyte, so we show the bytes around
|
// These strings are larger than a megabyte, so we show the bytes around
|
||||||
@@ -987,7 +989,8 @@ void UnicodeTest() {
|
|||||||
true);
|
true);
|
||||||
std::string jsongen;
|
std::string jsongen;
|
||||||
parser.opts.indent_step = -1;
|
parser.opts.indent_step = -1;
|
||||||
GenerateText(parser, parser.builder_.GetBufferPointer(), &jsongen);
|
auto result = GenerateText(parser, parser.builder_.GetBufferPointer(), &jsongen);
|
||||||
|
TEST_EQ(result, true);
|
||||||
TEST_EQ(jsongen,
|
TEST_EQ(jsongen,
|
||||||
std::string(
|
std::string(
|
||||||
"{F: \"\\u20AC\\u00A2\\u30E6\\u30FC\\u30B6\\u30FC"
|
"{F: \"\\u20AC\\u00A2\\u30E6\\u30FC\\u30B6\\u30FC"
|
||||||
@@ -1003,13 +1006,31 @@ void UnicodeTestAllowNonUTF8() {
|
|||||||
"\\u5225\\u30B5\\u30A4\\u30C8\\x01\\x80\\u0080\\uD83D\\uDE0E\" }"), true);
|
"\\u5225\\u30B5\\u30A4\\u30C8\\x01\\x80\\u0080\\uD83D\\uDE0E\" }"), true);
|
||||||
std::string jsongen;
|
std::string jsongen;
|
||||||
parser.opts.indent_step = -1;
|
parser.opts.indent_step = -1;
|
||||||
GenerateText(parser, parser.builder_.GetBufferPointer(), &jsongen);
|
auto result = GenerateText(parser, parser.builder_.GetBufferPointer(), &jsongen);
|
||||||
|
TEST_EQ(result, true);
|
||||||
TEST_EQ(jsongen,
|
TEST_EQ(jsongen,
|
||||||
std::string(
|
std::string(
|
||||||
"{F: \"\\u20AC\\u00A2\\u30E6\\u30FC\\u30B6\\u30FC"
|
"{F: \"\\u20AC\\u00A2\\u30E6\\u30FC\\u30B6\\u30FC"
|
||||||
"\\u5225\\u30B5\\u30A4\\u30C8\\u0001\\x80\\u0080\\uD83D\\uDE0E\"}"));
|
"\\u5225\\u30B5\\u30A4\\u30C8\\u0001\\x80\\u0080\\uD83D\\uDE0E\"}"));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void UnicodeTestGenerateTextFailsOnNonUTF8() {
|
||||||
|
flatbuffers::Parser parser;
|
||||||
|
// Allow non-UTF-8 initially to model what happens when we load a binary flatbuffer from disk
|
||||||
|
// which contains non-UTF-8 strings.
|
||||||
|
parser.opts.allow_non_utf8 = true;
|
||||||
|
TEST_EQ(parser.Parse("table T { F:string; }"
|
||||||
|
"root_type T;"
|
||||||
|
"{ F:\"\\u20AC\\u00A2\\u30E6\\u30FC\\u30B6\\u30FC"
|
||||||
|
"\\u5225\\u30B5\\u30A4\\u30C8\\x01\\x80\\u0080\\uD83D\\uDE0E\" }"), true);
|
||||||
|
std::string jsongen;
|
||||||
|
parser.opts.indent_step = -1;
|
||||||
|
// Now, disallow non-UTF-8 (the default behavior) so GenerateText indicates failure.
|
||||||
|
parser.opts.allow_non_utf8 = false;
|
||||||
|
auto result = GenerateText(parser, parser.builder_.GetBufferPointer(), &jsongen);
|
||||||
|
TEST_EQ(result, false);
|
||||||
|
}
|
||||||
|
|
||||||
void UnicodeSurrogatesTest() {
|
void UnicodeSurrogatesTest() {
|
||||||
flatbuffers::Parser parser;
|
flatbuffers::Parser parser;
|
||||||
|
|
||||||
@@ -1157,7 +1178,8 @@ void UnknownFieldsTest() {
|
|||||||
|
|
||||||
std::string jsongen;
|
std::string jsongen;
|
||||||
parser.opts.indent_step = -1;
|
parser.opts.indent_step = -1;
|
||||||
GenerateText(parser, parser.builder_.GetBufferPointer(), &jsongen);
|
auto result = GenerateText(parser, parser.builder_.GetBufferPointer(), &jsongen);
|
||||||
|
TEST_EQ(result, true);
|
||||||
TEST_EQ(jsongen == "{str: \"test\",i: 10}", true);
|
TEST_EQ(jsongen == "{str: \"test\",i: 10}", true);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -1222,6 +1244,7 @@ int main(int /*argc*/, const char * /*argv*/[]) {
|
|||||||
IntegerOutOfRangeTest();
|
IntegerOutOfRangeTest();
|
||||||
UnicodeTest();
|
UnicodeTest();
|
||||||
UnicodeTestAllowNonUTF8();
|
UnicodeTestAllowNonUTF8();
|
||||||
|
UnicodeTestGenerateTextFailsOnNonUTF8();
|
||||||
UnicodeSurrogatesTest();
|
UnicodeSurrogatesTest();
|
||||||
UnicodeInvalidSurrogatesTest();
|
UnicodeInvalidSurrogatesTest();
|
||||||
InvalidUTF8Test();
|
InvalidUTF8Test();
|
||||||
|
|||||||
Reference in New Issue
Block a user