Geary.RFC822.Message: Add accessors for message headers and raw body

Allow accessing Header and Text representations of the message.
This commit is contained in:
Michael Gratton 2020-06-30 14:33:06 +10:00 committed by Michael James Gratton
parent 0b8bf7375f
commit e2f2b6cdab
3 changed files with 91 additions and 8 deletions

View file

@ -369,9 +369,15 @@ public class Geary.RFC822.Header :
Geary.MessageData.BlockMessageData, EncodedMessageData {
private GMime.Message? message = null;
private GMime.HeaderList headers;
private string[]? names = null;
// The ctors for this class seem the wrong way around, but the
// default accepts a memory buffer and not a GMime.HeaderList to
// keep it consistent with other EncodedMessageData
// implementations.
public Header(Memory.Buffer buffer) throws Error {
base("RFC822.Header", buffer);
@ -381,15 +387,25 @@ public class Geary.RFC822.Header :
parser.set_respect_content_length(false);
parser.set_format(MESSAGE);
this.message = parser.construct_message(null);
if (this.message == null) {
var message = parser.construct_message(null);
if (message == null) {
throw new Error.INVALID("Unable to parse RFC 822 headers");
}
this.headers = message.get_header_list();
}
public Header.from_gmime(GMime.Object gmime) {
base(
"RFC822.Header",
new Memory.StringBuffer(gmime.get_headers(get_format_options()))
);
this.headers = gmime.get_header_list();
}
public string? get_header(string name) {
string? value = null;
var header = this.message.get_header_list().get_header(name);
var header = this.headers.get_header(name);
if (header != null) {
value = header.get_value();
}
@ -398,7 +414,7 @@ public class Geary.RFC822.Header :
public string? get_raw_header(string name) {
string? value = null;
var header = this.message.get_header_list().get_header(name);
var header = this.headers.get_header(name);
if (header != null) {
value = header.get_raw_value();
}
@ -407,10 +423,9 @@ public class Geary.RFC822.Header :
public string[] get_header_names() {
if (this.names == null) {
GMime.HeaderList headers = this.message.get_header_list();
var names = new string[headers.get_count()];
var names = new string[this.headers.get_count()];
for (int i = 0; i < names.length; i++) {
names[i] = headers.get_header_at(i).get_name();
names[i] = this.headers.get_header_at(i).get_name();
}
this.names = names;
}
@ -422,10 +437,49 @@ public class Geary.RFC822.Header :
public class Geary.RFC822.Text :
Geary.MessageData.BlockMessageData, EncodedMessageData {
private class GMimeBuffer : Memory.Buffer, Memory.UnownedBytesBuffer {
public override size_t allocated_size {
get { return (size_t) this.stream.length; }
}
public override size_t size {
get { return (size_t) this.stream.length; }
}
private GMime.Stream stream;
private GLib.Bytes buf = null;
public GMimeBuffer(GMime.Stream stream) {
this.stream = stream;
}
public override GLib.Bytes get_bytes() {
if (this.buf == null) {
this.stream.seek(0, SET);
uint8[] bytes = new uint8[this.stream.length()];
this.stream.read(bytes);
this.buf = new GLib.Bytes.take(bytes);
}
return this.buf;
}
public unowned uint8[] to_unowned_uint8_array() {
return get_bytes().get_data();
}
}
public Text(Memory.Buffer buffer) {
base("RFC822.Text", buffer);
}
public Text.from_gmime(GMime.Stream gmime) {
base("RFC822.Text", new GMimeBuffer(gmime));
}
}
public class Geary.RFC822.Full :

View file

@ -658,6 +658,21 @@ public class Geary.RFC822.Message : BaseObject, EmailHeaderSet {
return (addrs.size > 0) ? addrs : null;
}
/**
* Returns the header of the message.
*/
public Header get_header() {
return new Header.from_gmime(this.message);
}
/**
* Returns the possibly body of the message.
*/
public Text get_body() {
GMime.Part part = (GMime.Part) this.message.get_mime_part();
return new Text.from_gmime(part.get_content().get_stream());
}
/**
* Serialises the message using native (i.e. LF) line endings.
*/

View file

@ -53,6 +53,8 @@ This is the second line.
multipart_alternative_as_converted_html);
add_test("multipart_alternative_as_html",
multipart_alternative_as_html);
add_test("get_header", get_header);
add_test("get_body", get_body);
add_test("get_preview", get_preview);
add_test("get_recipients", get_recipients);
add_test("get_searchable_body", get_searchable_body);
@ -177,6 +179,18 @@ This is the second line.
assert_equal(test.get_html_body(null), BASIC_HTML_BODY);
}
public void get_header() throws GLib.Error {
Message message = resource_to_message(BASIC_TEXT_PLAIN);
Header header = message.get_header();
assert(header.get_header("From") == "Alice <alice@example.net>");
}
public void get_body() throws GLib.Error {
Message message = resource_to_message(BASIC_TEXT_PLAIN);
Text body = message.get_body();
assert(body.buffer.to_string().replace("\r", "") == BASIC_PLAIN_BODY);
}
public void get_preview() throws GLib.Error {
Message multipart_signed = string_to_message(MULTIPART_SIGNED_MESSAGE_TEXT);