118f27ade48405475ed610ee0067faa773211d598Janis Danisevskis// TODO: Insert description here. (generated by jdanis) 218f27ade48405475ed610ee0067faa773211d598Janis Danisevskis 318f27ade48405475ed610ee0067faa773211d598Janis Danisevskis#ifndef KEYSTORE_INCLUDE_KEYSTORE_UTILS_H_ 418f27ade48405475ed610ee0067faa773211d598Janis Danisevskis#define KEYSTORE_INCLUDE_KEYSTORE_UTILS_H_ 518f27ade48405475ed610ee0067faa773211d598Janis Danisevskis 618f27ade48405475ed610ee0067faa773211d598Janis Danisevskis#include <iterator> 718f27ade48405475ed610ee0067faa773211d598Janis Danisevskis#include <memory> 818f27ade48405475ed610ee0067faa773211d598Janis Danisevskis#include <vector> 918f27ade48405475ed610ee0067faa773211d598Janis Danisevskis 1018f27ade48405475ed610ee0067faa773211d598Janis Danisevskisnamespace android { 1118f27ade48405475ed610ee0067faa773211d598Janis Danisevskisnamespace security { 1218f27ade48405475ed610ee0067faa773211d598Janis Danisevskis 1318f27ade48405475ed610ee0067faa773211d598Janis Danisevskis/* 1418f27ade48405475ed610ee0067faa773211d598Janis Danisevskis * This iterator abstracts from a collection of the form 1518f27ade48405475ed610ee0067faa773211d598Janis Danisevskis * std::shared_ptr<COLLECTION_TYPE<std::unique_ptr<T>>> 1618f27ade48405475ed610ee0067faa773211d598Janis Danisevskis * such that it is defined both for nulled outer pointer and 1718f27ade48405475ed610ee0067faa773211d598Janis Danisevskis * nulled entries. If shared_ptr(nullptr) is passed in, the iterator behaves 1818f27ade48405475ed610ee0067faa773211d598Janis Danisevskis * like the end iterator yielding an empty collection. Nulled 1918f27ade48405475ed610ee0067faa773211d598Janis Danisevskis * entries are skipped so that the iterator is always dereferencable unless 2018f27ade48405475ed610ee0067faa773211d598Janis Danisevskis * it is equal to end. 2118f27ade48405475ed610ee0067faa773211d598Janis Danisevskis * The default constructor always yields an iterator equal to end. 2218f27ade48405475ed610ee0067faa773211d598Janis Danisevskis * The same iterator invalidation rules apply as they do for the iterators 2318f27ade48405475ed610ee0067faa773211d598Janis Danisevskis * of the corresponding collection. 2418f27ade48405475ed610ee0067faa773211d598Janis Danisevskis */ 2518f27ade48405475ed610ee0067faa773211d598Janis Danisevskistemplate <typename T, template <typename...> class Coll = std::vector> 2618f27ade48405475ed610ee0067faa773211d598Janis Danisevskisclass SharedNullableIterator { 2718f27ade48405475ed610ee0067faa773211d598Janis Danisevskis public: 2818f27ade48405475ed610ee0067faa773211d598Janis Danisevskis typedef Coll<std::unique_ptr<typename std::remove_const<T>::type>> CollectionType; 2918f27ade48405475ed610ee0067faa773211d598Janis Danisevskis typedef std::shared_ptr<CollectionType> CollectionPtr; 3018f27ade48405475ed610ee0067faa773211d598Janis Danisevskis 3118f27ade48405475ed610ee0067faa773211d598Janis Danisevskis SharedNullableIterator() {} 3218f27ade48405475ed610ee0067faa773211d598Janis Danisevskis SharedNullableIterator(const std::shared_ptr<CollectionType>& coll) : coll_(coll) { init(); } 3318f27ade48405475ed610ee0067faa773211d598Janis Danisevskis SharedNullableIterator(std::shared_ptr<CollectionType>&& coll) : coll_(coll) { init(); } 3418f27ade48405475ed610ee0067faa773211d598Janis Danisevskis 3518f27ade48405475ed610ee0067faa773211d598Janis Danisevskis SharedNullableIterator(const SharedNullableIterator& other) 3618f27ade48405475ed610ee0067faa773211d598Janis Danisevskis : coll_(other.coll_), cur_(other.cur_) {} 3718f27ade48405475ed610ee0067faa773211d598Janis Danisevskis SharedNullableIterator(SharedNullableIterator&& other) 3818f27ade48405475ed610ee0067faa773211d598Janis Danisevskis : coll_(std::move(other.coll_)), cur_(std::move(other.cur_)) {} 3918f27ade48405475ed610ee0067faa773211d598Janis Danisevskis 4018f27ade48405475ed610ee0067faa773211d598Janis Danisevskis SharedNullableIterator& operator++() { 4118f27ade48405475ed610ee0067faa773211d598Janis Danisevskis inc(); 4218f27ade48405475ed610ee0067faa773211d598Janis Danisevskis return *this; 4318f27ade48405475ed610ee0067faa773211d598Janis Danisevskis } 4418f27ade48405475ed610ee0067faa773211d598Janis Danisevskis SharedNullableIterator operator++(int) { 4518f27ade48405475ed610ee0067faa773211d598Janis Danisevskis SharedNullableIterator retval(*this); 4618f27ade48405475ed610ee0067faa773211d598Janis Danisevskis ++(*this); 4718f27ade48405475ed610ee0067faa773211d598Janis Danisevskis return retval; 4818f27ade48405475ed610ee0067faa773211d598Janis Danisevskis } 4918f27ade48405475ed610ee0067faa773211d598Janis Danisevskis T& operator*() const { return **cur_; } 5018f27ade48405475ed610ee0067faa773211d598Janis Danisevskis 5118f27ade48405475ed610ee0067faa773211d598Janis Danisevskis T* operator->() const { return &**cur_; } 5218f27ade48405475ed610ee0067faa773211d598Janis Danisevskis 5318f27ade48405475ed610ee0067faa773211d598Janis Danisevskis bool operator==(const SharedNullableIterator& other) const { 5418f27ade48405475ed610ee0067faa773211d598Janis Danisevskis return cur_ == other.cur_ || (is_end() && other.is_end()); 5518f27ade48405475ed610ee0067faa773211d598Janis Danisevskis } 5618f27ade48405475ed610ee0067faa773211d598Janis Danisevskis bool operator!=(const SharedNullableIterator& other) const { return !(*this == other); } 5718f27ade48405475ed610ee0067faa773211d598Janis Danisevskis 5818f27ade48405475ed610ee0067faa773211d598Janis Danisevskis SharedNullableIterator& operator=(const SharedNullableIterator&) = default; 5918f27ade48405475ed610ee0067faa773211d598Janis Danisevskis SharedNullableIterator& operator=(SharedNullableIterator&&) = default; 6018f27ade48405475ed610ee0067faa773211d598Janis Danisevskis 6118f27ade48405475ed610ee0067faa773211d598Janis Danisevskis private: 6218f27ade48405475ed610ee0067faa773211d598Janis Danisevskis inline bool is_end() const { return !coll_ || cur_ == coll_->end(); } 6318f27ade48405475ed610ee0067faa773211d598Janis Danisevskis inline void inc() { 6418f27ade48405475ed610ee0067faa773211d598Janis Danisevskis if (!is_end()) { 6518f27ade48405475ed610ee0067faa773211d598Janis Danisevskis do { 6618f27ade48405475ed610ee0067faa773211d598Janis Danisevskis ++cur_; 6718f27ade48405475ed610ee0067faa773211d598Janis Danisevskis // move forward to the next non null member or stay at end 6818f27ade48405475ed610ee0067faa773211d598Janis Danisevskis } while (cur_ != coll_->end() && !(*cur_)); 6918f27ade48405475ed610ee0067faa773211d598Janis Danisevskis } 7018f27ade48405475ed610ee0067faa773211d598Janis Danisevskis } 7118f27ade48405475ed610ee0067faa773211d598Janis Danisevskis void init() { 7218f27ade48405475ed610ee0067faa773211d598Janis Danisevskis if (coll_) { 7318f27ade48405475ed610ee0067faa773211d598Janis Danisevskis // move forward to the first non null member 7418f27ade48405475ed610ee0067faa773211d598Janis Danisevskis for (cur_ = coll_->begin(); cur_ != coll_->end() && !(*cur_); ++cur_) { 7518f27ade48405475ed610ee0067faa773211d598Janis Danisevskis } 7618f27ade48405475ed610ee0067faa773211d598Janis Danisevskis } 7718f27ade48405475ed610ee0067faa773211d598Janis Danisevskis } 7818f27ade48405475ed610ee0067faa773211d598Janis Danisevskis 7918f27ade48405475ed610ee0067faa773211d598Janis Danisevskis CollectionPtr coll_; 8018f27ade48405475ed610ee0067faa773211d598Janis Danisevskis typename CollectionType::iterator cur_; 8118f27ade48405475ed610ee0067faa773211d598Janis Danisevskis}; 8218f27ade48405475ed610ee0067faa773211d598Janis Danisevskis 8318f27ade48405475ed610ee0067faa773211d598Janis Danisevskis} // namespace security 8418f27ade48405475ed610ee0067faa773211d598Janis Danisevskis} // namespace android 8518f27ade48405475ed610ee0067faa773211d598Janis Danisevskis 8618f27ade48405475ed610ee0067faa773211d598Janis Danisevskisnamespace std { 8718f27ade48405475ed610ee0067faa773211d598Janis Danisevskistemplate <typename T, template <typename...> class COLL> 8818f27ade48405475ed610ee0067faa773211d598Janis Danisevskisstruct iterator_traits<android::security::SharedNullableIterator<T, COLL>> { 8918f27ade48405475ed610ee0067faa773211d598Janis Danisevskis typedef T& reference; 9018f27ade48405475ed610ee0067faa773211d598Janis Danisevskis typedef T value_type; 9118f27ade48405475ed610ee0067faa773211d598Janis Danisevskis typedef T* pointer; 9218f27ade48405475ed610ee0067faa773211d598Janis Danisevskis typedef forward_iterator_tag iterator_category; 9318f27ade48405475ed610ee0067faa773211d598Janis Danisevskis}; 9418f27ade48405475ed610ee0067faa773211d598Janis Danisevskis} 9518f27ade48405475ed610ee0067faa773211d598Janis Danisevskis 9618f27ade48405475ed610ee0067faa773211d598Janis Danisevskis#endif // KEYSTORE_INCLUDE_KEYSTORE_UTILS_H_ 97