aboutsummaryrefslogtreecommitdiffhomepage
path: root/include/grpc++/impl/call.h
diff options
context:
space:
mode:
authorGravatar Craig Tiller <craig.tiller@gmail.com>2015-06-04 16:19:22 -0700
committerGravatar Craig Tiller <craig.tiller@gmail.com>2015-06-04 16:19:22 -0700
commit789471cfc64cd0200a53914939a0485846b5a80f (patch)
treedcd82e74ceddc6f73dcbe0a5b14dc3ef61fe2864 /include/grpc++/impl/call.h
parente850f3caad7db8cb353a42479c3e03704e8dc1e8 (diff)
Client side compiles/links
Diffstat (limited to 'include/grpc++/impl/call.h')
-rw-r--r--include/grpc++/impl/call.h178
1 files changed, 159 insertions, 19 deletions
diff --git a/include/grpc++/impl/call.h b/include/grpc++/impl/call.h
index 3701e403de..40dbf9e641 100644
--- a/include/grpc++/impl/call.h
+++ b/include/grpc++/impl/call.h
@@ -35,6 +35,7 @@
#define GRPCXX_IMPL_CALL_H
#include <grpc/grpc.h>
+#include <grpc++/client_context.h>
#include <grpc++/completion_queue.h>
#include <grpc++/config.h>
#include <grpc++/status.h>
@@ -51,6 +52,10 @@ namespace grpc {
class ByteBuffer;
class Call;
+void FillMetadataMap(grpc_metadata_array* arr,
+ std::multimap<grpc::string, grpc::string>* metadata);
+grpc_metadata* FillMetadataArray(const std::multimap<grpc::string, grpc::string>& metadata);
+
class CallNoOp {
protected:
void AddOp(grpc_op* ops, size_t* nops) {}
@@ -59,11 +64,29 @@ class CallNoOp {
class CallOpSendInitialMetadata {
public:
- void SendInitialMetadata(const std::multimap<grpc::string, grpc::string>& metadata);
+ CallOpSendInitialMetadata() : send_(false) {}
+
+ void SendInitialMetadata(const std::multimap<grpc::string, grpc::string>& metadata) {
+ send_ = true;
+ initial_metadata_count_ = metadata.size();
+ initial_metadata_ = FillMetadataArray(metadata);
+ }
protected:
- void AddOp(grpc_op* ops, size_t* nops);
- void FinishOp(void* tag, bool* status, int max_message_size);
+ void AddOp(grpc_op* ops, size_t* nops) {
+ if (!send_) return;
+ grpc_op* op = &ops[(*nops)++];
+ op->op = GRPC_OP_SEND_INITIAL_METADATA;
+ op->data.send_initial_metadata.count = initial_metadata_count_;
+ op->data.send_initial_metadata.metadata = initial_metadata_;
+ }
+ void FinishOp(void* tag, bool* status, int max_message_size) {
+ // nothing to do
+ }
+
+ bool send_;
+ size_t initial_metadata_count_;
+ grpc_metadata* initial_metadata_;
};
class CallOpSendMessage {
@@ -71,7 +94,7 @@ class CallOpSendMessage {
CallOpSendMessage() : send_buf_(nullptr) {}
template <class M>
- bool SendMessage(const M& message) {
+ bool SendMessage(const M& message) GRPC_MUST_USE_RESULT {
return SerializationTraits<M>::Serialize(message, &send_buf_);
}
@@ -132,50 +155,167 @@ class CallOpRecvMessage {
class CallOpGenericRecvMessage {
public:
+ CallOpGenericRecvMessage() : got_message(false) {}
+
template <class R>
- void RecvMessage(R* message);
+ void RecvMessage(R* message) {
+ deserialize_ = [message](grpc_byte_buffer* buf, int max_message_size) -> Status {
+ return SerializationTraits<R>::Deserialize(buf, message, max_message_size);
+ };
+ }
bool got_message;
protected:
- void AddOp(grpc_op* ops, size_t* nops);
- void FinishOp(void* tag, bool* status, int max_message_size);
+ void AddOp(grpc_op* ops, size_t* nops) {
+ if (!deserialize_) return;
+ grpc_op *op = &ops[(*nops)++];
+ op->op = GRPC_OP_RECV_MESSAGE;
+ op->data.recv_message = &recv_buf_;
+ }
+
+ void FinishOp(void* tag, bool* status, int max_message_size) {
+ if (!deserialize_) return;
+ if (recv_buf_) {
+ if (*status) {
+ got_message = true;
+ *status = deserialize_(recv_buf_, max_message_size).IsOk();
+ } else {
+ got_message = false;
+ grpc_byte_buffer_destroy(recv_buf_);
+ }
+ } else {
+ got_message = false;
+ *status = false;
+ }
+ }
+
+ private:
+ std::function<Status(grpc_byte_buffer*, int)> deserialize_;
+ grpc_byte_buffer* recv_buf_;
};
class CallOpClientSendClose {
public:
- void ClientSendClose();
+ CallOpClientSendClose() : send_(false) {}
+
+ void ClientSendClose() { send_ = true; }
protected:
- void AddOp(grpc_op* ops, size_t* nops);
- void FinishOp(void* tag, bool* status, int max_message_size);
+ void AddOp(grpc_op* ops, size_t* nops) {
+ if (!send_) return;
+ ops[(*nops)++].op = GRPC_OP_SEND_CLOSE_FROM_CLIENT;
+ }
+ void FinishOp(void* tag, bool* status, int max_message_size) {
+ // nothing to do
+ }
+
+ private:
+ bool send_;
};
class CallOpServerSendStatus {
public:
- void ServerSendStatus(const std::multimap<grpc::string, grpc::string>& trailing_metadata, const Status& status);
+ CallOpServerSendStatus() : send_status_available_(false) {}
+
+ void ServerSendStatus(const std::multimap<grpc::string, grpc::string>& trailing_metadata, const Status& status){
+ trailing_metadata_count_ = trailing_metadata.size();
+ trailing_metadata_ = FillMetadataArray(trailing_metadata);
+ send_status_available_ = true;
+ send_status_code_ = static_cast<grpc_status_code>(status.code());
+ send_status_details_ = status.details();
+ }
protected:
- void AddOp(grpc_op* ops, size_t* nops);
- void FinishOp(void* tag, bool* status, int max_message_size);
+ void AddOp(grpc_op* ops, size_t* nops) {
+ grpc_op* op = &ops[(*nops)++];
+ op->op = GRPC_OP_SEND_STATUS_FROM_SERVER;
+ op->data.send_status_from_server.trailing_metadata_count =
+ trailing_metadata_count_;
+ op->data.send_status_from_server.trailing_metadata =
+ trailing_metadata_;
+ op->data.send_status_from_server.status = send_status_code_;
+ op->data.send_status_from_server.status_details =
+ send_status_details_.empty() ? nullptr : send_status_details_.c_str();
+ }
+
+ void FinishOp(void* tag, bool* status, int max_message_size) {
+ // nothing to do
+ }
+
+ private:
+ bool send_status_available_;
+ grpc_status_code send_status_code_;
+ grpc::string send_status_details_;
+ size_t trailing_metadata_count_;
+ grpc_metadata* trailing_metadata_;
};
class CallOpRecvInitialMetadata {
public:
- void RecvInitialMetadata(ClientContext* context);
+ CallOpRecvInitialMetadata() : recv_initial_metadata_(nullptr) {
+ memset(&recv_initial_metadata_arr_, 0, sizeof(recv_initial_metadata_arr_));
+ }
+
+ void RecvInitialMetadata(ClientContext* context) {
+ context->initial_metadata_received_ = true;
+ recv_initial_metadata_ = &context->recv_initial_metadata_;
+ }
protected:
- void AddOp(grpc_op* ops, size_t* nops);
- void FinishOp(void* tag, bool* status, int max_message_size);
+ void AddOp(grpc_op* ops, size_t* nops) {
+ if (!recv_initial_metadata_) return;
+ grpc_op* op = &ops[(*nops)++];
+ op->op = GRPC_OP_RECV_INITIAL_METADATA;
+ op->data.recv_initial_metadata = &recv_initial_metadata_arr_;
+ }
+ void FinishOp(void* tag, bool* status, int max_message_size) {
+ FillMetadataMap(&recv_initial_metadata_arr_, recv_initial_metadata_);
+ }
+
+ private:
+ std::multimap<grpc::string, grpc::string>* recv_initial_metadata_;
+ grpc_metadata_array recv_initial_metadata_arr_;
};
class CallOpClientRecvStatus {
public:
- void ClientRecvStatus(ClientContext* context, Status* status);
+ CallOpClientRecvStatus() {
+ memset(this, 0, sizeof(*this));
+ }
+
+ void ClientRecvStatus(ClientContext* context, Status* status) {
+ recv_trailing_metadata_ = &context->trailing_metadata_;
+ recv_status_ = status;
+ }
protected:
- void AddOp(grpc_op* ops, size_t* nops);
- void FinishOp(void* tag, bool* status, int max_message_size);
+ void AddOp(grpc_op* ops, size_t* nops) {
+ if (recv_status_ == nullptr) return;
+ grpc_op* op = &ops[(*nops)++];
+ op->op = GRPC_OP_RECV_STATUS_ON_CLIENT;
+ op->data.recv_status_on_client.trailing_metadata =
+ &recv_trailing_metadata_arr_;
+ op->data.recv_status_on_client.status = &status_code_;
+ op->data.recv_status_on_client.status_details = &status_details_;
+ op->data.recv_status_on_client.status_details_capacity =
+ &status_details_capacity_;
+ }
+
+ void FinishOp(void* tag, bool* status, int max_message_size) {
+ FillMetadataMap(&recv_trailing_metadata_arr_, recv_trailing_metadata_);
+ *recv_status_ = Status(
+ static_cast<StatusCode>(status_code_),
+ status_details_ ? grpc::string(status_details_) : grpc::string());
+ }
+
+ private:
+ std::multimap<grpc::string, grpc::string>* recv_trailing_metadata_;
+ Status* recv_status_;
+ grpc_metadata_array recv_trailing_metadata_arr_;
+ grpc_status_code status_code_;
+ char* status_details_;
+ size_t status_details_capacity_;
};
class CallOpSetInterface : public CompletionQueueTag {