Squashed 'third_party/flatbuffers/' content from commit acc9990ab
Change-Id: I48550d40d78fea996ebe74e9723a5d1f910de491
git-subtree-dir: third_party/flatbuffers
git-subtree-split: acc9990abd2206491480291b0f85f925110102ea
diff --git a/grpc/samples/greeter/Makefile b/grpc/samples/greeter/Makefile
new file mode 100644
index 0000000..3746705
--- /dev/null
+++ b/grpc/samples/greeter/Makefile
@@ -0,0 +1,14 @@
+CXXFLAGS ?= -I../../../include
+LDFLAGS ?=
+
+.PHONY: all
+all: server client
+
+greeter_generated.h: greeter.fbs
+ flatc --grpc --cpp $<
+
+server: server.cpp greeter.grpc.fb.cc greeter_generated.h greeter.grpc.fb.h
+ g++ -std=c++11 -O2 $(CXXFLAGS) $(LDFLAGS) -lgpr -lgrpc -lgrpc++ server.cpp greeter.grpc.fb.cc -o $@
+
+client: client.cpp greeter.grpc.fb.cc greeter_generated.h greeter.grpc.fb.h
+ g++ -std=c++11 -O2 $(CXXFLAGS) $(LDFLAGS) -lgpr -lgrpc -lgrpc++ client.cpp greeter.grpc.fb.cc -o $@
diff --git a/grpc/samples/greeter/client.cpp b/grpc/samples/greeter/client.cpp
new file mode 100644
index 0000000..2e42f8f
--- /dev/null
+++ b/grpc/samples/greeter/client.cpp
@@ -0,0 +1,85 @@
+#include "greeter.grpc.fb.h"
+#include "greeter_generated.h"
+
+#include <grpc++/grpc++.h>
+
+#include <iostream>
+#include <memory>
+#include <string>
+
+class GreeterClient {
+ public:
+ GreeterClient(std::shared_ptr<grpc::Channel> channel)
+ : stub_(Greeter::NewStub(channel)) {}
+
+ std::string SayHello(const std::string &name) {
+ flatbuffers::grpc::MessageBuilder mb;
+ auto name_offset = mb.CreateString(name);
+ auto request_offset = CreateHelloRequest(mb, name_offset);
+ mb.Finish(request_offset);
+ auto request_msg = mb.ReleaseMessage<HelloRequest>();
+
+ flatbuffers::grpc::Message<HelloReply> response_msg;
+
+ grpc::ClientContext context;
+
+ auto status = stub_->SayHello(&context, request_msg, &response_msg);
+ if (status.ok()) {
+ const HelloReply *response = response_msg.GetRoot();
+ return response->message()->str();
+ } else {
+ std::cerr << status.error_code() << ": " << status.error_message()
+ << std::endl;
+ return "RPC failed";
+ }
+ }
+
+ void SayManyHellos(const std::string &name, int num_greetings,
+ std::function<void(const std::string &)> callback) {
+ flatbuffers::grpc::MessageBuilder mb;
+ auto name_offset = mb.CreateString(name);
+ auto request_offset =
+ CreateManyHellosRequest(mb, name_offset, num_greetings);
+ mb.Finish(request_offset);
+ auto request_msg = mb.ReleaseMessage<ManyHellosRequest>();
+
+ flatbuffers::grpc::Message<HelloReply> response_msg;
+
+ grpc::ClientContext context;
+
+ auto stream = stub_->SayManyHellos(&context, request_msg);
+ while (stream->Read(&response_msg)) {
+ const HelloReply *response = response_msg.GetRoot();
+ callback(response->message()->str());
+ }
+ auto status = stream->Finish();
+ if (!status.ok()) {
+ std::cerr << status.error_code() << ": " << status.error_message()
+ << std::endl;
+ callback("RPC failed");
+ }
+ }
+
+ private:
+ std::unique_ptr<Greeter::Stub> stub_;
+};
+
+int main(int argc, char **argv) {
+ std::string server_address("localhost:50051");
+
+ auto channel =
+ grpc::CreateChannel(server_address, grpc::InsecureChannelCredentials());
+ GreeterClient greeter(channel);
+
+ std::string name("world");
+
+ std::string message = greeter.SayHello(name);
+ std::cerr << "Greeter received: " << message << std::endl;
+
+ int num_greetings = 10;
+ greeter.SayManyHellos(name, num_greetings, [](const std::string &message) {
+ std::cerr << "Greeter received: " << message << std::endl;
+ });
+
+ return 0;
+}
diff --git a/grpc/samples/greeter/greeter.fbs b/grpc/samples/greeter/greeter.fbs
new file mode 100644
index 0000000..811303c
--- /dev/null
+++ b/grpc/samples/greeter/greeter.fbs
@@ -0,0 +1,17 @@
+table HelloReply {
+ message:string;
+}
+
+table HelloRequest {
+ name:string;
+}
+
+table ManyHellosRequest {
+ name:string;
+ num_greetings:int;
+}
+
+rpc_service Greeter {
+ SayHello(HelloRequest):HelloReply;
+ SayManyHellos(ManyHellosRequest):HelloReply (streaming: "server");
+}
diff --git a/grpc/samples/greeter/server.cpp b/grpc/samples/greeter/server.cpp
new file mode 100644
index 0000000..82c97dc
--- /dev/null
+++ b/grpc/samples/greeter/server.cpp
@@ -0,0 +1,80 @@
+#include "greeter.grpc.fb.h"
+#include "greeter_generated.h"
+
+#include <grpc++/grpc++.h>
+
+#include <iostream>
+#include <memory>
+#include <string>
+
+class GreeterServiceImpl final : public Greeter::Service {
+ virtual grpc::Status SayHello(
+ grpc::ServerContext *context,
+ const flatbuffers::grpc::Message<HelloRequest> *request_msg,
+ flatbuffers::grpc::Message<HelloReply> *response_msg) override {
+ // flatbuffers::grpc::MessageBuilder mb_;
+ // We call GetRoot to "parse" the message. Verification is already
+ // performed by default. See the notes below for more details.
+ const HelloRequest *request = request_msg->GetRoot();
+
+ // Fields are retrieved as usual with FlatBuffers
+ const std::string &name = request->name()->str();
+
+ // `flatbuffers::grpc::MessageBuilder` is a `FlatBufferBuilder` with a
+ // special allocator for efficient gRPC buffer transfer, but otherwise
+ // usage is the same as usual.
+ auto msg_offset = mb_.CreateString("Hello, " + name);
+ auto hello_offset = CreateHelloReply(mb_, msg_offset);
+ mb_.Finish(hello_offset);
+
+ // The `ReleaseMessage<T>()` function detaches the message from the
+ // builder, so we can transfer the resopnse to gRPC while simultaneously
+ // detaching that memory buffer from the builer.
+ *response_msg = mb_.ReleaseMessage<HelloReply>();
+ assert(response_msg->Verify());
+
+ // Return an OK status.
+ return grpc::Status::OK;
+ }
+
+ virtual grpc::Status SayManyHellos(
+ grpc::ServerContext *context,
+ const flatbuffers::grpc::Message<ManyHellosRequest> *request_msg,
+ grpc::ServerWriter<flatbuffers::grpc::Message<HelloReply>> *writer)
+ override {
+ // The streaming usage below is simply a combination of standard gRPC
+ // streaming with the FlatBuffers usage shown above.
+ const ManyHellosRequest *request = request_msg->GetRoot();
+ const std::string &name = request->name()->str();
+ int num_greetings = request->num_greetings();
+
+ for (int i = 0; i < num_greetings; i++) {
+ auto msg_offset = mb_.CreateString("Many hellos, " + name);
+ auto hello_offset = CreateHelloReply(mb_, msg_offset);
+ mb_.Finish(hello_offset);
+ writer->Write(mb_.ReleaseMessage<HelloReply>());
+ }
+
+ return grpc::Status::OK;
+ }
+
+ flatbuffers::grpc::MessageBuilder mb_;
+};
+
+void RunServer() {
+ std::string server_address("0.0.0.0:50051");
+ GreeterServiceImpl service;
+
+ grpc::ServerBuilder builder;
+ builder.AddListeningPort(server_address, grpc::InsecureServerCredentials());
+ builder.RegisterService(&service);
+ std::unique_ptr<grpc::Server> server(builder.BuildAndStart());
+ std::cerr << "Server listening on " << server_address << std::endl;
+
+ server->Wait();
+}
+
+int main(int argc, const char *argv[]) {
+ RunServer();
+ return 0;
+}