-
Notifications
You must be signed in to change notification settings - Fork 0
build: add isolated v2 FlatBuffers protocol library #22
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Changes from all commits
36cf263
d4c1816
cb158ba
f1a2246
b70e698
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,10 @@ | ||
| #include "udf_protocol.hpp" | ||
|
|
||
| #include <flatbuffers/flatbuffers.h> | ||
|
|
||
| void isolated_flatbuffers_first() { | ||
| exasol::udf::v2::third_party::flatbuffers::FlatBufferBuilder isolated_builder; | ||
| ::flatbuffers::FlatBufferBuilder ordinary_builder; | ||
| (void)ordinary_builder; | ||
| (void)isolated_builder; | ||
| } |
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,14 @@ | ||
| #include <flatbuffers/flatbuffers.h> | ||
|
|
||
| #include "udf_protocol.hpp" | ||
|
|
||
| void ordinary_flatbuffers_first() { | ||
| ::flatbuffers::FlatBufferBuilder ordinary_builder; | ||
| exasol::udf::v2::third_party::flatbuffers::FlatBufferBuilder isolated_builder; | ||
| (void)ordinary_builder; | ||
| (void)isolated_builder; | ||
| } | ||
|
|
||
| int main() { | ||
| ordinary_flatbuffers_first(); | ||
| } |
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,20 @@ | ||
| #!/usr/bin/env bash | ||
| set -euo pipefail | ||
|
|
||
| # The first argument is the directory containing the generated private | ||
| # headers. All remaining arguments are the public FlatBuffers headers supplied | ||
| # by Bazel from @flatbuffers//:public_headers. | ||
| output_dir="$(dirname "$1")" | ||
| shift | ||
| mkdir -p "$output_dir" | ||
|
|
||
| for source in "$@"; do | ||
| header="$(basename "$source")" | ||
| # Use a private include prefix so ordinary flatbuffers/... headers can be | ||
| # included in the same translation unit. Prefix every FlatBuffers macro | ||
| # to isolate include guards and configuration macros as well. | ||
| sed \ | ||
| -e 's#"flatbuffers/#"exasol/udf/v2/third_party/flatbuffers/#g' \ | ||
| -e 's/FLATBUFFERS_/EXASOL_UDF_V2_FLATBUFFERS_/g' \ | ||
| "$source" > "$output_dir/$header" | ||
| done |
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,12 @@ | ||
| #include "udf_protocol.hpp" | ||
|
|
||
| namespace exasol::udf::protocol { | ||
|
|
||
| bool VerifyFrameBuffer(const void* data, std::size_t size) { | ||
| using IsolatedVerifier = | ||
| exasol::udf::v2::third_party::flatbuffers::Verifier; | ||
| IsolatedVerifier verifier(static_cast<const uint8_t*>(data), size); | ||
| return verifier.VerifyBuffer<Frame>(); | ||
| } | ||
|
|
||
| } // namespace exasol::udf::protocol |
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,19 @@ | ||
| #ifndef EXASOL_UDF_V2_UDF_PROTOCOL_HPP_ | ||
| #define EXASOL_UDF_V2_UDF_PROTOCOL_HPP_ | ||
|
|
||
| #include <cstddef> | ||
|
|
||
| // The generated API uses FlatBuffers runtime types. Rewrite the runtime | ||
| // namespace only while parsing the generated header, so the global | ||
| // ::flatbuffers namespace is never part of this library's API or ABI. | ||
| #define flatbuffers exasol::udf::v2::third_party::flatbuffers | ||
| #include "udf_protocol_generated.h" | ||
|
tkilias marked this conversation as resolved.
|
||
| #undef flatbuffers | ||
|
|
||
| namespace exasol::udf::protocol { | ||
|
|
||
| bool VerifyFrameBuffer(const void* data, std::size_t size); | ||
|
|
||
| } // namespace exasol::udf::protocol | ||
|
|
||
| #endif // EXASOL_UDF_V2_UDF_PROTOCOL_HPP_ | ||
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,49 @@ | ||
| #include <cassert> | ||
| #include <cstdio> | ||
| #include <stdexcept> | ||
| #include <string> | ||
| #include <string_view> | ||
|
|
||
| namespace { | ||
|
|
||
| [[noreturn]] void fail(const std::string& message) { | ||
| throw std::runtime_error(message); | ||
| } | ||
|
|
||
| void verify_symbols(const std::string& archive_path) { | ||
| const std::string command = "nm -g --defined-only -- '" + archive_path + "'"; | ||
|
Collaborator
Author
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. this we need to fix later, the AI tried to cheat
Collaborator
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. i do agree; tried implementing some code that really use the flatbuffer symbols, but it seems a lot of changes; therefore, i leave it as it is for this PR and create an issue for this
Collaborator
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. created an issue to track this |
||
| FILE* pipe = popen(command.c_str(), "r"); | ||
| if (pipe == nullptr) { | ||
| fail("cannot inspect protocol archive symbols"); | ||
| } | ||
|
|
||
| char line[4096]; | ||
| while (std::fgets(line, sizeof(line), pipe) != nullptr) { | ||
| const std::string symbol(line); | ||
| const std::size_t name_start = symbol.find_last_of(' '); | ||
| if (name_start != std::string::npos && | ||
| symbol.compare(name_start + 1, 16, "_ZN11flatbuffers") == 0) { | ||
| pclose(pipe); | ||
| fail("protocol archive exports a global flatbuffers symbol: " + symbol); | ||
| } | ||
| } | ||
|
|
||
| if (pclose(pipe) != 0) { | ||
| fail("cannot complete protocol archive symbol inspection"); | ||
| } | ||
| } | ||
|
|
||
| } // namespace | ||
|
|
||
| int main(int argc, char** argv) { | ||
| assert(argc > 1); | ||
| bool found_archive = false; | ||
| for (int index = 1; index < argc; ++index) { | ||
| const std::string_view path(argv[index]); | ||
| if (path.ends_with(".a")) { | ||
| verify_symbols(std::string(path)); | ||
| found_archive = true; | ||
| } | ||
| } | ||
| assert(found_archive); | ||
| } | ||
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,40 @@ | ||
| #include <cassert> | ||
| #include <cstdio> | ||
| #include <stdexcept> | ||
| #include <string> | ||
|
|
||
| namespace { | ||
|
|
||
| [[noreturn]] void fail(const std::string& message) { | ||
| throw std::runtime_error(message); | ||
| } | ||
|
|
||
| void verify_symbols(const std::string& library_path) { | ||
| const std::string command = "nm -D --defined-only -- '" + library_path + "'"; | ||
|
Collaborator
Author
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. this we need to fix later, the AI tried to cheat
Collaborator
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. created an issue for this |
||
| FILE* pipe = popen(command.c_str(), "r"); | ||
| if (pipe == nullptr) { | ||
| fail("cannot inspect protocol library symbols"); | ||
| } | ||
|
|
||
| char line[4096]; | ||
| while (std::fgets(line, sizeof(line), pipe) != nullptr) { | ||
| const std::string symbol(line); | ||
| const std::size_t name_start = symbol.find_last_of(' '); | ||
| if (name_start != std::string::npos && | ||
| symbol.compare(name_start + 1, 16, "_ZN11flatbuffers") == 0) { | ||
| pclose(pipe); | ||
| fail("protocol library exports a global flatbuffers symbol: " + symbol); | ||
| } | ||
| } | ||
|
|
||
| if (pclose(pipe) != 0) { | ||
| fail("cannot complete protocol library symbol inspection"); | ||
| } | ||
| } | ||
|
|
||
| } // namespace | ||
|
|
||
| int main(int argc, char** argv) { | ||
| assert(argc == 2); | ||
| verify_symbols(argv[1]); | ||
| } | ||
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,20 @@ | ||
| #include "udf_protocol.hpp" | ||
|
|
||
| #include <cassert> | ||
| #include <cstdint> | ||
|
|
||
| int main() { | ||
| exasol::udf::v2::third_party::flatbuffers::FlatBufferBuilder builder; | ||
| const auto call_name = builder.CreateString("example"); | ||
| const auto open_call = exasol::udf::protocol::CreateOpenCall(builder, call_name); | ||
| const auto message = exasol::udf::protocol::CreateStreamMessage( | ||
| builder, 0, 0, open_call); | ||
| const auto frame = exasol::udf::protocol::CreateFrame(builder, 7, message); | ||
| builder.Finish(frame); | ||
|
|
||
| assert(exasol::udf::protocol::VerifyFrameBuffer( | ||
| builder.GetBufferPointer(), builder.GetSize())); | ||
| const auto* decoded = exasol::udf::protocol::GetFrame(builder.GetBufferPointer()); | ||
| assert(decoded->stream_id() == 7); | ||
| assert(decoded->message()->open_call()->call_name()->str() == "example"); | ||
| } |
Uh oh!
There was an error while loading. Please reload this page.