39 string genBoundary() {
50 string multipartTypeToString(mail::MimeEmail::MimePartList::MultipartType
const& multipartType) {
51 switch (multipartType) {
52 case mail::MimeEmail::MimePartList::MultipartType::MIXED:
54 case mail::MimeEmail::MimePartList::MultipartType::DIGEST:
56 case mail::MimeEmail::MimePartList::MultipartType::ALTERNATIVE:
58 case mail::MimeEmail::MimePartList::MultipartType::RELATED:
60 case mail::MimeEmail::MimePartList::MultipartType::REPORT:
62 case mail::MimeEmail::MimePartList::MultipartType::SIGNED:
64 case mail::MimeEmail::MimePartList::MultipartType::ENCRYPTED:
75 string mergeMimePartList(mail::MimeEmail::MimePartList
const& mimePartList,
string const& boundary,
76 shared_ptr<mail::ReplacementRules>
const& replacementRules) {
80 for (
auto const& part : mimePartList.mimeParts()) {
81 ret <<
"--" << boundary <<
"\r\n";
83 if (part.mimePart()) {
84 auto const& mimePart = *(part.mimePart());
85 ret <<
"Content-Type: " << mimePart.contentType() <<
"\r\n";
86 if (!mimePart.contentDisposition().empty()) {
87 ret <<
"Content-Disposition: " << mimePart.contentDisposition() <<
"\r\n";
89 for (
auto const& e : mimePart.partHeaders()) {
90 ret << e.first <<
": " << e.second <<
"\r\n";
94 switch (mimePart.applyEncoding()) {
95 case mail::MimeEmail::MimePart::ApplyEncoding::BASE64:
96 ret <<
"Content-Transfer-Encoding: base64\r\n\r\n";
98 (mimePart.allowReplacements() && replacementRules)
100 : mimePart.partData(),
103 case mail::MimeEmail::MimePart::ApplyEncoding::QUOTED_PRINTABLE:
104 ret <<
"Content-Transfer-Encoding: quoted-printable\r\n\r\n";
106 (mimePart.allowReplacements() && replacementRules)
108 : mimePart.partData());
110 case mail::MimeEmail::MimePart::ApplyEncoding::NONE:
112 << ((mimePart.allowReplacements() && replacementRules)
114 : mimePart.partData());
122 else if (part.mimePartList()) {
123 ret <<
"Content-Type: multipart/" << multipartTypeToString(part.mimePartList()->multipartType());
124 string partBoundary = genBoundary();
125 ret <<
"; boundary=\"" << partBoundary <<
"\"\r\n\r\n";
126 ret << mergeMimePartList(*part.mimePartList(), partBoundary, replacementRules) <<
"\r\n\r\n";
130 ret <<
"--" << boundary <<
"--";
135struct mail::MimeEmail::Data {
136 MimePartList mimePartList;
153struct mail::MimeEmail::MimePart::Data {
154 std::string contentType;
155 std::string contentDisposition;
156 ApplyEncoding applyEncoding = ApplyEncoding::QUOTED_PRINTABLE;
157 HeadersMap partHeaders;
158 bool allowReplacements =
false;
159 std::string partData;
186struct mail::MimeEmail::MimePartList::Data {
187 MultipartType multipartType = MultipartType::MIXED;
188 std::vector<MimePartOrList> mimeParts;
207struct mail::MimeEmail::MimePartOrList::Data {
208 unique_ptr<MimePart> mimePart;
209 unique_ptr<MimePartList> mimePartList;
213 Data(Data
const& other) {
217 Data& operator=(MimePart::Data
const& otherMimePartData) {
219 mimePart = make_unique<MimePart>();
222 mimePartList.reset(
nullptr);
224 *mimePart->data = otherMimePartData;
228 Data& operator=(MimePartList::Data
const& otherMimePartListData) {
230 mimePartList = make_unique<MimePartList>();
233 mimePart.reset(
nullptr);
235 *mimePartList->data = otherMimePartListData;
239 Data& operator=(Data
const& other) {
240 if (&other ==
this) {
243 if (other.mimePart) {
245 mimePart = make_unique<MimePart>();
248 mimePartList.reset(
nullptr);
250 *mimePart = *(other.mimePart);
251 }
else if (other.mimePartList) {
253 mimePartList = make_unique<MimePartList>();
256 mimePart.reset(
nullptr);
258 *mimePartList = *(other.mimePartList);
280mail::MimeEmail::MimePartOrList::MimePartOrList(MimeEmail::MimePart
const& otherMimePart) : MimePartOrList() {
281 *data = *otherMimePart.data;
284mail::MimeEmail::MimePartOrList::MimePartOrList(MimeEmail::MimePartList
const& otherMimePartList) : MimePartOrList() {
285 *data = *otherMimePartList.data;
288mail::MimeEmail::MimePartOrList& mail::MimeEmail::MimePartOrList::operator=(MimeEmail::MimePart
const& otherMimePart) {
289 *data = *otherMimePart.data;
293mail::MimeEmail::MimePartOrList& mail::MimeEmail::MimePartOrList::operator=(MimeEmail::MimePartList
const& otherMimePartList) {
294 *data = *otherMimePartList.data;
298std::string mail::MimeEmail::getRaw(shared_ptr<ReplacementRules>
const& replacementRules)
const {
300 for (
auto const& e : headers()) {
301 if (e.first ==
"MIME-Version" || e.first ==
"Content-Type")
303 ret << e.first <<
": " << e.second <<
"\r\n";
305 string boundary = genBoundary();
306 ret <<
"MIME-Version: 1.0\r\nContent-Type: multipart/" << multipartTypeToString(data->mimePartList.multipartType());
307 ret <<
"; boundary=\"" << boundary;
308 ret <<
"\"\r\n\r\nThis is a multi-part message in MIME format\r\n\r\n";
309 ret << mergeMimePartList(data->mimePartList, boundary, replacementRules);
Structure representing a MIME email.
A bunch of useful cryptographic functions (esp. hashing), acting as a wrapper to C crypto libraries.
Namespace containing functions for text encoding and decoding.
#define NAWA_MOVE_CONSTRUCTOR_IMPL_WITH_NS(Namespace, Class)
#define NAWA_PRIMITIVE_DATA_ACCESSORS_IMPL(Class, Member, Type)
#define NAWA_MOVE_ASSIGNMENT_OPERATOR_IMPL_WITH_NS(Namespace, Class)
#define NAWA_COMPLEX_DATA_ACCESSORS_IMPL(Class, Member, Type)
#define NAWA_DEFAULT_CONSTRUCTOR_IMPL_WITH_NS(Namespace, Class)
#define NAWA_MOVE_CONSTRUCTOR_DERIVED_IMPL_WITH_NS(Namespace, Class, Parent)
#define NAWA_COPY_ASSIGNMENT_OPERATOR_DERIVED_IMPL(Class, Parent)
#define NAWA_COPY_CONSTRUCTOR_IMPL_WITH_NS(Namespace, Class)
#define NAWA_COPY_ASSIGNMENT_OPERATOR_IMPL_WITH_NS(Namespace, Class)
#define NAWA_MOVE_ASSIGNMENT_OPERATOR_DERIVED_IMPL(Class, Parent)
#define NAWA_COPY_CONSTRUCTOR_DERIVED_IMPL_WITH_NS(Namespace, Class, Parent)
#define NAWA_DEFAULT_DESTRUCTOR_IMPL_WITH_NS(Namespace, Class)
std::string md5(std::string const &input, bool hex=true)
std::string base64Encode(std::string const &input, size_t breakAfter=0, std::string const &breakSequence="")
std::string quotedPrintableEncode(std::string const &input, std::string const &lineEnding="\r\n", bool replaceCrlf=false, bool qEncoding=false)
std::string stringReplace(std::string input, std::unordered_map< char, char > const &patterns)
Contains useful functions that improve the readability and facilitate maintenance of the NAWA code.