Added STATUS command and decoder.

Although no place in the code uses this yet, it will be useful in the near future.
This commit is contained in:
Jim Nelson 2011-05-31 18:47:54 -07:00
parent 9ac3fd0b68
commit ce4ee132ed
4 changed files with 189 additions and 0 deletions

View file

@ -29,6 +29,7 @@ ENGINE_SRC := \
src/engine/imap/ResponseCodeType.vala \
src/engine/imap/ServerResponse.vala \
src/engine/imap/StatusResponse.vala \
src/engine/imap/StatusDataType.vala \
src/engine/imap/ServerData.vala \
src/engine/imap/ServerDataType.vala \
src/engine/imap/FetchDataType.vala \
@ -46,6 +47,7 @@ ENGINE_SRC := \
src/engine/imap/decoders/NoopResults.vala \
src/engine/imap/decoders/ListResults.vala \
src/engine/imap/decoders/SelectExamineResults.vala \
src/engine/imap/decoders/StatusResults.vala \
src/engine/rfc822/MailboxAddress.vala \
src/engine/rfc822/MessageData.vala \
src/engine/util/String.vala \

View file

@ -109,3 +109,20 @@ public class Geary.Imap.FetchCommand : Command {
}
}
public class Geary.Imap.StatusCommand : Command {
public const string NAME = "status";
public StatusCommand(Tag tag, string mailbox, StatusDataType[] data_items) {
base (tag, NAME);
add (new StringParameter(mailbox));
assert(data_items.length > 0);
ListParameter data_item_list = new ListParameter(this);
foreach (StatusDataType data_item in data_items)
data_item_list.add(data_item.to_parameter());
add(data_item_list);
}
}

View file

@ -0,0 +1,70 @@
/* Copyright 2011 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.
*/
public enum Geary.Imap.StatusDataType {
MESSAGES,
RECENT,
UIDNEXT,
UIDVALIDITY,
UNSEEN;
public static StatusDataType[] all() {
return { MESSAGES, RECENT, UIDNEXT, UIDVALIDITY, UNSEEN };
}
public string to_string() {
switch (this) {
case MESSAGES:
return "messages";
case RECENT:
return "recent";
case UIDNEXT:
return "uidnext";
case UIDVALIDITY:
return "uidvalidity";
case UNSEEN:
return "unseen";
default:
assert_not_reached();
}
}
public static StatusDataType decode(string value) throws ImapError {
switch (value.down()) {
case "messages":
return MESSAGES;
case "recent":
return RECENT;
case "uidnext":
return UIDNEXT;
case "uidvalidity":
return UIDVALIDITY;
case "unseen":
return UNSEEN;
default:
throw new ImapError.PARSE_ERROR("Unknown status data type \"%s\"", value);
}
}
public StringParameter to_parameter() {
return new StringParameter(to_string());
}
public static StatusDataType from_parameter(StringParameter stringp) throws ImapError {
return decode(stringp.value);
}
}

View file

@ -0,0 +1,100 @@
/* Copyright 2011 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.
*/
public class Geary.Imap.StatusResults : Geary.Imap.CommandResults {
public string mailbox { get; private set; }
/**
* -1 if not set.
*/
public int messages { get; private set; }
/**
* -1 if not set.
*/
public int recent { get; private set; }
public UID? uidnext { get; private set; }
public UID? uidvalidity { get; private set; }
/**
* -1 if not set.
*/
public int unseen { get; private set; }
public StatusResults(StatusResponse status_response, string mailbox, int messages, int recent,
UID? uidnext, UID? uidvalidity, int unseen) {
base (status_response);
this.mailbox = mailbox;
this.messages = messages;
this.recent = recent;
this.uidnext = uidnext;
this.uidvalidity = uidvalidity;
this.unseen = unseen;
}
public static StatusResults decode(CommandResponse response) throws ImapError {
assert(response.is_sealed());
// only use the first untagged response of status; zero is a problem, more than one are
// ignored
if (response.server_data.size == 0)
throw new ImapError.PARSE_ERROR("No STATUS response line: \"%s\"", response.to_string());
ServerData data = response.server_data[0];
StringParameter cmd = data.get_as_string(1);
StringParameter mailbox = data.get_as_string(2);
ListParameter values = data.get_as_list(3);
if (!cmd.equals_ci(StatusCommand.NAME)) {
throw new ImapError.PARSE_ERROR("Bad STATUS command name in response \"%s\"",
response.to_string());
}
int messages = -1;
int recent = -1;
UID? uidnext = null;
UID? uidvalidity = null;
int unseen = -1;
for (int ctr = 0; ctr < values.get_count(); ctr += 2) {
try {
StringParameter typep = values.get_as_string(ctr);
StringParameter valuep = values.get_as_string(ctr + 1);
switch (StatusDataType.from_parameter(typep)) {
case StatusDataType.MESSAGES:
messages = valuep.as_int(-1, int.MAX);
break;
case StatusDataType.RECENT:
recent = valuep.as_int(-1, int.MAX);
break;
case StatusDataType.UIDNEXT:
uidnext = new UID(valuep.as_int());
break;
case StatusDataType.UIDVALIDITY:
uidvalidity = new UID(valuep.as_int());
break;
case StatusDataType.UNSEEN:
unseen = valuep.as_int(-1, int.MAX);
break;
default:
message("Bad STATUS data type %s", typep.value);
break;
}
} catch (ImapError ierr) {
message("Bad value at %d/%d in STATUS response \"%s\": %s", ctr, ctr + 1,
response.to_string(), ierr.message);
}
}
return new StatusResults(response.status_response, mailbox.value, messages, recent, uidnext,
uidvalidity, unseen);
}
}