📄 commandparser.java
字号:
throw new ProtocolException( "Invalid escaped character in quote: '" + next + "'" ); } } quoted.append( next ); request.consume(); next = request.nextChar(); } consumeChar( request, '"' ); return quoted.toString(); } /** * Reads a base64 argument from the request. */ public byte[] base64( ImapRequestLineReader request ) throws ProtocolException { return null; } /** * Reads a "flags" argument from the request. */ public MessageFlags flagList( ImapRequestLineReader request ) throws ProtocolException { MessageFlags flags = new MessageFlags(); request.nextWordChar(); consumeChar( request, '(' ); CharacterValidator validator = new NoopCharValidator(); String nextWord = consumeWord( request, validator ); while ( ! nextWord.endsWith(")" ) ) { setFlag( nextWord, flags ); nextWord = consumeWord( request, validator ); } // Got the closing ")", may be attached to a word. if ( nextWord.length() > 1 ) { setFlag( nextWord.substring(0, nextWord.length() - 1 ), flags ); } return flags; } public void setFlag( String flagString, MessageFlags flags ) throws ProtocolException { if ( flagString.equalsIgnoreCase( MessageFlags.ANSWERED ) ) { flags.setAnswered( true ); } else if ( flagString.equalsIgnoreCase( MessageFlags.DELETED ) ) { flags.setDeleted( true ); } else if ( flagString.equalsIgnoreCase( MessageFlags.DRAFT ) ) { flags.setDraft( true ); } else if ( flagString.equalsIgnoreCase( MessageFlags.FLAGGED ) ) { flags.setFlagged( true ); } else if ( flagString.equalsIgnoreCase( MessageFlags.SEEN ) ) { flags.setSeen( true ); } else { throw new ProtocolException( "Invalid flag string." ); } } /** * Reads an argument of type "number" from the request. */ public long number( ImapRequestLineReader request ) throws ProtocolException { String digits = consumeWord( request, new DigitCharValidator() ); return Long.parseLong( digits ); } /** * Reads an argument of type "nznumber" (a non-zero number) * (NOTE this isn't strictly as per the spec, since the spec disallows * numbers such as "0123" as nzNumbers (although it's ok as a "number". * I think the spec is a bit shonky.) */ public long nzNumber( ImapRequestLineReader request ) throws ProtocolException { long number = number( request ); if ( number == 0 ) { throw new ProtocolException( "Zero value not permitted." ); } return number; } private boolean isCHAR( char chr ) { return ( chr >= 0x01 && chr <= 0x7f ); } private boolean isCHAR8( char chr ) { return ( chr >= 0x01 && chr <= 0xff ); } protected boolean isListWildcard( char chr ) { return ( chr == '*' || chr == '%' ); } private boolean isQuotedSpecial( char chr ) { return ( chr == '"' || chr == '\\' ); } /** * Consumes the request up to and including the eno-of-line. * @param request The request * @throws ProtocolException If characters are encountered before the endLine. */ public void endLine( ImapRequestLineReader request ) throws ProtocolException { request.eol(); } /** * Reads a "message set" argument, and parses into an IdSet. * Currently only supports a single range of values. */ public IdSet set( ImapRequestLineReader request ) throws ProtocolException { CharacterValidator validator = new MessageSetCharValidator(); String nextWord = consumeWord( request, validator ); int commaPos = nextWord.indexOf( ',' ); if ( commaPos == -1 ) { return singleRangeSet( nextWord ); } CompoundIdSet compoundSet = new CompoundIdSet(); int pos = 0; while ( commaPos != -1 ) { String range = nextWord.substring( pos, commaPos ); IdSet set = singleRangeSet( range ); compoundSet.addIdSet( set ); pos = commaPos + 1; commaPos = nextWord.indexOf( ',', pos ); } String range = nextWord.substring( pos ); compoundSet.addIdSet( singleRangeSet( range ) ); return compoundSet; } private IdSet singleRangeSet( String range ) throws ProtocolException { int pos = range.indexOf( ':' ); try { if ( pos == -1 ) { long value = parseLong( range ); return new HighLowIdSet( value, value ); } else { long lowVal = parseLong( range.substring(0, pos ) ); long highVal = parseLong( range.substring( pos + 1 ) ); return new HighLowIdSet( lowVal, highVal ); } } catch ( NumberFormatException e ) { throw new ProtocolException( "Invalid message set."); } } private long parseLong( String value ) { if ( value.length() == 1 && value.charAt(0) == '*' ) { return Long.MAX_VALUE; } return Long.parseLong( value ); } /** * Provides the ability to ensure characters are part of a permitted set. */ protected interface CharacterValidator { /** * Validates the supplied character. * @param chr The character to validate. * @return <code>true</code> if chr is valid, <code>false</code> if not. */ boolean isValid( char chr ); } protected class NoopCharValidator implements CharacterValidator { public boolean isValid( char chr ) { return true; } } protected class ATOM_CHARValidator implements CharacterValidator { public boolean isValid( char chr ) { return ( isCHAR( chr ) && !isAtomSpecial( chr ) && !isListWildcard( chr ) && !isQuotedSpecial( chr ) ); } private boolean isAtomSpecial( char chr ) { return ( chr == '(' || chr == ')' || chr == '{' || chr == ' ' || chr == Character.CONTROL ); } } protected class DigitCharValidator implements CharacterValidator { public boolean isValid( char chr ) { return ( ( chr >= '0' && chr <= '9' ) || chr == '*' ); } } private class TagCharValidator extends ATOM_CHARValidator { public boolean isValid( char chr ) { if ( chr == '+' ) return false; return super.isValid( chr ); } } private class MessageSetCharValidator implements CharacterValidator { public boolean isValid( char chr ) { return ( isDigit( chr ) || chr == ':' || chr == '*' || chr == ',' ); } private boolean isDigit( char chr ) { return '0' <= chr && chr <= '9'; } } private class HighLowIdSet implements IdSet { private long lowVal; private long highVal; public HighLowIdSet( long lowVal, long highVal ) { this.lowVal = lowVal; this.highVal = highVal; } public boolean includes( long value ) { return ( lowVal <= value ) && ( value <= highVal ); } } private class CompoundIdSet implements IdSet { private List idSets = new ArrayList(); void addIdSet( IdSet set ) { idSets.add( set ); } public boolean includes( long value ) { for ( int i = 0; i < idSets.size(); i++ ) { IdSet idSet = ( IdSet ) idSets.get( i ); if ( idSet.includes( value ) ) { return true; } } return false; } }}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -