/** * Skip past any spaces. If the next non-space character is c, * consume it and return true. Otherwise stop at that point * and return false. * * @param c the character to look for * @return true if the character is found */ public boolean isNextNonSpace(char c) { skipSpaces(); if (index < size && buffer[index] == (byte)c) { index++; return true; } return false; }
/** * Return the rest of the response as a string, usually used to * return the arbitrary message text after a NO response. * * @return the rest of the response */ public String getRest() { skipSpaces(); return toString(buffer, index, size); }
/** * Return the rest of the response as a string, usually used to * return the arbitrary message text after a NO response. * * @return the rest of the response */ public String getRest() { skipSpaces(); return ASCIIUtility.toString(buffer, index, size); }
/** * Extract a string stopping at control characters or any * character in delim. */ private String readDelimString(String delim) { skipSpaces(); if (index >= size) // already at end of response return null; byte b; int start = index; while (index < size && ((b = buffer[index]) > ' ') && delim.indexOf((char)b) < 0 && b >= ' ' && b != 0x7f) index++; return ASCIIUtility.toString(buffer, start, index); }
/** * Extract a string stopping at control characters or any * character in delim. */ private String readDelimString(String delim) { skipSpaces(); if (index >= size) // already at end of response return null; int b; int start = index; while (index < size && ((b = (((int)buffer[index])&0xff)) >= ' ') && delim.indexOf((char)b) < 0 && b != 0x7f) index++; return toString(buffer, start, index); }
/** * Read a string as an arbitrary sequence of characters, * stopping at the delimiter Used to read part of a * response code inside []. * * @param delim the delimiter character * @return the string */ public String readString(char delim) { skipSpaces(); if (index >= size) // already at end of response return null; int start = index; while (index < size && buffer[index] != delim) index++; return ASCIIUtility.toString(buffer, start, index); }
/** * Read a string as an arbitrary sequence of characters, * stopping at the delimiter Used to read part of a * response code inside []. * * @param delim the delimiter character * @return the string */ public String readString(char delim) { skipSpaces(); if (index >= size) // already at end of response return null; int start = index; while (index < size && buffer[index] != delim) index++; return toString(buffer, start, index); }
/** * Extract a long number, starting at the current position. Updates the * internal index to beyond the number. Returns -1 if a long number * was not found. * * @return a long */ public long readLong() { // Skip leading spaces skipSpaces(); int start = index; while (index < size && Character.isDigit((char)buffer[index])) index++; if (index > start) { try { return ASCIIUtility.parseLong(buffer, start, index); } catch (NumberFormatException nex) { } } return -1; }
/** * Extract a long number, starting at the current position. Updates the * internal index to beyond the number. Returns -1 if a long number * was not found. * * @return a long */ public long readLong() { // Skip leading spaces skipSpaces(); int start = index; while (index < size && Character.isDigit((char)buffer[index])) index++; if (index > start) { try { return ASCIIUtility.parseLong(buffer, start, index); } catch (NumberFormatException nex) { } } return -1; }
/** * Extract an integer, starting at the current position. Updates the * internal index to beyond the number. Returns -1 if a number was * not found. * * @return a number */ public int readNumber() { // Skip leading spaces skipSpaces(); int start = index; while (index < size && Character.isDigit((char)buffer[index])) index++; if (index > start) { try { return ASCIIUtility.parseInt(buffer, start, index); } catch (NumberFormatException nex) { } } return -1; }
private String[] readStringList(boolean atom) { skipSpaces(); if (buffer[index] != '(') { // not what we expected return null; } index++; // skip '(' List<String> result = new ArrayList<String>(); skipSpaces(); if (peekByte() != ')') { do { result.add(atom ? readAtomString() : readString()); } while (index < size && buffer[index++] != ')'); } else index++; // skip ')' return result.toArray(new String[result.size()]); }
/** * Extract an integer, starting at the current position. Updates the * internal index to beyond the number. Returns -1 if a number was * not found. * * @return a number */ public int readNumber() { // Skip leading spaces skipSpaces(); int start = index; while (index < size && Character.isDigit((char)buffer[index])) index++; if (index > start) { try { return ASCIIUtility.parseInt(buffer, start, index); } catch (NumberFormatException nex) { } } return -1; }
private String[] readStringList(boolean atom) { skipSpaces(); if (buffer[index] != '(') { // not what we expected return null; } index++; // skip '(' // to handle buggy IMAP servers, we tolerate multiple spaces as // well as spaces after the left paren or before the right paren List<String> result = new ArrayList<>(); while (!isNextNonSpace(')')) { String s = atom ? readAtomString() : readString(); if (s == null) // not the expected string or atom break; result.add(s); } return result.toArray(new String[result.size()]); }
/** * Extract a NSTRING, starting at the current position. Return it as * a ByteArray. The sequence 'NIL' is returned as null * * NSTRING := QuotedString | Literal | "NIL" * * @return a ByteArray */ public ByteArray readByteArray() { /* * Special case, return the data after the continuation uninterpreted. * It's usually a challenge for an AUTHENTICATE command. */ if (isContinuation()) { skipSpaces(); return new ByteArray(buffer, index, size - index); } return (ByteArray)parseString(false, false); }
/** * Extract a NSTRING, starting at the current position. Return it as * a ByteArray. The sequence 'NIL' is returned as null * * NSTRING := QuotedString | Literal | "NIL" * * @return a ByteArray */ public ByteArray readByteArray() { /* * Special case, return the data after the continuation uninterpreted. * It's usually a challenge for an AUTHENTICATE command. */ if (isContinuation()) { skipSpaces(); return new ByteArray(buffer, index, size - index); } return (ByteArray)parseString(false, false); }
/** * Parse out one of the three sets of namespaces. */ private Namespace[] getNamespaces(Response r) throws ProtocolException { r.skipSpaces(); // Namespace = nil / "(" 1*( Namespace_Element) ")" if (r.peekByte() == '(') { List<Namespace> v = new ArrayList<Namespace>(); r.readByte(); do { Namespace ns = new Namespace(r); v.add(ns); } while (r.peekByte() != ')'); r.readByte(); return v.toArray(new Namespace[v.size()]); } else { String s = r.readAtom(); if (s == null) throw new ProtocolException("Expected NIL, got null"); if (!s.equalsIgnoreCase("NIL")) throw new ProtocolException("Expected NIL, got " + s); return null; } } }
private void parseBodyExtension(Response r) throws ParsingException { r.skipSpaces(); byte b = r.peekByte(); if (b == '(') { r.skip(1); // skip '(' do { parseBodyExtension(r); } while (!r.isNextNonSpace(')')); } else if (Character.isDigit((char)b)) // number r.readNumber(); else // nstring r.readString(); } }
private void parseBodyExtension(Response r) throws ParsingException { r.skipSpaces(); byte b = r.peekByte(); if (b == '(') { r.skip(1); // skip '(' do { parseBodyExtension(r); } while (r.readByte() != ')'); } else if (Character.isDigit((char)b)) // number r.readNumber(); else // nstring r.readString(); } }
/** * Parse a QUOTA response. */ private Quota parseQuota(Response r) throws ParsingException { // quota_response ::= "QUOTA" SP astring SP quota_list String quotaRoot = r.readAtomString(); // quotaroot ::= astring Quota q = new Quota(quotaRoot); r.skipSpaces(); // quota_list ::= "(" #quota_resource ")" if (r.readByte() != '(') throw new ParsingException("parse error in QUOTA"); List<Quota.Resource> v = new ArrayList<>(); while (!r.isNextNonSpace(')')) { // quota_resource ::= atom SP number SP number String name = r.readAtom(); if (name != null) { long usage = r.readLong(); long limit = r.readLong(); Quota.Resource res = new Quota.Resource(name, usage, limit); v.add(res); } } q.resources = v.toArray(new Quota.Resource[v.size()]); return q; }
/** * Parse a QUOTA response. */ private Quota parseQuota(Response r) throws ParsingException { // quota_response ::= "QUOTA" SP astring SP quota_list String quotaRoot = r.readAtomString(); // quotaroot ::= astring Quota q = new Quota(quotaRoot); r.skipSpaces(); // quota_list ::= "(" #quota_resource ")" if (r.readByte() != '(') throw new ParsingException("parse error in QUOTA"); List<Quota.Resource> v = new ArrayList<Quota.Resource>(); while (r.peekByte() != ')') { // quota_resource ::= atom SP number SP number String name = r.readAtom(); if (name != null) { long usage = r.readLong(); long limit = r.readLong(); Quota.Resource res = new Quota.Resource(name, usage, limit); v.add(res); } } r.readByte(); q.resources = v.toArray(new Quota.Resource[v.size()]); return q; }