Broke out Parameters, misc. other fixes
This commit is contained in:
parent
1f71f02a9d
commit
ce45d19b9a
27 changed files with 666 additions and 350 deletions
|
|
@ -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
|
||||
|
|
|
|||
|
|
@ -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<FolderPath, Imap.Folder>(result,
|
||||
yield enumerate_remote_folders_async(remote_child.path, cancellable));
|
||||
if (remote_child.properties.has_children.is_possible()) {
|
||||
Collection.map_set_all<FolderPath, Imap.Folder>(result,
|
||||
yield enumerate_remote_folders_async(remote_child.path, cancellable));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -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));
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -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");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -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;
|
||||
|
|
|
|||
|
|
@ -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);
|
||||
}
|
||||
|
|
|
|||
|
|
@ -152,9 +152,7 @@ public class Geary.Imap.FetchBodyDataType : BaseObject {
|
|||
}
|
||||
|
||||
public Parameter to_request_parameter() {
|
||||
// Because of the kooky formatting of the Body[section]<partial> 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() {
|
||||
|
|
|
|||
|
|
@ -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());
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
|
|||
|
|
@ -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;
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -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 {
|
||||
|
|
|
|||
|
|
@ -15,7 +15,7 @@
|
|||
* See [[http://tools.ietf.org/html/rfc3501#section-2.2.1]]
|
||||
*/
|
||||
|
||||
public class Geary.Imap.Tag : StringParameter, Gee.Hashable<Geary.Imap.Tag> {
|
||||
public class Geary.Imap.Tag : AtomParameter, Gee.Hashable<Geary.Imap.Tag> {
|
||||
public const string UNTAGGED_VALUE = "*";
|
||||
public const string CONTINUATION_VALUE = "+";
|
||||
public const string UNASSIGNED_VALUE = "----";
|
||||
|
|
|
|||
32
src/engine/imap/parameter/imap-atom-parameter.vala
Normal file
32
src/engine/imap/parameter/imap-atom-parameter.vala
Normal file
|
|
@ -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);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -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<Parameter> 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();
|
||||
}
|
||||
}
|
||||
|
||||
67
src/engine/imap/parameter/imap-literal-parameter.vala
Normal file
67
src/engine/imap/parameter/imap-literal-parameter.vala
Normal file
|
|
@ -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());
|
||||
}
|
||||
}
|
||||
|
||||
61
src/engine/imap/parameter/imap-nil-parameter.vala
Normal file
61
src/engine/imap/parameter/imap-nil-parameter.vala
Normal file
|
|
@ -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;
|
||||
}
|
||||
}
|
||||
|
||||
27
src/engine/imap/parameter/imap-parameter.vala
Normal file
27
src/engine/imap/parameter/imap-parameter.vala
Normal file
|
|
@ -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();
|
||||
}
|
||||
|
||||
37
src/engine/imap/parameter/imap-quoted-string-parameter.vala
Normal file
37
src/engine/imap/parameter/imap-quoted-string-parameter.vala
Normal file
|
|
@ -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);
|
||||
}
|
||||
}
|
||||
|
||||
74
src/engine/imap/parameter/imap-root-parameters.vala
Normal file
74
src/engine/imap/parameter/imap-root-parameters.vala
Normal file
|
|
@ -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();
|
||||
}
|
||||
}
|
||||
|
||||
136
src/engine/imap/parameter/imap-string-parameter.vala
Normal file
136
src/engine/imap/parameter/imap-string-parameter.vala
Normal file
|
|
@ -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);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -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;
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -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
|
||||
|
|
|
|||
|
|
@ -171,7 +171,7 @@ public enum Geary.Imap.ResponseCodeType {
|
|||
}
|
||||
|
||||
public StringParameter to_parameter() {
|
||||
return new StringParameter(to_string());
|
||||
return new AtomParameter(to_string());
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -105,7 +105,7 @@ public enum Geary.Imap.ServerDataType {
|
|||
}
|
||||
|
||||
public StringParameter to_parameter() {
|
||||
return new StringParameter(to_string());
|
||||
return new AtomParameter(to_string());
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
|
|||
|
|
@ -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());
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -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);
|
||||
|
|
|
|||
|
|
@ -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;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -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.
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue