am 51801db8
: Merge branch \'readonly-p4-donut\' into donut
Merge commit '51801db8e9e07865c87296bfccea7964e4c0ad99' * commit '51801db8e9e07865c87296bfccea7964e4c0ad99': AI 149020: Manually merge CLs 148814, 148818 which fix IMAP response parsing to be
This commit is contained in:
commit
91ae3e87d5
@ -358,6 +358,37 @@ public class ImapResponseParser {
|
||||
boolean mCommandContinuationRequested;
|
||||
String mTag;
|
||||
|
||||
/*
|
||||
* Return true if this response is completely read and parsed.
|
||||
*/
|
||||
public boolean completed() {
|
||||
return mCompleted;
|
||||
}
|
||||
|
||||
/*
|
||||
* Nail down the last element that possibly is FixedLengthInputStream literal.
|
||||
*/
|
||||
public void nailDown() throws IOException {
|
||||
int last = size() - 1;
|
||||
if (last >= 0) {
|
||||
Object o = get(last);
|
||||
if (o instanceof FixedLengthInputStream) {
|
||||
FixedLengthInputStream is = (FixedLengthInputStream) o;
|
||||
byte[] buffer = new byte[is.available()];
|
||||
is.read(buffer);
|
||||
set(last, (Object) new String(buffer));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* Append all response elements to this and copy completed flag.
|
||||
*/
|
||||
public void appendAll(ImapResponse other) {
|
||||
addAll(other);
|
||||
mCompleted = other.mCompleted;
|
||||
}
|
||||
|
||||
public boolean more() throws IOException {
|
||||
if (mCompleted) {
|
||||
return false;
|
||||
|
@ -1216,9 +1216,25 @@ public class ImapStore extends Store {
|
||||
String tag = sendCommand(command, sensitive);
|
||||
ArrayList<ImapResponse> responses = new ArrayList<ImapResponse>();
|
||||
ImapResponse response;
|
||||
ImapResponse previous = null;
|
||||
do {
|
||||
// This is work around to parse literal in the middle of response.
|
||||
// We should nail down the previous response literal string if any.
|
||||
if (previous != null && !previous.completed()) {
|
||||
previous.nailDown();
|
||||
}
|
||||
response = mParser.readResponse();
|
||||
// This is work around to parse literal in the middle of response.
|
||||
// If we found unmatched tagged response, it possibly be the continuous
|
||||
// response just after the literal string.
|
||||
if (response.mTag != null && !response.mTag.equals(tag)
|
||||
&& previous != null && !previous.completed()) {
|
||||
previous.appendAll(response);
|
||||
response.mTag = null;
|
||||
continue;
|
||||
}
|
||||
responses.add(response);
|
||||
previous = response;
|
||||
} while (response.mTag == null);
|
||||
if (response.size() < 1 || !response.get(0).equals("OK")) {
|
||||
throw new ImapException(response.toString(), response.getAlertText());
|
||||
|
@ -0,0 +1,86 @@
|
||||
/*
|
||||
* Copyright (C) 2009 The Android Open Source Project
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package com.android.email.mail.store;
|
||||
|
||||
import com.android.email.FixedLengthInputStream;
|
||||
import com.android.email.mail.store.ImapResponseParser.ImapList;
|
||||
import com.android.email.mail.store.ImapResponseParser.ImapResponse;
|
||||
|
||||
import android.test.AndroidTestCase;
|
||||
import android.test.suitebuilder.annotation.SmallTest;
|
||||
|
||||
import java.io.ByteArrayInputStream;
|
||||
|
||||
/**
|
||||
* This is a series of unit tests for the ImapStore class. These tests must be locally
|
||||
* complete - no server(s) required.
|
||||
*/
|
||||
@SmallTest
|
||||
public class ImapResponseParserUnitTests extends AndroidTestCase {
|
||||
|
||||
// TODO more comprehensive test for parsing
|
||||
|
||||
/**
|
||||
* Test for parsing literal string
|
||||
*/
|
||||
public void testParseLiteral() throws Exception {
|
||||
ByteArrayInputStream is = new ByteArrayInputStream(
|
||||
("* STATUS \"INBOX\" (UNSEEN 2)\r\n"
|
||||
+ "100 OK STATUS completed\r\n"
|
||||
+ "* STATUS {5}\r\n"
|
||||
+ "INBOX (UNSEEN 10)\r\n"
|
||||
+ "101 OK STATUS completed\r\n")
|
||||
.getBytes());
|
||||
ImapResponseParser parser = new ImapResponseParser(is);
|
||||
|
||||
ImapResponse line1 = parser.readResponse();
|
||||
assertNull("Line 1 tag", line1.mTag);
|
||||
assertTrue("Line 1 completed", line1.completed());
|
||||
assertEquals("Line 1 count", 3, line1.size());
|
||||
|
||||
ImapResponse line2 = parser.readResponse();
|
||||
assertEquals("Line 2 tag", "100", line2.mTag);
|
||||
assertTrue("Line 2 completed", line2.completed());
|
||||
assertEquals("Line 2 count", 3, line2.size());
|
||||
|
||||
ImapResponse line3 = parser.readResponse();
|
||||
assertNull("Line 3 tag", line3.mTag);
|
||||
assertFalse("Line 3 completed", line3.completed());
|
||||
assertEquals("Line 3 count", 2, line3.size());
|
||||
assertEquals("Line 3 word 2 class", FixedLengthInputStream.class, line3.get(1).getClass());
|
||||
|
||||
line3.nailDown();
|
||||
assertEquals("Line 3 word 2 nailed down", String.class, line3.get(1).getClass());
|
||||
assertEquals("Line 3 word 2 value", "INBOX", line3.getString(1));
|
||||
|
||||
ImapResponse line4 = parser.readResponse();
|
||||
assertEquals("Line 4 tag", "", line4.mTag);
|
||||
assertTrue("Line 4 completed", line4.completed());
|
||||
assertEquals("Line 4 count", 1, line4.size());
|
||||
|
||||
line3.appendAll(line4);
|
||||
assertNull("Line 3-4 tag", line3.mTag);
|
||||
assertTrue("Line 3-4 completed", line3.completed());
|
||||
assertEquals("Line 3-4 count", 3, line3.size());
|
||||
assertEquals("Line 3-4 word 3 class", ImapList.class, line3.get(2).getClass());
|
||||
|
||||
ImapResponse line5 = parser.readResponse();
|
||||
assertEquals("Line 5 tag", "101", line5.mTag);
|
||||
assertTrue("Line 5 completed", line5.completed());
|
||||
assertEquals("Line 5 count", 3, line5.size());
|
||||
}
|
||||
}
|
@ -176,4 +176,33 @@ public class ImapStoreUnitTests extends AndroidTestCase {
|
||||
"* OK [UIDNEXT 1]",
|
||||
"2 OK [READ-WRITE] INBOX selected. (Success)"});
|
||||
}
|
||||
|
||||
/**
|
||||
* Test for getUnreadMessageCount with quoted string in the middle of response.
|
||||
*/
|
||||
public void testGetUnreadMessageCountWithQuotedString() throws Exception {
|
||||
MockTransport mock = openAndInjectMockTransport();
|
||||
setupOpenFolder(mock);
|
||||
mock.expect("3 STATUS \"INBOX\" \\(UNSEEN\\)", new String[] {
|
||||
"* STATUS \"INBOX\" (UNSEEN 2)",
|
||||
"3 OK STATUS completed"});
|
||||
mFolder.open(OpenMode.READ_WRITE, null);
|
||||
int unreadCount = mFolder.getUnreadMessageCount();
|
||||
assertEquals("getUnreadMessageCount with quoted string", 2, unreadCount);
|
||||
}
|
||||
|
||||
/**
|
||||
* Test for getUnreadMessageCount with literal string in the middle of response.
|
||||
*/
|
||||
public void testGetUnreadMessageCountWithLiteralString() throws Exception {
|
||||
MockTransport mock = openAndInjectMockTransport();
|
||||
setupOpenFolder(mock);
|
||||
mock.expect("3 STATUS \"INBOX\" \\(UNSEEN\\)", new String[] {
|
||||
"* STATUS {5}",
|
||||
"INBOX (UNSEEN 10)",
|
||||
"3 OK STATUS completed"});
|
||||
mFolder.open(OpenMode.READ_WRITE, null);
|
||||
int unreadCount = mFolder.getUnreadMessageCount();
|
||||
assertEquals("getUnreadMessageCount with literal string", 10, unreadCount);
|
||||
}
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user