File indexing completed on 2025-03-09 04:54:12
0001 /* 0002 SPDX-FileCopyrightText: 2009 Constantin Berzan <exit3219@gmail.com> 0003 0004 SPDX-License-Identifier: LGPL-2.0-or-later 0005 */ 0006 0007 #include "attachmentpart.h" 0008 0009 #include <KMime/Content> 0010 #include <KMime/Util> 0011 0012 #include <QUrl> 0013 0014 using namespace MessageCore; 0015 0016 size_t qHash(const MessageCore::AttachmentPart::Ptr &ptr, size_t seed) 0017 { 0018 return ::qHash(ptr.data(), seed); 0019 } 0020 0021 // TODO move to kmime_util? 0022 static qint64 sizeWithEncoding(const QByteArray &data, KMime::Headers::contentEncoding encoding) // local 0023 { 0024 auto content = new KMime::Content; 0025 content->setBody(data); 0026 content->contentTransferEncoding()->setEncoding(encoding); 0027 0028 const int size = content->size(); 0029 delete content; 0030 0031 return size; 0032 } 0033 0034 static KMime::Headers::contentEncoding bestEncodingForTypeAndData(const QByteArray &mimeType, const QByteArray &data) 0035 { 0036 // Choose the best encoding for text/* and message/* attachments, but 0037 // always use base64 for anything else to prevent CRLF/LF conversions 0038 // etc. from corrupting the binary data 0039 if (mimeType.isEmpty() || mimeType.startsWith("text/") || mimeType.startsWith("message/")) { 0040 auto possibleEncodings = KMime::encodingsForData(data); 0041 possibleEncodings.removeAll(KMime::Headers::CE8Bit); 0042 if (!possibleEncodings.isEmpty()) { 0043 return possibleEncodings.first(); 0044 } else { 0045 return KMime::Headers::CEquPr; // TODO: maybe some other default? 0046 } 0047 } else { 0048 return KMime::Headers::CEbase64; 0049 } 0050 } 0051 0052 class MessageCore::AttachmentPart::AttachmentPartPrivate 0053 { 0054 public: 0055 AttachmentPartPrivate() = default; 0056 0057 QUrl mUrl; 0058 QString mName; 0059 QString mFileName; 0060 QString mDescription; 0061 QByteArray mCharset; 0062 QByteArray mMimeType; 0063 QByteArray mData; 0064 KMime::Headers::contentEncoding mEncoding = KMime::Headers::CE7Bit; 0065 qint64 mSize = -1; 0066 bool mIsInline = false; 0067 bool mAutoEncoding = true; 0068 bool mCompressed = false; 0069 bool mToEncrypt = false; 0070 bool mToSign = false; 0071 }; 0072 0073 AttachmentPart::AttachmentPart() 0074 : d(new AttachmentPartPrivate) 0075 { 0076 } 0077 0078 AttachmentPart::~AttachmentPart() 0079 { 0080 delete d; 0081 } 0082 0083 QString AttachmentPart::name() const 0084 { 0085 return d->mName; 0086 } 0087 0088 void AttachmentPart::setName(const QString &name) 0089 { 0090 d->mName = name; 0091 } 0092 0093 QString AttachmentPart::fileName() const 0094 { 0095 return d->mFileName; 0096 } 0097 0098 void AttachmentPart::setFileName(const QString &name) 0099 { 0100 d->mFileName = name; 0101 } 0102 0103 QString AttachmentPart::description() const 0104 { 0105 return d->mDescription; 0106 } 0107 0108 void AttachmentPart::setDescription(const QString &description) 0109 { 0110 d->mDescription = description; 0111 } 0112 0113 bool AttachmentPart::isInline() const 0114 { 0115 return d->mIsInline; 0116 } 0117 0118 void AttachmentPart::setInline(bool inl) 0119 { 0120 d->mIsInline = inl; 0121 } 0122 0123 bool AttachmentPart::isAutoEncoding() const 0124 { 0125 return d->mAutoEncoding; 0126 } 0127 0128 void AttachmentPart::setAutoEncoding(bool enabled) 0129 { 0130 d->mAutoEncoding = enabled; 0131 0132 if (enabled) { 0133 d->mEncoding = bestEncodingForTypeAndData(d->mMimeType, d->mData); 0134 } 0135 0136 d->mSize = sizeWithEncoding(d->mData, d->mEncoding); 0137 } 0138 0139 KMime::Headers::contentEncoding AttachmentPart::encoding() const 0140 { 0141 return d->mEncoding; 0142 } 0143 0144 void AttachmentPart::setEncoding(KMime::Headers::contentEncoding encoding) 0145 { 0146 d->mAutoEncoding = false; 0147 d->mEncoding = encoding; 0148 d->mSize = sizeWithEncoding(d->mData, d->mEncoding); 0149 } 0150 0151 QByteArray AttachmentPart::charset() const 0152 { 0153 return d->mCharset; 0154 } 0155 0156 void AttachmentPart::setCharset(const QByteArray &charset) 0157 { 0158 d->mCharset = charset; 0159 } 0160 0161 QByteArray AttachmentPart::mimeType() const 0162 { 0163 return d->mMimeType; 0164 } 0165 0166 void AttachmentPart::setMimeType(const QByteArray &mimeType) 0167 { 0168 d->mMimeType = mimeType; 0169 } 0170 0171 bool AttachmentPart::isCompressed() const 0172 { 0173 return d->mCompressed; 0174 } 0175 0176 void AttachmentPart::setCompressed(bool compressed) 0177 { 0178 d->mCompressed = compressed; 0179 } 0180 0181 bool AttachmentPart::isEncrypted() const 0182 { 0183 return d->mToEncrypt; 0184 } 0185 0186 void AttachmentPart::setEncrypted(bool encrypted) 0187 { 0188 d->mToEncrypt = encrypted; 0189 } 0190 0191 bool AttachmentPart::isSigned() const 0192 { 0193 return d->mToSign; 0194 } 0195 0196 void AttachmentPart::setSigned(bool sign) 0197 { 0198 d->mToSign = sign; 0199 } 0200 0201 QByteArray AttachmentPart::data() const 0202 { 0203 return d->mData; 0204 } 0205 0206 void AttachmentPart::setData(const QByteArray &data) 0207 { 0208 d->mData = data; 0209 0210 if (d->mAutoEncoding) { 0211 d->mEncoding = bestEncodingForTypeAndData(d->mMimeType, d->mData); 0212 } 0213 0214 d->mSize = sizeWithEncoding(d->mData, d->mEncoding); 0215 } 0216 0217 qint64 AttachmentPart::size() const 0218 { 0219 return d->mSize; 0220 } 0221 0222 bool AttachmentPart::isMessageOrMessageCollection() const 0223 { 0224 return (mimeType() == QByteArrayLiteral("message/rfc822")) || (mimeType() == QByteArrayLiteral("multipart/digest")); 0225 } 0226 0227 void AttachmentPart::setUrl(const QUrl &url) 0228 { 0229 d->mUrl = url; 0230 } 0231 0232 QUrl AttachmentPart::url() const 0233 { 0234 return d->mUrl; 0235 }