123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104 |
- //
- //
- // Copyright 2015 gRPC authors.
- //
- // Licensed under the Apache License, Version 2.0 (the "License");
- // you may not use this file except in compliance with the License.
- // You may obtain a copy of the License at
- //
- // http://www.apache.org/licenses/LICENSE-2.0
- //
- // Unless required by applicable law or agreed to in writing, software
- // distributed under the License is distributed on an "AS IS" BASIS,
- // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- // See the License for the specific language governing permissions and
- // limitations under the License.
- //
- //
- #ifndef GRPCPP_IMPL_METADATA_MAP_H
- #define GRPCPP_IMPL_METADATA_MAP_H
- #include <map>
- #include <grpc/grpc.h>
- #include <grpc/support/log.h>
- #include <grpcpp/support/slice.h>
- namespace grpc {
- namespace internal {
- const char kBinaryErrorDetailsKey[] = "grpc-status-details-bin";
- class MetadataMap {
- public:
- MetadataMap() { Setup(); }
- ~MetadataMap() { Destroy(); }
- TString GetBinaryErrorDetails() {
- // if filled_, extract from the multimap for O(log(n))
- if (filled_) {
- auto iter = map_.find(kBinaryErrorDetailsKey);
- if (iter != map_.end()) {
- return TString(iter->second.begin(), iter->second.length());
- }
- }
- // if not yet filled, take the O(n) lookup to avoid allocating the
- // multimap until it is requested.
- // TODO(ncteisen): plumb this through core as a first class object, just
- // like code and message.
- else {
- for (size_t i = 0; i < arr_.count; i++) {
- if (strncmp(reinterpret_cast<const char*>(
- GRPC_SLICE_START_PTR(arr_.metadata[i].key)),
- kBinaryErrorDetailsKey,
- GRPC_SLICE_LENGTH(arr_.metadata[i].key)) == 0) {
- return TString(reinterpret_cast<const char*>(
- GRPC_SLICE_START_PTR(arr_.metadata[i].value)),
- GRPC_SLICE_LENGTH(arr_.metadata[i].value));
- }
- }
- }
- return TString();
- }
- std::multimap<grpc::string_ref, grpc::string_ref>* map() {
- FillMap();
- return &map_;
- }
- grpc_metadata_array* arr() { return &arr_; }
- void Reset() {
- filled_ = false;
- map_.clear();
- Destroy();
- Setup();
- }
- private:
- bool filled_ = false;
- grpc_metadata_array arr_;
- std::multimap<grpc::string_ref, grpc::string_ref> map_;
- void Destroy() { grpc_metadata_array_destroy(&arr_); }
- void Setup() { memset(&arr_, 0, sizeof(arr_)); }
- void FillMap() {
- if (filled_) return;
- filled_ = true;
- for (size_t i = 0; i < arr_.count; i++) {
- // TODO(yangg) handle duplicates?
- map_.insert(std::pair<grpc::string_ref, grpc::string_ref>(
- StringRefFromSlice(&arr_.metadata[i].key),
- StringRefFromSlice(&arr_.metadata[i].value)));
- }
- }
- };
- } // namespace internal
- } // namespace grpc
- #endif // GRPCPP_IMPL_METADATA_MAP_H
|