Loading k9mail-library/src/main/java/com/fsck/k9/mail/Flag.java +32 −15 Original line number Diff line number Diff line Loading @@ -5,13 +5,13 @@ package com.fsck.k9.mail; * Flags that can be applied to Messages. */ public enum Flag { DELETED, SEEN, ANSWERED, FLAGGED, DRAFT, RECENT, FORWARDED, DELETED("DELETED", "UNDELETED"), SEEN("SEEN", "UNSEEN"), ANSWERED("ANSWERED", "UNANSWERED"), FLAGGED("FLAGGED", "UNFLAGGED"), DRAFT("DRAFT", "UNDRAFT"), RECENT("RECENT", "UNRECENT"), FORWARDED(null, null), /* * The following flags are for internal library use only. Loading @@ -19,35 +19,35 @@ public enum Flag { /** * Delete and remove from the LocalStore immediately. */ X_DESTROYED, X_DESTROYED(null, null), /** * Sending of an unsent message failed. It will be retried. Used to show status. */ X_SEND_FAILED, X_SEND_FAILED(null, null), /** * Sending of an unsent message is in progress. */ X_SEND_IN_PROGRESS, X_SEND_IN_PROGRESS(null, null), /** * Indicates that a message is fully downloaded from the server and can be viewed normally. * This does not include attachments, which are never downloaded fully. */ X_DOWNLOADED_FULL, X_DOWNLOADED_FULL(null, null), /** * Indicates that a message is partially downloaded from the server and can be viewed but * more content is available on the server. * This does not include attachments, which are never downloaded fully. */ X_DOWNLOADED_PARTIAL, X_DOWNLOADED_PARTIAL(null, null), /** * Indicates that the copy of a message to the Sent folder has started. */ X_REMOTE_COPY_STARTED, X_REMOTE_COPY_STARTED(null, null), /** * Messages with this flag have been migrated from database version 50 or earlier. Loading @@ -56,10 +56,27 @@ public enum Flag { * incomplete or broken. * TODO Messages with this flag should be redownloaded, if possible. */ X_MIGRATED_FROM_V50, X_MIGRATED_FROM_V50(null, null), /** * This flag is used for drafts where the message should be sent as PGP/INLINE. */ X_DRAFT_OPENPGP_INLINE, X_DRAFT_OPENPGP_INLINE(null, null); private String requiredImapString; private String forbiddenImapString; Flag(String requiredImapString, String forbiddenImapString) { this.requiredImapString = requiredImapString; this.forbiddenImapString = forbiddenImapString; } public String getRequiredImapString() { return requiredImapString; } public String getForbiddenImapString() { return forbiddenImapString; } } k9mail-library/src/main/java/com/fsck/k9/mail/store/imap/ImapConnection.java +3 −3 Original line number Diff line number Diff line Loading @@ -257,7 +257,7 @@ public class ImapConnection { } private List<ImapResponse> extractCapabilities(List<ImapResponse> responses) { CapabilityResponse capabilityResponse = CapabilityResponse.parse(responses); CapabilityResponse capabilityResponse = CapabilityResponse.parse(commandFactory, responses); if (capabilityResponse != null) { Set<String> receivedCapabilities = capabilityResponse.getCapabilities(); if (K9MailLib.isDebug()) { Loading @@ -270,7 +270,7 @@ public class ImapConnection { private List<ImapResponse> extractOrRequestCapabilities(List<ImapResponse> responses) throws IOException, MessagingException { CapabilityResponse capabilityResponse = CapabilityResponse.parse(responses); CapabilityResponse capabilityResponse = CapabilityResponse.parse(commandFactory, responses); if (capabilityResponse != null) { Set<String> receivedCapabilities = capabilityResponse.getCapabilities(); Timber.d("Saving %s capabilities for %s", receivedCapabilities, getLogId()); Loading @@ -295,7 +295,7 @@ public class ImapConnection { private void requestCapabilities() throws IOException, MessagingException { CapabilityCommand command = commandFactory.createCapabilityCommand(); List<ImapResponse> responses = extractCapabilities(command.execute()); List<ImapResponse> responses = extractCapabilities(command.executeInternal()); if (responses.size() != 2) { throw new MessagingException("Invalid CAPABILITY response received"); } Loading k9mail-library/src/main/java/com/fsck/k9/mail/store/imap/ImapFolder.java +59 −89 Original line number Diff line number Diff line Loading @@ -439,50 +439,46 @@ public class ImapFolder extends Folder<ImapMessage> { return messageCount; } private int getRemoteMessageCount(String criteria) throws MessagingException { private int getRemoteMessageCount(Set<Flag> requiredFlags, Set<Flag> forbiddenFlags) throws MessagingException { checkOpen(); try { int count = 0; int start = 1; UidSearchCommand searchCommand = commandFactory.createUidSearchCommandBuilder(this, null) .allIds(true) .requiredFlags(requiredFlags) .forbiddenFlags(forbiddenFlags) .build(); String command = String.format(Locale.US, "SEARCH %d:* %s", start, criteria); List<ImapResponse> responses = executeSimpleCommand(command); SearchResponse searchResponse = searchCommand.execute(); return searchResponse.getNumbers().size(); for (ImapResponse response : responses) { if (ImapResponseParser.equalsIgnoreCase(response.get(0), "SEARCH")) { count += response.size() - 1; } } return count; } catch (IOException ioe) { throw ioExceptionHandler(connection, ioe); } } @Override public int getUnreadMessageCount() throws MessagingException { return getRemoteMessageCount("UNSEEN NOT DELETED"); Set<Flag> forbiddenFlags = new HashSet<>(2); Collections.addAll(forbiddenFlags, Flag.SEEN, Flag.DELETED); return getRemoteMessageCount(null, forbiddenFlags); } @Override public int getFlaggedMessageCount() throws MessagingException { return getRemoteMessageCount("FLAGGED NOT DELETED"); Set<Flag> requiredFlags = Collections.singleton(Flag.FLAGGED); Set<Flag> forbiddenFlags = Collections.singleton(Flag.DELETED); return getRemoteMessageCount(requiredFlags, forbiddenFlags); } protected long getHighestUid() throws MessagingException { try { String command = "UID SEARCH *:*"; List<ImapResponse> responses = executeSimpleCommand(command); SearchResponse searchResponse = SearchResponse.parse(commandFactory, responses); UidSearchCommand searchCommand = commandFactory.createUidSearchCommandBuilder(this, null) .onlyHighestId(true) .build(); SearchResponse searchResponse = searchCommand.execute(); return extractHighestUid(searchResponse); } catch (NegativeImapResponseException e) { return -1L; } catch (IOException ioe) { throw ioExceptionHandler(connection, ioe); } } Loading Loading @@ -525,29 +521,16 @@ public class ImapFolder extends Folder<ImapMessage> { throw new MessagingException(String.format(Locale.US, "Invalid message set %d %d", start, end)); } Set<Flag> forbiddenFlags = null; if (!includeDeleted) { forbiddenFlags = new HashSet<>(); forbiddenFlags.add(Flag.DELETED); } UidSearchCommand searchCommand = commandFactory.createUidSearchCommandBuilder(this, listener) .addSequenceRange(String.valueOf(start), String.valueOf(end)) .useUids(false) .addIdRange((long) start, (long) end) .since(earliestDate) .forbiddenFlags(forbiddenFlags) .forbiddenFlags(includeDeleted ? null : Collections.singleton(Flag.DELETED)) .build(); return getMessages(searchCommand.execute(), listener); } private String getDateSearchString(Date earliestDate) { if (earliestDate == null) { return ""; } return " SINCE " + RFC3501_DATE.get().format(earliestDate); } @Override public boolean areMoreMessagesAvailable(int indexOfOldestMessage, Date earliestDate) throws IOException, MessagingException { Loading @@ -558,13 +541,12 @@ public class ImapFolder extends Folder<ImapMessage> { return false; } String dateSearchString = getDateSearchString(earliestDate); int endIndex = indexOfOldestMessage - 1; while (endIndex > 0) { int startIndex = Math.max(0, endIndex - MORE_MESSAGES_WINDOW_SIZE) + 1; if (existsNonDeletedMessageInRange(startIndex, endIndex, dateSearchString)) { if (existsNonDeletedMessageInRange(startIndex, endIndex, earliestDate)) { return true; } Loading @@ -574,35 +556,27 @@ public class ImapFolder extends Folder<ImapMessage> { return false; } private boolean existsNonDeletedMessageInRange(int startIndex, int endIndex, String dateSearchString) private boolean existsNonDeletedMessageInRange(int startIndex, int endIndex, Date earliestDate) throws MessagingException, IOException { String command = String.format(Locale.US, "SEARCH %d:%d%s NOT DELETED", startIndex, endIndex, dateSearchString); List<ImapResponse> responses = executeSimpleCommand(command); for (ImapResponse response : responses) { if (response.getTag() == null && ImapResponseParser.equalsIgnoreCase(response.get(0), "SEARCH")) { if (response.size() > 1) { return true; } } } UidSearchCommand searchCommand = commandFactory.createUidSearchCommandBuilder(this, null) .useUids(false) .addIdRange((long) startIndex, (long) endIndex) .since(earliestDate) .forbiddenFlags(Collections.singleton(Flag.DELETED)) .build(); return false; SearchResponse response = searchCommand.execute(); return response.getNumbers().size() > 0; } protected List<ImapMessage> getMessages(final List<Long> mesgSeqs, final boolean includeDeleted, final MessageRetrievalListener<ImapMessage> listener) throws MessagingException { Set<Flag> forbiddenFlags = null; if (!includeDeleted) { forbiddenFlags = new HashSet<>(); forbiddenFlags.add(Flag.DELETED); } UidSearchCommand searchCommand = commandFactory.createUidSearchCommandBuilder(this, listener) .sequenceSet(mesgSeqs) .forbiddenFlags(forbiddenFlags) .useUids(false) .idSet(mesgSeqs) .forbiddenFlags(includeDeleted ? null : Collections.singleton(Flag.DELETED)) .build(); return getMessages(searchCommand.execute(), listener); Loading @@ -617,7 +591,8 @@ public class ImapFolder extends Folder<ImapMessage> { } UidSearchCommand searchCommand = commandFactory.createUidSearchCommandBuilder(this, null) .uidSet(uidSet) .useUids(true) .idSet(uidSet) .build(); return getMessages(searchCommand.execute(), null); Loading @@ -626,7 +601,7 @@ public class ImapFolder extends Folder<ImapMessage> { private List<ImapMessage> getMessages(SearchResponse searchResponse, MessageRetrievalListener<ImapMessage> listener) throws MessagingException { handleUntaggedResponses(searchResponse); checkOpen(); List<ImapMessage> messages = new ArrayList<>(); Loading Loading @@ -1250,7 +1225,6 @@ public class ImapFolder extends Folder<ImapMessage> { @Override public String getUidFromMessageId(Message message) throws MessagingException { try { /* * Try to find the UID of the message we just appended using the * Message-ID header. Loading @@ -1269,20 +1243,16 @@ public class ImapFolder extends Folder<ImapMessage> { Timber.d("Looking for UID for message with message-id %s for %s", messageId, getLogId()); } String command = String.format("UID SEARCH HEADER MESSAGE-ID %s", ImapUtility.encodeString(messageId)); List<ImapResponse> responses = executeSimpleCommand(command); UidSearchCommand searchCommand = commandFactory.createUidSearchCommandBuilder(this, null) .messageId(messageId) .build(); for (ImapResponse response : responses) { if (response.getTag() == null && ImapResponseParser.equalsIgnoreCase(response.get(0), "SEARCH") && response.size() > 1) { return response.getString(1); } List<Long> uids = searchCommand.execute().getNumbers(); if (uids.size() > 0) { return Long.toString(uids.get(0)); } return null; } catch (IOException ioe) { throw new MessagingException("Could not find UID for message based on Message-ID", ioe); } } @Override Loading k9mail-library/src/main/java/com/fsck/k9/mail/store/imap/ImapMessage.java +2 −2 Original line number Diff line number Diff line package com.fsck.k9.mail.store.imap; import java.util.Collections; import com.fsck.k9.mail.Flag; import com.fsck.k9.mail.Folder; import com.fsck.k9.mail.MessagingException; import com.fsck.k9.mail.internet.MimeMessage; import java.util.Collections; public class ImapMessage extends MimeMessage { public ImapMessage(String uid, Folder folder) { Loading k9mail-library/src/main/java/com/fsck/k9/mail/store/imap/ImapUtility.java +1 −0 Original line number Diff line number Diff line Loading @@ -144,6 +144,7 @@ public class ImapUtility { * * @return The string encoded as quoted (IMAP) string. */ //TODO use a literal string public static String encodeString(String str) { return "\"" + str.replace("\\", "\\\\").replace("\"", "\\\"") + "\""; } Loading Loading
k9mail-library/src/main/java/com/fsck/k9/mail/Flag.java +32 −15 Original line number Diff line number Diff line Loading @@ -5,13 +5,13 @@ package com.fsck.k9.mail; * Flags that can be applied to Messages. */ public enum Flag { DELETED, SEEN, ANSWERED, FLAGGED, DRAFT, RECENT, FORWARDED, DELETED("DELETED", "UNDELETED"), SEEN("SEEN", "UNSEEN"), ANSWERED("ANSWERED", "UNANSWERED"), FLAGGED("FLAGGED", "UNFLAGGED"), DRAFT("DRAFT", "UNDRAFT"), RECENT("RECENT", "UNRECENT"), FORWARDED(null, null), /* * The following flags are for internal library use only. Loading @@ -19,35 +19,35 @@ public enum Flag { /** * Delete and remove from the LocalStore immediately. */ X_DESTROYED, X_DESTROYED(null, null), /** * Sending of an unsent message failed. It will be retried. Used to show status. */ X_SEND_FAILED, X_SEND_FAILED(null, null), /** * Sending of an unsent message is in progress. */ X_SEND_IN_PROGRESS, X_SEND_IN_PROGRESS(null, null), /** * Indicates that a message is fully downloaded from the server and can be viewed normally. * This does not include attachments, which are never downloaded fully. */ X_DOWNLOADED_FULL, X_DOWNLOADED_FULL(null, null), /** * Indicates that a message is partially downloaded from the server and can be viewed but * more content is available on the server. * This does not include attachments, which are never downloaded fully. */ X_DOWNLOADED_PARTIAL, X_DOWNLOADED_PARTIAL(null, null), /** * Indicates that the copy of a message to the Sent folder has started. */ X_REMOTE_COPY_STARTED, X_REMOTE_COPY_STARTED(null, null), /** * Messages with this flag have been migrated from database version 50 or earlier. Loading @@ -56,10 +56,27 @@ public enum Flag { * incomplete or broken. * TODO Messages with this flag should be redownloaded, if possible. */ X_MIGRATED_FROM_V50, X_MIGRATED_FROM_V50(null, null), /** * This flag is used for drafts where the message should be sent as PGP/INLINE. */ X_DRAFT_OPENPGP_INLINE, X_DRAFT_OPENPGP_INLINE(null, null); private String requiredImapString; private String forbiddenImapString; Flag(String requiredImapString, String forbiddenImapString) { this.requiredImapString = requiredImapString; this.forbiddenImapString = forbiddenImapString; } public String getRequiredImapString() { return requiredImapString; } public String getForbiddenImapString() { return forbiddenImapString; } }
k9mail-library/src/main/java/com/fsck/k9/mail/store/imap/ImapConnection.java +3 −3 Original line number Diff line number Diff line Loading @@ -257,7 +257,7 @@ public class ImapConnection { } private List<ImapResponse> extractCapabilities(List<ImapResponse> responses) { CapabilityResponse capabilityResponse = CapabilityResponse.parse(responses); CapabilityResponse capabilityResponse = CapabilityResponse.parse(commandFactory, responses); if (capabilityResponse != null) { Set<String> receivedCapabilities = capabilityResponse.getCapabilities(); if (K9MailLib.isDebug()) { Loading @@ -270,7 +270,7 @@ public class ImapConnection { private List<ImapResponse> extractOrRequestCapabilities(List<ImapResponse> responses) throws IOException, MessagingException { CapabilityResponse capabilityResponse = CapabilityResponse.parse(responses); CapabilityResponse capabilityResponse = CapabilityResponse.parse(commandFactory, responses); if (capabilityResponse != null) { Set<String> receivedCapabilities = capabilityResponse.getCapabilities(); Timber.d("Saving %s capabilities for %s", receivedCapabilities, getLogId()); Loading @@ -295,7 +295,7 @@ public class ImapConnection { private void requestCapabilities() throws IOException, MessagingException { CapabilityCommand command = commandFactory.createCapabilityCommand(); List<ImapResponse> responses = extractCapabilities(command.execute()); List<ImapResponse> responses = extractCapabilities(command.executeInternal()); if (responses.size() != 2) { throw new MessagingException("Invalid CAPABILITY response received"); } Loading
k9mail-library/src/main/java/com/fsck/k9/mail/store/imap/ImapFolder.java +59 −89 Original line number Diff line number Diff line Loading @@ -439,50 +439,46 @@ public class ImapFolder extends Folder<ImapMessage> { return messageCount; } private int getRemoteMessageCount(String criteria) throws MessagingException { private int getRemoteMessageCount(Set<Flag> requiredFlags, Set<Flag> forbiddenFlags) throws MessagingException { checkOpen(); try { int count = 0; int start = 1; UidSearchCommand searchCommand = commandFactory.createUidSearchCommandBuilder(this, null) .allIds(true) .requiredFlags(requiredFlags) .forbiddenFlags(forbiddenFlags) .build(); String command = String.format(Locale.US, "SEARCH %d:* %s", start, criteria); List<ImapResponse> responses = executeSimpleCommand(command); SearchResponse searchResponse = searchCommand.execute(); return searchResponse.getNumbers().size(); for (ImapResponse response : responses) { if (ImapResponseParser.equalsIgnoreCase(response.get(0), "SEARCH")) { count += response.size() - 1; } } return count; } catch (IOException ioe) { throw ioExceptionHandler(connection, ioe); } } @Override public int getUnreadMessageCount() throws MessagingException { return getRemoteMessageCount("UNSEEN NOT DELETED"); Set<Flag> forbiddenFlags = new HashSet<>(2); Collections.addAll(forbiddenFlags, Flag.SEEN, Flag.DELETED); return getRemoteMessageCount(null, forbiddenFlags); } @Override public int getFlaggedMessageCount() throws MessagingException { return getRemoteMessageCount("FLAGGED NOT DELETED"); Set<Flag> requiredFlags = Collections.singleton(Flag.FLAGGED); Set<Flag> forbiddenFlags = Collections.singleton(Flag.DELETED); return getRemoteMessageCount(requiredFlags, forbiddenFlags); } protected long getHighestUid() throws MessagingException { try { String command = "UID SEARCH *:*"; List<ImapResponse> responses = executeSimpleCommand(command); SearchResponse searchResponse = SearchResponse.parse(commandFactory, responses); UidSearchCommand searchCommand = commandFactory.createUidSearchCommandBuilder(this, null) .onlyHighestId(true) .build(); SearchResponse searchResponse = searchCommand.execute(); return extractHighestUid(searchResponse); } catch (NegativeImapResponseException e) { return -1L; } catch (IOException ioe) { throw ioExceptionHandler(connection, ioe); } } Loading Loading @@ -525,29 +521,16 @@ public class ImapFolder extends Folder<ImapMessage> { throw new MessagingException(String.format(Locale.US, "Invalid message set %d %d", start, end)); } Set<Flag> forbiddenFlags = null; if (!includeDeleted) { forbiddenFlags = new HashSet<>(); forbiddenFlags.add(Flag.DELETED); } UidSearchCommand searchCommand = commandFactory.createUidSearchCommandBuilder(this, listener) .addSequenceRange(String.valueOf(start), String.valueOf(end)) .useUids(false) .addIdRange((long) start, (long) end) .since(earliestDate) .forbiddenFlags(forbiddenFlags) .forbiddenFlags(includeDeleted ? null : Collections.singleton(Flag.DELETED)) .build(); return getMessages(searchCommand.execute(), listener); } private String getDateSearchString(Date earliestDate) { if (earliestDate == null) { return ""; } return " SINCE " + RFC3501_DATE.get().format(earliestDate); } @Override public boolean areMoreMessagesAvailable(int indexOfOldestMessage, Date earliestDate) throws IOException, MessagingException { Loading @@ -558,13 +541,12 @@ public class ImapFolder extends Folder<ImapMessage> { return false; } String dateSearchString = getDateSearchString(earliestDate); int endIndex = indexOfOldestMessage - 1; while (endIndex > 0) { int startIndex = Math.max(0, endIndex - MORE_MESSAGES_WINDOW_SIZE) + 1; if (existsNonDeletedMessageInRange(startIndex, endIndex, dateSearchString)) { if (existsNonDeletedMessageInRange(startIndex, endIndex, earliestDate)) { return true; } Loading @@ -574,35 +556,27 @@ public class ImapFolder extends Folder<ImapMessage> { return false; } private boolean existsNonDeletedMessageInRange(int startIndex, int endIndex, String dateSearchString) private boolean existsNonDeletedMessageInRange(int startIndex, int endIndex, Date earliestDate) throws MessagingException, IOException { String command = String.format(Locale.US, "SEARCH %d:%d%s NOT DELETED", startIndex, endIndex, dateSearchString); List<ImapResponse> responses = executeSimpleCommand(command); for (ImapResponse response : responses) { if (response.getTag() == null && ImapResponseParser.equalsIgnoreCase(response.get(0), "SEARCH")) { if (response.size() > 1) { return true; } } } UidSearchCommand searchCommand = commandFactory.createUidSearchCommandBuilder(this, null) .useUids(false) .addIdRange((long) startIndex, (long) endIndex) .since(earliestDate) .forbiddenFlags(Collections.singleton(Flag.DELETED)) .build(); return false; SearchResponse response = searchCommand.execute(); return response.getNumbers().size() > 0; } protected List<ImapMessage> getMessages(final List<Long> mesgSeqs, final boolean includeDeleted, final MessageRetrievalListener<ImapMessage> listener) throws MessagingException { Set<Flag> forbiddenFlags = null; if (!includeDeleted) { forbiddenFlags = new HashSet<>(); forbiddenFlags.add(Flag.DELETED); } UidSearchCommand searchCommand = commandFactory.createUidSearchCommandBuilder(this, listener) .sequenceSet(mesgSeqs) .forbiddenFlags(forbiddenFlags) .useUids(false) .idSet(mesgSeqs) .forbiddenFlags(includeDeleted ? null : Collections.singleton(Flag.DELETED)) .build(); return getMessages(searchCommand.execute(), listener); Loading @@ -617,7 +591,8 @@ public class ImapFolder extends Folder<ImapMessage> { } UidSearchCommand searchCommand = commandFactory.createUidSearchCommandBuilder(this, null) .uidSet(uidSet) .useUids(true) .idSet(uidSet) .build(); return getMessages(searchCommand.execute(), null); Loading @@ -626,7 +601,7 @@ public class ImapFolder extends Folder<ImapMessage> { private List<ImapMessage> getMessages(SearchResponse searchResponse, MessageRetrievalListener<ImapMessage> listener) throws MessagingException { handleUntaggedResponses(searchResponse); checkOpen(); List<ImapMessage> messages = new ArrayList<>(); Loading Loading @@ -1250,7 +1225,6 @@ public class ImapFolder extends Folder<ImapMessage> { @Override public String getUidFromMessageId(Message message) throws MessagingException { try { /* * Try to find the UID of the message we just appended using the * Message-ID header. Loading @@ -1269,20 +1243,16 @@ public class ImapFolder extends Folder<ImapMessage> { Timber.d("Looking for UID for message with message-id %s for %s", messageId, getLogId()); } String command = String.format("UID SEARCH HEADER MESSAGE-ID %s", ImapUtility.encodeString(messageId)); List<ImapResponse> responses = executeSimpleCommand(command); UidSearchCommand searchCommand = commandFactory.createUidSearchCommandBuilder(this, null) .messageId(messageId) .build(); for (ImapResponse response : responses) { if (response.getTag() == null && ImapResponseParser.equalsIgnoreCase(response.get(0), "SEARCH") && response.size() > 1) { return response.getString(1); } List<Long> uids = searchCommand.execute().getNumbers(); if (uids.size() > 0) { return Long.toString(uids.get(0)); } return null; } catch (IOException ioe) { throw new MessagingException("Could not find UID for message based on Message-ID", ioe); } } @Override Loading
k9mail-library/src/main/java/com/fsck/k9/mail/store/imap/ImapMessage.java +2 −2 Original line number Diff line number Diff line package com.fsck.k9.mail.store.imap; import java.util.Collections; import com.fsck.k9.mail.Flag; import com.fsck.k9.mail.Folder; import com.fsck.k9.mail.MessagingException; import com.fsck.k9.mail.internet.MimeMessage; import java.util.Collections; public class ImapMessage extends MimeMessage { public ImapMessage(String uid, Folder folder) { Loading
k9mail-library/src/main/java/com/fsck/k9/mail/store/imap/ImapUtility.java +1 −0 Original line number Diff line number Diff line Loading @@ -144,6 +144,7 @@ public class ImapUtility { * * @return The string encoded as quoted (IMAP) string. */ //TODO use a literal string public static String encodeString(String str) { return "\"" + str.replace("\\", "\\\\").replace("\"", "\\\"") + "\""; } Loading