message: allow extracting message parts to file

And add unit-test.

Fixes #2467
This commit is contained in:
Dirk-Jan C. Binnema 2023-04-05 00:05:10 +03:00
parent a156b52ddd
commit 0ff1f40679
5 changed files with 41 additions and 20 deletions

View File

@ -1,5 +1,5 @@
/*
** Copyright (C) 2022 Dirk-Jan C. Binnema <djcb@djcbsoftware.nl>
** Copyright (C) 2023 Dirk-Jan C. Binnema <djcb@djcbsoftware.nl>
**
** This program is free software; you can redistribute it and/or modify it
** under the terms of the GNU General Public License as published by the
@ -156,16 +156,18 @@ MessagePart::to_string() const noexcept
return mime_object().to_string_opt();
}
Result<size_t>
MessagePart::to_file(const std::string& path, bool overwrite) const noexcept
{
if (!mime_object().is_part())
return Err(Error::Code::InvalidArgument,
"not a part");
else
if (mime_object().is_part())
return MimePart{mime_object()}.to_file(path, overwrite);
else if (mime_object().is_message_part()) {
if (auto&& msg{MimeMessagePart{mime_object()}.get_message()}; !msg)
return Err(Error::Code::Message, "failed to get message-part");
else
return msg->to_file(path, overwrite);
} else
return mime_object().to_file(path, overwrite);
}
bool

View File

@ -1,5 +1,5 @@
/*
** Copyright (C) 2022 Dirk-Jan C. Binnema <djcb@djcbsoftware.nl>
** Copyright (C) 2023 Dirk-Jan C. Binnema <djcb@djcbsoftware.nl>
**
** This program is free software; you can redistribute it and/or modify it
** under the terms of the GNU General Public License as published by the
@ -53,7 +53,6 @@ public:
*/
~MessagePart();
/**
* Get the underlying MimeObject; you need to include mu-mime-object.hh
* to do anything useful with it.

View File

@ -125,8 +125,6 @@ MimeObject::headers() const noexcept
return hdrs;
}
Result<size_t>
MimeObject::write_to_stream(const MimeFormatOptions& f_opts,
MimeStream& stream) const
@ -139,6 +137,22 @@ MimeObject::write_to_stream(const MimeFormatOptions& f_opts,
return Ok(static_cast<size_t>(written));
}
Result<size_t>
MimeObject::to_file(const std::string& path, bool overwrite) const noexcept
{
GError *err{};
auto strm{g_mime_stream_fs_open(path.c_str(),
O_WRONLY | O_CREAT | O_TRUNC |(overwrite ? 0 : O_EXCL),
S_IRUSR|S_IWUSR,
&err)};
if (!strm)
return Err(Error::Code::File, &err, "failed to open '%s'", path.c_str());
MimeStream stream{MimeStream::make_from_stream(strm)};
return write_to_stream({}, stream);
}
Option<std::string>
MimeObject::to_string_opt() const noexcept
{
@ -525,11 +539,8 @@ MimePart::to_string() const noexcept
buffer.resize(buflen);
return buffer;
}
Result<size_t>
MimePart::to_file(const std::string& path, bool overwrite) const noexcept
{
@ -558,9 +569,6 @@ MimePart::to_file(const std::string& path, bool overwrite) const noexcept
return Ok(static_cast<size_t>(written));
}
void
MimeMultipart::for_each(const ForEachFunc& func) const noexcept
{

View File

@ -829,6 +829,16 @@ public:
*/
Option<std::string> to_string_opt() const noexcept;
/**
* Write object to a file
*
* @param path path to file
* @param overwrite if true, overwrite existing file, if it bqexists
*
* @return size of the wrtten file, or an error.
*/
Result<size_t> to_file(const std::string& path, bool overwrite) const noexcept;
/*
* subtypes.
*/
@ -1101,7 +1111,6 @@ public:
*/
Option<std::string> to_string() const noexcept;
/**
* Write part to a file
*
@ -1113,7 +1122,6 @@ public:
Result<size_t> to_file(const std::string& path, bool overwrite)
const noexcept;
/**
* Types of Content Encoding.
*

View File

@ -1,5 +1,5 @@
/*
** Copyright (C) 2022 Dirk-Jan C. Binnema <djcb@djcbsoftware.nl>
** Copyright (C) 2023 Dirk-Jan C. Binnema <djcb@djcbsoftware.nl>
**
** This program is free software; you can redistribute it and/or modify it
** under the terms of the GNU General Public License as published by the
@ -249,6 +249,10 @@ World!
{
auto&& part{message->parts().at(3)};
g_assert_true(part.mime_type() == "message/rfc822");
const auto fname{*cache_path + "/msgpart"};
g_assert_cmpuint(part.to_file(fname, true).value_or(123), ==, 139);
g_assert_true(::access(fname.c_str(), F_OK) == 0);
}
{