Stricter naming and controls on converting string data to ASCII
This is the result of the recent fix for Turkish locale users. That patch was sufficient to solve their issue, but this patch is more thorough in naming to ensure in the future it's understood that the IMAP StringParameter objects deal in ASCII, not UTF-8. If a string cannot be converted into a StringParameter (must be represented by a LiteralParameter), that is now also enforced via an ImapError.
This commit is contained in:
parent
26a328d7cc
commit
2c0e29552a
33 changed files with 187 additions and 143 deletions
|
|
@ -483,7 +483,8 @@ class ImapConsole : Gtk.Window {
|
|||
|
||||
Gee.ArrayList<Geary.Imap.FetchDataSpecifier> data_items = new Gee.ArrayList<Geary.Imap.FetchDataSpecifier>();
|
||||
for (int ctr = 1; ctr < args.length; ctr++) {
|
||||
Geary.Imap.FetchDataSpecifier data_type = Geary.Imap.FetchDataSpecifier.decode(args[ctr]);
|
||||
Geary.Imap.StringParameter stringp = Geary.Imap.StringParameter.get_best_for(args[ctr]);
|
||||
Geary.Imap.FetchDataSpecifier data_type = Geary.Imap.FetchDataSpecifier.from_parameter(stringp);
|
||||
data_items.add(data_type);
|
||||
}
|
||||
|
||||
|
|
@ -578,8 +579,10 @@ class ImapConsole : Gtk.Window {
|
|||
status("Status %s".printf(args[0]));
|
||||
|
||||
Geary.Imap.StatusDataType[] data_items = new Geary.Imap.StatusDataType[0];
|
||||
for (int ctr = 1; ctr < args.length; ctr++)
|
||||
data_items += Geary.Imap.StatusDataType.decode(args[ctr]);
|
||||
for (int ctr = 1; ctr < args.length; ctr++) {
|
||||
Geary.Imap.StringParameter stringp = Geary.Imap.StringParameter.get_best_for(args[ctr]);
|
||||
data_items += Geary.Imap.StatusDataType.from_parameter(stringp);
|
||||
}
|
||||
|
||||
cx.send_async.begin(new Geary.Imap.StatusCommand(new Geary.Imap.MailboxSpecifier(args[0]),
|
||||
data_items), null, on_get_status);
|
||||
|
|
|
|||
|
|
@ -74,13 +74,8 @@ public class Geary.Imap.Command : RootParameters {
|
|||
add(tag);
|
||||
add(new AtomParameter(name));
|
||||
if (args != null) {
|
||||
foreach (string arg in args) {
|
||||
StringParameter? stringp = StringParameter.get_best_for(arg);
|
||||
if (stringp != null)
|
||||
add(stringp);
|
||||
else
|
||||
add(new LiteralParameter(new Memory.StringBuffer(arg)));
|
||||
}
|
||||
foreach (string arg in args)
|
||||
add(Parameter.get_for_string(arg));
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -52,7 +52,7 @@ public class Geary.Imap.ListCommand : Command {
|
|||
if (return_param == null || return_param.size == 0)
|
||||
return;
|
||||
|
||||
add(StringParameter.get_best_for("return"));
|
||||
add(StringParameter.get_best_for_unchecked("return"));
|
||||
add(return_param);
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -30,7 +30,7 @@ public class Geary.Imap.ListReturnParameter : ListParameter {
|
|||
}
|
||||
|
||||
public void add_special_use() {
|
||||
add(StringParameter.get_best_for(SPECIAL_USE));
|
||||
add(StringParameter.get_best_for_unchecked(SPECIAL_USE));
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -44,16 +44,12 @@ public class Geary.Imap.SearchCriterion : BaseObject {
|
|||
* Create a single criterion with a simple name and custom value.
|
||||
*/
|
||||
public SearchCriterion.string_value(string name, string value) {
|
||||
Parameter? valuep = StringParameter.get_best_for(value);
|
||||
if (valuep == null)
|
||||
valuep = new LiteralParameter(new Memory.StringBuffer(value));
|
||||
|
||||
parameters.add(prep_name(name));
|
||||
parameters.add(valuep);
|
||||
parameters.add(Parameter.get_for_string(value));
|
||||
}
|
||||
|
||||
private static Parameter prep_name(string name) {
|
||||
Parameter? namep = StringParameter.get_best_for(name);
|
||||
Parameter? namep = StringParameter.try_get_best_for(name);
|
||||
if (namep == null) {
|
||||
warning("Using a search name that requires a literal parameter: %s", name);
|
||||
namep = new LiteralParameter(new Memory.StringBuffer(name));
|
||||
|
|
@ -106,7 +102,7 @@ public class Geary.Imap.SearchCriterion : BaseObject {
|
|||
/**
|
||||
* The IMAP SEARCH KEYWORD criterion, or if the {@link MessageFlag} has a macro, that value.
|
||||
*/
|
||||
public static SearchCriterion has_flag(MessageFlag flag) {
|
||||
public static SearchCriterion has_flag(MessageFlag flag) throws ImapError {
|
||||
string? keyword = flag.get_search_keyword(true);
|
||||
if (keyword != null)
|
||||
return new SearchCriterion.simple(keyword);
|
||||
|
|
@ -117,7 +113,7 @@ public class Geary.Imap.SearchCriterion : BaseObject {
|
|||
/**
|
||||
* The IMAP SEARCH UNKEYWORD criterion, or if the {@link MessageFlag} has a macro, that value.
|
||||
*/
|
||||
public static SearchCriterion has_not_flag(MessageFlag flag) {
|
||||
public static SearchCriterion has_not_flag(MessageFlag flag) throws ImapError {
|
||||
string? keyword = flag.get_search_keyword(false);
|
||||
if (keyword != null)
|
||||
return new SearchCriterion.simple(keyword);
|
||||
|
|
|
|||
|
|
@ -331,7 +331,8 @@ public class Geary.Imap.FetchBodyDataSpecifier : BaseObject, Gee.Hashable<FetchB
|
|||
break;
|
||||
|
||||
default:
|
||||
throw new ImapError.PARSE_ERROR("%s is not a FETCH body data type %d", stringp.value, count);
|
||||
throw new ImapError.PARSE_ERROR("%s is not a FETCH body data type %d", stringp.to_string(),
|
||||
count);
|
||||
}
|
||||
|
||||
// convert section string into its parts:
|
||||
|
|
@ -343,7 +344,7 @@ public class Geary.Imap.FetchBodyDataSpecifier : BaseObject, Gee.Hashable<FetchB
|
|||
unowned string? fields_string;
|
||||
if (section_string.contains("(")) {
|
||||
if (section_string.scanf("%[^(](%[^)])", part_chars, fields_chars) != 2)
|
||||
throw new ImapError.PARSE_ERROR("%s: malformed part/header names", stringp.value);
|
||||
throw new ImapError.PARSE_ERROR("%s: malformed part/header names", stringp.to_string());
|
||||
|
||||
part_string = (string) part_chars;
|
||||
fields_string = (string?) fields_chars;
|
||||
|
|
@ -398,12 +399,12 @@ public class Geary.Imap.FetchBodyDataSpecifier : BaseObject, Gee.Hashable<FetchB
|
|||
if (!String.is_empty(octet_string)) {
|
||||
if (octet_string.scanf("<%d>", out subset_start) != 1) {
|
||||
throw new ImapError.PARSE_ERROR("Improperly formed octet \"%s\" in %s", octet_string,
|
||||
stringp.value);
|
||||
stringp.to_string());
|
||||
}
|
||||
|
||||
if (subset_start < 0) {
|
||||
throw new ImapError.PARSE_ERROR("Invalid octet count %d in %s", subset_start,
|
||||
stringp.value);
|
||||
stringp.to_string());
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -78,12 +78,12 @@ public enum Geary.Imap.FetchDataSpecifier {
|
|||
}
|
||||
|
||||
/**
|
||||
* Converts a plain string into a {@link FetchDataType}.
|
||||
* Decoders a {@link StringParameter} into a {@link FetchDataType} using {@link decode}.
|
||||
*
|
||||
* @throws ImapError.PARSE_ERROR if not a recognized value.
|
||||
* @see decode
|
||||
*/
|
||||
public static FetchDataSpecifier decode(string value) throws ImapError {
|
||||
switch (Ascii.strdown(value)) {
|
||||
public static FetchDataSpecifier from_parameter(StringParameter strparam) throws ImapError {
|
||||
switch (strparam.as_lower()) {
|
||||
case "uid":
|
||||
return UID;
|
||||
|
||||
|
|
@ -124,7 +124,8 @@ public enum Geary.Imap.FetchDataSpecifier {
|
|||
return FULL;
|
||||
|
||||
default:
|
||||
throw new ImapError.PARSE_ERROR("\"%s\" is not a valid fetch-command data item", value);
|
||||
throw new ImapError.PARSE_ERROR("\"%s\" is not a valid fetch-command data item",
|
||||
strparam.to_string());
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -135,15 +136,6 @@ public enum Geary.Imap.FetchDataSpecifier {
|
|||
return new AtomParameter(to_string());
|
||||
}
|
||||
|
||||
/**
|
||||
* Decoders a {@link StringParameter} into a {@link FetchDataType} using {@link decode}.
|
||||
*
|
||||
* @see decode
|
||||
*/
|
||||
public static FetchDataSpecifier from_parameter(StringParameter strparam) throws ImapError {
|
||||
return decode(strparam.value);
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the appropriate {@link FetchDataDecoder} for this {@link FetchDataType}.
|
||||
*
|
||||
|
|
|
|||
|
|
@ -35,7 +35,7 @@ public abstract class Geary.Imap.Flag : BaseObject, Gee.Hashable<Geary.Imap.Flag
|
|||
/**
|
||||
* Returns the {@link Flag} as an appropriate {@link Parameter}.
|
||||
*/
|
||||
public Parameter to_parameter() {
|
||||
public StringParameter to_parameter() throws ImapError {
|
||||
return StringParameter.get_best_for(value);
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -42,8 +42,14 @@ public abstract class Geary.Imap.Flags : Geary.MessageData.AbstractMessageData,
|
|||
*/
|
||||
public virtual Parameter to_parameter() {
|
||||
ListParameter listp = new ListParameter();
|
||||
foreach (Flag flag in list)
|
||||
listp.add(flag.to_parameter());
|
||||
foreach (Flag flag in list) {
|
||||
try {
|
||||
listp.add(flag.to_parameter());
|
||||
} catch (ImapError ierr) {
|
||||
// drop on floor with warning
|
||||
message("Unable to parameterize flag \"%s\": %s", flag.to_string(), ierr.message);
|
||||
}
|
||||
}
|
||||
|
||||
return listp;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -98,7 +98,7 @@ public class Geary.Imap.InternalDate : Geary.MessageData.AbstractMessageData, Ge
|
|||
* Returns the {@link InternalDate} as a {@link Parameter}.
|
||||
*/
|
||||
public Parameter to_parameter() {
|
||||
return StringParameter.get_best_for(serialize());
|
||||
return Parameter.get_for_string(serialize());
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
@ -107,7 +107,7 @@ public class Geary.Imap.InternalDate : Geary.MessageData.AbstractMessageData, Ge
|
|||
* @see serialize_for_search
|
||||
*/
|
||||
public Parameter to_search_parameter() {
|
||||
return StringParameter.get_best_for(serialize_for_search());
|
||||
return Parameter.get_for_string(serialize());
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
|
|||
|
|
@ -18,7 +18,7 @@ public class Geary.Imap.MailboxParameter : StringParameter {
|
|||
}
|
||||
|
||||
public MailboxParameter.from_string_parameter(StringParameter string_parameter) {
|
||||
base (string_parameter.value);
|
||||
base (string_parameter.ascii);
|
||||
}
|
||||
|
||||
private static string utf8_to_imap_utf7(string utf8) {
|
||||
|
|
@ -40,7 +40,7 @@ public class Geary.Imap.MailboxParameter : StringParameter {
|
|||
}
|
||||
|
||||
public string decode() {
|
||||
return imap_utf7_to_utf8(value);
|
||||
return imap_utf7_to_utf8(ascii);
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
@ -54,7 +54,7 @@ public class Geary.Imap.MailboxParameter : StringParameter {
|
|||
* {@inheritDoc}
|
||||
*/
|
||||
public override string to_string() {
|
||||
return value;
|
||||
return ascii;
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -23,7 +23,7 @@ public class Geary.Imap.MessageFlags : Geary.Imap.Flags {
|
|||
public static MessageFlags from_list(ListParameter listp) throws ImapError {
|
||||
Gee.Collection<MessageFlag> list = new Gee.ArrayList<MessageFlag>();
|
||||
for (int ctr = 0; ctr < listp.size; ctr++)
|
||||
list.add(new MessageFlag(listp.get_as_string(ctr).value));
|
||||
list.add(new MessageFlag(listp.get_as_string(ctr).ascii));
|
||||
|
||||
return new MessageFlags(list);
|
||||
}
|
||||
|
|
|
|||
|
|
@ -45,8 +45,8 @@ public enum Geary.Imap.StatusDataType {
|
|||
}
|
||||
}
|
||||
|
||||
public static StatusDataType decode(string value) throws ImapError {
|
||||
switch (Ascii.strdown(value)) {
|
||||
public static StatusDataType from_parameter(StringParameter stringp) throws ImapError {
|
||||
switch (stringp.as_lower()) {
|
||||
case "messages":
|
||||
return MESSAGES;
|
||||
|
||||
|
|
@ -63,16 +63,12 @@ public enum Geary.Imap.StatusDataType {
|
|||
return UNSEEN;
|
||||
|
||||
default:
|
||||
throw new ImapError.PARSE_ERROR("Unknown status data type \"%s\"", value);
|
||||
throw new ImapError.PARSE_ERROR("Unknown status data type \"%s\"", stringp.to_string());
|
||||
}
|
||||
}
|
||||
|
||||
public StringParameter to_parameter() {
|
||||
return new AtomParameter(to_string());
|
||||
}
|
||||
|
||||
public static StatusDataType from_parameter(StringParameter stringp) throws ImapError {
|
||||
return decode(stringp.value);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -24,12 +24,12 @@ public class Geary.Imap.Tag : AtomParameter, Gee.Hashable<Geary.Imap.Tag> {
|
|||
private static Tag? unassigned = null;
|
||||
private static Tag? continuation = null;
|
||||
|
||||
public Tag(string value) {
|
||||
base (value);
|
||||
public Tag(string ascii) {
|
||||
base (ascii);
|
||||
}
|
||||
|
||||
public Tag.from_parameter(StringParameter strparam) {
|
||||
base (strparam.value);
|
||||
base (strparam.ascii);
|
||||
}
|
||||
|
||||
internal static void init() {
|
||||
|
|
@ -67,15 +67,15 @@ public class Geary.Imap.Tag : AtomParameter, Gee.Hashable<Geary.Imap.Tag> {
|
|||
if (stringp is QuotedStringParameter)
|
||||
return false;
|
||||
|
||||
if (String.is_empty(stringp.value))
|
||||
if (stringp.is_empty())
|
||||
return false;
|
||||
|
||||
if (stringp.value == UNTAGGED_VALUE || stringp.value == CONTINUATION_VALUE)
|
||||
if (stringp.equals_cs(UNTAGGED_VALUE) || stringp.equals_cs(CONTINUATION_VALUE))
|
||||
return true;
|
||||
|
||||
int index = 0;
|
||||
for (;;) {
|
||||
char ch = stringp.value[index++];
|
||||
char ch = stringp.ascii[index++];
|
||||
if (ch == String.EOS)
|
||||
break;
|
||||
|
||||
|
|
@ -87,26 +87,26 @@ public class Geary.Imap.Tag : AtomParameter, Gee.Hashable<Geary.Imap.Tag> {
|
|||
}
|
||||
|
||||
public bool is_tagged() {
|
||||
return (value != UNTAGGED_VALUE) && (value != CONTINUATION_VALUE) && (value != UNASSIGNED_VALUE);
|
||||
return !equals_cs(UNTAGGED_VALUE) && !equals_cs(CONTINUATION_VALUE) && !equals_cs(UNASSIGNED_VALUE);
|
||||
}
|
||||
|
||||
public bool is_continuation() {
|
||||
return value == CONTINUATION_VALUE;
|
||||
return equals_cs(CONTINUATION_VALUE);
|
||||
}
|
||||
|
||||
public bool is_assigned() {
|
||||
return (value != UNASSIGNED_VALUE) && (value != CONTINUATION_VALUE);
|
||||
return !equals_cs(UNASSIGNED_VALUE) && !equals_cs(CONTINUATION_VALUE);
|
||||
}
|
||||
|
||||
public uint hash() {
|
||||
return Ascii.str_hash(value);
|
||||
return Ascii.str_hash(ascii);
|
||||
}
|
||||
|
||||
public bool equal_to(Geary.Imap.Tag tag) {
|
||||
if (this == tag)
|
||||
return true;
|
||||
|
||||
return equals_cs(tag.value);
|
||||
return equals_cs(tag.ascii);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -26,7 +26,7 @@ public class Geary.Imap.AtomParameter : Geary.Imap.UnquotedStringParameter {
|
|||
* {@inheritDoc}
|
||||
*/
|
||||
public override void serialize(Serializer ser, Tag tag) throws Error {
|
||||
ser.push_unquoted_string(value);
|
||||
ser.push_unquoted_string(ascii);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -420,7 +420,7 @@ public class Geary.Imap.ListParameter : Geary.Imap.Parameter {
|
|||
|
||||
StringParameter? stringp = get_if_string(index);
|
||||
if (stringp != null)
|
||||
return new Memory.StringBuffer(stringp.value);
|
||||
return stringp.as_buffer();
|
||||
|
||||
return null;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -41,7 +41,7 @@ public class Geary.Imap.NilParameter : Geary.Imap.Parameter {
|
|||
* list.
|
||||
*/
|
||||
public static bool is_nil(StringParameter stringp) {
|
||||
return Ascii.stri_equal(VALUE, stringp.value);
|
||||
return stringp.equals_ci(VALUE);
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
|
|||
|
|
@ -41,12 +41,12 @@ public class Geary.Imap.NumberParameter : UnquotedStringParameter {
|
|||
* No checking is performed to verify that the string is only composed of numeric characters.
|
||||
* Use {@link is_numeric}.
|
||||
*/
|
||||
public NumberParameter.from_string(string str) {
|
||||
base (str);
|
||||
public NumberParameter.from_ascii(string ascii) {
|
||||
base (ascii);
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns true if the string is composed of numeric characters.
|
||||
* Returns true if the string is composed of numeric 7-bit characters.
|
||||
*
|
||||
* The only non-numeric character allowed is a dash ('-') at the beginning of the string to
|
||||
* indicate a negative value. However, note that almost every IMAP use of a number is for a
|
||||
|
|
|
|||
|
|
@ -13,6 +13,23 @@
|
|||
*/
|
||||
|
||||
public abstract class Geary.Imap.Parameter : BaseObject {
|
||||
/**
|
||||
* Returns an appropriate {@link Parameter} for the string.
|
||||
*
|
||||
* get_for_string() goes from simple to complexity in terms of parameter encoding. It uses
|
||||
* {@link StringParameter.get_best_for} first to attempt to produced an unquoted, then unquoted,
|
||||
* string. (It will also produce a {@link NumberParameter} if appropriate.) If the string
|
||||
* cannot be held in those forms, it returns a {@link LiteralParameter}, which is capable of
|
||||
* transmitting 8-bit data.
|
||||
*/
|
||||
public static Parameter get_for_string(string value) {
|
||||
try {
|
||||
return StringParameter.get_best_for(value);
|
||||
} catch (ImapError ierr) {
|
||||
return new LiteralParameter(new Memory.StringBuffer(value));
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Invoked when the {@link Parameter} is to be serialized out to the network.
|
||||
*
|
||||
|
|
|
|||
|
|
@ -16,22 +16,22 @@
|
|||
*/
|
||||
|
||||
public class Geary.Imap.QuotedStringParameter : Geary.Imap.StringParameter {
|
||||
public QuotedStringParameter(string value) {
|
||||
base (value);
|
||||
public QuotedStringParameter(string ascii) {
|
||||
base (ascii);
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritDoc}
|
||||
*/
|
||||
public override string to_string() {
|
||||
return "\"%s\"".printf(value);
|
||||
return "\"%s\"".printf(ascii);
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritDoc}
|
||||
*/
|
||||
public override void serialize(Serializer ser, Tag tag) throws Error {
|
||||
ser.push_quoted_string(value);
|
||||
ser.push_quoted_string(ascii);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -21,21 +21,21 @@
|
|||
|
||||
public abstract class Geary.Imap.StringParameter : Geary.Imap.Parameter {
|
||||
/**
|
||||
* The unquoted, decoded string.
|
||||
* The unquoted, decoded string as 7-bit ASCII.
|
||||
*/
|
||||
public string value { get; private set; }
|
||||
public string ascii { get; private set; }
|
||||
|
||||
/**
|
||||
* Returns {@link value} or null if value is empty (zero-length).
|
||||
*/
|
||||
public string? nullable_value {
|
||||
public string? nullable_ascii {
|
||||
get {
|
||||
return String.is_empty(value) ? null : value;
|
||||
return String.is_empty(ascii) ? null : ascii;
|
||||
}
|
||||
}
|
||||
|
||||
protected StringParameter(string value) {
|
||||
this.value = value;
|
||||
protected StringParameter(string ascii) {
|
||||
this.ascii = ascii;
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
@ -48,11 +48,12 @@ public abstract class Geary.Imap.StringParameter : Geary.Imap.Parameter {
|
|||
* 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}.
|
||||
* @throws ImapError.NOT_SUPPORTED if the string must be represented as a {@link LiteralParameter}.
|
||||
* @see Parameter.get_for_string
|
||||
*/
|
||||
public static StringParameter? get_best_for(string value) {
|
||||
public static StringParameter get_best_for(string value) throws ImapError {
|
||||
if (NumberParameter.is_numeric(value, null))
|
||||
return new NumberParameter.from_string(value);
|
||||
return new NumberParameter.from_ascii(value);
|
||||
|
||||
switch (DataFormat.is_quoting_required(value)) {
|
||||
case DataFormat.Quoting.REQUIRED:
|
||||
|
|
@ -62,26 +63,54 @@ public abstract class Geary.Imap.StringParameter : Geary.Imap.Parameter {
|
|||
return new UnquotedStringParameter(value);
|
||||
|
||||
case DataFormat.Quoting.UNALLOWED:
|
||||
return null;
|
||||
throw new ImapError.NOT_SUPPORTED("String must be a literal parameter");
|
||||
|
||||
default:
|
||||
assert_not_reached();
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Like {@link get_best_for} but the library will panic if the value cannot be turned into
|
||||
* a {@link StringParameter}.
|
||||
*
|
||||
* This should ''only'' be used with string constants that are guaranteed 7-bit ASCII.
|
||||
*/
|
||||
public static StringParameter get_best_for_unchecked(string value) {
|
||||
try {
|
||||
return get_best_for(value);
|
||||
} catch (ImapError ierr) {
|
||||
error("Unable to create StringParameter for \"%s\": %s", value, ierr.message);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Like {@link get_best_for} but returns null if the value cannot be stored as a
|
||||
* {@link StringParameter}.
|
||||
*
|
||||
* @see Parameter.get_for_string
|
||||
*/
|
||||
public static StringParameter? try_get_best_for(string value) {
|
||||
try {
|
||||
return get_best_for(value);
|
||||
} catch (ImapError ierr) {
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 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)) {
|
||||
switch (DataFormat.is_quoting_required(ascii)) {
|
||||
case DataFormat.Quoting.REQUIRED:
|
||||
ser.push_quoted_string(value);
|
||||
ser.push_quoted_string(ascii);
|
||||
break;
|
||||
|
||||
case DataFormat.Quoting.OPTIONAL:
|
||||
ser.push_unquoted_string(value);
|
||||
ser.push_unquoted_string(ascii);
|
||||
break;
|
||||
|
||||
case DataFormat.Quoting.UNALLOWED:
|
||||
|
|
@ -92,32 +121,46 @@ public abstract class Geary.Imap.StringParameter : Geary.Imap.Parameter {
|
|||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the string as a {@link Memory.Buffer}.
|
||||
*/
|
||||
public Memory.Buffer as_buffer() {
|
||||
return new Memory.StringBuffer(ascii);
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns true if the string is empty (zero-length).
|
||||
*/
|
||||
public bool is_empty() {
|
||||
return String.is_empty(ascii);
|
||||
}
|
||||
|
||||
/**
|
||||
* Case-sensitive comparison.
|
||||
*/
|
||||
public bool equals_cs(string value) {
|
||||
return Ascii.str_equal(this.value, value);
|
||||
return Ascii.str_equal(ascii, value);
|
||||
}
|
||||
|
||||
/**
|
||||
* Case-insensitive comparison.
|
||||
*/
|
||||
public bool equals_ci(string value) {
|
||||
return Ascii.stri_equal(this.value, value);
|
||||
return Ascii.stri_equal(ascii, value);
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the string lowercased.
|
||||
*/
|
||||
public string as_lower() {
|
||||
return Ascii.strdown(value);
|
||||
return Ascii.strdown(ascii);
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the string uppercased.
|
||||
*/
|
||||
public string as_upper() {
|
||||
return Ascii.strup(value);
|
||||
return Ascii.strup(ascii);
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
@ -127,7 +170,7 @@ public abstract class Geary.Imap.StringParameter : Geary.Imap.Parameter {
|
|||
*. 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);
|
||||
return int.parse(ascii).clamp(clamp_min, clamp_max);
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
@ -137,7 +180,7 @@ public abstract class Geary.Imap.StringParameter : Geary.Imap.Parameter {
|
|||
*. 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);
|
||||
return long.parse(ascii).clamp(clamp_min, clamp_max);
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
@ -147,7 +190,7 @@ public abstract class Geary.Imap.StringParameter : Geary.Imap.Parameter {
|
|||
*. 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);
|
||||
return int64.parse(ascii).clamp(clamp_min, clamp_max);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -18,22 +18,22 @@
|
|||
*/
|
||||
|
||||
public class Geary.Imap.UnquotedStringParameter : Geary.Imap.StringParameter {
|
||||
public UnquotedStringParameter(string value) {
|
||||
base (value);
|
||||
public UnquotedStringParameter(string ascii) {
|
||||
base (ascii);
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritDoc}
|
||||
*/
|
||||
public override void serialize(Serializer ser, Tag tag) throws Error {
|
||||
ser.push_unquoted_string(value);
|
||||
ser.push_unquoted_string(ascii);
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritDoc}
|
||||
*/
|
||||
public override string to_string() {
|
||||
return value;
|
||||
return ascii;
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -30,7 +30,7 @@ public class Geary.Imap.Capabilities : Geary.GenericCapabilities {
|
|||
}
|
||||
|
||||
public bool add_parameter(StringParameter stringp) {
|
||||
return parse_and_add_capability(stringp.value);
|
||||
return parse_and_add_capability(stringp.ascii);
|
||||
}
|
||||
|
||||
public override string to_string() {
|
||||
|
|
|
|||
|
|
@ -97,7 +97,7 @@ public class Geary.Imap.MessageFlagsDecoder : Geary.Imap.FetchDataDecoder {
|
|||
protected override MessageData decode_list(ListParameter listp) throws ImapError {
|
||||
Gee.List<Flag> flags = new Gee.ArrayList<Flag>();
|
||||
for (int ctr = 0; ctr < listp.size; ctr++)
|
||||
flags.add(new MessageFlag(listp.get_as_string(ctr).value));
|
||||
flags.add(new MessageFlag(listp.get_as_string(ctr).ascii));
|
||||
|
||||
return new MessageFlags(flags);
|
||||
}
|
||||
|
|
@ -109,7 +109,7 @@ public class Geary.Imap.InternalDateDecoder : Geary.Imap.FetchDataDecoder {
|
|||
}
|
||||
|
||||
protected override MessageData decode_string(StringParameter stringp) throws ImapError {
|
||||
return InternalDate.decode(stringp.value);
|
||||
return InternalDate.decode(stringp.ascii);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -142,17 +142,17 @@ public class Geary.Imap.EnvelopeDecoder : Geary.Imap.FetchDataDecoder {
|
|||
|
||||
// Although Message-ID is required to be returned by IMAP, it may be blank if the email
|
||||
// does not supply it (optional according to RFC822); deal with this cognitive dissonance
|
||||
if (message_id != null && String.is_empty(message_id.value))
|
||||
if (message_id != null && message_id.is_empty())
|
||||
message_id = null;
|
||||
|
||||
return new Envelope((sent != null) ? new Geary.RFC822.Date(sent.value) : null,
|
||||
new Geary.RFC822.Subject.decode(subject.value),
|
||||
return new Envelope((sent != null) ? new Geary.RFC822.Date(sent.ascii) : null,
|
||||
new Geary.RFC822.Subject.decode(subject.ascii),
|
||||
parse_addresses(from), parse_addresses(sender), parse_addresses(reply_to),
|
||||
(to != null) ? parse_addresses(to) : null,
|
||||
(cc != null) ? parse_addresses(cc) : null,
|
||||
(bcc != null) ? parse_addresses(bcc) : null,
|
||||
(in_reply_to != null) ? new Geary.RFC822.MessageIDList.from_rfc822_string(in_reply_to.value) : null,
|
||||
(message_id != null) ? new Geary.RFC822.MessageID(message_id.value) : null);
|
||||
(in_reply_to != null) ? new Geary.RFC822.MessageIDList.from_rfc822_string(in_reply_to.ascii) : null,
|
||||
(message_id != null) ? new Geary.RFC822.MessageID(message_id.ascii) : null);
|
||||
}
|
||||
|
||||
// TODO: This doesn't handle group lists (see Johnson, p.268) -- this will throw an
|
||||
|
|
@ -167,10 +167,10 @@ public class Geary.Imap.EnvelopeDecoder : Geary.Imap.FetchDataDecoder {
|
|||
StringParameter domain = fields.get_as_empty_string(3);
|
||||
|
||||
Geary.RFC822.MailboxAddress addr = new Geary.RFC822.MailboxAddress.imap(
|
||||
(name != null) ? name.nullable_value : null,
|
||||
(source_route != null) ? source_route.nullable_value : null,
|
||||
mailbox.value,
|
||||
domain.value);
|
||||
(name != null) ? name.nullable_ascii : null,
|
||||
(source_route != null) ? source_route.nullable_ascii : null,
|
||||
mailbox.ascii,
|
||||
domain.ascii);
|
||||
list.add(addr);
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -71,7 +71,7 @@ public class Geary.Imap.FetchedData : Object {
|
|||
else
|
||||
fetched_data.body_data_map.set(specifier, Memory.EmptyBuffer.instance);
|
||||
} else {
|
||||
FetchDataSpecifier data_item = FetchDataSpecifier.decode(data_item_param.value);
|
||||
FetchDataSpecifier data_item = FetchDataSpecifier.from_parameter(data_item_param);
|
||||
FetchDataDecoder? decoder = data_item.get_decoder();
|
||||
if (decoder == null) {
|
||||
debug("Unable to decode fetch response for \"%s\": No decoder available",
|
||||
|
|
|
|||
|
|
@ -33,7 +33,7 @@ public class Geary.Imap.MailboxAttributes : Geary.Imap.Flags {
|
|||
public static MailboxAttributes from_list(ListParameter listp) throws ImapError {
|
||||
Gee.Collection<MailboxAttribute> list = new Gee.ArrayList<MailboxAttribute>();
|
||||
for (int ctr = 0; ctr < listp.size; ctr++)
|
||||
list.add(new MailboxAttribute(listp.get_as_string(ctr).value));
|
||||
list.add(new MailboxAttribute(listp.get_as_string(ctr).ascii));
|
||||
|
||||
return new MailboxAttributes(list);
|
||||
}
|
||||
|
|
|
|||
|
|
@ -65,7 +65,7 @@ public class Geary.Imap.MailboxInformation : Object {
|
|||
continue;
|
||||
}
|
||||
|
||||
attrlist.add(new MailboxAttribute(stringp.value));
|
||||
attrlist.add(new MailboxAttribute(stringp.ascii));
|
||||
}
|
||||
|
||||
// decode everything
|
||||
|
|
@ -77,10 +77,10 @@ public class Geary.Imap.MailboxInformation : Object {
|
|||
// Set \Inbox to standard path
|
||||
if (canonical_inbox && Geary.Imap.MailboxAttribute.SPECIAL_FOLDER_INBOX in attributes) {
|
||||
return new MailboxInformation(MailboxSpecifier.inbox,
|
||||
(delim != null) ? delim.nullable_value : null, attributes);
|
||||
(delim != null) ? delim.nullable_ascii : null, attributes);
|
||||
} else {
|
||||
return new MailboxInformation(new MailboxSpecifier.from_parameter(mailbox),
|
||||
(delim != null) ? delim.nullable_value : null, attributes);
|
||||
(delim != null) ? delim.nullable_ascii : null, attributes);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -61,17 +61,17 @@ public class Geary.Imap.ResponseCodeType : BaseObject, Gee.Hashable<ResponseCode
|
|||
* an {link ResponseCodeType}.
|
||||
*/
|
||||
public ResponseCodeType.from_parameter(StringParameter stringp) throws ImapError {
|
||||
init(stringp.value);
|
||||
init(stringp.ascii);
|
||||
}
|
||||
|
||||
private void init(string str) throws ImapError {
|
||||
private void init(string ascii) throws ImapError {
|
||||
// note that is_quoting_required() also catches empty strings (as they require quoting)
|
||||
if (DataFormat.is_quoting_required(str) != DataFormat.Quoting.OPTIONAL)
|
||||
throw new ImapError.INVALID("\"%s\" cannot be represented as a ResponseCodeType", str);
|
||||
if (DataFormat.is_quoting_required(ascii) != DataFormat.Quoting.OPTIONAL)
|
||||
throw new ImapError.INVALID("\"%s\" cannot be represented as a ResponseCodeType", ascii);
|
||||
|
||||
// store lowercased so it's easily compared with const strings above
|
||||
original = str;
|
||||
value = Ascii.strdown(str);
|
||||
original = ascii;
|
||||
value = Ascii.strdown(ascii);
|
||||
}
|
||||
|
||||
public bool is_value(string str) {
|
||||
|
|
|
|||
|
|
@ -63,8 +63,13 @@ public enum Geary.Imap.ServerDataType {
|
|||
}
|
||||
}
|
||||
|
||||
public static ServerDataType decode(string value) throws ImapError {
|
||||
switch (Ascii.strdown(value)) {
|
||||
/**
|
||||
* Convert a {@link StringParameter} into a ServerDataType.
|
||||
*
|
||||
* @throws ImapError.PARSE_ERROR if the StringParameter is not recognized as a ServerDataType.
|
||||
*/
|
||||
public static ServerDataType from_parameter(StringParameter param) throws ImapError {
|
||||
switch (param.as_lower()) {
|
||||
case "capability":
|
||||
return CAPABILITY;
|
||||
|
||||
|
|
@ -100,7 +105,7 @@ public enum Geary.Imap.ServerDataType {
|
|||
return XLIST;
|
||||
|
||||
default:
|
||||
throw new ImapError.PARSE_ERROR("\"%s\" is not a valid server data type", value);
|
||||
throw new ImapError.PARSE_ERROR("\"%s\" is not a valid server data type", param.to_string());
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -108,15 +113,6 @@ public enum Geary.Imap.ServerDataType {
|
|||
return new AtomParameter(to_string());
|
||||
}
|
||||
|
||||
/**
|
||||
* Convert a {@link StringParameter} into a ServerDataType.
|
||||
*
|
||||
* @throws ImapError.PARSE_ERROR if the StringParameter is not recognized as a ServerDataType.
|
||||
*/
|
||||
public static ServerDataType from_parameter(StringParameter param) throws ImapError {
|
||||
return decode(param.value);
|
||||
}
|
||||
|
||||
/**
|
||||
* Examines the {@link RootParameters} looking for a ServerDataType.
|
||||
*
|
||||
|
|
|
|||
|
|
@ -115,7 +115,7 @@ public class Geary.Imap.StatusData : Object {
|
|||
break;
|
||||
|
||||
default:
|
||||
message("Bad STATUS data type %s", typep.value);
|
||||
message("Bad STATUS data type %s", typep.to_string());
|
||||
break;
|
||||
}
|
||||
} catch (ImapError ierr) {
|
||||
|
|
|
|||
|
|
@ -88,7 +88,7 @@ public class Geary.Imap.StatusResponse : ServerResponse {
|
|||
for (int index = 2; index < size; index++) {
|
||||
StringParameter? strparam = get_if_string(index);
|
||||
if (strparam != null) {
|
||||
builder.append(strparam.value);
|
||||
builder.append(strparam.ascii);
|
||||
if (index < (size - 1))
|
||||
builder.append_c(' ');
|
||||
}
|
||||
|
|
|
|||
|
|
@ -39,8 +39,8 @@ public enum Geary.Imap.Status {
|
|||
}
|
||||
}
|
||||
|
||||
public static Status decode(string value) throws ImapError {
|
||||
switch (Ascii.strdown(value)) {
|
||||
public static Status from_parameter(StringParameter strparam) throws ImapError {
|
||||
switch (strparam.as_lower()) {
|
||||
case "ok":
|
||||
return OK;
|
||||
|
||||
|
|
@ -57,14 +57,10 @@ public enum Geary.Imap.Status {
|
|||
return BYE;
|
||||
|
||||
default:
|
||||
throw new ImapError.PARSE_ERROR("Unrecognized status response \"%s\"", value);
|
||||
throw new ImapError.PARSE_ERROR("Unrecognized status response \"%s\"", strparam.to_string());
|
||||
}
|
||||
}
|
||||
|
||||
public static Status from_parameter(StringParameter strparam) throws ImapError {
|
||||
return decode(strparam.value);
|
||||
}
|
||||
|
||||
public Parameter to_parameter() {
|
||||
return new AtomParameter(to_string());
|
||||
}
|
||||
|
|
|
|||
|
|
@ -94,6 +94,9 @@ public class Geary.Imap.Deserializer : BaseObject {
|
|||
* {@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.
|
||||
*
|
||||
* All strings are ASCII (7-bit) with control characters stripped (with the exception of
|
||||
* {@link QuotedStringParameter} which allows for some control characters).
|
||||
*/
|
||||
public signal void parameters_ready(RootParameters root);
|
||||
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue