1 /* -*- mode: c++; c-basic-offset:4 -*-
2     models/predicates.h
3 
4     This file is part of Kleopatra, the KDE keymanager
5     SPDX-FileCopyrightText: 2007 Klarälvdalens Datakonsult AB
6 
7     SPDX-License-Identifier: GPL-2.0-or-later
8 */
9 
10 #pragma once
11 
12 #include <gpgme++/key.h>
13 
14 #include <string>
15 #include <cstring>
16 #include <algorithm>
17 #include <iterator>
18 #include <functional>
19 
20 namespace Kleo
21 {
22 namespace _detail
23 {
24 
mystrcmp(const char * s1,const char * s2)25 inline int mystrcmp(const char *s1, const char *s2)
26 {
27     using namespace std;
28     return s1 ? s2 ? strcmp(s1, s2) : 1 : s2 ? -1 : 0;
29 }
30 
31 #define make_comparator_str_impl( Name, expr, cmp )                     \
32     template <template <typename U> class Op>                           \
33     struct Name {                                                       \
34         typedef bool result_type;                                       \
35         \
36         bool operator()( const char * lhs, const char * rhs ) const {   \
37             return Op<int>()( cmp, 0 );                                 \
38         }                                                               \
39         \
40         bool operator()( const std::string & lhs, const std::string & rhs ) const { \
41             return operator()( lhs.c_str(), rhs.c_str() );              \
42         }                                                               \
43         bool operator()( const char * lhs, const std::string & rhs ) const { \
44             return operator()( lhs, rhs.c_str() );                      \
45         }                                                               \
46         bool operator()( const std::string & lhs, const char * rhs ) const { \
47             return operator()( lhs.c_str(), rhs );                      \
48         }                                                               \
49         \
50         template <typename T>                                           \
51         bool operator()( const T & lhs, const T & rhs ) const {         \
52             return operator()( (lhs expr), (rhs expr) );                \
53         }                                                               \
54         template <typename T>                                           \
55         bool operator()( const T & lhs, const char * rhs ) const {      \
56             return operator()( (lhs expr), rhs );                       \
57         }                                                               \
58         template <typename T>                                           \
59         bool operator()( const char * lhs, const T & rhs ) const {      \
60             return operator()( lhs, (rhs expr) );                       \
61         }                                                               \
62         template <typename T>                                           \
63         bool operator()( const T & lhs, const std::string & rhs ) const { \
64             return operator()( (lhs expr), rhs );                       \
65         }                                                               \
66         template <typename T>                                           \
67         bool operator()( const std::string & lhs, const T & rhs ) const {    \
68             return operator()( lhs, (rhs expr) );                       \
69         }                                                               \
70     }
71 
72 #define make_comparator_str_fast( Name, expr )                          \
73     make_comparator_str_impl( Name, expr, _detail::mystrcmp( lhs, rhs ) )
74 #define make_comparator_str( Name, expr )                               \
75     make_comparator_str_impl( Name, expr, qstricmp( lhs, rhs ) )
76 
77 make_comparator_str_fast(ByFingerprint, .primaryFingerprint());
78 make_comparator_str_fast(ByKeyID, .keyID());
79 make_comparator_str_fast(ByShortKeyID, .shortKeyID());
80 make_comparator_str_fast(ByChainID, .chainID());
81 make_comparator_str_fast(ByKeyGrip, .keyGrip());
82 
83 template <typename T>
sort_by_fpr(T & t)84 void sort_by_fpr(T &t)
85 {
86     std::sort(t.begin(), t.end(), ByFingerprint<std::less>());
87 }
88 
89 template <typename T>
remove_duplicates_by_fpr(T & t)90 void remove_duplicates_by_fpr(T &t)
91 {
92     t.erase(std::unique(t.begin(), t.end(), ByFingerprint<std::equal_to>()), t.end());
93 }
94 
95 template <typename T>
union_by_fpr(const T & t1,const T & t2)96 T union_by_fpr(const T &t1, const T &t2)
97 {
98     T result;
99     result.reserve(t1.size() + t2.size());
100     std::set_union(t1.begin(), t1.end(),
101                    t2.begin(), t2.end(),
102                    std::back_inserter(result),
103                    ByFingerprint<std::less>());
104     return result;
105 }
106 
107 template <typename T>
union_by_fpr_dirty(const T & t1,const T & t2)108 T union_by_fpr_dirty(const T &t1, const T &t2)
109 {
110     T cleaned(t1);
111     sort_by_fpr(cleaned);
112     remove_duplicates_by_fpr(cleaned);
113     return union_by_fpr(cleaned, t2);
114 }
115 
116 template <typename T>
grep_protocol(T & t,GpgME::Protocol proto)117 void grep_protocol(T &t, GpgME::Protocol proto)
118 {
119     t.erase(std::remove_if(t.begin(), t.end(),
120                            [proto](const GpgME::Key &key) {
121                                return key.protocol() != proto;
122                            }), t.end());
123 }
124 
125 template <typename T>
any_protocol(const T & t,GpgME::Protocol proto)126 bool any_protocol(const T &t, GpgME::Protocol proto)
127 {
128     return std::any_of(t.cbegin(), t.cend(),
129                        [proto](const GpgME::Key &key) {
130                            return key.protocol() == proto;
131                        });
132 }
133 
134 template <typename T>
all_protocol(const T & t,GpgME::Protocol proto)135 bool all_protocol(const T &t, GpgME::Protocol proto)
136 {
137     return std::all_of(t.cbegin(), t.cend(),
138                        [proto](const GpgME::Key &key) {
139                          return key.protocol() == proto;
140                        });
141 }
142 
143 template <typename T>
none_of_protocol(const T & t,GpgME::Protocol proto)144 bool none_of_protocol(const T &t, GpgME::Protocol proto)
145 {
146     return std::none_of(t.cbegin(), t.cend(),
147                         [proto](const GpgME::Key &key) {
148                             return key.protocol() == proto;
149                         });
150 }
151 
152 template <typename T>
grep_secret(T & t)153 void grep_secret(T &t)
154 {
155     t.erase(std::remove_if(t.begin(), t.end(), std::mem_fn(&GpgME::Key::hasSecret)), t.end());
156 }
157 
158 template <typename T>
any_secret(const T & t)159 bool any_secret(const T &t)
160 {
161     return std::any_of(t.cbegin(), t.cend(), std::mem_fn(&GpgME::Key::hasSecret));
162 }
163 
164 template <typename T>
all_secret(const T & t)165 bool all_secret(const T &t)
166 {
167     return std::all_of(t.cbegin(), t.cend(), std::mem_fn(&GpgME::Key::hasSecret));
168 }
169 
170 template <typename T>
none_of_secret(const T & t)171 bool none_of_secret(const T &t)
172 {
173     return std::none_of(t.cbegin(), t.cend(), std::mem_fn(&GpgME::Key::hasSecret));
174 }
175 
176 template <typename T>
grep_can_encrypt(T & t)177 void grep_can_encrypt(T &t)
178 {
179     t.erase(std::remove_if(t.begin(), t.end(),
180                            [](const GpgME::Key &key) {
181                                return !key.canEncrypt();
182                            }), t.end());
183 }
184 
185 }
186 }
187 
188