Line data Source code
1 : /*
2 : data.cpp - wraps a gpgme data object
3 : Copyright (C) 2003 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 : #ifdef HAVE_CONFIG_H
24 : #include "config.h"
25 : #endif
26 :
27 : #include "data_p.h"
28 : #include <error.h>
29 : #include <interfaces/dataprovider.h>
30 :
31 : #include <gpgme.h>
32 :
33 : #ifndef NDEBUG
34 : #include <iostream>
35 : #endif
36 :
37 228 : GpgME::Data::Private::~Private()
38 : {
39 114 : if (data) {
40 67 : gpgme_data_release(data);
41 : }
42 114 : }
43 :
44 8 : const GpgME::Data::Null GpgME::Data::null;
45 :
46 0 : GpgME::Data::Data()
47 : {
48 : gpgme_data_t data;
49 0 : const gpgme_error_t e = gpgme_data_new(&data);
50 0 : d.reset(new Private(e ? 0 : data));
51 0 : }
52 :
53 47 : GpgME::Data::Data(const Null &)
54 47 : : d(new Private(0))
55 : {
56 :
57 47 : }
58 :
59 0 : GpgME::Data::Data(gpgme_data_t data)
60 0 : : d(new Private(data))
61 : {
62 :
63 0 : }
64 :
65 0 : GpgME::Data::Data(const char *buffer, size_t size, bool copy)
66 : {
67 : gpgme_data_t data;
68 0 : const gpgme_error_t e = gpgme_data_new_from_mem(&data, buffer, size, int(copy));
69 0 : std::string sizestr = std::to_string(size);
70 : // Ignore errors as this is optional
71 0 : gpgme_data_set_flag(data, "size-hint", sizestr.c_str());
72 0 : d.reset(new Private(e ? 0 : data));
73 0 : }
74 :
75 0 : GpgME::Data::Data(const char *filename)
76 : {
77 : gpgme_data_t data;
78 0 : const gpgme_error_t e = gpgme_data_new(&data);
79 0 : d.reset(new Private(e ? 0 : data));
80 0 : if (!e) {
81 0 : setFileName(filename);
82 : }
83 0 : }
84 :
85 0 : GpgME::Data::Data(const char *filename, off_t offset, size_t length)
86 : {
87 : gpgme_data_t data;
88 0 : const gpgme_error_t e = gpgme_data_new_from_filepart(&data, filename, 0, offset, length);
89 0 : d.reset(new Private(e ? 0 : data));
90 0 : }
91 :
92 0 : GpgME::Data::Data(FILE *fp)
93 : {
94 : gpgme_data_t data;
95 0 : const gpgme_error_t e = gpgme_data_new_from_stream(&data, fp);
96 0 : d.reset(new Private(e ? 0 : data));
97 0 : }
98 :
99 0 : GpgME::Data::Data(FILE *fp, off_t offset, size_t length)
100 : {
101 : gpgme_data_t data;
102 0 : const gpgme_error_t e = gpgme_data_new_from_filepart(&data, 0, fp, offset, length);
103 0 : d.reset(new Private(e ? 0 : data));
104 0 : }
105 :
106 0 : GpgME::Data::Data(int fd)
107 : {
108 : gpgme_data_t data;
109 0 : const gpgme_error_t e = gpgme_data_new_from_fd(&data, fd);
110 0 : d.reset(new Private(e ? 0 : data));
111 0 : }
112 :
113 67 : GpgME::Data::Data(DataProvider *dp)
114 : {
115 67 : d.reset(new Private);
116 67 : if (!dp) {
117 0 : return;
118 : }
119 67 : if (!dp->isSupported(DataProvider::Read)) {
120 1 : d->cbs.read = 0;
121 : }
122 67 : if (!dp->isSupported(DataProvider::Write)) {
123 21 : d->cbs.write = 0;
124 : }
125 67 : if (!dp->isSupported(DataProvider::Seek)) {
126 0 : d->cbs.seek = 0;
127 : }
128 67 : if (!dp->isSupported(DataProvider::Release)) {
129 0 : d->cbs.release = 0;
130 : }
131 67 : const gpgme_error_t e = gpgme_data_new_from_cbs(&d->data, &d->cbs, dp);
132 67 : if (e) {
133 0 : d->data = 0;
134 : }
135 67 : if (dp->isSupported(DataProvider::Seek)) {
136 67 : off_t size = seek(0, SEEK_END);
137 67 : seek(0, SEEK_SET);
138 134 : std::string sizestr = std::to_string(size);
139 : // Ignore errors as this is optional
140 67 : gpgme_data_set_flag(d->data, "size-hint", sizestr.c_str());
141 : }
142 : #ifndef NDEBUG
143 : //std::cerr << "GpgME::Data(): DataProvider supports: "
144 : // << ( d->cbs.read ? "read" : "no read" ) << ", "
145 : // << ( d->cbs.write ? "write" : "no write" ) << ", "
146 : // << ( d->cbs.seek ? "seek" : "no seek" ) << ", "
147 : // << ( d->cbs.release ? "release" : "no release" ) << std::endl;
148 : #endif
149 : }
150 :
151 25 : bool GpgME::Data::isNull() const
152 : {
153 25 : return !d || !d->data;
154 : }
155 :
156 0 : GpgME::Data::Encoding GpgME::Data::encoding() const
157 : {
158 0 : switch (gpgme_data_get_encoding(d->data)) {
159 0 : case GPGME_DATA_ENCODING_NONE: return AutoEncoding;
160 0 : case GPGME_DATA_ENCODING_BINARY: return BinaryEncoding;
161 0 : case GPGME_DATA_ENCODING_BASE64: return Base64Encoding;
162 0 : case GPGME_DATA_ENCODING_ARMOR: return ArmorEncoding;
163 0 : case GPGME_DATA_ENCODING_MIME: return MimeEncoding;
164 0 : case GPGME_DATA_ENCODING_URL: return UrlEncoding;
165 0 : case GPGME_DATA_ENCODING_URLESC: return UrlEscEncoding;
166 0 : case GPGME_DATA_ENCODING_URL0: return Url0Encoding;
167 : }
168 0 : return AutoEncoding;
169 : }
170 :
171 0 : GpgME::Error GpgME::Data::setEncoding(Encoding enc)
172 : {
173 0 : gpgme_data_encoding_t ge = GPGME_DATA_ENCODING_NONE;
174 0 : switch (enc) {
175 0 : case AutoEncoding: ge = GPGME_DATA_ENCODING_NONE; break;
176 0 : case BinaryEncoding: ge = GPGME_DATA_ENCODING_BINARY; break;
177 0 : case Base64Encoding: ge = GPGME_DATA_ENCODING_BASE64; break;
178 0 : case ArmorEncoding: ge = GPGME_DATA_ENCODING_ARMOR; break;
179 0 : case MimeEncoding: ge = GPGME_DATA_ENCODING_MIME; break;
180 0 : case UrlEncoding: ge = GPGME_DATA_ENCODING_URL; break;
181 0 : case UrlEscEncoding: ge = GPGME_DATA_ENCODING_URLESC; break;
182 0 : case Url0Encoding: ge = GPGME_DATA_ENCODING_URL0; break;
183 : }
184 0 : return Error(gpgme_data_set_encoding(d->data, ge));
185 : }
186 :
187 0 : GpgME::Data::Type GpgME::Data::type() const
188 : {
189 0 : if (isNull()) {
190 0 : return Invalid;
191 : }
192 0 : switch (gpgme_data_identify(d->data, 0)) {
193 0 : case GPGME_DATA_TYPE_INVALID: return Invalid;
194 0 : case GPGME_DATA_TYPE_UNKNOWN: return Unknown;
195 0 : case GPGME_DATA_TYPE_PGP_SIGNED: return PGPSigned;
196 0 : case GPGME_DATA_TYPE_PGP_OTHER: return PGPOther;
197 0 : case GPGME_DATA_TYPE_PGP_KEY: return PGPKey;
198 0 : case GPGME_DATA_TYPE_CMS_SIGNED: return CMSSigned;
199 0 : case GPGME_DATA_TYPE_CMS_ENCRYPTED: return CMSEncrypted;
200 0 : case GPGME_DATA_TYPE_CMS_OTHER: return CMSOther;
201 0 : case GPGME_DATA_TYPE_X509_CERT: return X509Cert;
202 0 : case GPGME_DATA_TYPE_PKCS12: return PKCS12;
203 0 : case GPGME_DATA_TYPE_PGP_ENCRYPTED: return PGPEncrypted;
204 0 : case GPGME_DATA_TYPE_PGP_SIGNATURE: return PGPSignature;
205 : }
206 0 : return Invalid;
207 : }
208 :
209 0 : char *GpgME::Data::fileName() const
210 : {
211 0 : return gpgme_data_get_file_name(d->data);
212 : }
213 :
214 0 : GpgME::Error GpgME::Data::setFileName(const char *name)
215 : {
216 0 : return Error(gpgme_data_set_file_name(d->data, name));
217 : }
218 :
219 0 : ssize_t GpgME::Data::read(void *buffer, size_t length)
220 : {
221 0 : return gpgme_data_read(d->data, buffer, length);
222 : }
223 :
224 0 : ssize_t GpgME::Data::write(const void *buffer, size_t length)
225 : {
226 0 : return gpgme_data_write(d->data, buffer, length);
227 : }
228 :
229 134 : off_t GpgME::Data::seek(off_t offset, int whence)
230 : {
231 134 : return gpgme_data_seek(d->data, offset, whence);
232 24 : }
|