1/*
2 encryptionresult.cpp - wraps a gpgme verify result
3 Copyright (C) 2004 Klarälvdalens Datakonsult AB
4
5 This file is part of GPGME++.
6
7 GPGME++ is free software; you can redistribute it and/or
8 modify it under the terms of the GNU Library General Public
9 License as published by the Free Software Foundation; either
10 version 2 of the License, or (at your option) any later version.
11
12 GPGME++ is distributed in the hope that it will be useful,
13 but WITHOUT ANY WARRANTY; without even the implied warranty of
14 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15 GNU Library General Public License for more details.
16
17 You should have received a copy of the GNU Library General Public License
18 along with GPGME++; see the file COPYING.LIB. If not, write to the
19 Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
20 Boston, MA 02110-1301, USA.
21*/
22
23#include <gpgme++/config-gpgme++.h>
24
25#include <gpgme++/encryptionresult.h>
26#include "result_p.h"
27#include "util.h"
28
29#include <gpgme.h>
30
31#include <cstring>
32#include <cstdlib>
33#include <istream>
34#include <algorithm>
35#include <iterator>
36
37#include <string.h>
38
39class GpgME::EncryptionResult::Private {
40public:
41 explicit Private( const gpgme_encrypt_result_t r ) {
42 if ( !r ) {
43 return;
44 }
45 for ( gpgme_invalid_key_t ik = r->invalid_recipients ; ik ; ik = ik->next ) {
46 gpgme_invalid_key_t copy = new _gpgme_invalid_key( *ik );
47 if ( ik->fpr ) {
48 copy->fpr = strdup( ik->fpr );
49 }
50 copy->next = 0;
51 invalid.push_back( copy );
52 }
53 }
54 ~Private() {
55 for ( std::vector<gpgme_invalid_key_t>::iterator it = invalid.begin() ; it != invalid.end() ; ++it ) {
56 std::free( ( *it )->fpr );
57 delete *it; *it = 0;
58 }
59 }
60
61 std::vector<gpgme_invalid_key_t> invalid;
62};
63
64GpgME::EncryptionResult::EncryptionResult( gpgme_ctx_t ctx, int error )
65 : GpgME::Result( error ), d()
66{
67 init( ctx );
68}
69
70GpgME::EncryptionResult::EncryptionResult( gpgme_ctx_t ctx, const Error & error )
71 : GpgME::Result( error ), d()
72{
73 init( ctx );
74}
75
76void GpgME::EncryptionResult::init( gpgme_ctx_t ctx ) {
77 if ( !ctx ) {
78 return;
79 }
80 gpgme_encrypt_result_t res = gpgme_op_encrypt_result( ctx );
81 if ( !res ) {
82 return;
83 }
84 d.reset( new Private( res ) );
85}
86
87make_standard_stuff(EncryptionResult)
88
89
90unsigned int GpgME::EncryptionResult::numInvalidRecipients() const {
91 return d ? d->invalid.size() : 0 ;
92}
93
94GpgME::InvalidRecipient GpgME::EncryptionResult::invalidEncryptionKey( unsigned int idx ) const {
95 return InvalidRecipient( d, idx );
96}
97
98std::vector<GpgME::InvalidRecipient> GpgME::EncryptionResult::invalidEncryptionKeys() const {
99 if ( !d ) {
100 return std::vector<GpgME::InvalidRecipient>();
101 }
102 std::vector<GpgME::InvalidRecipient> result;
103 result.reserve( d->invalid.size() );
104 for ( unsigned int i = 0 ; i < d->invalid.size() ; ++i ) {
105 result.push_back( InvalidRecipient( d, i ) );
106 }
107 return result;
108}
109
110
111
112
113GpgME::InvalidRecipient::InvalidRecipient( const boost::shared_ptr<EncryptionResult::Private> & parent, unsigned int i )
114 : d( parent ), idx( i )
115{
116
117}
118
119GpgME::InvalidRecipient::InvalidRecipient() : d(), idx( 0 ) {}
120
121bool GpgME::InvalidRecipient::isNull() const {
122 return !d || idx >= d->invalid.size() ;
123}
124
125const char * GpgME::InvalidRecipient::fingerprint() const {
126 return isNull() ? 0 : d->invalid[idx]->fpr ;
127}
128
129GpgME::Error GpgME::InvalidRecipient::reason() const {
130 return Error( isNull() ? 0 : d->invalid[idx]->reason );
131}
132
133
134
135std::ostream & GpgME::operator<<( std::ostream & os, const EncryptionResult & result ) {
136 os << "GpgME::EncryptionResult(";
137 if ( !result.isNull() ) {
138 os << "\n error: " << result.error()
139 << "\n invalid recipients:\n";
140 const std::vector<InvalidRecipient> ir = result.invalidEncryptionKeys();
141 std::copy( ir.begin(), ir.end(),
142 std::ostream_iterator<InvalidRecipient>( os, "\n" ) );
143 }
144 return os << ')';
145}
146
147std::ostream & GpgME::operator<<( std::ostream & os, const InvalidRecipient & ir ) {
148 os << "GpgME::InvalidRecipient(";
149 if ( !ir.isNull() ) {
150 os << "\n fingerprint: " << protect( ir.fingerprint() )
151 << "\n reason: " << ir.reason()
152 << '\n';
153 }
154 return os << ')';
155}
156