From ce45d19b9a7daaaa0fd24ed711ed96fc638fa601 Mon Sep 17 00:00:00 2001 From: Jim Nelson Date: Wed, 5 Jun 2013 18:24:42 -0700 Subject: [PATCH] Broke out Parameters, misc. other fixes --- src/CMakeLists.txt | 10 +- .../imap-engine-generic-account.vala | 6 +- .../imap/api/imap-folder-properties.vala | 8 +- src/engine/imap/command/imap-command.vala | 22 +- src/engine/imap/command/imap-message-set.vala | 2 +- .../imap/command/imap-store-command.vala | 4 +- .../message/imap-fetch-body-data-type.vala | 4 +- .../imap/message/imap-fetch-data-type.vala | 2 +- .../imap/message/imap-mailbox-parameter.vala | 14 + .../imap/message/imap-status-data-type.vala | 2 +- src/engine/imap/message/imap-tag.vala | 2 +- .../imap/parameter/imap-atom-parameter.vala | 32 ++ .../imap-list-parameter.vala} | 400 ++++++------------ .../parameter/imap-literal-parameter.vala | 67 +++ .../imap/parameter/imap-nil-parameter.vala | 61 +++ src/engine/imap/parameter/imap-parameter.vala | 27 ++ .../imap-quoted-string-parameter.vala | 37 ++ .../imap/parameter/imap-root-parameters.vala | 74 ++++ .../imap/parameter/imap-string-parameter.vala | 136 ++++++ .../imap-unquoted-string-parameter.vala | 39 ++ .../response/imap-fetch-data-decoder.vala | 2 +- .../response/imap-response-code-type.vala | 2 +- .../imap/response/imap-server-data-type.vala | 2 +- src/engine/imap/response/imap-status.vala | 6 +- .../transport/imap-client-connection.vala | 2 +- .../imap/transport/imap-deserializer.vala | 34 +- .../imap/transport/imap-serializer.vala | 19 - 27 files changed, 666 insertions(+), 350 deletions(-) create mode 100644 src/engine/imap/parameter/imap-atom-parameter.vala rename src/engine/imap/{message/imap-parameter.vala => parameter/imap-list-parameter.vala} (50%) create mode 100644 src/engine/imap/parameter/imap-literal-parameter.vala create mode 100644 src/engine/imap/parameter/imap-nil-parameter.vala create mode 100644 src/engine/imap/parameter/imap-parameter.vala create mode 100644 src/engine/imap/parameter/imap-quoted-string-parameter.vala create mode 100644 src/engine/imap/parameter/imap-root-parameters.vala create mode 100644 src/engine/imap/parameter/imap-string-parameter.vala create mode 100644 src/engine/imap/parameter/imap-unquoted-string-parameter.vala diff --git a/src/CMakeLists.txt b/src/CMakeLists.txt index 58514d78..811d3d44 100644 --- a/src/CMakeLists.txt +++ b/src/CMakeLists.txt @@ -96,12 +96,20 @@ engine/imap/message/imap-flag.vala engine/imap/message/imap-mailbox-specifier.vala engine/imap/message/imap-mailbox-parameter.vala engine/imap/message/imap-message-data.vala -engine/imap/message/imap-parameter.vala engine/imap/message/imap-sequence-number.vala engine/imap/message/imap-status-data-type.vala engine/imap/message/imap-tag.vala engine/imap/message/imap-uid.vala engine/imap/message/imap-uid-validity.vala +engine/imap/parameter/imap-atom-parameter.vala +engine/imap/parameter/imap-list-parameter.vala +engine/imap/parameter/imap-literal-parameter.vala +engine/imap/parameter/imap-nil-parameter.vala +engine/imap/parameter/imap-parameter.vala +engine/imap/parameter/imap-quoted-string-parameter.vala +engine/imap/parameter/imap-root-parameters.vala +engine/imap/parameter/imap-string-parameter.vala +engine/imap/parameter/imap-unquoted-string-parameter.vala engine/imap/response/imap-capabilities.vala engine/imap/response/imap-continuation-response.vala engine/imap/response/imap-fetch-body-data-identifier.vala diff --git a/src/engine/imap-engine/imap-engine-generic-account.vala b/src/engine/imap-engine/imap-engine-generic-account.vala index c1c0fe08..917d8ebe 100644 --- a/src/engine/imap-engine/imap-engine-generic-account.vala +++ b/src/engine/imap-engine/imap-engine-generic-account.vala @@ -290,8 +290,10 @@ private abstract class Geary.ImapEngine.GenericAccount : Geary.AbstractAccount { if (remote_children != null) { foreach (Imap.Folder remote_child in remote_children) { result.set(remote_child.path, remote_child); - Collection.map_set_all(result, - yield enumerate_remote_folders_async(remote_child.path, cancellable)); + if (remote_child.properties.has_children.is_possible()) { + Collection.map_set_all(result, + yield enumerate_remote_folders_async(remote_child.path, cancellable)); + } } } diff --git a/src/engine/imap/api/imap-folder-properties.vala b/src/engine/imap/api/imap-folder-properties.vala index 61f1fb4d..a3493445 100644 --- a/src/engine/imap/api/imap-folder-properties.vala +++ b/src/engine/imap/api/imap-folder-properties.vala @@ -117,8 +117,6 @@ public class Geary.Imap.FolderProperties : Geary.FolderProperties { } private void init_flags() { - supports_children = Trillian.from_boolean(!attrs.contains(MailboxAttribute.NO_INFERIORS)); - // \HasNoChildren & \HasChildren are optional attributes (could check for CHILDREN extension, // but unnecessary here) if (attrs.contains(MailboxAttribute.HAS_NO_CHILDREN)) @@ -128,6 +126,12 @@ public class Geary.Imap.FolderProperties : Geary.FolderProperties { else has_children = Trillian.UNKNOWN; + // has_children implies supports_children + if (has_children != Trillian.UNKNOWN) + supports_children = has_children; + else + supports_children = Trillian.from_boolean(!attrs.contains(MailboxAttribute.NO_INFERIORS)); + is_openable = Trillian.from_boolean(!attrs.contains(MailboxAttribute.NO_SELECT)); } diff --git a/src/engine/imap/command/imap-command.vala b/src/engine/imap/command/imap-command.vala index 6e8806f3..77c68d76 100644 --- a/src/engine/imap/command/imap-command.vala +++ b/src/engine/imap/command/imap-command.vala @@ -72,24 +72,14 @@ public class Geary.Imap.Command : RootParameters { private void stock_params() { add(tag); - add(new UnquotedStringParameter(name)); + add(new AtomParameter(name)); if (args != null) { foreach (string arg in args) { - switch (DataFormat.is_quoting_required(arg)) { - case DataFormat.Quoting.REQUIRED: - add(new QuotedStringParameter(arg)); - break; - - case DataFormat.Quoting.OPTIONAL: - add(new UnquotedStringParameter(arg)); - break; - - case DataFormat.Quoting.UNALLOWED: - error("Command continuations currently unsupported"); - - default: - assert_not_reached(); - } + StringParameter? stringp = StringParameter.get_best_for(arg); + if (stringp != null) + add(stringp); + else + error("Command continuations currently unsupported"); } } } diff --git a/src/engine/imap/command/imap-message-set.vala b/src/engine/imap/command/imap-message-set.vala index f1cdac52..e2ad9968 100644 --- a/src/engine/imap/command/imap-message-set.vala +++ b/src/engine/imap/command/imap-message-set.vala @@ -236,7 +236,7 @@ public class Geary.Imap.MessageSet : BaseObject { // look for open-ended span if (span_count == 2) builder.append_printf(",%s", last_seq_num.to_string()); - else + else if (last_seq_num != start_of_span) builder.append_printf(":%s", last_seq_num.to_string()); return builder.str; diff --git a/src/engine/imap/command/imap-store-command.vala b/src/engine/imap/command/imap-store-command.vala index d9d32961..3bac606d 100644 --- a/src/engine/imap/command/imap-store-command.vala +++ b/src/engine/imap/command/imap-store-command.vala @@ -20,11 +20,11 @@ public class Geary.Imap.StoreCommand : Command { base (message_set.is_uid ? UID_NAME : NAME); add(message_set.to_parameter()); - add(new StringParameter("%sflags%s".printf(add_flag ? "+" : "-", silent ? ".silent" : ""))); + add(new AtomParameter("%sflags%s".printf(add_flag ? "+" : "-", silent ? ".silent" : ""))); ListParameter list = new ListParameter(this); foreach(MessageFlag flag in flag_list) - list.add(new StringParameter(flag.value)); + list.add(new AtomParameter(flag.value)); add(list); } diff --git a/src/engine/imap/message/imap-fetch-body-data-type.vala b/src/engine/imap/message/imap-fetch-body-data-type.vala index e1021eb1..fd0641d1 100644 --- a/src/engine/imap/message/imap-fetch-body-data-type.vala +++ b/src/engine/imap/message/imap-fetch-body-data-type.vala @@ -152,9 +152,7 @@ public class Geary.Imap.FetchBodyDataType : BaseObject { } public Parameter to_request_parameter() { - // Because of the kooky formatting of the Body[section] fetch field, use an - // unquoted string and format it ourselves. - return new UnquotedStringParameter(serialize_request()); + return new AtomParameter(serialize_request()); } private string serialize_part_number() { diff --git a/src/engine/imap/message/imap-fetch-data-type.vala b/src/engine/imap/message/imap-fetch-data-type.vala index 5431c254..f2907080 100644 --- a/src/engine/imap/message/imap-fetch-data-type.vala +++ b/src/engine/imap/message/imap-fetch-data-type.vala @@ -132,7 +132,7 @@ public enum Geary.Imap.FetchDataType { * Turns this {@link FetchDataType} into a {@link StringParameter} for transmission. */ public StringParameter to_parameter() { - return new StringParameter(to_string()); + return new AtomParameter(to_string()); } /** diff --git a/src/engine/imap/message/imap-mailbox-parameter.vala b/src/engine/imap/message/imap-mailbox-parameter.vala index 2c75b8bd..b6bb87a0 100644 --- a/src/engine/imap/message/imap-mailbox-parameter.vala +++ b/src/engine/imap/message/imap-mailbox-parameter.vala @@ -42,5 +42,19 @@ public class Geary.Imap.MailboxParameter : StringParameter { public string decode() { return imap_utf7_to_utf8(value); } + + /** + * {@inheritDoc} + */ + public override async void serialize(Serializer ser) throws Error { + serialize_string(ser); + } + + /** + * {@inheritDoc} + */ + public override string to_string() { + return value; + } } diff --git a/src/engine/imap/message/imap-status-data-type.vala b/src/engine/imap/message/imap-status-data-type.vala index 328117ea..b9340a6c 100644 --- a/src/engine/imap/message/imap-status-data-type.vala +++ b/src/engine/imap/message/imap-status-data-type.vala @@ -68,7 +68,7 @@ public enum Geary.Imap.StatusDataType { } public StringParameter to_parameter() { - return new StringParameter(to_string()); + return new AtomParameter(to_string()); } public static StatusDataType from_parameter(StringParameter stringp) throws ImapError { diff --git a/src/engine/imap/message/imap-tag.vala b/src/engine/imap/message/imap-tag.vala index 77ed3a71..03ee7a78 100644 --- a/src/engine/imap/message/imap-tag.vala +++ b/src/engine/imap/message/imap-tag.vala @@ -15,7 +15,7 @@ * See [[http://tools.ietf.org/html/rfc3501#section-2.2.1]] */ -public class Geary.Imap.Tag : StringParameter, Gee.Hashable { +public class Geary.Imap.Tag : AtomParameter, Gee.Hashable { public const string UNTAGGED_VALUE = "*"; public const string CONTINUATION_VALUE = "+"; public const string UNASSIGNED_VALUE = "----"; diff --git a/src/engine/imap/parameter/imap-atom-parameter.vala b/src/engine/imap/parameter/imap-atom-parameter.vala new file mode 100644 index 00000000..40a090ff --- /dev/null +++ b/src/engine/imap/parameter/imap-atom-parameter.vala @@ -0,0 +1,32 @@ +/* Copyright 2013 Yorba Foundation + * + * This software is licensed under the GNU Lesser General Public License + * (version 2.1 or later). See the COPYING file in this distribution. + */ + +/** + * A representation of an IMAP atom. + * + * This class does not check if quoting is required. Use {@link DataFormat.is_quoting_required} + * or {@link StringParameter.get_best_for}. + * + * See {@link StringParameter} for a note about class heirarchy. In particular, note that + * [@link Deserializer} will not create this type of {@link Parameter} because it's unable to + * deduce if a string is an atom or a string from syntax alone. + * + * See [[http://tools.ietf.org/html/rfc3501#section-4.1]] + */ + +public class Geary.Imap.AtomParameter : Geary.Imap.UnquotedStringParameter { + public AtomParameter(string value) { + base (value); + } + + /** + * {@inheritDoc} + */ + public override async void serialize(Serializer ser) throws Error { + ser.push_unquoted_string(value); + } +} + diff --git a/src/engine/imap/message/imap-parameter.vala b/src/engine/imap/parameter/imap-list-parameter.vala similarity index 50% rename from src/engine/imap/message/imap-parameter.vala rename to src/engine/imap/parameter/imap-list-parameter.vala index 6b49713d..bdfe113b 100644 --- a/src/engine/imap/message/imap-parameter.vala +++ b/src/engine/imap/parameter/imap-list-parameter.vala @@ -4,164 +4,11 @@ * (version 2.1 or later). See the COPYING file in this distribution. */ -public abstract class Geary.Imap.Parameter : BaseObject { - public abstract async void serialize(Serializer ser) throws Error; - - /** - * to_string() returns a representation of the Parameter suitable for logging and debugging, - * but should not be relied upon for wire or persistent representation. - */ - public abstract string to_string(); -} - -public class Geary.Imap.NilParameter : Geary.Imap.Parameter { - public const string VALUE = "NIL"; - - private static NilParameter? _instance = null; - - public static NilParameter instance { - get { - if (_instance == null) - _instance = new NilParameter(); - - return _instance; - } - } - - private NilParameter() { - } - - public static bool is_nil(string str) { - return String.ascii_equali(VALUE, str); - } - - public override async void serialize(Serializer ser) throws Error { - ser.push_nil(); - } - - public override string to_string() { - return VALUE; - } -} - -public class Geary.Imap.StringParameter : Geary.Imap.Parameter { - public string value { get; private set; } - public string? nullable_value { - get { - return String.is_empty(value) ? null : value; - } - } - - public StringParameter(string value) { - this.value = value; - } - - public bool equals_cs(string value) { - return this.value == value; - } - - public bool equals_ci(string value) { - return this.value.down() == value.down(); - } - - // TODO: This does not check that the value is a properly-formed integer. This should be - // added later. - public int as_int(int clamp_min = int.MIN, int clamp_max = int.MAX) throws ImapError { - return int.parse(value).clamp(clamp_min, clamp_max); - } - - // TODO: This does not check that the value is a properly-formed long. - public long as_long(int clamp_min = int.MIN, int clamp_max = int.MAX) throws ImapError { - return long.parse(value).clamp(clamp_min, clamp_max); - } - - // TODO: This does not check that the value is a properly-formed int64. - public int64 as_int64(int64 clamp_min = int64.MIN, int64 clamp_max = int64.MAX) throws ImapError { - return int64.parse(value).clamp(clamp_min, clamp_max); - } - - public override string to_string() { - return value; - } - - public override async void serialize(Serializer ser) throws Error { - ser.push_string(value); - } -} - /** - * This delivers the string to the IMAP server with quoting applied whether or not it's required. + * The representation of an IMAP parenthesized list. * - * This is generally legal, but some servers may not appreciate it. - * - * {@link Deserializer} will never generate this {@link Parameter}. + * See [[http://tools.ietf.org/html/rfc3501#section-4.4]] */ -public class Geary.Imap.QuotedStringParameter : Geary.Imap.StringParameter { - public QuotedStringParameter(string value) { - base (value); - } - - public override string to_string() { - return "\"%s\"".printf(value); - } - - public override async void serialize(Serializer ser) throws Error { - ser.push_quoted_string(value); - } -} - -/** - * This delivers the string to the IMAP server with no quoting or formatting applied. - * - * This can lead to server errors if misused. Use only if absolutely necessary. - * - * {@link Deserializer} will never generate this Parameter. - */ -public class Geary.Imap.UnquotedStringParameter : Geary.Imap.StringParameter { - public UnquotedStringParameter(string value) { - base (value); - } - - public override async void serialize(Serializer ser) throws Error { - ser.push_unquoted_string(value); - } -} - -public class Geary.Imap.LiteralParameter : Geary.Imap.Parameter { - private Geary.Memory.AbstractBuffer buffer; - - public LiteralParameter(Geary.Memory.AbstractBuffer buffer) { - this.buffer = buffer; - } - - public size_t get_size() { - return buffer.get_size(); - } - - public Geary.Memory.AbstractBuffer get_buffer() { - return buffer; - } - - /** - * Returns the LiteralParameter as though it had been a StringParameter on the wire. Note - * that this does not deal with quoting issues or NIL (which should never be literalized to - * begin with). It merely converts the literal data to a UTF-8 string and returns it as a - * StringParameter. - */ - public StringParameter to_string_parameter() { - return new StringParameter(buffer.to_valid_utf8()); - } - - public override string to_string() { - return "{literal/%lub}".printf(get_size()); - } - - public override async void serialize(Serializer ser) throws Error { - ser.push_string("{%lu}".printf(get_size())); - ser.push_eol(); - yield ser.push_input_stream_literal_data_async(buffer.get_input_stream()); - } -} public class Geary.Imap.ListParameter : Geary.Imap.Parameter { /** @@ -180,21 +27,35 @@ public class Geary.Imap.ListParameter : Geary.Imap.Parameter { add(initial); } + /** + * Returns null if no parent (top-level list). + * + * In a fully-formed set of {@link Parameter}s, this means this {@link ListParameter} is + * probably a {@link RootParameters}. + */ public ListParameter? get_parent() { return parent; } - public void add(Parameter param) { - bool added = list.add(param); - assert(added); + /** + * Returns true if added. + * + * The same {@link Parameter} can't be added more than once to the same {@link ListParameter}. + */ + public bool add(Parameter param) { + return list.add(param); } public int get_count() { return list.size; } + // + // Parameter retrieval + // + /** - * Returns the Parameter at the index in the list, null if index is out of range. + * Returns the {@link Parameter} at the index in the list, null if index is out of range. * * TODO: This call can cause memory leaks when used with the "as" operator until the following * Vala bug is fixed (probably in version 0.19.1). @@ -224,11 +85,14 @@ public class Geary.Imap.ListParameter : Geary.Imap.Parameter { } /** - * Returns Paramater at index if in range and of Type type, otherwise throws an - * ImapError.TYPE_ERROR. type must be of type Parameter. + * Returns {@link Paramater} at index if in range and of Type type, otherwise throws an + * {@link ImapError.TYPE_ERROR}. + * + * type must be of type Parameter. */ public Parameter get_as(int index, Type type) throws ImapError { - assert(type.is_a(typeof(Parameter))); + if (!type.is_a(typeof(Parameter))) + throw new ImapError.TYPE_ERROR("Attempting to cast non-Parameter at index %d", index); Parameter param = get_required(index); if (!param.get_type().is_a(type)) { @@ -240,15 +104,25 @@ public class Geary.Imap.ListParameter : Geary.Imap.Parameter { } /** - * Like get_as(), but returns null if the Parameter at index is a NilParameter. + * Like {@link get_as}, but returns null if the {@link Parameter} at index is a + * {@link NilParameter}. + * + * type must be of type Parameter. */ public Parameter? get_as_nullable(int index, Type type) throws ImapError { - assert(type.is_a(typeof(Parameter))); + if (!type.is_a(typeof(Parameter))) + throw new ImapError.TYPE_ERROR("Attempting to cast non-Parameter at index %d", index); Parameter param = get_required(index); if (param is NilParameter) return null; + // Because Deserializer doesn't produce NilParameters, check manually if this Parameter + // can legally be NIL according to IMAP grammer. + StringParameter? stringp = param as StringParameter; + if (stringp != null && NilParameter.is_nil(stringp.value)) + return null; + if (!param.get_type().is_a(type)) { throw new ImapError.TYPE_ERROR("Parameter %d is not of type %s (is %s)", index, type.name(), param.get_type().name()); @@ -258,11 +132,13 @@ public class Geary.Imap.ListParameter : Geary.Imap.Parameter { } /** - * Like get(), but returns null if Parameter at index is not of the specified type. type must - * be of type Parameter. + * Like {@link get}, but returns null if {@link Parameter} at index is not of the specified type. + * + * type must be of type Parameter. */ public Parameter? get_if(int index, Type type) { - assert(type.is_a(typeof(Parameter))); + if (!type.is_a(typeof(Parameter))) + return null; Parameter? param = get(index); if (param == null || !param.get_type().is_a(type)) @@ -271,44 +147,30 @@ public class Geary.Imap.ListParameter : Geary.Imap.Parameter { return param; } - /** - * Returns a StringParameter only if the Parameter at index is a StringParameter (quoted or - * atom string). - */ - public StringParameter get_only_as_string(int index) throws ImapError { - return (StringParameter) get_as(index, typeof(StringParameter)); - } + // + // String retrieval + // /** - * Returns a StringParameter only if the Parameter at index is a StringParameter (quoted or - * atom string). + * Returns a {@link StringParameter} only if the {@link Parameter} at index is a StringParameter. + * + * Compare to {@link get_if_string_or_literal}. */ - public StringParameter? get_only_as_nullable_string(int index) throws ImapError { - return (StringParameter?) get_as_nullable(index, typeof(StringParameter)); - } - - /** - * Returns a StringParameter only if the Parameter at index is a StringParameter (quoted or - * atom string). Returns an empty StringParameter if index is for a NilParameter; - */ - public StringParameter get_only_as_empty_string(int index) throws ImapError { - StringParameter? param = get_only_as_nullable_string(index); - - return param ?? new StringParameter(""); - } - - /** - * Returns a StringParameter only if the Parameter at index is a StringParameter (quoted or - * atom string). - */ - public StringParameter? get_only_if_string(int index) { + public StringParameter? get_if_string(int index) { return (StringParameter?) get_if(index, typeof(StringParameter)); } /** - * Returns the StringParameter at the index only if the Parameter is a StringParameter or a - * LiteralParameter with a length less than or equal to MAX_STRING_LITERAL_LENGTH. Throws an - * ImapError.TYPE_ERROR if a literal longer than that value. + * Returns a {@link StringParameter} for the value at the index only if the {@link Parameter} + * is a StringParameter or a {@link LiteralParameter} with a length less than or equal to + * {@link MAX_STRING_LITERAL_LENGTH}. + * + * Because literal data is being coerced into a StringParameter, the result may not be suitable + * for transmission as-is. + * + * @see get_as_nullable_string + * @throws ImapError.TYPE_ERROR if no StringParameter at index or the literal is longer than + * MAX_STRING_LITERAL_LENGTH. */ public StringParameter get_as_string(int index) throws ImapError { Parameter param = get_required(index); @@ -319,17 +181,25 @@ public class Geary.Imap.ListParameter : Geary.Imap.Parameter { LiteralParameter? literalp = param as LiteralParameter; if (literalp != null && literalp.get_size() <= MAX_STRING_LITERAL_LENGTH) - return literalp.to_string_parameter(); + return literalp.coerce_to_string_parameter(); throw new ImapError.TYPE_ERROR("Parameter %d not of type string or literal (is %s)", index, param.get_type().name()); } /** - * Much like get_nullable() for StringParameters, but will convert a LiteralParameter to a - * StringParameter if its length is less than or equal to MAX_STRING_LITERAL_LENGTH. Throws - * an ImapError.TYPE_ERROR if literal is longer than that value. + * Returns a {@link StringParameter} for the value at the index only if the {@link Parameter} + * is a StringParameter or a {@link LiteralParameter} with a length less than or equal to + * {@link MAX_STRING_LITERAL_LENGTH}. + * + * Because literal data is being coerced into a StringParameter, the result may not be suitable + * for transmission as-is. + * + * @return null if no StringParameter or LiteralParameter at index. + * @see get_as_string + * @throws ImapError.TYPE_ERROR if literal is longer than MAX_STRING_LITERAL_LENGTH. */ + public StringParameter? get_as_nullable_string(int index) throws ImapError { Parameter? param = get_as_nullable(index, typeof(Parameter)); if (param == null) @@ -341,7 +211,7 @@ public class Geary.Imap.ListParameter : Geary.Imap.Parameter { LiteralParameter? literalp = param as LiteralParameter; if (literalp != null && literalp.get_size() <= MAX_STRING_LITERAL_LENGTH) - return literalp.to_string_parameter(); + return literalp.coerce_to_string_parameter(); throw new ImapError.TYPE_ERROR("Parameter %d not of type string or literal (is %s)", index, param.get_type().name()); @@ -354,60 +224,83 @@ public class Geary.Imap.ListParameter : Geary.Imap.Parameter { public StringParameter get_as_empty_string(int index) throws ImapError { StringParameter? stringp = get_as_nullable_string(index); - return stringp ?? new StringParameter(""); + return stringp ?? StringParameter.get_best_for(""); } + // + // List retrieval + // + /** - * Returns the StringParameter at the index only if the Parameter is a StringParameter or a - * LiteralParameter with a length less than or equal to MAX_STRING_LITERAL_LENGTH. Returns null - * if either is not true. + * Returns a {@link ListParameter} at index. + * + * @see get_as */ - public StringParameter? get_if_string(int index) { - Parameter? param = get(index); - if (param == null) - return null; - - StringParameter? stringp = param as StringParameter; - if (stringp != null) - return stringp; - - LiteralParameter? literalp = param as LiteralParameter; - if (literalp != null && literalp.get_size() <= MAX_STRING_LITERAL_LENGTH) - return literalp.to_string_parameter(); - - return null; - } - public ListParameter get_as_list(int index) throws ImapError { return (ListParameter) get_as(index, typeof(ListParameter)); } + /** + * Returns a {@link ListParameter} at index, null if NIL. + * + * @see get_as_nullable + */ public ListParameter? get_as_nullable_list(int index) throws ImapError { return (ListParameter?) get_as_nullable(index, typeof(ListParameter)); } + /** + * Returns [@link ListParameter} at index, an empty list if NIL. + */ public ListParameter get_as_empty_list(int index) throws ImapError { ListParameter? param = get_as_nullable_list(index); return param ?? new ListParameter(this); } + /** + * Returns a {@link ListParameter} at index, null if not a list. + * + * @see get_if + */ public ListParameter? get_if_list(int index) { return (ListParameter?) get_if(index, typeof(ListParameter)); } + // + // Literal retrieval + // + + /** + * Returns a {@link LiteralParameter} at index. + * + * @see get_as + */ public LiteralParameter get_as_literal(int index) throws ImapError { return (LiteralParameter) get_as(index, typeof(LiteralParameter)); } + /** + * Returns a {@link LiteralParameter} at index, null if NIL. + * + * @see get_as_nullable + */ public LiteralParameter? get_as_nullable_literal(int index) throws ImapError { return (LiteralParameter?) get_as_nullable(index, typeof(LiteralParameter)); } + /** + * Returns a {@link LiteralParameter} at index, null if not a list. + * + * @see get_if + */ public LiteralParameter? get_if_literal(int index) { return (LiteralParameter?) get_if(index, typeof(LiteralParameter)); } + /** + * Returns [@link LiteralParameter} at index, an empty list if NIL. + */ public LiteralParameter get_as_empty_literal(int index) throws ImapError { LiteralParameter? param = get_as_nullable_literal(index); @@ -442,6 +335,9 @@ public class Geary.Imap.ListParameter : Geary.Imap.Parameter { return get_as_nullable_buffer(index) ?? Memory.EmptyBuffer.instance; } + /** + * Returns a read-only List of {@link Parameter}s. + */ public Gee.List get_all() { return list.read_only_view; } @@ -493,6 +389,9 @@ public class Geary.Imap.ListParameter : Geary.Imap.Parameter { return builder.str; } + /** + * {@inheritDoc} + */ public override string to_string() { return "(%s)".printf(stringize_list()); } @@ -506,6 +405,9 @@ public class Geary.Imap.ListParameter : Geary.Imap.Parameter { } } + /** + * {@inheritDoc} + */ public override async void serialize(Serializer ser) throws Error { ser.push_ascii('('); yield serialize_list(ser); @@ -513,55 +415,3 @@ public class Geary.Imap.ListParameter : Geary.Imap.Parameter { } } -public class Geary.Imap.RootParameters : Geary.Imap.ListParameter { - public RootParameters(Parameter? initial = null) { - base (null, initial); - } - - /** - * Moves all contained {@link Parameter} objects inside the supplied RootParameters into a - * new RootParameters. - * - * The supplied root object is stripped clean by this call. - */ - public RootParameters.migrate(RootParameters root) { - base (null); - - adopt_children(root); - } - - /** - * Returns null if the first parameter is not a StringParameter that resembles a Tag. - */ - public Tag? get_tag() { - StringParameter? strparam = get_only_if_string(0); - if (strparam == null) - return null; - - if (!Tag.is_tag(strparam)) - return null; - - return new Tag.from_parameter(strparam); - } - - /** - * Returns true if the first parameter is a StringParameter that resembles a Tag. - */ - public bool has_tag() { - StringParameter? strparam = get_only_if_string(0); - if (strparam == null) - return false; - - return (strparam != null) ? Tag.is_tag(strparam) : false; - } - - public override string to_string() { - return stringize_list(); - } - - public override async void serialize(Serializer ser) throws Error { - yield serialize_list(ser); - ser.push_eol(); - } -} - diff --git a/src/engine/imap/parameter/imap-literal-parameter.vala b/src/engine/imap/parameter/imap-literal-parameter.vala new file mode 100644 index 00000000..42aab27e --- /dev/null +++ b/src/engine/imap/parameter/imap-literal-parameter.vala @@ -0,0 +1,67 @@ +/* Copyright 2011-2013 Yorba Foundation + * + * This software is licensed under the GNU Lesser General Public License + * (version 2.1 or later). See the COPYING file in this distribution. + */ + +/** + * A representation of an IMAP literal parameter. + * + * Because a literal parameter can hold 8-bit data, this is not a descendent of + * {@link StringParameter}, although some times literal data is used to store 8-bit text (for + * example, UTF-8). + * + * See [[http://tools.ietf.org/html/rfc3501#section-4.3]] + */ + +public class Geary.Imap.LiteralParameter : Geary.Imap.Parameter { + private Geary.Memory.AbstractBuffer buffer; + + public LiteralParameter(Geary.Memory.AbstractBuffer buffer) { + this.buffer = buffer; + } + + /** + * Returns the number of bytes in the literal parameter's buffer. + */ + public size_t get_size() { + return buffer.get_size(); + } + + /** + * Returns the literal paremeter's buffer. + */ + public Geary.Memory.AbstractBuffer get_buffer() { + return buffer; + } + + /** + * Returns the {@link LiteralParameter} as though it had been a {@link StringParameter} on the + * wire. + * + * Note that this does not deal with quoting issues or NIL (which should never be + * literalized to begin with). It merely converts the literal data to a UTF-8 string and + * returns it as a StringParameter. Hence, the data is being coerced and may be unsuitable + * for transmitting on the wire. + */ + public StringParameter coerce_to_string_parameter() { + return new UnquotedStringParameter(buffer.to_valid_utf8()); + } + + /** + * {@inheritDoc} + */ + public override string to_string() { + return "{literal/%lub}".printf(get_size()); + } + + /** + * {@inheritDoc} + */ + public override async void serialize(Serializer ser) throws Error { + ser.push_unquoted_string("{%lu}".printf(get_size())); + ser.push_eol(); + yield ser.push_input_stream_literal_data_async(buffer.get_input_stream()); + } +} + diff --git a/src/engine/imap/parameter/imap-nil-parameter.vala b/src/engine/imap/parameter/imap-nil-parameter.vala new file mode 100644 index 00000000..234aa31d --- /dev/null +++ b/src/engine/imap/parameter/imap-nil-parameter.vala @@ -0,0 +1,61 @@ +/* Copyright 2011-2013 Yorba Foundation + * + * This software is licensed under the GNU Lesser General Public License + * (version 2.1 or later). See the COPYING file in this distribution. + */ + +/** + * The representation of IMAP's NIL value. + * + * Note that NIL 'represents the non-existence of a particular data item that is represented as a + * string or parenthesized list, as distinct from the empty string "" or the empty parenthesized + * list () ... NIL is never used for any data item which takes the form of an atom." + * + * Since there's only one form of a NilParameter, it should be retrieved via the {@link instance} + * property. + * + * See [[http://tools.ietf.org/html/rfc3501#section-4.5]] + */ + +public class Geary.Imap.NilParameter : Geary.Imap.Parameter { + public const string VALUE = "NIL"; + + private static NilParameter? _instance = null; + public static NilParameter instance { + get { + if (_instance == null) + _instance = new NilParameter(); + + return _instance; + } + } + + private NilParameter() { + } + + /** + * See note at {@link NilParameter} for comparison rules of "NIL". + * + * In particular, this should not be used when expecting an atom. A mailbox name of NIL + * means that the mailbox is actually named NIL and does not represent an empty string or empty + * list. + */ + public static bool is_nil(string str) { + return String.ascii_equali(VALUE, str); + } + + /** + * {@inheritDoc} + */ + public override async void serialize(Serializer ser) throws Error { + ser.push_nil(); + } + + /** + * {@inheritDoc} + */ + public override string to_string() { + return VALUE; + } +} + diff --git a/src/engine/imap/parameter/imap-parameter.vala b/src/engine/imap/parameter/imap-parameter.vala new file mode 100644 index 00000000..d63f5e1d --- /dev/null +++ b/src/engine/imap/parameter/imap-parameter.vala @@ -0,0 +1,27 @@ +/* Copyright 2011-2013 Yorba Foundation + * + * This software is licensed under the GNU Lesser General Public License + * (version 2.1 or later). See the COPYING file in this distribution. + */ + +/** + * The basic abstraction of a single IMAP parameter that may be serialized and deserialized to and + * from the network. + * + * @see Serializer + * @see Deserializer + */ + +public abstract class Geary.Imap.Parameter : BaseObject { + /** + * Invoked when the {@link Parameter} is to be serialized out to the network. + */ + public abstract async void serialize(Serializer ser) throws Error; + + /** + * Returns a representation of the {@link Parameter} suitable for logging and debugging, + * but should not be relied upon for wire or persistent representation. + */ + public abstract string to_string(); +} + diff --git a/src/engine/imap/parameter/imap-quoted-string-parameter.vala b/src/engine/imap/parameter/imap-quoted-string-parameter.vala new file mode 100644 index 00000000..14b165bd --- /dev/null +++ b/src/engine/imap/parameter/imap-quoted-string-parameter.vala @@ -0,0 +1,37 @@ +/* Copyright 2013 Yorba Foundation + * + * This software is licensed under the GNU Lesser General Public License + * (version 2.1 or later). See the COPYING file in this distribution. + */ + +/** + * A representation of an IMAP quoted string. + * + * This class does not check if quoting is required. Use {@link DataFormat.is_quoting_required} + * or {@link StringParameter.get_best_for}. + * + * {@link Deserializer} will never generate this {@link Parameter}. + * + * See [[http://tools.ietf.org/html/rfc3501#section-4.3]]. + */ + +public class Geary.Imap.QuotedStringParameter : Geary.Imap.StringParameter { + public QuotedStringParameter(string value) { + base (value); + } + + /** + * {@inheritDoc} + */ + public override string to_string() { + return "\"%s\"".printf(value); + } + + /** + * {@inheritDoc} + */ + public override async void serialize(Serializer ser) throws Error { + ser.push_quoted_string(value); + } +} + diff --git a/src/engine/imap/parameter/imap-root-parameters.vala b/src/engine/imap/parameter/imap-root-parameters.vala new file mode 100644 index 00000000..ca338c13 --- /dev/null +++ b/src/engine/imap/parameter/imap-root-parameters.vala @@ -0,0 +1,74 @@ +/* Copyright 2011-2013 Yorba Foundation + * + * This software is licensed under the GNU Lesser General Public License + * (version 2.1 or later). See the COPYING file in this distribution. + */ + +/** + * The base respresentation of an complete IMAP message. + * + * By definition, a top-level {@link ListParameter}. A RootParameters object should never be + * added to another list. + * + * @see ServerResponse + * @see Command + */ + +public class Geary.Imap.RootParameters : Geary.Imap.ListParameter { + public RootParameters(Parameter? initial = null) { + base (null, initial); + } + + /** + * Moves all contained {@link Parameter} objects inside the supplied RootParameters into a + * new RootParameters. + * + * The supplied root object is stripped clean by this call. + */ + public RootParameters.migrate(RootParameters root) { + base (null); + + adopt_children(root); + } + + /** + * Returns null if the first parameter is not a StringParameter that resembles a Tag. + */ + public Tag? get_tag() { + StringParameter? strparam = get_if_string(0); + if (strparam == null) + return null; + + if (!Tag.is_tag(strparam)) + return null; + + return new Tag.from_parameter(strparam); + } + + /** + * Returns true if the first parameter is a StringParameter that resembles a Tag. + */ + public bool has_tag() { + StringParameter? strparam = get_if_string(0); + if (strparam == null) + return false; + + return (strparam != null) ? Tag.is_tag(strparam) : false; + } + + /** + * {@inheritDoc} + */ + public override string to_string() { + return stringize_list(); + } + + /** + * {@inheritDoc} + */ + public override async void serialize(Serializer ser) throws Error { + yield serialize_list(ser); + ser.push_eol(); + } +} + diff --git a/src/engine/imap/parameter/imap-string-parameter.vala b/src/engine/imap/parameter/imap-string-parameter.vala new file mode 100644 index 00000000..4d1cdae7 --- /dev/null +++ b/src/engine/imap/parameter/imap-string-parameter.vala @@ -0,0 +1,136 @@ +/* Copyright 2011-2013 Yorba Foundation + * + * This software is licensed under the GNU Lesser General Public License + * (version 2.1 or later). See the COPYING file in this distribution. + */ + +/** + * A base abstract representation of string (text) data in IMAP. + * + * Although they may be transmitted in various ways, most parameters in IMAP are strings or text + * format, possibly with some quoting rules applied. This class handles most issues with these + * types of {@link Parameter}s. + * + * Although the IMAP specification doesn't list an atom as a "string", it is here because of the + * common functionality that is needed for comparison and other operations. + * + * Note that {@link NilParameter} is ''not'' a StringParameter, to avoid type confusion. + * + * See [[http://tools.ietf.org/html/rfc3501#section-4.3]] + */ + +public abstract class Geary.Imap.StringParameter : Geary.Imap.Parameter { + /** + * The unquoted, decoded string. + */ + public string value { get; private set; } + + /** + * Returns {@link} value or null if value is empty (zero-length). + */ + public string? nullable_value { + get { + return String.is_empty(value) ? null : value; + } + } + + protected StringParameter(string value) { + this.value = value; + } + + /** + * Returns a {@link StringParameter} appropriate for the contents of value. + * + * Will not return an {@link AtomParameter}, but rather an {@link UnquotedStringParameter} if + * suitable. Will not return a {@link NilParameter} for empty strings, but rather a + * {@link QuotedStringParameter}. + * + * Because of these restrictions, should only be used when the context or syntax of the + * Parameter is unknown or uncertain. + * + * @return null if the string must be represented with a {@link LiteralParameter}. + */ + public static StringParameter? get_best_for(string value) { + switch (DataFormat.is_quoting_required(value)) { + case DataFormat.Quoting.REQUIRED: + return new QuotedStringParameter(value); + + case DataFormat.Quoting.OPTIONAL: + return new UnquotedStringParameter(value); + + case DataFormat.Quoting.UNALLOWED: + return null; + + default: + assert_not_reached(); + } + } + + /** + * Can be used by subclasses to properly serialize the string value according to quoting rules. + * + * NOTE: Literal data is not currently supported. + */ + protected void serialize_string(Serializer ser) throws Error { + switch (DataFormat.is_quoting_required(value)) { + case DataFormat.Quoting.REQUIRED: + ser.push_quoted_string(value); + break; + + case DataFormat.Quoting.OPTIONAL: + ser.push_unquoted_string(value); + break; + + case DataFormat.Quoting.UNALLOWED: + error("Unable to serialize literal data"); + + default: + assert_not_reached(); + } + } + + /** + * Case-sensitive comparison. + */ + public bool equals_cs(string value) { + return this.value == value; + } + + /** + * Case-insensitive comparison. + */ + public bool equals_ci(string value) { + return this.value.down() == value.down(); + } + + /** + * Converts the {@link value} to an int, clamped between clamp_min and clamp_max. + * + * TODO: This does not check that the value is a properly-formed integer. This should be + *. added later. + */ + public int as_int(int clamp_min = int.MIN, int clamp_max = int.MAX) throws ImapError { + return int.parse(value).clamp(clamp_min, clamp_max); + } + + /** + * Converts the {@link value} to a long integer, clamped between clamp_min and clamp_max. + * + * TODO: This does not check that the value is a properly-formed long integer. This should be + *. added later. + */ + public long as_long(int clamp_min = int.MIN, int clamp_max = int.MAX) throws ImapError { + return long.parse(value).clamp(clamp_min, clamp_max); + } + + /** + * Converts the {@link value} to a 64-bit integer, clamped between clamp_min and clamp_max. + * + * TODO: This does not check that the value is a properly-formed 64-bit integer. This should be + *. added later. + */ + public int64 as_int64(int64 clamp_min = int64.MIN, int64 clamp_max = int64.MAX) throws ImapError { + return int64.parse(value).clamp(clamp_min, clamp_max); + } +} + diff --git a/src/engine/imap/parameter/imap-unquoted-string-parameter.vala b/src/engine/imap/parameter/imap-unquoted-string-parameter.vala new file mode 100644 index 00000000..e78ad376 --- /dev/null +++ b/src/engine/imap/parameter/imap-unquoted-string-parameter.vala @@ -0,0 +1,39 @@ +/* Copyright 2013 Yorba Foundation + * + * This software is licensed under the GNU Lesser General Public License + * (version 2.1 or later). See the COPYING file in this distribution. + */ + +/** + * A representation of an IMAP string that is not quoted. + * + * This class does not check if quoting is required. Use {@link DataFormat.is_quoting_required} + * or {@link StringParameter.get_best_for}. + * + * The difference between this class and {@link AtomParameter} is that this can be used in any + * circumstance where a string can (or is) represented without quotes or literal data, whereas an + * atom has strict definitions about where it's found. + * + * See [[http://tools.ietf.org/html/rfc3501#section-4.1]] + */ + +public class Geary.Imap.UnquotedStringParameter : Geary.Imap.StringParameter { + public UnquotedStringParameter(string value) { + base (value); + } + + /** + * {@inheritDoc} + */ + public override async void serialize(Serializer ser) throws Error { + ser.push_unquoted_string(value); + } + + /** + * {@inheritDoc} + */ + public override string to_string() { + return value; + } +} + diff --git a/src/engine/imap/response/imap-fetch-data-decoder.vala b/src/engine/imap/response/imap-fetch-data-decoder.vala index 425b2685..1315d76d 100644 --- a/src/engine/imap/response/imap-fetch-data-decoder.vala +++ b/src/engine/imap/response/imap-fetch-data-decoder.vala @@ -43,7 +43,7 @@ public abstract class Geary.Imap.FetchDataDecoder : BaseObject { // reasonably-length literals into StringParameters), do so here manually try { if (literalp.get_size() <= ListParameter.MAX_STRING_LITERAL_LENGTH) - return decode_string(literalp.to_string_parameter()); + return decode_string(literalp.coerce_to_string_parameter()); } catch (ImapError imap_err) { // if decode_string() throws a TYPE_ERROR, retry as a LiteralParameter, otherwise // relay the exception to the caller diff --git a/src/engine/imap/response/imap-response-code-type.vala b/src/engine/imap/response/imap-response-code-type.vala index fc16f82a..254b221f 100644 --- a/src/engine/imap/response/imap-response-code-type.vala +++ b/src/engine/imap/response/imap-response-code-type.vala @@ -171,7 +171,7 @@ public enum Geary.Imap.ResponseCodeType { } public StringParameter to_parameter() { - return new StringParameter(to_string()); + return new AtomParameter(to_string()); } } diff --git a/src/engine/imap/response/imap-server-data-type.vala b/src/engine/imap/response/imap-server-data-type.vala index 6c82ba2c..ed96d203 100644 --- a/src/engine/imap/response/imap-server-data-type.vala +++ b/src/engine/imap/response/imap-server-data-type.vala @@ -105,7 +105,7 @@ public enum Geary.Imap.ServerDataType { } public StringParameter to_parameter() { - return new StringParameter(to_string()); + return new AtomParameter(to_string()); } /** diff --git a/src/engine/imap/response/imap-status.vala b/src/engine/imap/response/imap-status.vala index cbee09db..1d7aabdc 100644 --- a/src/engine/imap/response/imap-status.vala +++ b/src/engine/imap/response/imap-status.vala @@ -66,11 +66,7 @@ public enum Geary.Imap.Status { } public Parameter to_parameter() { - return new StringParameter(to_string()); - } - - public void serialize(Serializer ser) throws Error { - ser.push_string(to_string()); + return new AtomParameter(to_string()); } } diff --git a/src/engine/imap/transport/imap-client-connection.vala b/src/engine/imap/transport/imap-client-connection.vala index c9b92276..a10bd62a 100644 --- a/src/engine/imap/transport/imap-client-connection.vala +++ b/src/engine/imap/transport/imap-client-connection.vala @@ -822,7 +822,7 @@ public class Geary.Imap.ClientConnection : BaseObject { try { Logging.debug(Logging.Flag.NETWORK, "[%s S] %s", to_string(), "done"); - ser.push_string("done"); + ser.push_unquoted_string("done"); ser.push_eol(); } catch (Error err) { debug("[%s] Unable to close IDLE: %s", to_string(), err.message); diff --git a/src/engine/imap/transport/imap-deserializer.vala b/src/engine/imap/transport/imap-deserializer.vala index cd36d0c0..4f8fd5c9 100644 --- a/src/engine/imap/transport/imap-deserializer.vala +++ b/src/engine/imap/transport/imap-deserializer.vala @@ -86,10 +86,10 @@ public class Geary.Imap.Deserializer : BaseObject { /** * Fired when a complete set of IMAP {@link Parameter}s have been received. * - * Note that {@link RootParameters} may contain {@link StringParameter}s, {@link ListParameter}s, - * {@link NilParameter}s, and so on. One special Parameter decoded by Deserializer is - * {@link ResponseCode}, which is structured internally as a ListParameter subclass for - * convenience when decoding and can be deduced at the syntax level. + * Note that {@link RootParameters} may contain {@link QuotedStringParameter}s, + * {@link UnquotedStringParameter}s, {@link ResponseCode}, and {@link ListParameter}s. + * Deserializer does not produce any other kind of Parameter due to its inability to deduce + * them from syntax alone. ResponseCode, however, can be. */ public signal void parameters_ready(RootParameters root); @@ -414,14 +414,14 @@ public class Geary.Imap.Deserializer : BaseObject { current_string.append_unichar(ch); } - private void save_string_parameter() { + private void save_string_parameter(bool quoted) { if (is_current_string_empty()) return; - if (NilParameter.is_nil(current_string.str)) - save_parameter(NilParameter.instance); + if (quoted) + save_parameter(new QuotedStringParameter(current_string.str)); else - save_parameter(new StringParameter(current_string.str)); + save_parameter(new UnquotedStringParameter(current_string.str)); current_string = null; } @@ -536,7 +536,7 @@ public class Geary.Imap.Deserializer : BaseObject { // space indicates end of tag if (ch == ' ') { - save_string_parameter(); + save_string_parameter(false); return State.START_PARAM; } @@ -575,15 +575,15 @@ public class Geary.Imap.Deserializer : BaseObject { return State.SYSTEM_FLAG; } - // space indicates end-of-atom, end-of-tag, or end-of-system-flag + // space indicates end-of-atom if (ch == ' ') { - save_string_parameter(); + save_string_parameter(false); return State.START_PARAM; } if (ch == get_current_context_terminator()) { - save_string_parameter(); + save_string_parameter(false); return pop(); } @@ -607,7 +607,7 @@ public class Geary.Imap.Deserializer : BaseObject { // space indicates end-of-system-flag if (ch == ' ') { - save_string_parameter(); + save_string_parameter(false); return State.START_PARAM; } @@ -615,7 +615,7 @@ public class Geary.Imap.Deserializer : BaseObject { // close-parens/close-square-bracket after a system flag indicates end-of-list/end-of-response // code if (ch == terminator) { - save_string_parameter(); + save_string_parameter(false); return pop(); } @@ -631,7 +631,7 @@ public class Geary.Imap.Deserializer : BaseObject { private uint on_atom_eol(uint state, uint event, void *user) { // clean up final atom - save_string_parameter(); + save_string_parameter(false); return flush_params(); } @@ -649,7 +649,7 @@ public class Geary.Imap.Deserializer : BaseObject { // DQUOTE ends quoted string and return to parsing atoms if (ch == '\"') { - save_string_parameter(); + save_string_parameter(true); return State.START_PARAM; } @@ -706,7 +706,7 @@ public class Geary.Imap.Deserializer : BaseObject { if (ch != ' ') return on_partial_body_atom_char(State.PARTIAL_BODY_ATOM, event, user); - save_string_parameter(); + save_string_parameter(false); return State.START_PARAM; } diff --git a/src/engine/imap/transport/imap-serializer.vala b/src/engine/imap/transport/imap-serializer.vala index 397cac97..bd74d72d 100644 --- a/src/engine/imap/transport/imap-serializer.vala +++ b/src/engine/imap/transport/imap-serializer.vala @@ -44,25 +44,6 @@ public class Geary.Imap.Serializer : BaseObject { douts.put_byte(ch, null); } - public void push_string(string str) throws Error { - // see if need to convert to quoted string, only emitting it if required - switch (DataFormat.is_quoting_required(str)) { - case DataFormat.Quoting.OPTIONAL: - douts.put_string(str); - break; - - case DataFormat.Quoting.REQUIRED: - bool required = push_quoted_string(str); - assert(required); - break; - - case DataFormat.Quoting.UNALLOWED: - default: - // TODO: Not handled currently - assert_not_reached(); - } - } - /** * Pushes the string to the IMAP server with quoting applied whether required or not. Returns * true if quoting was required.