private void parseListResponse(ImapResponse response) throws IOException { expect(' '); parseList(response, '(', ')'); expect(' '); // TODO: Add support for NIL String delimiter = parseQuoted(); response.add(delimiter); expect(' '); String name = parseString(); response.add(name); expect('\r'); expect('\n'); }
private void readContinuationRequest(ImapResponseCallback callback) throws IOException { parseCommandContinuationRequest(); response = ImapResponse.newContinuationRequest(callback); skipIfSpace(); String rest = readStringUntilEndOfLine(); response.add(rest); }
private void readTokens(ImapResponse response) throws IOException { response.clear(); Object firstToken = readToken(response); checkTokenIsString(firstToken); String symbol = (String) firstToken; response.add(symbol); if (isStatusResponse(symbol)) { parseResponseText(response); } else if (equalsIgnoreCase(symbol, Responses.LIST) || equalsIgnoreCase(symbol, Responses.LSUB)) { parseListResponse(response); } else { Object token; while ((token = readToken(response)) != null) { if (!(token instanceof ImapList)) { response.add(token); } } } }
/** * Parse {@code resp-text} tokens * * <p>Responses "OK", "PREAUTH", "BYE", "NO", "BAD", and continuation request responses can * contain {@code resp-text} tokens. We parse the {@code resp-text-code} part as tokens and read * the rest as sequence of characters to avoid the parser interpreting things like "{123}" as * start of a literal. * * <p>Example: * * <p>{@code * OK [UIDVALIDITY 3857529045] UIDs valid} * * <p>See RFC 3501, Section 9 Formal Syntax (resp-text) * * @param parent The {@link ImapResponse} instance that holds the parsed tokens of the response. * @throws IOException If there's a network error. * @see #isStatusResponse(String) */ private void parseResponseText(ImapResponse parent) throws IOException { skipIfSpace(); int next = inputStream.peek(); if (next == '[') { parseList(parent, '[', ']'); skipIfSpace(); } String rest = readStringUntilEndOfLine(); if (rest != null && !rest.isEmpty()) { // The rest is free-form text. parent.add(rest); } }
/** Parse and return the response line. */ private ImapResponse parseResponse() throws IOException, MessagingException { // We need to destroy the response if we get an exception. // So, we first store the response that's being built in responseToDestroy, until it's // completely built, at which point we copy it into responseToReturn and null out // responseToDestroyt. // If responseToDestroy is not null in finally, we destroy it because that means // we got an exception somewhere. ImapResponse responseToDestroy = null; final ImapResponse responseToReturn; try { final int ch = peek(); if (ch == '+') { // Continuation request readByte(); // skip + expect(' '); responseToDestroy = new ImapResponse(null, true); // If it's continuation request, we don't really care what's in it. responseToDestroy.add(new ImapSimpleString(readUntilEol())); // Response has successfully been built. Let's return it. responseToReturn = responseToDestroy; responseToDestroy = null; } else { // Status response or response data final String tag; if (ch == '*') { tag = null; readByte(); // skip * expect(' '); } else { tag = readUntil(' '); } responseToDestroy = new ImapResponse(tag, false); final ImapString firstString = parseBareString(); responseToDestroy.add(firstString); // parseBareString won't eat a space after the string, so we need to skip it, // if exists. // If the next char is not ' ', it should be EOL. if (peek() == ' ') { readByte(); // skip ' ' if (responseToDestroy.isStatusResponse()) { // It's a status response // Is there a response code? final int next = peek(); if (next == '[') { responseToDestroy.add(parseList('[', ']')); if (peek() == ' ') { // Skip following space readByte(); } } String rest = readUntilEol(); if (!TextUtils.isEmpty(rest)) { // The rest is free-form text. responseToDestroy.add(new ImapSimpleString(rest)); } } else { // It's a response data. parseElements(responseToDestroy, '\0'); } } else { expect('\r'); expect('\n'); } // Response has successfully been built. Let's return it. responseToReturn = responseToDestroy; responseToDestroy = null; } } finally { if (responseToDestroy != null) { // We get an exception. responseToDestroy.destroy(); } } return responseToReturn; }