aboutsummaryrefslogtreecommitdiffhomepage
path: root/src/cpp
diff options
context:
space:
mode:
Diffstat (limited to 'src/cpp')
-rw-r--r--src/cpp/client/secure_credentials.cc16
-rw-r--r--src/cpp/codegen/codegen_init.cc (renamed from src/cpp/codegen/grpc_library.cc)13
-rw-r--r--src/cpp/common/call.cc92
-rw-r--r--src/cpp/common/completion_queue.cc33
-rw-r--r--src/cpp/common/core_codegen.cc (renamed from src/cpp/proto/proto_utils.cc)106
-rw-r--r--src/cpp/common/core_codegen.h71
-rw-r--r--src/cpp/util/string_ref.cc66
7 files changed, 171 insertions, 226 deletions
diff --git a/src/cpp/client/secure_credentials.cc b/src/cpp/client/secure_credentials.cc
index 074dae7ca7..308455527c 100644
--- a/src/cpp/client/secure_credentials.cc
+++ b/src/cpp/client/secure_credentials.cc
@@ -83,14 +83,14 @@ std::shared_ptr<CallCredentials> WrapCallCredentials(
} // namespace
std::shared_ptr<ChannelCredentials> GoogleDefaultCredentials() {
- GrpcLibrary init; // To call grpc_init().
+ GrpcLibraryCodegen init; // To call grpc_init().
return WrapChannelCredentials(grpc_google_default_credentials_create());
}
// Builds SSL Credentials given SSL specific options
std::shared_ptr<ChannelCredentials> SslCredentials(
const SslCredentialsOptions& options) {
- GrpcLibrary init; // To call grpc_init().
+ GrpcLibraryCodegen init; // To call grpc_init().
grpc_ssl_pem_key_cert_pair pem_key_cert_pair = {
options.pem_private_key.c_str(), options.pem_cert_chain.c_str()};
@@ -102,7 +102,7 @@ std::shared_ptr<ChannelCredentials> SslCredentials(
// Builds credentials for use when running in GCE
std::shared_ptr<CallCredentials> GoogleComputeEngineCredentials() {
- GrpcLibrary init; // To call grpc_init().
+ GrpcLibraryCodegen init; // To call grpc_init().
return WrapCallCredentials(
grpc_google_compute_engine_credentials_create(nullptr));
}
@@ -110,7 +110,7 @@ std::shared_ptr<CallCredentials> GoogleComputeEngineCredentials() {
// Builds JWT credentials.
std::shared_ptr<CallCredentials> ServiceAccountJWTAccessCredentials(
const grpc::string& json_key, long token_lifetime_seconds) {
- GrpcLibrary init; // To call grpc_init().
+ GrpcLibraryCodegen init; // To call grpc_init().
if (token_lifetime_seconds <= 0) {
gpr_log(GPR_ERROR,
"Trying to create JWTCredentials with non-positive lifetime");
@@ -125,7 +125,7 @@ std::shared_ptr<CallCredentials> ServiceAccountJWTAccessCredentials(
// Builds refresh token credentials.
std::shared_ptr<CallCredentials> GoogleRefreshTokenCredentials(
const grpc::string& json_refresh_token) {
- GrpcLibrary init; // To call grpc_init().
+ GrpcLibraryCodegen init; // To call grpc_init().
return WrapCallCredentials(grpc_google_refresh_token_credentials_create(
json_refresh_token.c_str(), nullptr));
}
@@ -133,7 +133,7 @@ std::shared_ptr<CallCredentials> GoogleRefreshTokenCredentials(
// Builds access token credentials.
std::shared_ptr<CallCredentials> AccessTokenCredentials(
const grpc::string& access_token) {
- GrpcLibrary init; // To call grpc_init().
+ GrpcLibraryCodegen init; // To call grpc_init().
return WrapCallCredentials(
grpc_access_token_credentials_create(access_token.c_str(), nullptr));
}
@@ -142,7 +142,7 @@ std::shared_ptr<CallCredentials> AccessTokenCredentials(
std::shared_ptr<CallCredentials> GoogleIAMCredentials(
const grpc::string& authorization_token,
const grpc::string& authority_selector) {
- GrpcLibrary init; // To call grpc_init().
+ GrpcLibraryCodegen init; // To call grpc_init().
return WrapCallCredentials(grpc_google_iam_credentials_create(
authorization_token.c_str(), authority_selector.c_str(), nullptr));
}
@@ -224,7 +224,7 @@ MetadataCredentialsPluginWrapper::MetadataCredentialsPluginWrapper(
std::shared_ptr<CallCredentials> MetadataCredentialsFromPlugin(
std::unique_ptr<MetadataCredentialsPlugin> plugin) {
- GrpcLibrary init; // To call grpc_init().
+ GrpcLibraryCodegen init; // To call grpc_init().
const char* type = plugin->GetType();
MetadataCredentialsPluginWrapper* wrapper =
new MetadataCredentialsPluginWrapper(std::move(plugin));
diff --git a/src/cpp/codegen/grpc_library.cc b/src/cpp/codegen/codegen_init.cc
index 48acec3f3d..c5d22124b7 100644
--- a/src/cpp/codegen/grpc_library.cc
+++ b/src/cpp/codegen/codegen_init.cc
@@ -31,10 +31,15 @@
*
*/
+#include <grpc++/impl/codegen/core_codegen_interface.h>
#include <grpc++/impl/codegen/grpc_library.h>
-namespace grpc {
+/// Initializes the global gRPC variables for the codegen library. These will
+/// stay null in the absence of of grpc++ library. In this case, no gRPC
+/// features such as the ability to perform calls will be available. Trying to
+/// perform them would result in a segmentation fault when trying to deference
+/// the following nulled globals. These should be associated with actual
+/// as part of the instantiation of a \a grpc::GrpcLibraryInitializer variable.
-GrpcLibraryInterface *g_glip = nullptr;
-
-} // namespace grpc
+grpc::CoreCodegenInterface* grpc::g_core_codegen_interface = nullptr;
+grpc::GrpcLibraryInterface* grpc::g_glip = nullptr;
diff --git a/src/cpp/common/call.cc b/src/cpp/common/call.cc
deleted file mode 100644
index 5b87c2a806..0000000000
--- a/src/cpp/common/call.cc
+++ /dev/null
@@ -1,92 +0,0 @@
-/*
- *
- * 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.
- *
- */
-
-#include <grpc++/impl/call.h>
-
-#include <grpc/support/alloc.h>
-#include <grpc++/channel.h>
-#include <grpc++/client_context.h>
-#include <grpc++/support/byte_buffer.h>
-#include "src/core/profiling/timers.h"
-
-namespace grpc {
-
-void FillMetadataMap(
- grpc_metadata_array* arr,
- std::multimap<grpc::string_ref, grpc::string_ref>* metadata) {
- for (size_t i = 0; i < arr->count; i++) {
- // TODO(yangg) handle duplicates?
- metadata->insert(std::pair<grpc::string_ref, grpc::string_ref>(
- arr->metadata[i].key, grpc::string_ref(arr->metadata[i].value,
- arr->metadata[i].value_length)));
- }
- grpc_metadata_array_destroy(arr);
- grpc_metadata_array_init(arr);
-}
-
-// TODO(yangg) if the map is changed before we send, the pointers will be a
-// mess. Make sure it does not happen.
-grpc_metadata* FillMetadataArray(
- const std::multimap<grpc::string, grpc::string>& metadata) {
- if (metadata.empty()) {
- return nullptr;
- }
- grpc_metadata* metadata_array =
- (grpc_metadata*)gpr_malloc(metadata.size() * sizeof(grpc_metadata));
- size_t i = 0;
- for (auto iter = metadata.cbegin(); iter != metadata.cend(); ++iter, ++i) {
- metadata_array[i].key = iter->first.c_str();
- metadata_array[i].value = iter->second.c_str();
- metadata_array[i].value_length = iter->second.size();
- }
- return metadata_array;
-}
-
-Call::Call(grpc_call* call, CallHook* call_hook, CompletionQueue* cq)
- : call_hook_(call_hook), cq_(cq), call_(call), max_message_size_(-1) {}
-
-Call::Call(grpc_call* call, CallHook* call_hook, CompletionQueue* cq,
- int max_message_size)
- : call_hook_(call_hook),
- cq_(cq),
- call_(call),
- max_message_size_(max_message_size) {}
-
-void Call::PerformOps(CallOpSetInterface* ops) {
- if (max_message_size_ > 0) {
- ops->set_max_message_size(max_message_size_);
- }
- call_hook_->PerformOpsOnCall(ops, this);
-}
-
-} // namespace grpc
diff --git a/src/cpp/common/completion_queue.cc b/src/cpp/common/completion_queue.cc
index 4f76dfff1d..729dc33749 100644
--- a/src/cpp/common/completion_queue.cc
+++ b/src/cpp/common/completion_queue.cc
@@ -34,7 +34,6 @@
#include <memory>
-#include <grpc++/impl/codegen/completion_queue_tag.h>
#include <grpc++/impl/grpc_library.h>
#include <grpc++/support/time.h>
#include <grpc/grpc.h>
@@ -43,16 +42,13 @@
namespace grpc {
static internal::GrpcLibraryInitializer g_gli_initializer;
-CompletionQueue::CompletionQueue() {
- g_gli_initializer.summon();
- cq_ = grpc_completion_queue_create(nullptr);
-}
CompletionQueue::CompletionQueue(grpc_completion_queue* take) : cq_(take) {}
-CompletionQueue::~CompletionQueue() { grpc_completion_queue_destroy(cq_); }
-
-void CompletionQueue::Shutdown() { grpc_completion_queue_shutdown(cq_); }
+void CompletionQueue::Shutdown() {
+ g_gli_initializer.summon();
+ grpc_completion_queue_shutdown(cq_);
+}
CompletionQueue::NextStatus CompletionQueue::AsyncNextInternal(
void** tag, bool* ok, gpr_timespec deadline) {
@@ -75,25 +71,4 @@ CompletionQueue::NextStatus CompletionQueue::AsyncNextInternal(
}
}
-bool CompletionQueue::Pluck(CompletionQueueTag* tag) {
- auto deadline = gpr_inf_future(GPR_CLOCK_REALTIME);
- auto ev = grpc_completion_queue_pluck(cq_, tag, deadline, nullptr);
- bool ok = ev.success != 0;
- void* ignored = tag;
- GPR_ASSERT(tag->FinalizeResult(&ignored, &ok));
- GPR_ASSERT(ignored == tag);
- // Ignore mutations by FinalizeResult: Pluck returns the C API status
- return ev.success != 0;
-}
-
-void CompletionQueue::TryPluck(CompletionQueueTag* tag) {
- auto deadline = gpr_time_0(GPR_CLOCK_REALTIME);
- auto ev = grpc_completion_queue_pluck(cq_, tag, deadline, nullptr);
- if (ev.type == GRPC_QUEUE_TIMEOUT) return;
- bool ok = ev.success != 0;
- void* ignored = tag;
- // the tag must be swallowed if using TryPluck
- GPR_ASSERT(!tag->FinalizeResult(&ignored, &ok));
-}
-
} // namespace grpc
diff --git a/src/cpp/proto/proto_utils.cc b/src/cpp/common/core_codegen.cc
index 79e7bf1801..45e9e278a0 100644
--- a/src/cpp/proto/proto_utils.cc
+++ b/src/cpp/common/core_codegen.cc
@@ -1,6 +1,6 @@
/*
*
- * Copyright 2015, Google Inc.
+ * Copyright 2016, Google Inc.
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
@@ -31,28 +31,31 @@
*
*/
-#include <grpc++/impl/proto_utils.h>
+#include "src/cpp/common/core_codegen.h"
-#include <climits>
+#include <stdlib.h>
-#include <grpc/grpc.h>
+#include <grpc++/support/config.h>
#include <grpc/byte_buffer.h>
#include <grpc/byte_buffer_reader.h>
-#include <grpc/support/log.h>
+#include <grpc/grpc.h>
+#include <grpc/impl/codegen/alloc.h>
+#include <grpc/impl/codegen/byte_buffer.h>
+#include <grpc/impl/codegen/log.h>
+#include <grpc/support/port_platform.h>
#include <grpc/support/slice.h>
#include <grpc/support/slice_buffer.h>
-#include <grpc/support/port_platform.h>
-#include <grpc++/support/config.h>
#include "src/core/profiling/timers.h"
-const int kMaxBufferLength = 8192;
+namespace {
+
+const int kGrpcBufferWriterMaxBufferLength = 8192;
class GrpcBufferWriter GRPC_FINAL
: public ::grpc::protobuf::io::ZeroCopyOutputStream {
public:
- explicit GrpcBufferWriter(grpc_byte_buffer** bp,
- int block_size = kMaxBufferLength)
+ explicit GrpcBufferWriter(grpc_byte_buffer** bp, int block_size)
: block_size_(block_size), byte_count_(0), have_backup_(false) {
*bp = grpc_raw_byte_buffer_create(NULL, 0);
slice_buffer_ = &(*bp)->data.raw.slice_buffer;
@@ -161,14 +164,56 @@ class GrpcBufferReader GRPC_FINAL
grpc_byte_buffer_reader reader_;
gpr_slice slice_;
};
+} // namespace
namespace grpc {
-Status SerializeProto(const grpc::protobuf::Message& msg,
- grpc_byte_buffer** bp) {
+grpc_completion_queue* CoreCodegen::grpc_completion_queue_create(
+ void* reserved) {
+ return ::grpc_completion_queue_create(reserved);
+}
+
+void CoreCodegen::grpc_completion_queue_destroy(grpc_completion_queue* cq) {
+ ::grpc_completion_queue_destroy(cq);
+}
+
+grpc_event CoreCodegen::grpc_completion_queue_pluck(grpc_completion_queue* cq,
+ void* tag,
+ gpr_timespec deadline,
+ void* reserved) {
+ return ::grpc_completion_queue_pluck(cq, tag, deadline, reserved);
+}
+
+void* CoreCodegen::gpr_malloc(size_t size) { return ::gpr_malloc(size); }
+
+void CoreCodegen::gpr_free(void* p) { return ::gpr_free(p); }
+
+void CoreCodegen::grpc_byte_buffer_destroy(grpc_byte_buffer* bb) {
+ ::grpc_byte_buffer_destroy(bb);
+}
+
+void CoreCodegen::grpc_metadata_array_init(grpc_metadata_array* array) {
+ ::grpc_metadata_array_init(array);
+}
+
+void CoreCodegen::grpc_metadata_array_destroy(grpc_metadata_array* array) {
+ ::grpc_metadata_array_destroy(array);
+}
+
+gpr_timespec CoreCodegen::gpr_inf_future(gpr_clock_type type) {
+ return ::gpr_inf_future(type);
+}
+
+void CoreCodegen::assert_fail(const char* failed_assertion) {
+ gpr_log(GPR_ERROR, "assertion failed: %s", failed_assertion);
+ abort();
+}
+
+Status CoreCodegen::SerializeProto(const grpc::protobuf::Message& msg,
+ grpc_byte_buffer** bp) {
GPR_TIMER_SCOPE("SerializeProto", 0);
int byte_size = msg.ByteSize();
- if (byte_size <= kMaxBufferLength) {
+ if (byte_size <= kGrpcBufferWriterMaxBufferLength) {
gpr_slice slice = gpr_slice_malloc(byte_size);
GPR_ASSERT(GPR_SLICE_END_PTR(slice) ==
msg.SerializeWithCachedSizesToArray(GPR_SLICE_START_PTR(slice)));
@@ -176,31 +221,36 @@ Status SerializeProto(const grpc::protobuf::Message& msg,
gpr_slice_unref(slice);
return Status::OK;
} else {
- GrpcBufferWriter writer(bp);
+ GrpcBufferWriter writer(bp, kGrpcBufferWriterMaxBufferLength);
return msg.SerializeToZeroCopyStream(&writer)
? Status::OK
: Status(StatusCode::INTERNAL, "Failed to serialize message");
}
}
-Status DeserializeProto(grpc_byte_buffer* buffer, grpc::protobuf::Message* msg,
- int max_message_size) {
+Status CoreCodegen::DeserializeProto(grpc_byte_buffer* buffer,
+ grpc::protobuf::Message* msg,
+ int max_message_size) {
GPR_TIMER_SCOPE("DeserializeProto", 0);
- if (!buffer) {
+ if (buffer == nullptr) {
return Status(StatusCode::INTERNAL, "No payload");
}
- GrpcBufferReader reader(buffer);
- ::grpc::protobuf::io::CodedInputStream decoder(&reader);
- if (max_message_size > 0) {
- decoder.SetTotalBytesLimit(max_message_size, max_message_size);
- }
- if (!msg->ParseFromCodedStream(&decoder)) {
- return Status(StatusCode::INTERNAL, msg->InitializationErrorString());
- }
- if (!decoder.ConsumedEntireMessage()) {
- return Status(StatusCode::INTERNAL, "Did not read entire message");
+ Status result = Status::OK;
+ {
+ GrpcBufferReader reader(buffer);
+ ::grpc::protobuf::io::CodedInputStream decoder(&reader);
+ if (max_message_size > 0) {
+ decoder.SetTotalBytesLimit(max_message_size, max_message_size);
+ }
+ if (!msg->ParseFromCodedStream(&decoder)) {
+ result = Status(StatusCode::INTERNAL, msg->InitializationErrorString());
+ }
+ if (!decoder.ConsumedEntireMessage()) {
+ result = Status(StatusCode::INTERNAL, "Did not read entire message");
+ }
}
- return Status::OK;
+ grpc_byte_buffer_destroy(buffer);
+ return result;
}
} // namespace grpc
diff --git a/src/cpp/common/core_codegen.h b/src/cpp/common/core_codegen.h
new file mode 100644
index 0000000000..0d8c6b79f7
--- /dev/null
+++ b/src/cpp/common/core_codegen.h
@@ -0,0 +1,71 @@
+/*
+ *
+ * Copyright 2016, 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.
+ *
+ */
+
+// This file should be compiled as part of grpc++.
+
+#include <grpc++/impl/codegen/core_codegen_interface.h>
+#include <grpc/impl/codegen/grpc_types.h>
+#include <grpc/byte_buffer.h>
+
+namespace grpc {
+
+/// Implementation of the core codegen interface.
+class CoreCodegen : public CoreCodegenInterface {
+ private:
+ Status SerializeProto(const grpc::protobuf::Message& msg,
+ grpc_byte_buffer** bp) override;
+
+ Status DeserializeProto(grpc_byte_buffer* buffer,
+ grpc::protobuf::Message* msg,
+ int max_message_size) override;
+
+ grpc_completion_queue* grpc_completion_queue_create(void* reserved) override;
+ void grpc_completion_queue_destroy(grpc_completion_queue* cq) override;
+ grpc_event grpc_completion_queue_pluck(grpc_completion_queue* cq, void* tag,
+ gpr_timespec deadline,
+ void* reserved) override;
+
+ void* gpr_malloc(size_t size) override;
+ void gpr_free(void* p) override;
+
+ void grpc_byte_buffer_destroy(grpc_byte_buffer* bb) override;
+
+ void grpc_metadata_array_init(grpc_metadata_array* array) override;
+ void grpc_metadata_array_destroy(grpc_metadata_array* array) override;
+
+ gpr_timespec gpr_inf_future(gpr_clock_type type) override;
+
+ void assert_fail(const char* failed_assertion) override;
+};
+
+} // namespace grpc
diff --git a/src/cpp/util/string_ref.cc b/src/cpp/util/string_ref.cc
index 66c79a1818..b55019b5f2 100644
--- a/src/cpp/util/string_ref.cc
+++ b/src/cpp/util/string_ref.cc
@@ -1,6 +1,6 @@
/*
*
- * Copyright 2015, Google Inc.
+ * Copyright 2015-2016, Google Inc.
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
@@ -33,72 +33,8 @@
#include <grpc++/support/string_ref.h>
-#include <string.h>
-
-#include <algorithm>
-#include <iostream>
-
namespace grpc {
const size_t string_ref::npos = size_t(-1);
-string_ref& string_ref::operator=(const string_ref& rhs) {
- data_ = rhs.data_;
- length_ = rhs.length_;
- return *this;
-}
-
-string_ref::string_ref(const char* s) : data_(s), length_(strlen(s)) {}
-
-string_ref string_ref::substr(size_t pos, size_t n) const {
- if (pos > length_) pos = length_;
- if (n > (length_ - pos)) n = length_ - pos;
- return string_ref(data_ + pos, n);
-}
-
-int string_ref::compare(string_ref x) const {
- size_t min_size = length_ < x.length_ ? length_ : x.length_;
- int r = memcmp(data_, x.data_, min_size);
- if (r < 0) return -1;
- if (r > 0) return 1;
- if (length_ < x.length_) return -1;
- if (length_ > x.length_) return 1;
- return 0;
-}
-
-bool string_ref::starts_with(string_ref x) const {
- return length_ >= x.length_ && (memcmp(data_, x.data_, x.length_) == 0);
-}
-
-bool string_ref::ends_with(string_ref x) const {
- return length_ >= x.length_ &&
- (memcmp(data_ + (length_ - x.length_), x.data_, x.length_) == 0);
-}
-
-size_t string_ref::find(string_ref s) const {
- auto it = std::search(cbegin(), cend(), s.cbegin(), s.cend());
- return it == cend() ? npos : std::distance(cbegin(), it);
-}
-
-size_t string_ref::find(char c) const {
- auto it = std::find(cbegin(), cend(), c);
- return it == cend() ? npos : std::distance(cbegin(), it);
-}
-
-bool operator==(string_ref x, string_ref y) { return x.compare(y) == 0; }
-
-bool operator!=(string_ref x, string_ref y) { return x.compare(y) != 0; }
-
-bool operator<(string_ref x, string_ref y) { return x.compare(y) < 0; }
-
-bool operator<=(string_ref x, string_ref y) { return x.compare(y) <= 0; }
-
-bool operator>(string_ref x, string_ref y) { return x.compare(y) > 0; }
-
-bool operator>=(string_ref x, string_ref y) { return x.compare(y) >= 0; }
-
-std::ostream& operator<<(std::ostream& out, const string_ref& string) {
- return out << grpc::string(string.begin(), string.end());
-}
-
} // namespace grpc