auth context iterator
diff --git a/include/grpc++/auth_context.h b/include/grpc++/auth_context.h
index 158f8e3..394cb34 100644
--- a/include/grpc++/auth_context.h
+++ b/include/grpc++/auth_context.h
@@ -34,15 +34,43 @@
#ifndef GRPCXX_AUTH_CONTEXT_H
#define GRPCXX_AUTH_CONTEXT_H
+#include <iterator>
#include <vector>
#include <grpc++/config.h>
+struct grpc_auth_context;
+struct grpc_auth_property;
+struct grpc_auth_property_iterator;
+
namespace grpc {
+class SecureAuthContext;
class AuthContext {
public:
typedef std::pair<grpc::string, grpc::string> Property;
+ class PropertyIterator
+ : public std::iterator<std::input_iterator_tag, const Property> {
+ public:
+ ~PropertyIterator();
+ PropertyIterator& operator++();
+ PropertyIterator operator++(int);
+ bool operator==(const PropertyIterator& rhs) const;
+ bool operator!=(const PropertyIterator& rhs) const;
+ const Property operator*();
+
+ private:
+ friend SecureAuthContext;
+ PropertyIterator();
+ PropertyIterator(const grpc_auth_property* property,
+ const grpc_auth_property_iterator* iter);
+ const grpc_auth_property* property_;
+ // The following items form a grpc_auth_property_iterator.
+ const grpc_auth_context* ctx_;
+ size_t index_;
+ const char* name_;
+ };
+ typedef PropertyIterator const_iterator;
virtual ~AuthContext() {}
@@ -54,6 +82,10 @@
// Returns all the property values with the given name.
virtual std::vector<grpc::string> FindPropertyValues(
const grpc::string& name) const = 0;
+
+ // Iteration over all the properties.
+ virtual const_iterator begin() const = 0;
+ virtual const_iterator end() const = 0;
};
} // namespace grpc
diff --git a/src/cpp/common/secure_auth_context.cc b/src/cpp/common/secure_auth_context.cc
index 4513723..53b940f 100644
--- a/src/cpp/common/secure_auth_context.cc
+++ b/src/cpp/common/secure_auth_context.cc
@@ -77,4 +77,67 @@
return values;
}
+AuthContext::PropertyIterator::PropertyIterator()
+ : property_(nullptr), ctx_(nullptr), index_(0), name_(nullptr) {}
+
+AuthContext::PropertyIterator::PropertyIterator(
+ const grpc_auth_property* property, const grpc_auth_property_iterator* iter)
+ : property_(property),
+ ctx_(iter->ctx),
+ index_(iter->index),
+ name_(iter->name) {}
+
+AuthContext::PropertyIterator::~PropertyIterator() {}
+
+AuthContext::PropertyIterator& AuthContext::PropertyIterator::operator++() {
+ grpc_auth_property_iterator iter = {ctx_, index_, name_};
+ property_ = grpc_auth_property_iterator_next(&iter);
+ ctx_ = iter.ctx;
+ index_ = iter.index;
+ name_ = iter.name;
+ return *this;
+}
+
+AuthContext::PropertyIterator AuthContext::PropertyIterator::operator++(int) {
+ PropertyIterator tmp(*this);
+ operator++();
+ return tmp;
+}
+
+bool AuthContext::PropertyIterator::operator==(
+ const AuthContext::PropertyIterator& rhs) const {
+ if (property_ == nullptr || rhs.property_ == nullptr) {
+ return property_ == rhs.property_;
+ } else {
+ return index_ == rhs.index_;
+ }
+}
+
+bool AuthContext::PropertyIterator::operator!=(
+ const AuthContext::PropertyIterator& rhs) const {
+ return !operator==(rhs);
+}
+
+const AuthContext::Property AuthContext::PropertyIterator::operator*() {
+ return std::make_pair<grpc::string, grpc::string>(
+ grpc::string(property_->name),
+ grpc::string(property_->value, property_->value_length));
+}
+
+SecureAuthContext::const_iterator SecureAuthContext::begin() const {
+ if (ctx_) {
+ grpc_auth_property_iterator iter =
+ grpc_auth_context_property_iterator(ctx_);
+ const grpc_auth_property* property =
+ grpc_auth_property_iterator_next(&iter);
+ return AuthContext::PropertyIterator(property, &iter);
+ } else {
+ return end();
+ }
+}
+
+SecureAuthContext::const_iterator SecureAuthContext::end() const {
+ return AuthContext::PropertyIterator();
+}
+
} // namespace grpc
diff --git a/src/cpp/common/secure_auth_context.h b/src/cpp/common/secure_auth_context.h
index bba4680..9ea4eb1 100644
--- a/src/cpp/common/secure_auth_context.h
+++ b/src/cpp/common/secure_auth_context.h
@@ -53,6 +53,10 @@
std::vector<grpc::string> FindPropertyValues(const grpc::string& name) const
GRPC_OVERRIDE;
+ const_iterator begin() const GRPC_OVERRIDE;
+
+ const_iterator end() const GRPC_OVERRIDE;
+
private:
grpc_auth_context* ctx_;
};
diff --git a/test/cpp/common/secure_auth_context_test.cc b/test/cpp/common/secure_auth_context_test.cc
index a1819dc..6cc271f 100644
--- a/test/cpp/common/secure_auth_context_test.cc
+++ b/test/cpp/common/secure_auth_context_test.cc
@@ -48,6 +48,7 @@
EXPECT_TRUE(context.GetPeerIdentityPropertyName().empty());
EXPECT_TRUE(context.FindPropertyValues("").empty());
EXPECT_TRUE(context.FindPropertyValues("whatever").empty());
+ EXPECT_TRUE(context.begin() == context.end());
}
TEST_F(SecureAuthContextTest, Properties) {
@@ -68,6 +69,31 @@
EXPECT_EQ("bar", bar[0]);
}
+TEST_F(SecureAuthContextTest, Iterators) {
+ grpc_auth_context* ctx = grpc_auth_context_create(NULL, 3);
+ ctx->properties[0] = grpc_auth_property_init_from_cstring("name", "chapi");
+ ctx->properties[1] = grpc_auth_property_init_from_cstring("name", "chapo");
+ ctx->properties[2] = grpc_auth_property_init_from_cstring("foo", "bar");
+ ctx->peer_identity_property_name = ctx->properties[0].name;
+
+ SecureAuthContext context(ctx);
+ AuthContext::const_iterator iter = context.begin();
+ EXPECT_TRUE(context.end() != iter);
+ AuthContext::Property p0 = *iter;
+ ++iter;
+ AuthContext::Property p1 = *iter;
+ iter++;
+ AuthContext::Property p2 = *iter;
+ EXPECT_EQ("name", p0.first);
+ EXPECT_EQ("chapi", p0.second);
+ EXPECT_EQ("name", p1.first);
+ EXPECT_EQ("chapo", p1.second);
+ EXPECT_EQ("foo", p2.first);
+ EXPECT_EQ("bar", p2.second);
+ ++iter;
+ EXPECT_EQ(context.end(), iter);
+}
+
} // namespace
} // namespace grpc