Changeset 689
- Timestamp:
- 08/21/10 14:10:33 (18 months ago)
- Location:
- trunk
- Files:
-
- 3 added
- 21 edited
-
LogicMail/src/org/logicprobe/LogicMail/mail/imap/ImapClient.java (modified) (4 diffs)
-
LogicMail/src/org/logicprobe/LogicMail/mail/imap/ImapParser.java (modified) (24 diffs)
-
LogicMail/src/org/logicprobe/LogicMail/mail/imap/ImapProtocol.java (modified) (75 diffs)
-
LogicMail/src/org/logicprobe/LogicMail/mail/pop/PopProtocol.java (modified) (3 diffs)
-
LogicMail/src/org/logicprobe/LogicMail/mail/smtp/SmtpProtocol.java (modified) (2 diffs)
-
LogicMail/src/org/logicprobe/LogicMail/message/ApplicationContent.java (modified) (2 diffs)
-
LogicMail/src/org/logicprobe/LogicMail/message/AudioContent.java (modified) (2 diffs)
-
LogicMail/src/org/logicprobe/LogicMail/message/ImageContent.java (modified) (3 diffs)
-
LogicMail/src/org/logicprobe/LogicMail/message/MessageContent.java (modified) (2 diffs)
-
LogicMail/src/org/logicprobe/LogicMail/message/MimeMessageContent.java (modified) (3 diffs)
-
LogicMail/src/org/logicprobe/LogicMail/message/MimeMessageContentFactory.java (modified) (3 diffs)
-
LogicMail/src/org/logicprobe/LogicMail/message/TextContent.java (modified) (3 diffs)
-
LogicMail/src/org/logicprobe/LogicMail/message/VideoContent.java (modified) (2 diffs)
-
LogicMail/src/org/logicprobe/LogicMail/ui/CompositionScreen.java (modified) (2 diffs)
-
LogicMail/src/org/logicprobe/LogicMail/util/Connection.java (modified) (14 diffs)
-
LogicMail/src/org/logicprobe/LogicMail/util/ConnectionResponseTester.java (added)
-
LogicMail/src/org/logicprobe/LogicMail/util/MailMessageParser.java (modified) (3 diffs)
-
LogicMail/src/org/logicprobe/LogicMail/util/StringArrays.java (added)
-
LogicMail/src/org/logicprobe/LogicMail/util/StringParser.java (modified) (4 diffs)
-
LogicMailTests/src/org/logicprobe/LogicMail/mail/imap/ImapParserTest.java (modified) (7 diffs)
-
LogicMailTests/src/org/logicprobe/LogicMail/mail/imap/ImapProtocolTest.java (modified) (19 diffs)
-
LogicMailTests/src/org/logicprobe/LogicMail/util/StringArraysTest.java (added)
-
LogicMailTests/src/org/logicprobe/LogicMail/util/StringParserTest.java (modified) (5 diffs)
-
LogicMailTests/src/org/logicprobe/LogicMail/util/UtilTests.java (modified) (1 diff)
Legend:
- Unmodified
- Added
- Removed
-
trunk/LogicMail/src/org/logicprobe/LogicMail/mail/imap/ImapClient.java
r678 r689 917 917 918 918 919 Stringdata = getMessageBody(imapMessageToken.getImapMessageUid(), partAddress, progressHandler);919 byte[] data = getMessageBody(imapMessageToken.getImapMessageUid(), partAddress, progressHandler); 920 920 MimeMessageContent content; 921 921 try { 922 content = MimeMessageContentFactory.createContent (mimeMessagePart, data);922 content = MimeMessageContentFactory.createContentEncoded(mimeMessagePart, data); 923 923 } catch (UnsupportedContentException e) { 924 924 content = null; … … 937 937 MimeMessagePart part; 938 938 if(MimeMessagePartFactory.isMimeMessagePartSupported(structure.type, structure.subtype)) { 939 Stringdata;939 byte[] data; 940 940 if(structure.type.equalsIgnoreCase("multipart")) 941 941 data = null; … … 961 961 structure.address); 962 962 try { 963 contentMap.put(part, MimeMessageContentFactory.createContent (part, data));963 contentMap.put(part, MimeMessageContentFactory.createContentEncoded(part, data)); 964 964 } catch (UnsupportedContentException e) { 965 965 System.err.println("UnsupportedContentException: " + e.getMessage()); … … 1042 1042 } 1043 1043 1044 private StringgetMessageBody(int uid, String address, MailProgressHandler progressHandler) throws IOException, MailException {1044 private byte[] getMessageBody(int uid, String address, MailProgressHandler progressHandler) throws IOException, MailException { 1045 1045 if(activeMailbox == null) { 1046 1046 throw new MailException("Mailbox not selected"); -
trunk/LogicMail/src/org/logicprobe/LogicMail/mail/imap/ImapParser.java
r656 r689 1 1 /*- 2 * Copyright (c) 20 06, Derek Konigsberg2 * Copyright (c) 2010, Derek Konigsberg 3 3 * All rights reserved. 4 4 * … … 32 32 33 33 import net.rim.device.api.system.EventLogger; 34 import net.rim.device.api.util.Arrays; 35 import net.rim.device.api.util.ByteVector; 34 36 35 37 import org.logicprobe.LogicMail.AppInfo; 36 38 import org.logicprobe.LogicMail.message.MessageEnvelope; 39 import org.logicprobe.LogicMail.util.StringArrays; 37 40 import org.logicprobe.LogicMail.util.StringParser; 38 41 … … 48 51 */ 49 52 class ImapParser { 50 private static String strNIL = "NIL"; 51 private static String MODIFIED_BASE64_ALPHABET = 52 "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+,"; 53 53 private static String NIL = "NIL"; 54 private static String BODYSTRUCTURE = "BODYSTRUCTURE"; 55 private static String MODIFIED_BASE64_ALPHABET = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+,"; 56 private static Character LPAREN = new Character('('); 57 private static Character RPAREN = new Character(')'); 58 private static String US_ASCII = "US-ASCII"; 54 59 static String FLAG_SEEN = "\\Seen"; 55 60 static String FLAG_ANSWERED = "\\Answered"; … … 61 66 static String FLAG_JUNK0 = "Junk"; 62 67 static String FLAG_JUNK1 = "$Junk"; 63 68 64 69 private ImapParser() { 65 70 } … … 110 115 buf.append(' '); 111 116 } 117 112 118 buf.append(FLAG_ANSWERED); 113 119 } … … 117 123 buf.append(' '); 118 124 } 125 119 126 buf.append(FLAG_FLAGGED); 120 127 } … … 124 131 buf.append(' '); 125 132 } 133 126 134 buf.append(FLAG_DELETED); 127 135 } … … 131 139 buf.append(' '); 132 140 } 141 133 142 buf.append(FLAG_DRAFT); 134 143 } … … 138 147 buf.append(' '); 139 148 } 149 140 150 buf.append(FLAG_RECENT); 141 151 } … … 145 155 buf.append(' '); 146 156 } 157 147 158 buf.append(FLAG_FORWARDED); 148 159 } … … 163 174 MessageEnvelope env = new MessageEnvelope(); 164 175 165 if (parsedEnv.elementAt(0) instanceof String) {176 if (parsedEnv.elementAt(0) instanceof byte[]) { 166 177 try { 167 env.date = StringParser.parseDateString( (String) parsedEnv.elementAt(168 0));178 env.date = StringParser.parseDateString( 179 new String((byte[]) parsedEnv.elementAt(0))); 169 180 } catch (Exception e) { 170 181 env.date = Calendar.getInstance().getTime(); 171 182 } 172 183 } 173 174 if (parsedEnv.elementAt(1) instanceof String) { 175 String subject = (String) parsedEnv.elementAt(1); 176 177 if (subject.equals(strNIL)) { 178 env.subject = ""; 179 } else { 180 env.subject = StringParser.parseEncodedHeader(subject); 181 } 184 else { 185 env.date = Calendar.getInstance().getTime(); 186 } 187 188 if (parsedEnv.elementAt(1) instanceof byte[]) { 189 env.subject = StringParser.parseEncodedHeader( 190 new String((byte[])parsedEnv.elementAt(1))); 191 } 192 else { 193 env.subject = ""; 182 194 } 183 195 … … 206 218 } 207 219 208 if (parsedEnv.elementAt(8) instanceof String) { 209 env.inReplyTo = (String) parsedEnv.elementAt(8); 210 211 if (env.inReplyTo.equals(strNIL)) { 212 env.inReplyTo = ""; 213 } 214 } 215 216 if (parsedEnv.elementAt(9) instanceof String) { 217 env.messageId = (String) parsedEnv.elementAt(9); 218 219 if (env.messageId.equals(strNIL)) { 220 env.messageId = ""; 221 } 220 if (parsedEnv.elementAt(8) instanceof byte[]) { 221 env.inReplyTo = new String((byte[])parsedEnv.elementAt(8)); 222 } 223 else { 224 env.inReplyTo = ""; 225 } 226 227 if (parsedEnv.elementAt(9) instanceof byte[]) { 228 env.messageId = new String((byte[])parsedEnv.elementAt(9)); 229 } 230 else { 231 env.messageId = ""; 222 232 } 223 233 … … 235 245 Vector entry = (Vector) addrVec.elementAt(i); 236 246 237 String realName = strNIL;238 239 if (entry.elementAt(0) instanceof String) {240 realName = StringParser.parseEncodedHeader( (String) entry.elementAt(241 0));242 } 243 244 String mbName = strNIL;245 246 if (entry.elementAt(2) instanceof String) {247 mbName = (String) entry.elementAt(2);248 } 249 250 String hostName = strNIL;251 252 if (entry.elementAt(3) instanceof String) {253 hostName = (String) entry.elementAt(3);254 } 255 256 String addrStr = (mbName.equals( strNIL) ? "" : mbName) +257 (hostName.equals( strNIL) ? "" : ('@' + hostName));247 String realName = NIL; 248 249 if (entry.elementAt(0) instanceof byte[]) { 250 realName = StringParser.parseEncodedHeader( 251 new String((byte[]) entry.elementAt(0))); 252 } 253 254 String mbName = NIL; 255 256 if (entry.elementAt(2) instanceof byte[]) { 257 mbName = new String((byte[]) entry.elementAt(2)); 258 } 259 260 String hostName = NIL; 261 262 if (entry.elementAt(3) instanceof byte[]) { 263 hostName = new String((byte[]) entry.elementAt(3)); 264 } 265 266 String addrStr = (mbName.equals(NIL) ? "" : mbName) + 267 (hostName.equals(NIL) ? "" : ('@' + hostName)); 258 268 259 269 // Now assemble these into a single address entry 260 270 // (possibly eventually storing them separately) 261 if ((realName.length() > 0) && !realName.equals( strNIL)) {271 if ((realName.length() > 0) && !realName.equals(NIL)) { 262 272 addrList[index] = realName + " <" + addrStr + ">"; 263 273 } else { … … 288 298 * @return Root of the message structure tree 289 299 */ 290 static MessageSection parseMessageStructure( StringrawText) {300 static MessageSection parseMessageStructure(byte[] rawText) { 291 301 Vector parsedText = null; 292 302 293 303 try { 294 parsedText = StringParser.nestedParenStringLexer(rawText.substring(295 rawText.indexOf('(')));304 int offset = Arrays.getIndex(rawText, (byte)'('); 305 parsedText = ImapParser.parenListParser(rawText, offset, rawText.length - offset); 296 306 } catch (Exception exp) { 297 307 EventLogger.logEvent(AppInfo.GUID, … … 311 321 String label = (String) parsedText.elementAt(i); 312 322 313 if (label.equalsIgnoreCase( "BODYSTRUCTURE") &&323 if (label.equalsIgnoreCase(BODYSTRUCTURE) && 314 324 (i < (size - 1)) && 315 325 parsedText.elementAt(i + 1) instanceof Vector) { … … 335 345 /** 336 346 * Parse the IMAP message structure tree from a prepared object tree 337 * generated by {@link StringParser#nestedParenStringLexer(String)}.347 * generated by {@link ImapParser#parenListParser(String)}. 338 348 * 339 349 * @param parsedStruct Tree containing the {@link Vector} that follows a BODYSTRUCTURE string … … 341 351 */ 342 352 static MessageSection parseMessageStructureParameter(Vector parsedStruct) { 343 MessageSection msgStructure = parseMessageStructureHelper(null, 1, parsedStruct); 353 MessageSection msgStructure = parseMessageStructureHelper( 354 null, 1, parsedStruct); 344 355 fixMessageStructure(msgStructure); 356 345 357 return msgStructure; 346 358 } 347 359 348 360 /** 349 361 * This method implements a kludge to fix body part addresses … … 380 392 381 393 // Determine the number of body parts and parse 382 if (parsedStruct.elementAt(0) instanceof String) {394 if (parsedStruct.elementAt(0) instanceof byte[]) { 383 395 // The first element is a string, so we hit a simple message part 384 396 MessageSection section = parseMessageStructureSection(parsedStruct); … … 396 408 subSectionsVector.addElement(parseMessageStructureHelper( 397 409 address, i + 1, (Vector) parsedStruct.elementAt(i))); 398 } else if (parsedStruct.elementAt(i) instanceof String) {410 } else if (parsedStruct.elementAt(i) instanceof byte[]) { 399 411 MessageSection section = new MessageSection(); 400 412 section.type = "multipart"; 401 section.subtype = ( (String) parsedStruct.elementAt(i)).toLowerCase();413 section.subtype = (new String((byte[]) parsedStruct.elementAt(i))).toLowerCase(); 402 414 section.subsections = new MessageSection[subSectionsVector.size()]; 403 415 subSectionsVector.copyInto(section.subsections); … … 412 424 } 413 425 414 private static MessageSection parseMessageStructureSection(Vector sectionList) { 426 private static MessageSection parseMessageStructureSection( 427 Vector sectionList) { 415 428 MessageSection sec = new MessageSection(); 416 429 Vector tmpVec; 417 430 int sectionListSize = sectionList.size(); 418 431 419 if (sectionList.elementAt(0) instanceof String) {420 sec.type = ( (String) sectionList.elementAt(0)).toLowerCase();421 } 422 423 if (sectionList.elementAt(1) instanceof String) {424 sec.subtype = ( (String) sectionList.elementAt(1)).toLowerCase();432 if (sectionList.elementAt(0) instanceof byte[]) { 433 sec.type = (new String((byte[])sectionList.elementAt(0))).toLowerCase(); 434 } 435 436 if (sectionList.elementAt(1) instanceof byte[]) { 437 sec.subtype = (new String((byte[])sectionList.elementAt(1))).toLowerCase(); 425 438 } 426 439 … … 431 444 432 445 int size = tmpVec.size(); 433 for(int i=0; i < size - 1; i+=2) { 434 if(tmpVec.elementAt(i) instanceof String && 435 tmpVec.elementAt(i+1) instanceof String) { 436 String key = (String)tmpVec.elementAt(i); 437 String value = (String)tmpVec.elementAt(i+1); 438 if(key.equalsIgnoreCase("charset")) { 439 sec.charset = value; 440 } 441 else if(key.equalsIgnoreCase("name")) { 442 sec.name = value; 443 } 444 } 445 } 446 } 447 448 if (sectionList.elementAt(3) instanceof String) { 449 sec.contentId = (String) sectionList.elementAt(3); 450 } 451 452 if (sectionList.elementAt(5) instanceof String) { 453 sec.encoding = ((String) sectionList.elementAt(5)).toLowerCase(); 446 447 for (int i = 0; i < (size - 1); i += 2) { 448 if (tmpVec.elementAt(i) instanceof byte[] && 449 tmpVec.elementAt(i + 1) instanceof byte[]) { 450 String key = new String((byte[]) tmpVec.elementAt(i)); 451 String value = new String((byte[]) tmpVec.elementAt(i + 1)); 452 453 if (key.equalsIgnoreCase("charset")) { 454 sec.charset = value; 455 } else if (key.equalsIgnoreCase("name")) { 456 sec.name = value; 457 } 458 } 459 } 460 } 461 462 if (sectionList.elementAt(3) instanceof byte[]) { 463 sec.contentId = new String((byte[]) sectionList.elementAt(3)); 464 } 465 466 if (sectionList.elementAt(5) instanceof byte[]) { 467 sec.encoding = new String(((byte[]) sectionList.elementAt(5))).toLowerCase(); 454 468 } 455 469 … … 462 476 } 463 477 464 if (sectionListSize > 8 && sectionList.elementAt(8) instanceof Vector) { 465 tmpVec = (Vector) sectionList.elementAt(8); 466 if(tmpVec.elementAt(0) instanceof String) { 467 sec.disposition = ((String)tmpVec.elementAt(0)).toLowerCase(); 468 } 469 } 470 478 if ((sectionListSize > 8) && 479 sectionList.elementAt(8) instanceof Vector) { 480 tmpVec = (Vector) sectionList.elementAt(8); 481 482 if (tmpVec.elementAt(0) instanceof byte[]) { 483 sec.disposition = new String((byte[]) tmpVec.elementAt(0)).toLowerCase(); 484 } 485 } 486 471 487 return sec; 472 488 } … … 574 590 } 575 591 592 static Vector parenListLexer(byte[] rawText, int offset, int length) { 593 if(offset + length > rawText.length) { 594 throw new ArrayIndexOutOfBoundsException(); 595 } 596 597 Vector result = new Vector(); 598 ByteVector buf = new ByteVector(); 599 600 int size = offset + length; 601 int i = offset; 602 603 while (i < size) { 604 byte ch = rawText[i]; 605 606 if (ch == (byte)'(') { 607 result.addElement(LPAREN); 608 i++; 609 } else if (ch == (byte)')') { 610 result.addElement(RPAREN); 611 i++; 612 } else if (ch == (byte)'"') { 613 // Quoted string 614 i++; 615 buf.setSize(0); 616 617 while (i < (size - 1)) { 618 ch = rawText[i]; 619 620 if (ch == (byte)'\\') { 621 byte ch1 = rawText[i + 1]; 622 623 if (ch1 == (byte)'\\' || ch1 == (byte)'"') { 624 buf.addElement(ch1); 625 } 626 627 i += 2; 628 } else if (ch == '"') { 629 result.addElement(buf.toArray()); 630 i++; 631 632 break; 633 } else { 634 buf.addElement(ch); 635 i++; 636 } 637 } 638 } else if (ch == '{') { 639 // Literal string 640 int p = StringArrays.indexOf(rawText, (byte)'}', i); 641 int len = StringArrays.parseInt(rawText, i + 1, p - i - 1); 642 i = p + 3; 643 result.addElement(Arrays.copy(rawText, i, len)); 644 i += len; 645 646 // Check for invalid length, etc 647 } else if (ch == ' ') { 648 // Skip the space 649 i++; 650 } else { 651 // Keyword 652 int p1 = StringArrays.indexOf(rawText, (byte)' ', i); 653 int p2 = StringArrays.indexOf(rawText, (byte)')', i); 654 int p; 655 656 if (p1 == -1) { 657 p = p2; 658 } else if (p2 == -1) { 659 p = p1; 660 } else { 661 p = Math.min(p1, p2); 662 } 663 664 // check if p == -1, and bomb out 665 if(p == -1) { 666 p = size; 667 } 668 try { 669 result.addElement(new String(rawText, i, p - i, US_ASCII)); 670 } catch (UnsupportedEncodingException e) { 671 result.addElement(new String(rawText, i, p - i)); 672 } 673 674 i = p; 675 } 676 } 677 678 return result; 679 } 680 681 /** 682 * Recursively parse an IMAP parenthesized string. 683 * <p> 684 * Parses through a string of the form "(A (B C (D) E F))" and 685 * returns a tree of representing its contents. Each element will either 686 * be a <code>Vector</code>, <code>String</code>, or a <code>byte[]</code>. 687 * Vectors are elements that contain other elements, strings are unquoted 688 * elements (e.g. keywords, flags, numbers), and byte arrays are quoted 689 * text or literals. 690 * </p> 691 * 692 * @param rawText The raw text to be parsed 693 * @return A tree containing the parsed data 694 */ 695 static Vector parenListParser(byte[] rawText) { 696 return parenListParser(rawText, 0, rawText.length); 697 } 698 699 /** 700 * Recursively parse an IMAP parenthesized string. 701 * <p> 702 * Parses through a string of the form "(A (B C (D) E F))" and 703 * returns a tree of representing its contents. Each element will either 704 * be a <code>Vector</code>, <code>String</code>, or a <code>byte[]</code>. 705 * Vectors are elements that contain other elements, strings are unquoted 706 * elements (e.g. keywords, flags, numbers), and byte arrays are quoted 707 * text or literals. 708 * </p> 709 * 710 * @param rawText The raw text to be parsed 711 * @param The offset to start parsing from 712 * @param length The length of the data to parse 713 * @return A tree containing the parsed data 714 */ 715 static Vector parenListParser(byte[] rawText, int offset, int length) { 716 Vector tokenized = parenListLexer(rawText, offset, length); 717 MutableInteger mutableInteger = new MutableInteger(); 718 Vector result = parenListParserImpl(tokenized, mutableInteger); 719 return result; 720 } 721 722 static Vector parenListParserImpl(Vector tokenized, MutableInteger index) { 723 Vector result = new Vector(); 724 Object element = tokenized.elementAt(++index.value); 725 726 while (element != RPAREN) { 727 if (element == LPAREN) { 728 result.addElement(parenListParserImpl(tokenized, index)); 729 } else { 730 result.addElement(element); 731 } 732 733 element = tokenized.elementAt(++index.value); 734 } 735 736 return result; 737 } 738 576 739 /** 577 740 * Simple container for a parsed message structure tree … … 589 752 public MessageSection[] subsections; 590 753 } 754 755 private static class MutableInteger { 756 public int value = 0; 757 } 591 758 } -
trunk/LogicMail/src/org/logicprobe/LogicMail/mail/imap/ImapProtocol.java
r676 r689 33 33 import net.rim.device.api.system.EventLogger; 34 34 import net.rim.device.api.util.Arrays; 35 import net.rim.device.api.util. ToIntHashtable;35 import net.rim.device.api.util.IntIntHashtable; 36 36 37 37 import org.logicprobe.LogicMail.AppInfo; … … 40 40 import org.logicprobe.LogicMail.message.MessageEnvelope; 41 41 import org.logicprobe.LogicMail.util.Connection; 42 import org.logicprobe.LogicMail.util.ConnectionResponseTester; 43 import org.logicprobe.LogicMail.util.StringArrays; 42 44 import org.logicprobe.LogicMail.util.StringParser; 43 45 … … 52 54 */ 53 55 public class ImapProtocol { 56 54 57 private Connection connection; 55 58 private String idleCommandTag; 56 59 57 60 /** 58 61 * Counts the commands executed so far in this session. Every command of an … … 66 69 } 67 70 68 69 71 /** 70 72 * Execute the "STARTTLS" command. … … 75 77 if (EventLogger.getMinimumLevel() >= EventLogger.DEBUG_INFO) { 76 78 EventLogger.logEvent(AppInfo.GUID, 77 ("ImapProtocol.executeStartTLS()").getBytes(), 78 EventLogger.DEBUG_INFO); 79 } 79 ("ImapProtocol.executeStartTLS()").getBytes(), 80 EventLogger.DEBUG_INFO); 81 } 82 80 83 execute(STARTTLS, null, null); 81 84 } … … 88 91 */ 89 92 public boolean executeLogin(String username, String password) 90 throws IOException, MailException {91 if (EventLogger.getMinimumLevel() >= EventLogger.DEBUG_INFO) { 92 EventLogger.logEvent(AppInfo.GUID, 93 ("ImapProtocol.executeLogin(\"" + username + "\", \"" +94 password + "\")").getBytes(), EventLogger.DEBUG_INFO);93 throws IOException, MailException { 94 if (EventLogger.getMinimumLevel() >= EventLogger.DEBUG_INFO) { 95 EventLogger.logEvent(AppInfo.GUID, 96 ("ImapProtocol.executeLogin(\"" + username + "\", \"" + 97 password + "\")").getBytes(), EventLogger.DEBUG_INFO); 95 98 } 96 99 … … 98 101 try { 99 102 execute(LOGIN, 100 CHAR_QUOTE + StringParser.addEscapedChars(username) + "\" \"" +101 StringParser.addEscapedChars(password) + CHAR_QUOTE, null);103 CHAR_QUOTE + StringParser.addEscapedChars(username) + "\" \"" + 104 StringParser.addEscapedChars(password) + CHAR_QUOTE, null); 102 105 } catch (MailException exp) { 103 106 // Invalid users are caught by execute() … … 115 118 if (EventLogger.getMinimumLevel() >= EventLogger.DEBUG_INFO) { 116 119 EventLogger.logEvent(AppInfo.GUID, 117 ("ImapProtocol.executeLogout()").getBytes(),118 EventLogger.DEBUG_INFO);120 ("ImapProtocol.executeLogout()").getBytes(), 121 EventLogger.DEBUG_INFO); 119 122 } 120 123 … … 128 131 if (EventLogger.getMinimumLevel() >= EventLogger.DEBUG_INFO) { 129 132 EventLogger.logEvent(AppInfo.GUID, 130 ("ImapProtocol.executeClose()").getBytes(),131 EventLogger.DEBUG_INFO);133 ("ImapProtocol.executeClose()").getBytes(), 134 EventLogger.DEBUG_INFO); 132 135 } 133 136 … … 143 146 if (EventLogger.getMinimumLevel() >= EventLogger.DEBUG_INFO) { 144 147 EventLogger.logEvent(AppInfo.GUID, 145 ("ImapProtocol.executeCapability()").getBytes(),146 EventLogger.DEBUG_INFO);148 ("ImapProtocol.executeCapability()").getBytes(), 149 EventLogger.DEBUG_INFO); 147 150 } 148 151 … … 170 173 */ 171 174 public NamespaceResponse executeNamespace() 172 throws IOException, MailException {173 if (EventLogger.getMinimumLevel() >= EventLogger.DEBUG_INFO) { 174 EventLogger.logEvent(AppInfo.GUID, 175 ("ImapProtocol.executeNamespace()").getBytes(),176 EventLogger.DEBUG_INFO);177 } 178 179 String[] replyText = execute(NAMESPACE, null, null);175 throws IOException, MailException { 176 if (EventLogger.getMinimumLevel() >= EventLogger.DEBUG_INFO) { 177 EventLogger.logEvent(AppInfo.GUID, 178 ("ImapProtocol.executeNamespace()").getBytes(), 179 EventLogger.DEBUG_INFO); 180 } 181 182 byte[][] replyText = executeResponse(NAMESPACE, null, null); 180 183 181 184 if ((replyText == null) || (replyText.length < 1)) { … … 183 186 } 184 187 185 // Assume a single-line reply 186 Vector tokens = StringParser.nestedParenStringLexer("(" + 187 replyText[0].substring(replyText[0].indexOf('(')) + ")"); 188 // Assume a single-line reply, and modify that reply so its enclosed 189 // within a set of outer parenthesis so that the parser is happy. 190 int offset = Arrays.getIndex(replyText[0], (byte)'('); 191 byte[] data = new byte[(replyText[0].length - offset) + 2]; 192 data[0] = (byte)'('; 193 int j = 1; 194 for(int i=offset; i<replyText[0].length; i++) { 195 data[j++] = replyText[0][i]; 196 } 197 data[j] = (byte)')'; 198 199 Vector tokens = ImapParser.parenListParser(data); 188 200 189 201 // Sanity check on results … … 210 222 211 223 if (temp.size() >= 2) { 212 if (temp.elementAt(0) instanceof String) { 213 response.personal[i].prefix = 214 StringParser.removeEscapedChars((String) temp.elementAt(0)); 224 if (temp.elementAt(0) instanceof byte[]) { 225 response.personal[i].prefix = new String((byte[]) temp.elementAt(0)); 215 226 } 216 227 217 if (temp.elementAt(1) instanceof String) { 218 response.personal[i].delimiter = 219 StringParser.removeEscapedChars((String) temp.elementAt(1)); 228 if (temp.elementAt(1) instanceof byte[]) { 229 response.personal[i].delimiter = new String((byte[]) temp.elementAt(1)); 220 230 } 221 231 } … … 236 246 237 247 if (temp.size() >= 2) { 238 if (temp.elementAt(0) instanceof String) { 239 response.other[i].prefix = 240 StringParser.removeEscapedChars((String) temp.elementAt(0)); 248 if (temp.elementAt(0) instanceof byte[]) { 249 response.other[i].prefix = new String((byte[]) temp.elementAt(0)); 241 250 } 242 251 243 if (temp.elementAt(1) instanceof String) { 244 response.other[i].delimiter = 245 StringParser.removeEscapedChars((String) temp.elementAt(1)); 252 if (temp.elementAt(1) instanceof byte[]) { 253 response.other[i].delimiter = new String((byte[]) temp.elementAt(1)); 246 254 } 247 255 } … … 262 270 263 271 if (temp.size() >= 2) { 264 if (temp.elementAt(0) instanceof String) { 265 response.shared[i].prefix = 266 StringParser.removeEscapedChars((String) temp.elementAt(0)); 272 if (temp.elementAt(0) instanceof byte[]) { 273 response.shared[i].prefix = new String((byte[]) temp.elementAt(0)); 267 274 } 268 275 269 if (temp.elementAt(1) instanceof String) { 270 response.shared[i].delimiter = 271 StringParser.removeEscapedChars((String) temp.elementAt(1)); 276 if (temp.elementAt(1) instanceof byte[]) { 277 response.shared[i].delimiter = new String((byte[]) temp.elementAt(1)); 272 278 } 273 279 } … … 285 291 */ 286 292 public SelectResponse executeSelect(String mboxpath) 287 throws IOException, MailException {288 if (EventLogger.getMinimumLevel() >= EventLogger.DEBUG_INFO) { 289 EventLogger.logEvent(AppInfo.GUID, 290 ("ImapProtocol.executeSelect(\"" + mboxpath + "\")").getBytes(),291 EventLogger.DEBUG_INFO);293 throws IOException, MailException { 294 if (EventLogger.getMinimumLevel() >= EventLogger.DEBUG_INFO) { 295 EventLogger.logEvent(AppInfo.GUID, 296 ("ImapProtocol.executeSelect(\"" + mboxpath + "\")").getBytes(), 297 EventLogger.DEBUG_INFO); 292 298 } 293 299 294 300 String[] replyText = execute(SELECT, 295 CHAR_QUOTE + StringParser.addEscapedChars(mboxpath) + CHAR_QUOTE, null); 301 CHAR_QUOTE + StringParser.addEscapedChars(mboxpath) + 302 CHAR_QUOTE, null); 296 303 SelectResponse response = new SelectResponse(); 297 304 … … 308 315 if ((q != -1) && (p != -1) && (q > p)) { 309 316 try { 310 response.exists = Integer.parseInt( 311 rowText.substring(p +1, q));317 response.exists = Integer.parseInt(rowText.substring(p + 318 1, q)); 312 319 } catch (NumberFormatException e) { 313 320 response.exists = 0; … … 320 327 if ((q != -1) && (p != -1) && (q > p)) { 321 328 try { 322 response.recent = Integer.parseInt( 323 rowText.substring(p +1, q));329 response.recent = Integer.parseInt(rowText.substring(p + 330 1, q)); 324 331 } catch (NumberFormatException e) { 325 332 response.recent = 0; … … 332 339 if ((q != -1) && (p != -1) && (q > p)) { 333 340 try { 334 response.unseen = Integer.parseInt( 335 rowText.substring(p +1, q));341 response.unseen = Integer.parseInt(rowText.substring(p + 342 1, q)); 336 343 } catch (NumberFormatException e) { 337 344 response.unseen = 0; … … 344 351 if ((q != -1) && (p != -1) && (q > p)) { 345 352 try { 346 response.uidValidity = Integer.parseInt( 347 rowText.substring(p +1, q));353 response.uidValidity = Integer.parseInt(rowText.substring(p + 354 1, q)); 348 355 } catch (NumberFormatException e) { 349 356 response.uidValidity = 0; … … 356 363 if ((q != -1) && (p != -1) && (q > p)) { 357 364 try { 358 response.uidNext = Integer.parseInt( 359 rowText.substring(p +1, q));365 response.uidNext = Integer.parseInt(rowText.substring(p + 366 1, q)); 360 367 } catch (NumberFormatException e) { 361 368 response.uidNext = -1; … … 371 378 if (EventLogger.getMinimumLevel() >= EventLogger.DEBUG_INFO) { 372 379 EventLogger.logEvent(AppInfo.GUID, 373 ("ImapProtocol.executeExpunge()").getBytes(),374 EventLogger.DEBUG_INFO);380 ("ImapProtocol.executeExpunge()").getBytes(), 381 EventLogger.DEBUG_INFO); 375 382 } 376 383 … … 378 385 } 379 386 380 public StatusResponse[] executeStatus(String[] mboxpaths, MailProgressHandler progressHandler)381 throws IOException, MailException {387 public StatusResponse[] executeStatus(String[] mboxpaths, 388 MailProgressHandler progressHandler) throws IOException, MailException { 382 389 if (EventLogger.getMinimumLevel() >= EventLogger.DEBUG_INFO) { 383 390 StringBuffer buf = new StringBuffer(); … … 394 401 buf.append("})"); 395 402 EventLogger.logEvent(AppInfo.GUID, buf.toString().getBytes(), 396 EventLogger.DEBUG_INFO);403 EventLogger.DEBUG_INFO); 397 404 } 398 405 … … 403 410 404 411 for (i = 0; i < mboxpaths.length; i++) { 405 arguments[i] = CHAR_QUOTE + StringParser.addEscapedChars(mboxpaths[i]) + 406 "\" (MESSAGES UNSEEN)"; 412 arguments[i] = CHAR_QUOTE + 413 StringParser.addEscapedChars(mboxpaths[i]) + 414 "\" (MESSAGES UNSEEN)"; 407 415 } 408 416 … … 427 435 } 428 436 429 String[] fields = StringParser.parseTokenString( 430 result[i].substring(p +1, q), CHAR_SP);437 String[] fields = StringParser.parseTokenString(result[i].substring(p + 438 1, q), CHAR_SP); 431 439 432 440 if (fields.length != 4) { … … 459 467 * @return Array of FetchFlagsResponse objects 460 468 */ 461 public FetchFlagsResponse[] executeFetchFlags( 462 int firstIndex, 463 int lastIndex, 464 MailProgressHandler progressHandler) throws IOException, MailException { 465 if (EventLogger.getMinimumLevel() >= EventLogger.DEBUG_INFO) { 466 EventLogger.logEvent(AppInfo.GUID, 467 ("ImapProtocol.executeFetchFlags(" + firstIndex + ", " + 468 lastIndex + ")").getBytes(), EventLogger.DEBUG_INFO); 469 } 470 471 String[] rawList = execute(FETCH, 469 public FetchFlagsResponse[] executeFetchFlags(int firstIndex, 470 int lastIndex, MailProgressHandler progressHandler) 471 throws IOException, MailException { 472 if (EventLogger.getMinimumLevel() >= EventLogger.DEBUG_INFO) { 473 EventLogger.logEvent(AppInfo.GUID, 474 ("ImapProtocol.executeFetchFlags(" + firstIndex + ", " + 475 lastIndex + ")").getBytes(), EventLogger.DEBUG_INFO); 476 } 477 478 byte[][] rawList = executeResponse(FETCH, 472 479 Integer.toString(firstIndex) + CHAR_COLON + 473 480 Integer.toString(lastIndex) + " (FLAGS UID)", progressHandler); … … 482 489 * @return Array of FetchFlagsResponse objects 483 490 */ 484 public FetchFlagsResponse[] executeFetchFlagsUid( 485 int uidNext,486 MailProgressHandler progressHandler) throws IOException, MailException{487 if (EventLogger.getMinimumLevel() >= EventLogger.DEBUG_INFO) {488 EventLogger.logEvent(AppInfo.GUID,489 ("ImapProtocol.executeFetchFlagsUid(" + uidNext + ")").getBytes(),490 EventLogger.DEBUG_INFO);491 } 492 493 String[] rawList = execute(UID_FETCH,494 Integer.toString(uidNext) + CHAR_COLON_ASTERISK +" (FLAGS UID)", progressHandler);491 public FetchFlagsResponse[] executeFetchFlagsUid(int uidNext, 492 MailProgressHandler progressHandler) throws IOException, MailException { 493 if (EventLogger.getMinimumLevel() >= EventLogger.DEBUG_INFO) { 494 EventLogger.logEvent(AppInfo.GUID, 495 ("ImapProtocol.executeFetchFlagsUid(" + uidNext + ")").getBytes(), 496 EventLogger.DEBUG_INFO); 497 } 498 499 byte[][] rawList = executeResponse(UID_FETCH, 500 Integer.toString(uidNext) + CHAR_COLON_ASTERISK + 501 " (FLAGS UID)", progressHandler); 495 502 496 503 return prepareFetchFlagsResponse(rawList, progressHandler); 497 504 } 498 505 499 private FetchFlagsResponse[] prepareFetchFlagsResponse( 500 String[] rawList, MailProgressHandler progressHandler) throws IOException, MailException { 501 502 if(progressHandler != null) { progressHandler.mailProgress(MailProgressHandler.TYPE_PROCESSING, 0, -1); } 503 // Preprocess the returned text to clean up mid-field line breaks 504 // This should all become unnecessary once execute() 505 // becomes more intelligent in how it handles replies 506 Vector rawList2 = prepareCleanFetchResponse(rawList); 506 private FetchFlagsResponse[] prepareFetchFlagsResponse(byte[][] rawList, 507 MailProgressHandler progressHandler) throws IOException, MailException { 508 if (progressHandler != null) { 509 progressHandler.mailProgress(MailProgressHandler.TYPE_PROCESSING, 510 0, -1); 511 } 507 512 508 513 Vector flagResponses = new Vector(); 509 int size = rawList2.size(); 510 511 if(progressHandler != null) { progressHandler.mailProgress(MailProgressHandler.TYPE_PROCESSING, 0, size); } 512 for (int i = 0; i < size; i++) { 514 515 if (progressHandler != null) { 516 progressHandler.mailProgress( 517 MailProgressHandler.TYPE_PROCESSING, 0, rawList.length); 518 } 519 520 for (int i = 0; i < rawList.length; i++) { 521 byte[] rawText = rawList[i]; 522 if(rawText == null || rawText.length == 0 || rawText[0] != CHAR_ASTERISK) { 523 continue; 524 } 525 513 526 try { 514 String rawText = (String) rawList2.elementAt(i);515 516 527 Vector parsedText = null; 517 528 518 529 try { 519 parsedText = StringParser.nestedParenStringLexer(rawText.substring(520 rawText.indexOf('(')));530 int offset = Arrays.getIndex(rawText, (byte)'('); 531 parsedText = ImapParser.parenListParser(rawText, offset, rawText.length - offset); 521 532 } catch (Exception exp) { 522 533 parsedText = null; 534 523 535 continue; 524 536 } … … 533 545 for (int j = 0; j < parsedSize; j++) { 534 546 if (parsedText.elementAt(j) instanceof String) { 535 if (((String) parsedText.elementAt(j)).equals(FLAGS)536 && (parsedSize > (j + 1))537 &&parsedText.elementAt(j + 1) instanceof Vector) {538 flagRespItem.flags = ImapParser.parseMessageFlags((Vector) parsedText.elementAt(j + 1));539 }540 else if (((String)parsedText.elementAt(j)).equals(UID)541 && (parsedSize > (j + 1))542 &&parsedText.elementAt(j + 1) instanceof String) {547 if (((String) parsedText.elementAt(j)).equals(FLAGS) && 548 (parsedSize > (j + 1)) && 549 parsedText.elementAt(j + 1) instanceof Vector) { 550 flagRespItem.flags = ImapParser.parseMessageFlags((Vector) parsedText.elementAt(j + 551 1)); 552 } else if (((String) parsedText.elementAt(j)).equals( 553 UID) && (parsedSize > (j + 1)) && 554 parsedText.elementAt(j + 1) instanceof String) { 543 555 try { 544 flagRespItem.uid = Integer.parseInt((String) parsedText.elementAt(j + 1)); 556 flagRespItem.uid = Integer.parseInt((String) parsedText.elementAt(j + 557 1)); 545 558 } catch (NumberFormatException e) { 546 559 flagRespItem.uid = -1; … … 555 568 556 569 // Find the message index in the reply 557 int midx = Integer.parseInt(rawText.substring(rawText.indexOf( 558 ' '), rawText.indexOf(FETCH) - 1).trim()); 570 int spaceIndex = Arrays.getIndex(rawText, (byte)' '); 571 int fetchIndex = StringArrays.indexOf(rawText, FETCH.getBytes(), spaceIndex); 572 int midx = StringArrays.parseInt(rawText, spaceIndex + 1, fetchIndex - spaceIndex - 2); 559 573 560 574 flagRespItem.index = midx; … … 562 576 } catch (Exception exp) { 563 577 EventLogger.logEvent(AppInfo.GUID, 564 ("Parse error: " + exp).getBytes(), 565 EventLogger.ERROR); 566 } 567 if(progressHandler != null) { progressHandler.mailProgress(MailProgressHandler.TYPE_PROCESSING, i, size); } 578 ("Parse error: " + exp).getBytes(), EventLogger.ERROR); 579 } 580 581 if (progressHandler != null) { 582 progressHandler.mailProgress( 583 MailProgressHandler.TYPE_PROCESSING, i, rawList.length); 584 } 568 585 } 569 586 570 587 FetchFlagsResponse[] result = new FetchFlagsResponse[flagResponses.size()]; 571 588 flagResponses.copyInto(result); 572 if(progressHandler != null) { progressHandler.mailProgress(MailProgressHandler.TYPE_PROCESSING, size, size); } 589 590 if (progressHandler != null) { 591 progressHandler.mailProgress( 592 MailProgressHandler.TYPE_PROCESSING, 593 rawList.length, rawList.length); 594 } 573 595 574 596 return result; … … 582 604 * @param progressHandler the progress handler 583 605 */ 584 public void executeFetchEnvelope( 585 int firstIndex, 586 int lastIndex, 587 FetchEnvelopeCallback callback, 588 MailProgressHandler progressHandler) throws IOException, MailException { 589 if (EventLogger.getMinimumLevel() >= EventLogger.DEBUG_INFO) { 590 EventLogger.logEvent(AppInfo.GUID, 591 ("ImapProtocol.executeFetchEnvelope(" + firstIndex + ", " + 592 lastIndex + ")").getBytes(), EventLogger.DEBUG_INFO); 593 } 594 595 String[] rawList = execute(FETCH, 606 public void executeFetchEnvelope(int firstIndex, int lastIndex, 607 FetchEnvelopeCallback callback, MailProgressHandler progressHandler) 608 throws IOException, MailException { 609 if (EventLogger.getMinimumLevel() >= EventLogger.DEBUG_INFO) { 610 EventLogger.logEvent(AppInfo.GUID, 611 ("ImapProtocol.executeFetchEnvelope(" + firstIndex + ", " + 612 lastIndex + ")").getBytes(), EventLogger.DEBUG_INFO); 613 } 614 615 byte[][] rawList = executeResponse(FETCH, 596 616 Integer.toString(firstIndex) + CHAR_COLON + 597 Integer.toString(lastIndex) + " (FLAGS UID ENVELOPE BODYSTRUCTURE)", progressHandler); 617 Integer.toString(lastIndex) + 618 " (FLAGS UID ENVELOPE BODYSTRUCTURE)", progressHandler); 598 619 599 620 prepareFetchEnvelopeResponse(rawList, callback, progressHandler); … … 606 627 * @param progressHandler the progress handler 607 628 */ 608 public void executeFetchEnvelopeUid(int uidNext, FetchEnvelopeCallback callback, MailProgressHandler progressHandler) 609 throws IOException, MailException { 610 if (EventLogger.getMinimumLevel() >= EventLogger.DEBUG_INFO) { 611 EventLogger.logEvent(AppInfo.GUID, 612 ("ImapProtocol.executeFetchEnvelopeUid(" + uidNext + ")").getBytes(), 613 EventLogger.DEBUG_INFO); 614 } 615 616 String[] rawList = execute(UID_FETCH, 617 Integer.toString(uidNext) + CHAR_COLON_ASTERISK + " (FLAGS UID ENVELOPE BODYSTRUCTURE)", progressHandler); 629 public void executeFetchEnvelopeUid(int uidNext, 630 FetchEnvelopeCallback callback, MailProgressHandler progressHandler) 631 throws IOException, MailException { 632 if (EventLogger.getMinimumLevel() >= EventLogger.DEBUG_INFO) { 633 EventLogger.logEvent(AppInfo.GUID, 634 ("ImapProtocol.executeFetchEnvelopeUid(" + uidNext + ")").getBytes(), 635 EventLogger.DEBUG_INFO); 636 } 637 638 byte[][] rawList = executeResponse(UID_FETCH, 639 Integer.toString(uidNext) + CHAR_COLON_ASTERISK + 640 " (FLAGS UID ENVELOPE BODYSTRUCTURE)", progressHandler); 618 641 619 642 prepareFetchEnvelopeResponse(rawList, callback, progressHandler); … … 626 649 * @param progressHandler the progress handler 627 650 */ 628 public void executeFetchEnvelopeUid(int[] uids, FetchEnvelopeCallback callback, MailProgressHandler progressHandler) 629 throws IOException, MailException { 630 if(uids.length == 0) { callback.responseAvailable(null); return; } 651 public void executeFetchEnvelopeUid(int[] uids, 652 FetchEnvelopeCallback callback, MailProgressHandler progressHandler) 653 throws IOException, MailException { 654 if (uids.length == 0) { 655 callback.responseAvailable(null); 656 657 return; 658 } 659 631 660 StringBuffer buf = new StringBuffer(); 632 for(int i=0; i<uids.length - 1; i++) { 661 662 for (int i = 0; i < (uids.length - 1); i++) { 633 663 buf.append(uids[i]); 634 664 buf.append(','); 635 665 } 666 636 667 buf.append(uids[uids.length - 1]); 668 637 669 String uidList = buf.toString(); 638 670 639 671 if (EventLogger.getMinimumLevel() >= EventLogger.DEBUG_INFO) { 640 672 EventLogger.logEvent(AppInfo.GUID, 641 ("ImapProtocol.executeFetchEnvelopeUid(" + uidList + ")").getBytes(),642 EventLogger.DEBUG_INFO);643 } 644 645 String[] rawList = execute(UID_FETCH,673 ("ImapProtocol.executeFetchEnvelopeUid(" + uidList + ")").getBytes(), 674 EventLogger.DEBUG_INFO); 675 } 676 677 byte[][] rawList = executeResponse(UID_FETCH, 646 678 uidList + " (FLAGS UID ENVELOPE BODYSTRUCTURE)", progressHandler); 647 679 … … 649 681 } 650 682 651 private void prepareFetchEnvelopeResponse( 652 String[] rawList, FetchEnvelopeCallback callback, MailProgressHandler progressHandler) throws IOException, MailException { 653 654 if(progressHandler != null) { progressHandler.mailProgress(MailProgressHandler.TYPE_PROCESSING, 0, -1); } 655 // Preprocess the returned text to clean up mid-field line breaks 656 // This should all become unnecessary once execute() 657 // becomes more intelligent in how it handles replies 658 Vector rawList2 = prepareCleanFetchResponse(rawList); 659 660 int size = rawList2.size(); 661 662 if(progressHandler != null) { progressHandler.mailProgress(MailProgressHandler.TYPE_PROCESSING, 0, size); } 663 for (int i = 0; i < size; i++) { 683 private void prepareFetchEnvelopeResponse(byte[][] rawList, 684 FetchEnvelopeCallback callback, MailProgressHandler progressHandler) 685 throws IOException, MailException { 686 if (progressHandler != null) { 687 progressHandler.mailProgress(MailProgressHandler.TYPE_PROCESSING, 688 0, -1); 689 } 690 691 if (progressHandler != null) { 692 progressHandler.mailProgress( 693 MailProgressHandler.TYPE_PROCESSING, 0, rawList.length); 694 } 695 696 for (int i = 0; i < rawList.length; i++) { 697 byte[] rawText = rawList[i]; 698 if(rawText == null || rawText.length == 0 || rawText[0] != CHAR_ASTERISK) { 699 continue; 700 } 701 664 702 FetchEnvelopeResponse envRespItem = null; 665 703 try { 666 String rawText = (String) rawList2.elementAt(i);667 668 704 MessageEnvelope env = null; 669 705 ImapParser.MessageSection structure = null; … … 671 707 672 708 try { 673 parsedText = StringParser.nestedParenStringLexer(rawText.substring(674 rawText.indexOf('(')));709 int offset = Arrays.getIndex(rawText, (byte)'('); 710 parsedText = ImapParser.parenListParser(rawText, offset, rawText.length - offset); 675 711 } catch (Exception exp) { 676 712 continue; … … 685 721 686 722 for (int j = 0; j < parsedSize; j++) { 687 if (parsedText.elementAt(j) instanceof String) { 688 if (((String)parsedText.elementAt(j)).equals(FLAGS) 689 && (parsedSize > (j + 1)) 690 && parsedText.elementAt(j + 1) instanceof Vector) { 691 envRespItem.flags = ImapParser.parseMessageFlags((Vector) parsedText.elementAt(j + 1)); 723 if (FLAGS.equals(parsedText.elementAt(j)) 724 && (parsedSize > (j + 1)) 725 && parsedText.elementAt(j + 1) instanceof Vector) { 726 envRespItem.flags = ImapParser.parseMessageFlags((Vector) parsedText.elementAt(j + 1)); 727 } 728 else if (UID.equals(parsedText.elementAt(j)) 729 && (parsedSize > (j + 1)) 730 && parsedText.elementAt(j + 1) instanceof String) { 731 try { 732 envRespItem.uid = Integer.parseInt((String) parsedText.elementAt(j + 1)); 733 } catch (NumberFormatException e) { 734 envRespItem.uid = -1; 692 735 } 693 else if (((String)parsedText.elementAt(j)).equals(UID) 694 && (parsedSize > (j + 1)) 695 && parsedText.elementAt(j + 1) instanceof String) { 696 try { 697 envRespItem.uid = Integer.parseInt((String) parsedText.elementAt(j + 1)); 698 } catch (NumberFormatException e) { 699 envRespItem.uid = -1; 700 } 701 } 702 else if (((String)parsedText.elementAt(j)).equals(ENVELOPE) 703 && (parsedSize > (j + 1)) 704 && parsedText.elementAt(j + 1) instanceof Vector) { 705 env = ImapParser.parseMessageEnvelope((Vector) parsedText.elementAt(j + 1)); 706 } 707 else if (((String)parsedText.elementAt(j)).equals(BODYSTRUCTURE) 708 && (parsedSize > (j + 1)) 709 && parsedText.elementAt(j + 1) instanceof Vector) { 710 structure = ImapParser.parseMessageStructureParameter( 711 (Vector)parsedText.elementAt(j + 1)); 712 } 736 } 737 else if (ENVELOPE.equals(parsedText.elementAt(j)) 738 && (parsedSize > (j + 1)) 739 && parsedText.elementAt(j + 1) instanceof Vector) { 740 env = ImapParser.parseMessageEnvelope((Vector) parsedText.elementAt(j + 1)); 741 } 742 else if (BODYSTRUCTURE.equals(parsedText.elementAt(j)) 743 && (parsedSize > (j + 1)) 744 && parsedText.elementAt(j + 1) instanceof Vector) { 745 structure = ImapParser.parseMessageStructureParameter((Vector) parsedText.elementAt(j + 1)); 713 746 } 714 747 } … … 725 758 726 759 // Find the message index in the reply 727 int midx = Integer.parseInt(rawText.substring(rawText.indexOf( 728 ' '), rawText.indexOf(FETCH) - 1).trim()); 760 int spaceIndex = Arrays.getIndex(rawText, (byte)' '); 761 int fetchIndex = StringArrays.indexOf(rawText, FETCH.getBytes(), spaceIndex); 762 int midx = StringArrays.parseInt(rawText, spaceIndex + 1, fetchIndex - spaceIndex - 2); 729 763 730 764 envRespItem.index = midx; … … 733 767 } catch (Exception exp) { 734 768 EventLogger.logEvent(AppInfo.GUID, 735 ("Parse error: " + exp).getBytes(), 736 EventLogger.ERROR); 769 ("Parse error: " + exp).getBytes(), EventLogger.ERROR); 737 770 envRespItem = null; 738 771 } 739 if(envRespItem != null) { 772 773 if (envRespItem != null) { 740 774 callback.responseAvailable(envRespItem); 741 775 } 742 if(progressHandler != null) { progressHandler.mailProgress(MailProgressHandler.TYPE_PROCESSING, i, size); } 776 777 if (progressHandler != null) { 778 progressHandler.mailProgress( 779 MailProgressHandler.TYPE_PROCESSING, i, rawList.length); 780 } 743 781 } 744 782 745 783 callback.responseAvailable(null); 746 }747 748 private static Vector prepareCleanFetchResponse(String[] rawList) {749 Vector cleanList = new Vector();750 String line;751 StringBuffer lineBuf = new StringBuffer();752 for (int i = 0; i < rawList.length; i++) {753 line = rawList[i];754 755 if ((line.length() > 0) && lineBuf.toString().startsWith(CHAR_ASTERISK_SP) &&756 line.startsWith(CHAR_ASTERISK_SP)) {757 cleanList.addElement(lineBuf.toString());758 lineBuf = new StringBuffer();759 }760 761 lineBuf.append(line);762 763 if ((i == (rawList.length - 1)) &&764 lineBuf.toString().startsWith(CHAR_ASTERISK_SP)) {765 cleanList.addElement(lineBuf.toString());766 }767 }768 return cleanList;769 784 } 770 785 … … 775 790 */ 776 791 public ImapParser.MessageSection executeFetchBodystructure(int uid) 777 throws IOException, MailException { 778 if (EventLogger.getMinimumLevel() >= EventLogger.DEBUG_INFO) { 779 EventLogger.logEvent(AppInfo.GUID, 780 ("ImapProtocol.executeFetchBodyStructure(" + uid + ")").getBytes(), 781 EventLogger.DEBUG_INFO); 782 } 783 784 String[] rawList = execute(UID_FETCH, uid + " (BODYSTRUCTURE)", null); 785 786 // Pre-process the returned text to clean up mid-field line breaks 787 // This should all become unnecessary once execute() 788 // becomes more intelligent in how it handles replies 789 String line; 790 StringBuffer lineBuf = new StringBuffer(); 791 Vector rawList2 = new Vector(); 792 throws IOException, MailException { 793 if (EventLogger.getMinimumLevel() >= EventLogger.DEBUG_INFO) { 794 EventLogger.logEvent(AppInfo.GUID, 795 ("ImapProtocol.executeFetchBodyStructure(" + uid + ")").getBytes(), 796 EventLogger.DEBUG_INFO); 797 } 798 799 byte[][] rawList = executeResponse(UID_FETCH, uid + " (BODYSTRUCTURE)", null); 800 801 ImapParser.MessageSection msgStructure = null; 792 802 793 803 for (int i = 0; i < rawList.length; i++) { 794 line = rawList[i]; 795 796 if ((line.length() > 0) && lineBuf.toString().startsWith(CHAR_ASTERISK_SP) && 797 line.startsWith(CHAR_ASTERISK_SP)) { 798 rawList2.addElement(lineBuf.toString()); 799 lineBuf = new StringBuffer(); 800 } 801 802 lineBuf.append(line); 803 804 if ((i == (rawList.length - 1)) && 805 lineBuf.toString().startsWith(CHAR_ASTERISK_SP)) { 806 rawList2.addElement(lineBuf.toString()); 807 } 808 } 809 810 ImapParser.MessageSection msgStructure = null; 811 int size = rawList2.size(); 812 813 for (int i = 0; i < size; i++) { 804 byte[] rawText = rawList[i]; 805 if(rawText == null || rawText.length == 0 || rawText[0] != CHAR_ASTERISK) { 806 continue; 807 } 808 814 809 try { 815 msgStructure = ImapParser.parseMessageStructure( (String) rawList2.elementAt(i));810 msgStructure = ImapParser.parseMessageStructure(rawText); 816 811 } catch (Exception exp) { 817 812 EventLogger.logEvent(AppInfo.GUID, 818 ("Parse error: " + exp).getBytes(), 819 EventLogger.ERROR); 813 ("Parse error: " + exp).getBytes(), EventLogger.ERROR); 820 814 } 821 815 } … … 831 825 * @return Body text as a string 832 826 */ 833 public String executeFetchBody(int uid, String address, MailProgressHandler progressHandler) 834 throws IOException, MailException { 835 if (EventLogger.getMinimumLevel() >= EventLogger.DEBUG_INFO) { 836 EventLogger.logEvent(AppInfo.GUID, 837 ("ImapProtocol.executeFetchBody(" + uid + ", \"" + address + 838 "\")").getBytes(), EventLogger.DEBUG_INFO); 839 } 840 841 String[] rawList = execute( 842 UID_FETCH, 843 uid + " (BODY[" + address + "])", 844 progressHandler); 845 846 if (rawList.length <= 1) { 847 return ""; 848 } 849 850 // Attempt to parse the message length out of the first line of the response 851 int p = rawList[0].indexOf('{'); 852 int q = rawList[0].indexOf('}'); 853 int messageLength = -1; 854 855 if ((p != -1) && (q != -1) && ((q - p) > 1)) { 856 try { 857 messageLength = Integer.parseInt(rawList[0].substring(p + 1, q)); 858 } catch (NumberFormatException e) { 859 messageLength = -1; 860 } 861 } 862 863 StringBuffer msgBuf = new StringBuffer(); 864 865 if (messageLength != -1) { 866 for (int i = 1; i < rawList.length; i++) { 867 int rawListLength = rawList[i].length(); 868 if ((rawListLength + 2) <= messageLength) { 869 msgBuf.append(rawList[i]); 870 messageLength -= rawListLength; 871 msgBuf.append(CRLF); 872 messageLength -= 2; 873 } else if (!(messageLength == 1 && rawListLength == 1 && rawList[i].charAt(0) == ')')) { 874 msgBuf.append(rawList[i].substring(0, messageLength)); 875 } 876 } 877 } else { 878 // Workaround for mail servers that sometimes append untagged 879 // replies to the end of this response 880 int lastLineIndex = rawList.length - 1; 881 882 while ((lastLineIndex > 0) && rawList[lastLineIndex].startsWith(CHAR_ASTERISK_SP)) { 883 lastLineIndex--; 884 } 885 886 for (int i = 1; i < lastLineIndex; i++) { 887 msgBuf.append(rawList[i]); 888 msgBuf.append(CRLF); 889 } 890 891 String lastLine = rawList[lastLineIndex]; 892 msgBuf.append(lastLine.substring(0, lastLine.lastIndexOf(')'))); 893 } 894 895 return msgBuf.toString(); 827 public byte[] executeFetchBody(int uid, String address, 828 MailProgressHandler progressHandler) throws IOException, MailException { 829 if (EventLogger.getMinimumLevel() >= EventLogger.DEBUG_INFO) { 830 EventLogger.logEvent(AppInfo.GUID, 831 ("ImapProtocol.executeFetchBody(" + uid + ", \"" + address + 832 "\")").getBytes(), EventLogger.DEBUG_INFO); 833 } 834 835 byte[][] rawList = executeResponse(UID_FETCH, 836 uid + " (BODY[" + address + "])", progressHandler); 837 838 if (rawList.length < 1) { 839 return new byte[0]; 840 } 841 842 int offset = Arrays.getIndex(rawList[0], (byte)'('); 843 Vector parsedList = ImapParser.parenListParser(rawList[0], offset, rawList[0].length - offset); 844 int size = parsedList.size(); 845 846 byte[] rawMessage = null; 847 for(int i=0; i<(size - 1); i++) { 848 Object element = parsedList.elementAt(i); 849 if(element instanceof String 850 && ((String)element).startsWith(BODY) 851 && parsedList.elementAt(i + 1) instanceof byte[]) { 852 rawMessage = (byte[])parsedList.elementAt(i + 1); 853 } 854 } 855 856 if(rawMessage == null) { 857 rawMessage = new byte[0]; 858 } 859 860 861 return rawMessage; 896 862 } 897 863 … … 903 869 * @return Updated standard message flags, or null if there was a parse error. 904 870 */ 905 public MessageFlags executeStore(int uid, boolean addOrRemove, String[] flags)906 throws IOException, MailException {871 public MessageFlags executeStore(int uid, boolean addOrRemove, 872 String[] flags) throws IOException, MailException { 907 873 if (EventLogger.getMinimumLevel() >= EventLogger.DEBUG_INFO) { 908 874 StringBuffer buf = new StringBuffer(); … … 919 885 920 886 EventLogger.logEvent(AppInfo.GUID, 921 ("ImapProtocol.executeStore(" + uid + ", " +922 (addOrRemove ? "add" : "remove") + ", {" + buf.toString() +923 "})").getBytes(), EventLogger.DEBUG_INFO);887 ("ImapProtocol.executeStore(" + uid + ", " + 888 (addOrRemove ? "add" : "remove") + ", {" + buf.toString() + 889 "})").getBytes(), EventLogger.DEBUG_INFO); 924 890 } 925 891 … … 947 913 948 914 MessageFlags result; 915 949 916 try { 950 917 int p = rawList[0].indexOf('('); 951 918 int q = rawList[0].lastIndexOf(')'); 952 919 Vector tokenVec = null; 920 953 921 if ((p != -1) && (q != -1) && (p < q)) { 954 Vector parsedText = 955 StringParser.nestedParenStringLexer(rawList[0].substring(p, q + 1));922 Vector parsedText = ImapParser.parenListParser( 923 rawList[0].substring(p, q + 1).getBytes()); 956 924 int size = parsedText.size(); 957 for(int i=0; i<size; i++) { 925 926 for (int i = 0; i < size; i++) { 958 927 Object element = parsedText.elementAt(i); 959 if(element instanceof String 960 && element.equals(FLAGS) 961 && i < size - 1 962 && parsedText.elementAt(i + 1) instanceof Vector) { 963 tokenVec = (Vector)parsedText.elementAt(i + 1); 928 929 if (element instanceof String && element.equals(FLAGS) && 930 (i < (size - 1)) && 931 parsedText.elementAt(i + 1) instanceof Vector) { 932 tokenVec = (Vector) parsedText.elementAt(i + 1); 933 964 934 break; 965 935 } … … 967 937 } 968 938 969 if (tokenVec != null) {939 if (tokenVec != null) { 970 940 result = ImapParser.parseMessageFlags(tokenVec); 971 } 972 else { 941 } else { 973 942 result = null; 974 943 } 975 944 } catch (Exception e) { 976 945 EventLogger.logEvent(AppInfo.GUID, 977 ("Unable to parse STORE response: " + e.toString()).getBytes(),978 EventLogger.ERROR);946 ("Unable to parse STORE response: " + e.toString()).getBytes(), 947 EventLogger.ERROR); 979 948 980 949 result = null; 981 950 } 951 982 952 return result; 983 953 } … … 990 960 */ 991 961 public void executeAppend(String mboxName, String rawMessage, 992 MessageFlags flags) throws IOException, MailException {962 MessageFlags flags) throws IOException, MailException { 993 963 String flagsString = ImapParser.createMessageFlagsString(flags); 994 964 995 965 if (EventLogger.getMinimumLevel() >= EventLogger.DEBUG_INFO) { 996 966 EventLogger.logEvent(AppInfo.GUID, 997 ("ImapProtocol.executeAppend(rawMessage, \"" + flagsString +998 "\")").getBytes(), EventLogger.DEBUG_INFO);967 ("ImapProtocol.executeAppend(rawMessage, \"" + flagsString + 968 "\")").getBytes(), EventLogger.DEBUG_INFO); 999 969 } 1000 970 1001 971 executeContinue(APPEND, 1002 CHAR_QUOTE + StringParser.addEscapedChars(mboxName) + "\" (" +1003 flagsString + ") {" + rawMessage.length() + "}", rawMessage,1004 "Unable to append message to " + mboxName);972 CHAR_QUOTE + StringParser.addEscapedChars(mboxName) + "\" (" + 973 flagsString + ") {" + rawMessage.length() + "}", rawMessage, 974 "Unable to append message to " + mboxName); 1005 975 } 1006 976 … … 1008 978 * Execute the "COPY" command to copy a message from the current mailbox 1009 979 * to a different mailbox. 1010 * 1011 * @param uid The IMAP unique ID of the message to copy. 980 * 981 * @param uid The IMAP unique ID of the message to copy. 1012 982 * @param mboxPath The path of the destination mailbox 1013 983 */ 1014 public void executeCopy(int uid, String mboxPath) throws IOException, MailException { 1015 if (EventLogger.getMinimumLevel() >= EventLogger.DEBUG_INFO) { 1016 EventLogger.logEvent(AppInfo.GUID, 1017 ("ImapProtocol.executeCopy(\"" + uid + "\", \"" + mboxPath + 1018 "\")").getBytes(), EventLogger.DEBUG_INFO); 984 public void executeCopy(int uid, String mboxPath) 985 throws IOException, MailException { 986 if (EventLogger.getMinimumLevel() >= EventLogger.DEBUG_INFO) { 987 EventLogger.logEvent(AppInfo.GUID, 988 ("ImapProtocol.executeCopy(\"" + uid + "\", \"" + mboxPath + 989 "\")").getBytes(), EventLogger.DEBUG_INFO); 1019 990 } 1020 991 1021 992 execute(UID_COPY, 1022 uid + " \"" + StringParser.addEscapedChars(mboxPath) + CHAR_QUOTE,1023 null);993 uid + " \"" + StringParser.addEscapedChars(mboxPath) + CHAR_QUOTE, 994 null); 1024 995 } 1025 996 1026 997 /** 1027 998 * Execute the "LIST" command, and return a fully parsed response. 1028 * 999 * 1029 1000 * @param refName Reference name 1030 1001 * @param mboxName Mailbox name or wildcards (i.e. "%") … … 1032 1003 * @return Vector of ListResponse objects 1033 1004 */ 1034 public Vector executeList(String refName, String mboxName, MailProgressHandler progressHandler)1035 throws IOException, MailException {1005 public Vector executeList(String refName, String mboxName, 1006 MailProgressHandler progressHandler) throws IOException, MailException { 1036 1007 // 1037 1008 // The default behavior should be to use executeListSubscribed. … … 1045 1016 /** 1046 1017 * Execute the "LSUB" command, and return a fully parsed response. 1047 * 1018 * 1048 1019 * @param refName Reference name 1049 1020 * @param mboxName Mailbox name or wildcards (i.e. "%") … … 1051 1022 * @return Vector of ListResponse objects 1052 1023 */ 1053 public Vector executeLsub(String refName, String mboxName, MailProgressHandler progressHandler)1054 throws IOException, MailException {1024 public Vector executeLsub(String refName, String mboxName, 1025 MailProgressHandler progressHandler) throws IOException, MailException { 1055 1026 return executeListImpl(LSUB, refName, mboxName, progressHandler); 1056 1027 } 1057 1028 1058 private Vector executeListImpl(String ListVerb, String refName, String mboxName, MailProgressHandler progressHandler) 1059 throws IOException, MailException { 1060 if (EventLogger.getMinimumLevel() >= EventLogger.DEBUG_INFO) { 1061 EventLogger.logEvent(AppInfo.GUID, 1062 ("ImapProtocol.executeList(\"" + refName + "\", \"" + mboxName + 1063 "\")").getBytes(), EventLogger.DEBUG_INFO); 1029 private Vector executeListImpl(String ListVerb, String refName, 1030 String mboxName, MailProgressHandler progressHandler) 1031 throws IOException, MailException { 1032 if (EventLogger.getMinimumLevel() >= EventLogger.DEBUG_INFO) { 1033 EventLogger.logEvent(AppInfo.GUID, 1034 ("ImapProtocol.executeList(\"" + refName + "\", \"" + mboxName + 1035 "\")").getBytes(), EventLogger.DEBUG_INFO); 1064 1036 } 1065 1037 … … 1067 1039 results = execute(ListVerb, 1068 1040 CHAR_QUOTE + StringParser.addEscapedChars(refName) + "\" \"" + 1069 StringParser.addEscapedChars(mboxName) + CHAR_QUOTE, progressHandler); 1041 StringParser.addEscapedChars(mboxName) + CHAR_QUOTE, 1042 progressHandler); 1070 1043 1071 1044 Vector retVec = new Vector(results.length); … … 1081 1054 int line = 0; 1082 1055 1083 if(progressHandler != null) { progressHandler.mailProgress(MailProgressHandler.TYPE_PROCESSING, 0, -1); } 1056 if (progressHandler != null) { 1057 progressHandler.mailProgress(MailProgressHandler.TYPE_PROCESSING, 1058 0, -1); 1059 } 1084 1060 1085 1061 StringBuffer buf = new StringBuffer(); 1062 1086 1063 while (line < results.length) { 1087 1064 p = results[line].indexOf('{'); … … 1091 1068 (p < q) && (q == (results[line].length() - 1))) { 1092 1069 int len = Integer.parseInt(results[line].substring(p + 1, q)); 1093 1070 1094 1071 buf.append(results[line].substring(0, p)); 1095 1072 buf.append('"'); … … 1107 1084 int resultsSize = resultsVec.size(); 1108 1085 1109 if(progressHandler != null) { progressHandler.mailProgress(MailProgressHandler.TYPE_PROCESSING, 0, resultsSize); } 1086 if (progressHandler != null) { 1087 progressHandler.mailProgress(MailProgressHandler.TYPE_PROCESSING, 1088 0, resultsSize); 1089 } 1090 1110 1091 for (int i = 0; i < resultsSize; i++) { 1111 1092 // Separate out the flag and argument strings … … 1125 1106 1126 1107 // List response is invalid if both parts are not available 1127 if(flagStr == null || argStr == null) { continue; } 1128 1108 if ((flagStr == null) || (argStr == null)) { 1109 continue; 1110 } 1111 1129 1112 response = new ListResponse(); 1130 1113 response.delim = ""; … … 1136 1119 response.noInferiors = (flagStr.indexOf(FLAG_NOINFERIORS) != -1); 1137 1120 response.marked = (flagStr.indexOf(FLAG_MARKED) != -1); 1121 1138 1122 try { 1139 1123 p = 0; … … 1198 1182 // Prevent parse errors from being fatal 1199 1183 } 1200 if(progressHandler != null) { progressHandler.mailProgress(MailProgressHandler.TYPE_PROCESSING, i, resultsSize); } 1201 } 1202 if(progressHandler != null) { progressHandler.mailProgress(MailProgressHandler.TYPE_PROCESSING, resultsSize, resultsSize); } 1184 1185 if (progressHandler != null) { 1186 progressHandler.mailProgress(MailProgressHandler.TYPE_PROCESSING, 1187 i, resultsSize); 1188 } 1189 } 1190 1191 if (progressHandler != null) { 1192 progressHandler.mailProgress(MailProgressHandler.TYPE_PROCESSING, 1193 resultsSize, resultsSize); 1194 } 1203 1195 1204 1196 return retVec; … … 1213 1205 if (EventLogger.getMinimumLevel() >= EventLogger.DEBUG_INFO) { 1214 1206 EventLogger.logEvent(AppInfo.GUID, 1215 ("ImapProtocol.executeNoop()").getBytes(), 1216 EventLogger.DEBUG_INFO); 1217 } 1207 ("ImapProtocol.executeNoop()").getBytes(), 1208 EventLogger.DEBUG_INFO); 1209 } 1210 1218 1211 String[] replyText = execute(NOOP, null, null); 1219 1212 1220 1213 if ((replyText == null) || (replyText.length < 1)) { 1221 1214 EventLogger.logEvent(AppInfo.GUID, 1222 ("Unable to read NOOP response").getBytes(),1223 EventLogger.WARNING); 1215 ("Unable to read NOOP response").getBytes(), EventLogger.WARNING); 1216 1224 1217 return false; 1225 1218 } 1226 1219 1227 for(int i=0; i<replyText.length; i++) { 1228 if(replyText[i].startsWith(CHAR_ASTERISK) && replyText[i].toLowerCase().endsWith("recent")) { 1220 for (int i = 0; i < replyText.length; i++) { 1221 if (replyText[i].startsWith(ASTERISK) && 1222 replyText[i].toLowerCase().endsWith("recent")) { 1229 1223 return true; 1230 1224 } … … 1240 1234 if (EventLogger.getMinimumLevel() >= EventLogger.DEBUG_INFO) { 1241 1235 EventLogger.logEvent(AppInfo.GUID, 1242 ("ImapProtocol.executeIdle()").getBytes(),1243 EventLogger.DEBUG_INFO);1236 ("ImapProtocol.executeIdle()").getBytes(), 1237 EventLogger.DEBUG_INFO); 1244 1238 } 1245 1239 … … 1253 1247 if (EventLogger.getMinimumLevel() >= EventLogger.DEBUG_INFO) { 1254 1248 EventLogger.logEvent(AppInfo.GUID, 1255 ("ImapProtocol.executeIdleDone()").getBytes(),1256 EventLogger.DEBUG_INFO);1249 ("ImapProtocol.executeIdleDone()").getBytes(), 1250 EventLogger.DEBUG_INFO); 1257 1251 } 1258 1252 … … 1270 1264 String result = receive(); 1271 1265 1272 if ((result != null) && result.startsWith( CHAR_ASTERISK) &&1266 if ((result != null) && result.startsWith(ASTERISK) && 1273 1267 result.toLowerCase().endsWith("recent")) { 1274 1268 return true; … … 1286 1280 * @return List of returned strings 1287 1281 */ 1288 protected String[] executeBatch(String command, String[] arguments, MailProgressHandler progressHandler)1289 throws IOException, MailException {1282 protected String[] executeBatch(String command, String[] arguments, 1283 MailProgressHandler progressHandler) throws IOException, MailException { 1290 1284 String[] result = new String[arguments.length]; 1291 1285 int count = 0; 1292 1286 1293 ToIntHashtable commandMap = new ToIntHashtable();1287 IntIntHashtable commandMap = new IntIntHashtable(); 1294 1288 StringBuffer commandBuf = new StringBuffer(); 1295 1289 1296 1290 for (int i = 0; i < arguments.length; i++) { 1297 1291 String tag = TAG_PREFIX + (commandCount++); 1298 commandMap.put( tag, i);1292 commandMap.put(StringArrays.hashCode(tag.getBytes()), i); 1299 1293 commandBuf.append(tag); 1300 1294 commandBuf.append(' '); 1301 1295 commandBuf.append(command); 1302 commandBuf.append(((arguments[i] == null) ? "" : (CHAR_SP + 1303 arguments[i]))); 1296 commandBuf.append(((arguments[i] == null) ? "" 1297 : (CHAR_SP + 1298 arguments[i]))); 1304 1299 commandBuf.append(CRLF); 1305 1300 } … … 1307 1302 int preCount = connection.getBytesReceived(); 1308 1303 connection.sendRaw(commandBuf.toString()); 1304 1309 1305 int postCount = connection.getBytesReceived(); 1310 if(progressHandler != null) { progressHandler.mailProgress(MailProgressHandler.TYPE_NETWORK, (postCount - preCount), -1); } 1311 1312 String temp; 1306 1307 if (progressHandler != null) { 1308 progressHandler.mailProgress(MailProgressHandler.TYPE_NETWORK, 1309 (postCount - preCount), -1); 1310 } 1311 1312 byte[] temp; 1313 1313 String tempResult = ""; 1314 1314 int p; … … 1318 1318 temp = connection.receive(); 1319 1319 postCount = connection.getBytesReceived(); 1320 if(progressHandler != null) { progressHandler.mailProgress(MailProgressHandler.TYPE_NETWORK, (postCount - preCount), -1); } 1321 1322 String temp2 = temp.substring(temp.indexOf(CHAR_SP) + 1); 1323 1324 if (temp2.startsWith(BAD_PREFIX) || temp2.startsWith(NO_PREFIX)) { 1325 throw new MailException(temp); 1326 } 1327 1328 p = temp.indexOf(CHAR_SP); 1329 1330 if ((p != -1) && commandMap.containsKey(temp.substring(0, p))) { 1331 result[commandMap.get(temp.substring(0, p))] = tempResult; 1320 1321 if (progressHandler != null) { 1322 progressHandler.mailProgress(MailProgressHandler.TYPE_NETWORK, 1323 (postCount - preCount), -1); 1324 } 1325 1326 p = Arrays.getIndex(temp, (byte) ' '); 1327 1328 if ((StringArrays.indexOf(temp, BAD_PREFIX, p + 1) != -1) || 1329 (StringArrays.indexOf(temp, NO_PREFIX, p + 1) != -1)) { 1330 throw new MailException(new String(temp)); 1331 } 1332 1333 int keyHashCode = StringArrays.hashCode(temp, 0, p); 1334 1335 if ((p != -1) && commandMap.containsKey(keyHashCode)) { 1336 result[commandMap.get(keyHashCode)] = tempResult; 1332 1337 tempResult = ""; 1333 1338 count++; 1334 1339 } else { 1335 tempResult = temp;1340 tempResult = new String(temp); 1336 1341 } 1337 1342 } … … 1348 1353 * @return List of returned strings 1349 1354 */ 1350 protected String[] execute(String command, String arguments, MailProgressHandler progressHandler)1351 throws IOException, MailException {1352 String[] result = new String[0];1355 protected byte[][] executeResponse(String command, String arguments, 1356 MailProgressHandler progressHandler) throws IOException, MailException { 1357 byte[][] result = new byte[0][]; 1353 1358 1354 1359 String tag = TAG_PREFIX + commandCount++ + CHAR_SP; 1355 1360 connection.sendCommand(tag + command + 1356 ((arguments == null) ? "" : (CHAR_SP + arguments))); 1361 ((arguments == null) ? "" : (CHAR_SP + arguments))); 1362 1363 byte[] tagBytes = tag.getBytes(); 1357 1364 1358 1365 int preCount = connection.getBytesReceived(); 1359 String temp = connection.receive();1366 byte[] temp = connection.receive(executeResponseTester); 1360 1367 int postCount = connection.getBytesReceived(); 1361 if(progressHandler != null) { progressHandler.mailProgress(MailProgressHandler.TYPE_NETWORK, (postCount - preCount), -1); } 1362 1363 while (!temp.startsWith(tag)) { 1368 1369 if (progressHandler != null) { 1370 progressHandler.mailProgress(MailProgressHandler.TYPE_NETWORK, 1371 (postCount - preCount), -1); 1372 } 1373 1374 while (!StringArrays.startsWith(temp, tagBytes)) { 1364 1375 Arrays.add(result, temp); 1376 preCount = postCount; 1377 temp = connection.receive(executeResponseTester); 1378 postCount = connection.getBytesReceived(); 1379 1380 if (progressHandler != null) { 1381 progressHandler.mailProgress(MailProgressHandler.TYPE_NETWORK, 1382 (postCount - preCount), -1); 1383 } 1384 } 1385 1386 if (StringArrays.startsWith(temp, BAD_PREFIX, tagBytes.length) || 1387 StringArrays.startsWith(temp, NO_PREFIX, 1388 tagBytes.length)) { 1389 throw new MailException(new String(temp)); 1390 } 1391 1392 return result; 1393 } 1394 1395 /** 1396 * Executes an IMAP command, and returns the reply as an 1397 * array of strings. 1398 * @param command IMAP command 1399 * @param arguments Arguments for the command 1400 * @param progressHandler the progress handler 1401 * @return List of returned strings 1402 */ 1403 protected String[] execute(String command, String arguments, 1404 MailProgressHandler progressHandler) throws IOException, MailException { 1405 String[] result = new String[0]; 1406 1407 String tag = TAG_PREFIX + commandCount++ + CHAR_SP; 1408 connection.sendCommand(tag + command + 1409 ((arguments == null) ? "" : (CHAR_SP + arguments))); 1410 1411 byte[] tagBytes = tag.getBytes(); 1412 1413 int preCount = connection.getBytesReceived(); 1414 byte[] temp = connection.receive(); 1415 int postCount = connection.getBytesReceived(); 1416 1417 if (progressHandler != null) { 1418 progressHandler.mailProgress(MailProgressHandler.TYPE_NETWORK, 1419 (postCount - preCount), -1); 1420 } 1421 1422 while (!StringArrays.startsWith(temp, tagBytes)) { 1423 Arrays.add(result, new String(temp)); 1365 1424 preCount = postCount; 1366 1425 temp = connection.receive(); 1367 1426 postCount = connection.getBytesReceived(); 1368 if(progressHandler != null) { progressHandler.mailProgress(MailProgressHandler.TYPE_NETWORK, (postCount - preCount), -1); } 1369 } 1370 1371 temp = temp.substring(tag.length()); 1372 1373 if (temp.startsWith(BAD_PREFIX) || temp.startsWith(NO_PREFIX)) { 1374 throw new MailException(temp); 1427 1428 if (progressHandler != null) { 1429 progressHandler.mailProgress(MailProgressHandler.TYPE_NETWORK, 1430 (postCount - preCount), -1); 1431 } 1432 } 1433 1434 if (StringArrays.startsWith(temp, BAD_PREFIX, tagBytes.length) || 1435 StringArrays.startsWith(temp, NO_PREFIX, 1436 tagBytes.length)) { 1437 throw new MailException(new String(temp)); 1375 1438 } 1376 1439 … … 1389 1452 */ 1390 1453 protected String[] executeContinue(String command, String arguments, 1391 String text, String errorMsg) throws IOException, MailException {1454 String text, String errorMsg) throws IOException, MailException { 1392 1455 String[] result = new String[0]; 1393 1456 1394 1457 String tag = TAG_PREFIX + commandCount++ + CHAR_SP; 1395 1458 connection.sendCommand(tag + command + 1396 ((arguments == null) ? "" : (CHAR_SP + arguments))); 1397 1398 String temp = connection.receive(); 1399 1400 if (!temp.startsWith(CHAR_PLUS)) { 1459 ((arguments == null) ? "" : (CHAR_SP + arguments))); 1460 1461 byte[] tagBytes = tag.getBytes(); 1462 1463 byte[] temp = connection.receive(); 1464 1465 if (Arrays.getIndex(temp, CHAR_PLUS) == -1) { 1401 1466 throw new MailException(errorMsg); 1402 1467 } … … 1407 1472 temp = connection.receive(); 1408 1473 1409 while (! temp.startsWith(tag)) {1410 Arrays.add(result, temp);1474 while (!StringArrays.startsWith(temp, tagBytes)) { 1475 Arrays.add(result, new String(temp)); 1411 1476 temp = connection.receive(); 1412 1477 } 1413 1478 1414 temp = temp.substring(tag.length());1415 1416 if (temp.startsWith(BAD_PREFIX) || temp.startsWith(NO_PREFIX)) {1417 throw new MailException( temp);1479 if (StringArrays.startsWith(temp, BAD_PREFIX, tagBytes.length) || 1480 StringArrays.startsWith(temp, NO_PREFIX, 1481 tagBytes.length)) { 1482 throw new MailException(new String(temp)); 1418 1483 } 1419 1484 … … 1430 1495 1431 1496 if (connection.available() > 0) { 1432 result = connection.receive();1497 result = new String(connection.receive()); 1433 1498 } else { 1434 1499 result = null; … … 1445 1510 */ 1446 1511 protected String executeNoReply(String command, String arguments) 1447 throws IOException, MailException {1512 throws IOException, MailException { 1448 1513 String tag = TAG_PREFIX + commandCount++ + CHAR_SP; 1449 1514 connection.sendCommand(tag + command + 1450 ((arguments == null) ? "" : (CHAR_SP + arguments)));1515 ((arguments == null) ? "" : (CHAR_SP + arguments))); 1451 1516 1452 1517 return tag; … … 1461 1526 * @return List of returned strings 1462 1527 */ 1463 protected String[] executeUntagged(String command, String arguments, String endTag)1464 throws IOException, MailException {1528 protected String[] executeUntagged(String command, String arguments, 1529 String endTag) throws IOException, MailException { 1465 1530 String[] result = new String[0]; 1466 1531 1467 1532 connection.sendCommand(command + 1468 ((arguments == null) ? "" : (CHAR_SP + arguments))); 1469 1470 String temp = connection.receive(); 1471 1472 while (!temp.startsWith(endTag)) { 1473 Arrays.add(result, temp); 1533 ((arguments == null) ? "" : (CHAR_SP + arguments))); 1534 1535 byte[] tagBytes = endTag.getBytes(); 1536 byte[] temp = connection.receive(); 1537 1538 while (!StringArrays.startsWith(temp, tagBytes)) { 1539 Arrays.add(result, new String(temp)); 1474 1540 temp = connection.receive(); 1475 1541 } 1476 1542 1477 temp = temp.substring(endTag.length());1478 1479 if (temp.startsWith(BAD_PREFIX) || temp.startsWith(NO_PREFIX)) {1480 throw new MailException( temp);1543 if (StringArrays.startsWith(temp, BAD_PREFIX, tagBytes.length) || 1544 StringArrays.startsWith(temp, NO_PREFIX, 1545 tagBytes.length)) { 1546 throw new MailException(new String(temp)); 1481 1547 } 1482 1548 1483 1549 return result; 1550 } 1551 1552 /** 1553 * Callback for fetching envelopes. 1554 */ 1555 public static interface FetchEnvelopeCallback { 1556 void responseAvailable(FetchEnvelopeResponse response); 1484 1557 } 1485 1558 … … 1506 1579 /** Message has recently arrived */ 1507 1580 public boolean recent; 1508 1581 1509 1582 /** Message has been forwarded */ 1510 1583 public boolean forwarded; … … 1580 1653 1581 1654 /** 1582 * Callback for fetching envelopes.1583 */1584 public static interface FetchEnvelopeCallback {1585 void responseAvailable(FetchEnvelopeResponse response);1586 }1587 1588 /**1589 1655 * Container for a LIST response 1590 1656 */ … … 1597 1663 public String name; 1598 1664 } 1599 1665 1666 private static ConnectionResponseTester executeResponseTester = new ConnectionResponseTester() { 1667 private static final byte CR = (byte) 0x0D; 1668 private static final byte LF = (byte) 0x0A; 1669 private int trimCount; 1670 private int lastLength = 0; 1671 private int literalLength = 0; 1672 1673 public int checkForCompleteResponse(byte[] buf, int len) { 1674 trimCount = 0; 1675 1676 if (literalLength > 0) { 1677 if ((lastLength + literalLength) < len) { 1678 lastLength += literalLength; 1679 literalLength = 0; 1680 } else { 1681 literalLength -= (len - lastLength); 1682 lastLength = len; 1683 1684 return -1; 1685 } 1686 } 1687 1688 int p = StringArrays.indexOf(buf, LF, lastLength); 1689 1690 while ((p != -1) && (p < len)) { 1691 if ((p > 0) && (buf[p - 1] == CR)) { 1692 if ((p > 3) && (buf[p - 2] == '}')) { 1693 int i = p - 3; 1694 1695 while (i >= 0) { 1696 if ((buf[i] >= '0') && (buf[i] <= '9')) { 1697 i--; 1698 } else if (buf[i] == '{') { 1699 try { 1700 literalLength = StringArrays.parseInt(buf, i + 1, p - i - 3); 1701 break; 1702 } catch (NumberFormatException e) { } 1703 } 1704 } 1705 } 1706 1707 trimCount = 2; 1708 } else { 1709 trimCount = 1; 1710 } 1711 1712 p++; 1713 1714 if (literalLength > 0) { 1715 if ((len - p) >= literalLength) { 1716 p += literalLength; 1717 literalLength = 0; 1718 } else { 1719 literalLength -= (len - p); 1720 lastLength = len; 1721 1722 return -1; 1723 } 1724 } else { 1725 lastLength = 0; 1726 literalLength = 0; 1727 1728 return p; 1729 } 1730 1731 p = StringArrays.indexOf(buf, LF, p); 1732 } 1733 1734 lastLength = len; 1735 1736 return -1; 1737 } 1738 1739 public int trimCount() { 1740 return trimCount; 1741 } 1742 1743 public String logString(byte[] result) { 1744 return new String(result); 1745 } 1746 }; 1747 1600 1748 // String constants 1601 1749 private static String UID_COPY = "UID COPY"; … … 1610 1758 private static String FETCH = "FETCH"; 1611 1759 private static String BODYSTRUCTURE = "BODYSTRUCTURE"; 1760 private static String BODY = "BODY"; 1612 1761 private static String ENVELOPE = "ENVELOPE"; 1613 1762 private static String UID = "UID"; … … 1629 1778 private static String FLAG_NOSELECT = "\\Noselect"; 1630 1779 private static String TAG_PREFIX = "A"; 1631 private static String NO_PREFIX = "NO ";1632 private static String BAD_PREFIX = "BAD ";1780 private static final byte[] NO_PREFIX = "NO ".getBytes(); 1781 private static final byte[] BAD_PREFIX = "BAD ".getBytes(); 1633 1782 private static String CHAR_SP = " "; 1634 private static String CHAR_ASTERISK = "*"; 1635 private static String CHAR_PLUS = "+"; 1783 private static final byte CHAR_PLUS = (byte) '+'; 1636 1784 private static String CHAR_COLON = ":"; 1637 private static String CHAR_ASTERISK_SP = "* "; 1785 private static final byte CHAR_ASTERISK = (byte)'*'; 1786 private static String ASTERISK = "*"; 1638 1787 private static String CHAR_QUOTE = "\""; 1639 1788 private static String CHAR_COLON_ASTERISK = ":*"; -
trunk/LogicMail/src/org/logicprobe/LogicMail/mail/pop/PopProtocol.java
r658 r689 265 265 if(execute(command, errorFatal) == null) { return null; } 266 266 267 String buffer = connection.receive();267 String buffer = new String(connection.receive()); 268 268 int postCount = connection.getBytesReceived(); 269 269 if(progressHandler != null) { progressHandler.mailProgress(MailProgressHandler.TYPE_NETWORK, (postCount - preCount), -1); } … … 273 273 Arrays.add(lines, buffer); 274 274 preCount = postCount; 275 buffer = connection.receive();275 buffer = new String(connection.receive()); 276 276 postCount = connection.getBytesReceived(); 277 277 if(progressHandler != null) { progressHandler.mailProgress(MailProgressHandler.TYPE_NETWORK, (postCount - preCount), -1); } … … 308 308 } 309 309 310 String result = connection.receive();310 String result = new String(connection.receive()); 311 311 312 312 if((result.length() > 1) && (result.charAt(0) == '-')) { -
trunk/LogicMail/src/org/logicprobe/LogicMail/mail/smtp/SmtpProtocol.java
r677 r689 397 397 } 398 398 399 String result = connection.receive();399 String result = new String(connection.receive()); 400 400 401 401 return result; … … 414 414 execute(command); 415 415 416 String buffer = connection.receive();416 String buffer = new String(connection.receive()); 417 417 String[] lines = new String[0]; 418 418 while(buffer != null) { 419 buffer = connection.receive();419 buffer = new String(connection.receive()); 420 420 Arrays.add(lines, buffer); 421 421 if(buffer.length() >=4 && buffer.charAt(3) == ' ') { -
trunk/LogicMail/src/org/logicprobe/LogicMail/message/ApplicationContent.java
r674 r689 33 33 import java.io.IOException; 34 34 35 import net.rim.device.api.io.Base64InputStream;36 37 35 public class ApplicationContent extends MimeMessageContent { 38 36 private byte[] rawData; 39 37 40 public ApplicationContent(ApplicationPart applicationPart, String encoding, Stringdata) throws UnsupportedContentException {38 public ApplicationContent(ApplicationPart applicationPart, String encoding, byte[] data) throws UnsupportedContentException { 41 39 super(applicationPart); 42 40 // Decode the binary data 43 if (encoding.equalsIgnoreCase( "base64")) {41 if (encoding.equalsIgnoreCase(ENCODING_BASE64)) { 44 42 try { 45 this.rawData = Base64InputStream.decode(data);43 this.rawData = decodeBase64(data); 46 44 } catch (IOException e) { 47 45 throw new UnsupportedContentException("Unable to decode"); … … 54 52 public ApplicationContent(ApplicationPart applicationPart, byte[] rawData) throws UnsupportedContentException { 55 53 super(applicationPart); 56 applicationPart.setEncoding( "base64");54 applicationPart.setEncoding(ENCODING_BASE64); 57 55 this.rawData = rawData; 58 56 } -
trunk/LogicMail/src/org/logicprobe/LogicMail/message/AudioContent.java
r674 r689 33 33 import java.io.IOException; 34 34 35 import net.rim.device.api.io.Base64InputStream;36 37 35 public class AudioContent extends MimeMessageContent { 38 36 private byte[] rawData; 39 37 40 public AudioContent(AudioPart audioPart, String encoding, Stringdata) throws UnsupportedContentException {38 public AudioContent(AudioPart audioPart, String encoding, byte[] data) throws UnsupportedContentException { 41 39 super(audioPart); 42 40 // Decode the binary data 43 if (encoding.equalsIgnoreCase( "base64")) {41 if (encoding.equalsIgnoreCase(ENCODING_BASE64)) { 44 42 try { 45 this.rawData = Base64InputStream.decode(data);43 this.rawData = decodeBase64(data); 46 44 } catch (IOException e) { 47 45 throw new UnsupportedContentException("Unable to decode"); … … 54 52 public AudioContent(AudioPart audioPart, byte[] rawData) { 55 53 super(audioPart); 56 audioPart.setEncoding( "base64");54 audioPart.setEncoding(ENCODING_BASE64); 57 55 this.rawData = rawData; 58 56 } -
trunk/LogicMail/src/org/logicprobe/LogicMail/message/ImageContent.java
r674 r689 33 33 import java.io.IOException; 34 34 35 import net.rim.device.api.io.Base64InputStream;36 35 import net.rim.device.api.system.EncodedImage; 37 36 … … 52 51 } 53 52 54 public ImageContent(ImagePart imagePart, String encoding, Stringdata) throws UnsupportedContentException {53 public ImageContent(ImagePart imagePart, String encoding, byte[] data) throws UnsupportedContentException { 55 54 super(imagePart); 56 55 // Decode the binary data, and create an image 57 if (encoding.equalsIgnoreCase( "base64")) {56 if (encoding.equalsIgnoreCase(ENCODING_BASE64) && data != null && data.length > 0) { 58 57 try { 59 58 String mimeSubtype = imagePart.getMimeSubtype(); 60 byte[] imgBytes = Base64InputStream.decode(data); 59 60 byte[] imgBytes = decodeBase64(data); 61 61 62 this.image = EncodedImage.createEncodedImage( 62 63 imgBytes, … … 74 75 public ImageContent(ImagePart imagePart, byte[] rawData) { 75 76 super(imagePart); 76 imagePart.setEncoding( "base64");77 imagePart.setEncoding(ENCODING_BASE64); 77 78 this.rawData = rawData; 78 79 } -
trunk/LogicMail/src/org/logicprobe/LogicMail/message/MessageContent.java
r674 r689 33 33 import java.io.IOException; 34 34 35 import net.rim.device.api.io.Base64InputStream;36 37 35 public class MessageContent extends MimeMessageContent { 38 36 private byte[] rawData; 39 37 40 public MessageContent(MessagePart messagePart, String encoding, Stringdata) throws UnsupportedContentException {38 public MessageContent(MessagePart messagePart, String encoding, byte[] data) throws UnsupportedContentException { 41 39 super(messagePart); 42 40 // Decode the binary data 43 if (encoding.equalsIgnoreCase( "base64")) {41 if (encoding.equalsIgnoreCase(ENCODING_BASE64)) { 44 42 try { 45 this.rawData = Base64InputStream.decode(data);43 this.rawData = decodeBase64(data); 46 44 } catch (IOException e) { 47 45 throw new UnsupportedContentException("Unable to decode"); 48 46 } 49 47 } else { 50 rawData = data .getBytes();48 rawData = data; 51 49 } 52 50 } … … 54 52 public MessageContent(MessagePart messagePart, byte[] rawData) { 55 53 super(messagePart); 56 messagePart.setEncoding( "base64");54 messagePart.setEncoding(ENCODING_BASE64); 57 55 this.rawData = rawData; 58 56 } -
trunk/LogicMail/src/org/logicprobe/LogicMail/message/MimeMessageContent.java
r551 r689 31 31 package org.logicprobe.LogicMail.message; 32 32 33 import java.io.ByteArrayInputStream; 34 import java.io.ByteArrayOutputStream; 33 35 import java.io.DataInput; 34 36 import java.io.DataOutput; 35 37 import java.io.IOException; 38 39 import net.rim.device.api.io.Base64InputStream; 36 40 37 41 import org.logicprobe.LogicMail.util.Serializable; … … 47 51 private long uniqueId; 48 52 private ContentPart messagePart; 53 protected static String ENCODING_BASE64 = "base64"; 49 54 50 55 /** … … 92 97 protected abstract void putRawData(byte[] rawData); 93 98 99 /** 100 * Decode the provided data as Base64. 101 * 102 * @param data byte array representing a Base64-encoded string 103 * @return decoded form of the input data 104 * @throws IOException thrown if a decoding error occurred. 105 */ 106 protected static byte[] decodeBase64(byte[] data) throws IOException { 107 if(data == null || data.length == 0) { 108 return new byte[0]; 109 } 110 111 byte[] decodedData; 112 if(data.length < 32768) { 113 decodedData = Base64InputStream.decode(data, 0, data.length); 114 } 115 else { 116 Base64InputStream inputStream = new Base64InputStream(new ByteArrayInputStream(data, 0, data.length)); 117 ByteArrayOutputStream outputStream = new ByteArrayOutputStream(65536); 118 119 byte[] buf = new byte[1024]; 120 int count; 121 while ((count = inputStream.read(buf)) >= 0) 122 { 123 outputStream.write(buf, 0, count); 124 } 125 inputStream.close(); 126 127 decodedData = outputStream.toByteArray(); 128 } 129 return decodedData; 130 } 131 94 132 /* (non-Javadoc) 95 133 * @see org.logicprobe.LogicMail.util.Serializable#getUniqueId() -
trunk/LogicMail/src/org/logicprobe/LogicMail/message/MimeMessageContentFactory.java
r674 r689 35 35 */ 36 36 public class MimeMessageContentFactory { 37 // TODO: Refactor encoding/param up into the MessagePart classes38 39 37 /** 40 38 * Creates a new MessageContent object. … … 47 45 * @throws UnsupportedContentException Thrown if the content type was not supported or the data could not be decoded. 48 46 */ 49 public static MimeMessageContent createContent (MimeMessagePart mimeMessagePart, StringencodedData) throws UnsupportedContentException {47 public static MimeMessageContent createContentEncoded(MimeMessagePart mimeMessagePart, byte[] encodedData) throws UnsupportedContentException { 50 48 MimeMessageContent content; 51 49 if(mimeMessagePart instanceof TextPart) { … … 89 87 * @throws UnsupportedContentException Thrown if the content type was not supported or the data could not be decoded. 90 88 */ 91 public static MimeMessageContent createContent (MimeMessagePart mimeMessagePart, byte[] rawData) throws UnsupportedContentException {89 public static MimeMessageContent createContentRaw(MimeMessagePart mimeMessagePart, byte[] rawData) throws UnsupportedContentException { 92 90 MimeMessageContent content; 93 91 if(mimeMessagePart instanceof TextPart) { -
trunk/LogicMail/src/org/logicprobe/LogicMail/message/TextContent.java
r674 r689 34 34 import java.io.UnsupportedEncodingException; 35 35 36 import net.rim.device.api.io.Base64InputStream;37 38 36 import org.logicprobe.LogicMail.util.StringFactory; 39 37 import org.logicprobe.LogicMail.util.StringParser; … … 54 52 String encoding, 55 53 String charset, 56 Stringdata) throws UnsupportedContentException {54 byte[] data) throws UnsupportedContentException { 57 55 super(textPart); 58 56 String mimeSubtype = textPart.getMimeSubtype(); 59 57 58 // Check for a supported text sub-type 59 if (!mimeSubtype.equalsIgnoreCase("plain") && 60 !mimeSubtype.equalsIgnoreCase("html")) { 61 throw new UnsupportedContentException("Unsupported subtype"); 62 } 63 60 64 // Check for any encodings that need to be handled 61 65 if (encoding.equalsIgnoreCase("quoted-printable")) { 62 data= StringParser.decodeQuotedPrintable(data);66 this.text = StringParser.decodeQuotedPrintable(data); 63 67 } 64 else if (encoding.equalsIgnoreCase( "base64")) {68 else if (encoding.equalsIgnoreCase(ENCODING_BASE64)) { 65 69 byte[] textBytes; 66 70 67 71 try { 68 textBytes = Base64InputStream.decode(data);72 textBytes = decodeBase64(data); 69 73 } catch (IOException exp) { 70 74 throw new UnsupportedContentException("Unable to decode"); … … 77 81 } 78 82 79 data= StringFactory.create(textBytes, charset);83 this.text = StringFactory.create(textBytes, charset); 80 84 } catch (UnsupportedEncodingException exp) { 81 85 // If encoding type is bad, attempt with the default encoding 82 86 // so the user will at least see something. 83 data= new String(textBytes);87 this.text = new String(textBytes); 84 88 } 85 89 } 86 else if ((charset != null) && 87 !charset.equalsIgnoreCase("ISO-8859-1") && 88 !charset.equalsIgnoreCase("US-ASCII")) { 90 else if (charset != null) { 89 91 // If the text is not encoded (i.e. 7bit or 8bit) and uses a 90 92 // non-Latin charset, then bring the text back to a byte array 91 93 // and attempt to decode it based on the charset parameter. 92 byte[] textBytes = data.getBytes();93 94 94 95 try { 95 data = StringFactory.create(textBytes, charset);96 this.text = StringFactory.create(data, charset); 96 97 } catch (UnsupportedEncodingException exp) { 97 // If encoding type is bad, leave the message text as98 // it was originally. This may result in the user seeing99 // garbage, but at least they'll know there was a100 // decoding problem.98 // If encoding type is bad, use the default platform charset. 99 // This may result in the user seeing garbage, but at least 100 // they'll know there was a decoding problem. 101 this.text = new String(data); 101 102 } 102 }103 104 // Check for a supported text sub-type and decode if necessary105 if (mimeSubtype.equalsIgnoreCase("plain") ||106 mimeSubtype.equalsIgnoreCase("html")) {107 this.text = data;108 }109 else {110 throw new UnsupportedContentException("Unsupported subtype");111 103 } 112 104 } -
trunk/LogicMail/src/org/logicprobe/LogicMail/message/VideoContent.java
r674 r689 33 33 import java.io.IOException; 34 34 35 import net.rim.device.api.io.Base64InputStream;36 37 35 public class VideoContent extends MimeMessageContent { 38 36 private byte[] rawData; 39 37 40 public VideoContent(VideoPart videoPart, String encoding, Stringdata) throws UnsupportedContentException {38 public VideoContent(VideoPart videoPart, String encoding, byte[] data) throws UnsupportedContentException { 41 39 super(videoPart); 42 40 // Decode the binary data 43 if (encoding.equalsIgnoreCase( "base64")) {41 if (encoding.equalsIgnoreCase(ENCODING_BASE64)) { 44 42 try { 45 this.rawData = Base64InputStream.decode(data);43 this.rawData = decodeBase64(data); 46 44 } catch (IOException e) { 47 45 throw new UnsupportedContentException("Unable to decode"); … … 54 52 public VideoContent(VideoPart videoPart, byte[] rawData) { 55 53 super(videoPart); 56 videoPart.setEncoding( "base64");54 videoPart.setEncoding(ENCODING_BASE64); 57 55 this.rawData = rawData; 58 56 } -
trunk/LogicMail/src/org/logicprobe/LogicMail/ui/CompositionScreen.java
r675 r689 659 659 MimeMessageContent bodyContent; 660 660 try { 661 bodyContent = MimeMessageContentFactory.createContent (662 bodyPart, contentText );661 bodyContent = MimeMessageContentFactory.createContentEncoded( 662 bodyPart, contentText.getBytes()); 663 663 } catch (UnsupportedContentException e) { 664 664 bodyContent = null; … … 763 763 try { 764 764 MimeMessageContent attachmentContent = 765 MimeMessageContentFactory.createContent (attachmentPart, data);765 MimeMessageContentFactory.createContentRaw(attachmentPart, data); 766 766 MultiPart multiPart = (MultiPart)pendingMessage.getStructure(); 767 767 multiPart.addPart(attachmentPart); -
trunk/LogicMail/src/org/logicprobe/LogicMail/util/Connection.java
r685 r689 97 97 private int bytesSent = 0; 98 98 private int bytesReceived = 0; 99 private final Object socketLock = new Object(); 99 100 100 101 /** … … 103 104 */ 104 105 private final ByteArrayOutputStream byteStream = new NoCopyByteArrayOutputStream(1024); 105 106 107 /** 108 * Temporary read buffer used as an intermediary between the socket and 109 * the byteStream. 110 */ 111 private final byte[] readBuffer = new byte[1024]; 112 106 113 /** 107 114 * Initializes a new connection object. … … 163 170 * Opens a connection. 164 171 */ 165 public synchronizedvoid open() throws IOException {172 public void open() throws IOException { 166 173 if ((input != null) || (output != null) || (socket != null)) { 167 174 close(); … … 170 177 utilFactory.addOpenConnection(this); 171 178 172 socket = openStreamConnection(); 173 if(socket == null) { 174 throw new IOException(resources.getString(LogicMailResource.ERROR_UNABLE_TO_OPEN_CONNECTION)); 175 } 176 177 input = socket.openDataInputStream(); 178 output = socket.openDataOutputStream(); 179 localAddress = ((SocketConnection) socket).getLocalAddress(); 180 bytesSent = 0; 181 bytesReceived = 0; 182 179 synchronized(socketLock) { 180 socket = openStreamConnection(); 181 if(socket == null) { 182 throw new IOException(resources.getString(LogicMailResource.ERROR_UNABLE_TO_OPEN_CONNECTION)); 183 } 184 185 input = socket.openDataInputStream(); 186 output = socket.openDataOutputStream(); 187 localAddress = ((SocketConnection) socket).getLocalAddress(); 188 bytesSent = 0; 189 bytesReceived = 0; 190 } 191 183 192 if (EventLogger.getMinimumLevel() >= EventLogger.INFORMATION) { 184 193 String msg = "Connection established:\r\n" + "Socket: " + … … 224 233 * Closes a connection. 225 234 */ 226 public synchronized void close() throws IOException { 227 try { 228 if (input != null) { 229 input.close(); 235 public void close() throws IOException { 236 synchronized(socketLock) { 237 try { 238 if (input != null) { 239 input.close(); 240 input = null; 241 } 242 } catch (Exception exp) { 230 243 input = null; 231 244 } 232 } catch (Exception exp) {233 input = null;234 }235 236 try {237 if (output != null) {238 output.close();245 246 try { 247 if (output != null) { 248 output.close(); 249 output = null; 250 } 251 } catch (Exception exp) { 239 252 output = null; 240 253 } 241 } catch (Exception exp) {242 output = null;243 }244 245 try {246 if (socket != null) {247 socket.close();254 255 try { 256 if (socket != null) { 257 socket.close(); 258 socket = null; 259 } 260 } catch (Exception exp) { 248 261 socket = null; 249 262 } 250 } catch (Exception exp) { 251 socket = null; 252 } 253 263 setConnectionUrl(null); 264 } 265 254 266 utilFactory.removeOpenConnection(this); 255 256 setConnectionUrl(null);257 267 258 268 EventLogger.logEvent(AppInfo.GUID, "Connection closed".getBytes(), … … 321 331 * is a prepared protocol command. 322 332 */ 323 public synchronizedvoid sendCommand(String s) throws IOException {333 public void sendCommand(String s) throws IOException { 324 334 if (globalConfig.getConnDebug()) { 325 335 EventLogger.logEvent(AppInfo.GUID, ("[SEND CMD] " + s).getBytes(), … … 327 337 } 328 338 329 if (s == null) { 330 output.write(CRLF, 0, 2); 331 bytesSent += 2; 332 } else { 333 byte[] buf = (s + strCRLF).getBytes(); 334 output.write(buf); 335 bytesSent += buf.length; 336 } 337 338 output.flush(); 339 synchronized(socketLock) { 340 if (s == null) { 341 output.write(CRLF, 0, 2); 342 bytesSent += 2; 343 } else { 344 byte[] buf = (s + strCRLF).getBytes(); 345 output.write(buf); 346 bytesSent += buf.length; 347 } 348 349 output.flush(); 350 } 339 351 } 340 352 … … 347 359 * @see #send 348 360 */ 349 public synchronizedvoid sendRaw(String s) throws IOException {361 public void sendRaw(String s) throws IOException { 350 362 byte[] buf = s.getBytes(); 351 363 … … 355 367 } 356 368 357 output.write(buf, 0, buf.length); 358 bytesSent += buf.length; 359 360 output.flush(); 369 synchronized(socketLock) { 370 output.write(buf, 0, buf.length); 371 bytesSent += buf.length; 372 373 output.flush(); 374 } 361 375 } 362 376 … … 374 388 } 375 389 } 376 390 377 391 /** 378 392 * Receives a string from the server. This method is used internally for … … 382 396 * returned as part of the result. 383 397 * 384 * @see #send 385 */ 386 public synchronized String receive() throws IOException { 387 // Check existing data for a usable line 388 String line = checkForLine(); 389 if(line != null) { 390 return line; 391 } 392 393 // Read from the socket 394 int firstByte = input.read(); 395 if(firstByte != -1) { 396 byteStream.write((byte)firstByte); 397 bytesReceived++; 398 int bytesAvailable = input.available(); 399 while(bytesAvailable > 0) { 400 byte[] buf = new byte[bytesAvailable]; 401 int len = input.read(buf); 402 byteStream.write(buf, 0, len); 403 bytesReceived += len; 398 * @return the complete line, minus the CRLF, as a byte array 399 */ 400 public byte[] receive() throws IOException { 401 return receive(lineResponseTester); 402 } 403 404 405 /** 406 * Receives a string from the server. This method is used internally for 407 * incoming communication from the server. 408 * 409 * @param responseTester class to determine when a complete response has 410 * been read from the network, and whether to trim it prior to returning 411 * @return the complete response, as a byte array 412 */ 413 public byte[] receive(ConnectionResponseTester responseTester) throws IOException { 414 byte[] result = receiveImpl(responseTester); 415 416 if(result != null && globalConfig.getConnDebug()) { 417 EventLogger.logEvent(AppInfo.GUID, 418 ("[RECV] " + responseTester.logString(result)).getBytes(), 419 EventLogger.DEBUG_INFO); 420 } 421 422 return result; 423 } 424 425 private byte[] receiveImpl(ConnectionResponseTester responseTester) throws IOException { 426 synchronized(socketLock) { 427 // Check existing data for a usable line 428 byte[] line = checkForLine(responseTester); 429 if(line != null) { 430 return line; 431 } 432 433 // Read from the socket 434 int firstByte = input.read(); 435 if(firstByte != -1) { 436 byteStream.write((byte)firstByte); 437 bytesReceived++; 438 int bytesAvailable = input.available(); 439 while(bytesAvailable > 0) { 440 int len = input.read(readBuffer); 441 byteStream.write(readBuffer, 0, len); 442 bytesReceived += len; 443 444 // Check read data for a usable line 445 line = checkForLine(responseTester); 446 if(line != null) { 447 return line; 448 } 449 450 bytesAvailable = input.available(); 451 452 // If no bytes are reported as being available, but we have 453 // not yet received a full line, then we need to attempt 454 // another single-byte blocking read. 455 if(bytesAvailable == 0) { 456 firstByte = input.read(); 457 byteStream.write((byte)firstByte); 458 bytesReceived++; 459 bytesAvailable = input.available(); 460 } 461 } 462 } 463 else { 464 // If we got here, that means that the InputStream is either closed 465 // or we are in some otherwise unrecoverable state. This means we 466 // will try to close the connection, ignore any errors from the 467 // close operation, and throw an IOException. 404 468 405 // Check read data for a usable line 406 line = checkForLine(); 407 if(line != null) { 408 return line; 409 } 410 411 bytesAvailable = input.available(); 412 413 // If no bytes are reported as being available, but we have 414 // not yet received a full line, then we need to attempt 415 // another single-byte blocking read. 416 if(bytesAvailable == 0) { 417 firstByte = input.read(); 418 byteStream.write((byte)firstByte); 419 bytesReceived++; 420 bytesAvailable = input.available(); 421 } 422 } 423 } 424 else { 425 // If we got here, that means that the InputStream is either closed 426 // or we are in some otherwise unrecoverable state. This means we 427 // will try to close the connection, ignore any errors from the 428 // close operation, and throw an IOException. 429 430 EventLogger.logEvent(AppInfo.GUID, 431 "Unable to read from socket, closing connection".getBytes(), 432 EventLogger.INFORMATION); 433 434 try { 435 close(); 436 } catch (IOException e) { } 437 438 throw new IOException("Connection closed"); 439 } 440 469 EventLogger.logEvent(AppInfo.GUID, 470 "Unable to read from socket, closing connection".getBytes(), 471 EventLogger.INFORMATION); 472 473 try { 474 close(); 475 } catch (IOException e) { } 476 477 throw new IOException("Connection closed"); 478 } 479 } 441 480 // This should never normally happen 442 481 return null; … … 450 489 * @return the trimmed string which ended in a CRLF in the source data 451 490 */ 452 private String checkForLine() throws IOException {453 Stringresult;491 private byte[] checkForLine(ConnectionResponseTester responseTester) throws IOException { 492 byte[] result; 454 493 455 494 byte[] buf = byteStream.toByteArray(); 456 495 int size = byteStream.size(); 457 496 458 int p = Arrays.getIndex(buf, LF); 459 if(p != -1 && p < size) { 460 int q = p + 1; 461 if(p > 0 && buf[p - 1] == CR) { 462 p--; 463 } 464 result = new String(buf, 0, p); 497 int p = responseTester.checkForCompleteResponse(buf, size); 498 499 if(p != -1) { 500 int trimCount = responseTester.trimCount(); 465 501 466 if (globalConfig.getConnDebug()) { 467 EventLogger.logEvent(AppInfo.GUID, 468 ("[RECV] " + result).getBytes(), 469 EventLogger.DEBUG_INFO); 470 } 502 result = Arrays.copy(buf, 0, p - trimCount); 471 503 472 if( q< size) {473 buf = Arrays.copy(buf, q, size - q);504 if(p < size) { 505 buf = Arrays.copy(buf, p, size - p); 474 506 byteStream.reset(); 475 507 byteStream.write(buf); … … 488 520 } 489 521 522 private static ConnectionResponseTester lineResponseTester = new ConnectionResponseTester() { 523 private int trimCount; 524 525 public int checkForCompleteResponse(byte[] buf, int len) { 526 trimCount = 0; 527 int p = Arrays.getIndex(buf, LF); 528 if(p != -1 && p < len) { 529 if(p > 0 && buf[p - 1] == CR) { 530 trimCount = 2; 531 } 532 else { 533 trimCount = 1; 534 } 535 return ++p; 536 } 537 else { 538 return -1; 539 } 540 } 541 542 public int trimCount() { 543 return trimCount; 544 } 545 546 public String logString(byte[] result) { 547 return new String(result); 548 }; 549 }; 550 490 551 /** 491 552 * Switches the underlying connection to SSL mode, as commonly done after … … 495 556 */ 496 557 public void startTLS() throws IOException { 497 // Shortcut the method if we're already in SSL mode 498 if(socket instanceof TLS10Connection) { return; } 499 500 if(socket == null || connectionUrl == null) { 501 throw new IOException("Connection has not been opened"); 502 } 503 504 try { 505 TLS10Connection tlsSocket = new TLS10Connection( 506 new StreamConnectionWrapper( 507 socket, 508 (DataInputStream)input, 509 (DataOutputStream)output), 510 connectionUrl, 511 true); 512 513 socket = tlsSocket; 514 input = socket.openDataInputStream(); 515 output = socket.openDataOutputStream(); 516 } catch (IOException e) { 517 EventLogger.logEvent(AppInfo.GUID, 518 ("Unable to switch to TLS mode: " + e.getMessage()).getBytes(), EventLogger.ERROR); 519 throw new IOException("Unable to switch to TLS mode"); 520 } catch (TLSException e) { 521 EventLogger.logEvent(AppInfo.GUID, 522 ("Unable to switch to TLS mode: " + e.getMessage()).getBytes(), EventLogger.ERROR); 523 throw new IOException("Unable to switch to TLS mode"); 558 synchronized(socketLock) { 559 // Shortcut the method if we're already in SSL mode 560 if(socket instanceof TLS10Connection) { return; } 561 562 if(socket == null || connectionUrl == null) { 563 throw new IOException("Connection has not been opened"); 564 } 565 566 try { 567 TLS10Connection tlsSocket = new TLS10Connection( 568 new StreamConnectionWrapper( 569 socket, 570 (DataInputStream)input, 571 (DataOutputStream)output), 572 connectionUrl, 573 true); 574 575 socket = tlsSocket; 576 input = socket.openDataInputStream(); 577 output = socket.openDataOutputStream(); 578 } catch (IOException e) { 579 EventLogger.logEvent(AppInfo.GUID, 580 ("Unable to switch to TLS mode: " + e.getMessage()).getBytes(), EventLogger.ERROR); 581 throw new IOException("Unable to switch to TLS mode"); 582 } catch (TLSException e) { 583 EventLogger.logEvent(AppInfo.GUID, 584 ("Unable to switch to TLS mode: " + e.getMessage()).getBytes(), EventLogger.ERROR); 585 throw new IOException("Unable to switch to TLS mode"); 586 } 524 587 } 525 588 } -
trunk/LogicMail/src/org/logicprobe/LogicMail/util/MailMessageParser.java
r640 r689 34 34 import net.rim.device.api.mime.MIMEInputStream; 35 35 import net.rim.device.api.mime.MIMEParsingException; 36 import net.rim.device.api.util.Arrays; 36 37 37 38 import org.logicprobe.LogicMail.AppInfo; … … 275 276 int size = buffer.length - offset; 276 277 277 String data = new String(buffer, offset, size);278 byte[] data = Arrays.copy(buffer, offset, size); 278 279 MimeMessagePart part = MimeMessagePartFactory.createMimeMessagePart( 279 280 type, subtype, name, encoding, charset, disposition, contentId, size); 280 281 try { 281 contentMap.put(part, MimeMessageContentFactory.createContent (part, data));282 contentMap.put(part, MimeMessageContentFactory.createContentEncoded(part, data)); 282 283 } catch (UnsupportedContentException e) { 283 284 System.err.println("UnsupportedContentException: " + e.getMessage()); … … 287 288 buffer = StringParser.readWholeStream(mimeInputStream); 288 289 289 String data = new String(buffer);290 290 MimeMessagePart part = MimeMessagePartFactory.createMimeMessagePart( 291 type, subtype, name, encoding, charset, disposition, contentId, data.length());291 type, subtype, name, encoding, charset, disposition, contentId, buffer.length); 292 292 try { 293 contentMap.put(part, MimeMessageContentFactory.createContent (part, data));293 contentMap.put(part, MimeMessageContentFactory.createContentEncoded(part, buffer)); 294 294 } catch (UnsupportedContentException e) { 295 295 System.err.println("UnsupportedContentException: " + e.getMessage()); -
trunk/LogicMail/src/org/logicprobe/LogicMail/util/StringParser.java
r643 r689 49 49 import java.util.Hashtable; 50 50 import java.util.TimeZone; 51 import java.util.Vector;52 51 53 52 import org.logicprobe.LogicMail.AppInfo; … … 469 468 470 469 /** 471 * Recursively parse a nested paren string.472 * Parses through a string of the form "(A (B C (D) E F))" and473 * returns a tree of Vector and String objects representing its474 * contents. This is useful for parsing the response to the475 * IMAP "ENVELOPE" fetch command.476 *477 * @param rawText The raw text to be parsed478 * @return A tree of Vector and String objects479 */480 public static Vector nestedParenStringLexer(String rawText) {481 Vector parsedText = new Vector();482 483 // Sanity checking484 if (!((rawText.charAt(0) == '(') &&485 (rawText.charAt(rawText.length() - 1) == ')'))) {486 return null;487 }488 489 int p = 1;490 int q = p;491 int len;492 String tmpText;493 boolean inQuote = false;494 495 while (q < rawText.length()) {496 if (isQuoteChar(rawText, q, p)) {497 if (!inQuote) {498 inQuote = true;499 p = q;500 } else {501 parsedText.addElement(rawText.substring(p + 1, q));502 p = q + 1;503 inQuote = false;504 }505 } else if ((rawText.charAt(q) == '{') && !inQuote) {506 p = rawText.indexOf('}', q);507 len = Integer.parseInt(rawText.substring(q + 1, p));508 p++;509 510 while ((rawText.charAt(p) == '\r') ||511 (rawText.charAt(p) == '\n'))512 p++;513 514 // Quick kludge for length miscalculation due to the way515 // line breaks are currently handled516 tmpText = rawText.substring(p, p + len);517 518 if (tmpText.endsWith(" NIL")) {519 len -= 4;520 } else if (tmpText.endsWith(" NI")) {521 len -= 3;522 } else if (tmpText.endsWith(" N")) {523 len -= 2;524 } else if (tmpText.endsWith(" ")) {525 len -= 1;526 }527 528 parsedText.addElement(rawText.substring(p, p + len));529 q = p + len;530 } else if (((rawText.charAt(q) == ' ') && !inQuote) ||531 (q == (rawText.length() - 1))) {532 if ((q - p) > 0) {533 parsedText.addElement(rawText.substring(p, q).trim());534 p = q;535 } else {536 p++;537 }538 } else if ((rawText.charAt(q) == '(') && !inQuote) {539 p = q;540 541 // paren matching542 int level = 0;543 boolean subInQuote = false;544 545 for (int i = q + 1; i < rawText.length(); i++) {546 if ((rawText.charAt(i) == '{') && !subInQuote) {547 int matchIndex = rawText.indexOf('}', i);548 549 if ((matchIndex > (i + 1)) &&550 (rawText.charAt(matchIndex + 1) != ' ')) {551 int matchLen = Integer.parseInt(rawText.substring(i +552 1, matchIndex));553 matchIndex++;554 555 while ((rawText.charAt(matchIndex) == '\r') ||556 (rawText.charAt(matchIndex) == '\n')) {557 matchIndex++;558 }559 560 i = matchIndex + matchLen;561 }562 }563 564 if (isQuoteChar(rawText, i, q + 1) && !subInQuote) {565 subInQuote = true;566 } else if (isQuoteChar(rawText, i, q + 1) && subInQuote) {567 subInQuote = false;568 }569 570 if ((rawText.charAt(i) == '(') && !subInQuote) {571 level++;572 } else if ((rawText.charAt(i) == ')') && !subInQuote) {573 if (level == 0) {574 q = i;575 576 break;577 } else {578 level--;579 }580 }581 }582 583 if ((q == 1) || (q < p)) {584 return null;585 } else {586 parsedText.addElement(nestedParenStringLexer(587 rawText.substring(p, q + 1)));588 }589 590 p = q + 1;591 }592 593 q++;594 }595 596 return parsedText;597 }598 599 /**600 * Helper method to determine if a character is a quote.601 */602 private static boolean isQuoteChar(String rawText, int index, int startIndex) {603 if (index == startIndex) {604 return rawText.charAt(index) == '\"';605 } else if (rawText.charAt(index) == '\"') {606 if (rawText.charAt(index - 1) == '\\') {607 if (((index - 2) < startIndex) ||608 (rawText.charAt(index - 2) == '\\')) {609 return true;610 } else {611 return false;612 }613 } else {614 return true;615 }616 } else {617 return false;618 }619 }620 621 /**622 470 * This method iterates through the raw lines that make up 623 471 * standard E-Mail headers, and parses them out into hash … … 799 647 // Quoted-Printable 800 648 result = new String( 801 decodeQuotedPrintable(encodedText ).getBytes(),649 decodeQuotedPrintable(encodedText.getBytes()).getBytes(), 802 650 charset); 803 651 } catch (UnsupportedEncodingException ex) { … … 1271 1119 * Decode a quoted-printable string 1272 1120 */ 1273 public static String decodeQuotedPrintable( Stringtext) {1121 public static String decodeQuotedPrintable(byte[] text) { 1274 1122 StringBuffer buffer = new StringBuffer(); 1275 1123 int index = 0; 1276 int length = text.length ();1124 int length = text.length; 1277 1125 1278 1126 while (index < length) { 1279 if (text .charAt(index) =='=') {1127 if (text[index] == (byte)'=') { 1280 1128 if ((index + 2) >= length) { 1281 1129 break; 1282 1130 } else { 1283 char ch1 = text.charAt(index + 1);1284 char ch2 = text.charAt(index + 2);1285 1286 if ((ch1 == '\r') && (ch2 =='\n')) {1131 byte ch1 = text[index + 1]; 1132 byte ch2 = text[index + 2]; 1133 1134 if ((ch1 == (byte)'\r') && (ch2 == (byte)'\n')) { 1287 1135 index += 3; 1288 } else if (ch1 == '\n') {1136 } else if (ch1 == (byte)'\n') { 1289 1137 index += 2; 1290 1138 } else { 1291 1139 try { 1292 int charVal = Integer.parseInt(text.substring(index + 1293 1, index + 3), 16); 1140 int charVal = StringArrays.parseHexInt(text, index + 1, 2); 1294 1141 buffer.append((char) charVal); 1295 } catch (NumberFormatException exp) { 1296 } 1142 } catch (NumberFormatException exp) { } 1297 1143 1298 1144 index += 3; 1299 1145 } 1300 1146 } 1301 } else if (text .charAt(index) =='_') {1147 } else if (text[index] == (byte)'_') { 1302 1148 buffer.append(' '); 1303 1149 index++; 1304 1150 } else { 1305 buffer.append( text.charAt(index));1151 buffer.append((char)text[index]); 1306 1152 index++; 1307 1153 } -
trunk/LogicMailTests/src/org/logicprobe/LogicMail/mail/imap/ImapParserTest.java
r196 r689 1 1 /*- 2 * Copyright (c) 20 08, Derek Konigsberg2 * Copyright (c) 2010, Derek Konigsberg 3 3 * All rights reserved. 4 4 * … … 8 8 * 9 9 * 1. Redistributions of source code must retain the above copyright 10 * notice, this list of conditions and the following disclaimer. 10 * notice, this list of conditions and the following disclaimer. 11 11 * 2. Redistributions in binary form must reproduce the above copyright 12 12 * notice, this list of conditions and the following disclaimer in the 13 * documentation and/or other materials provided with the distribution. 13 * documentation and/or other materials provided with the distribution. 14 14 * 3. Neither the name of the project nor the names of its 15 15 * contributors may be used to endorse or promote products derived … … 29 29 * OF THE POSSIBILITY OF SUCH DAMAGE. 30 30 */ 31 32 31 package org.logicprobe.LogicMail.mail.imap; 33 32 … … 37 36 import j2meunit.framework.TestSuite; 38 37 38 import java.util.Vector; 39 40 39 41 /** 40 42 * Unit test for ImapParser 41 43 */ 42 44 public class ImapParserTest extends TestCase { 43 44 45 public ImapParserTest() { 45 46 } … … 48 49 super(testName, testMethod); 49 50 } 50 51 51 52 public void setUp() { 52 53 } 53 54 54 55 public void tearDown() { 55 56 } 56 57 57 58 public void testParseFolderName() { 58 59 String result = ImapParser.parseFolderName("Hello"); … … 68 69 assertEquals("Umlaut Test 2", "Gelöschte Objekte", result); 69 70 } 71 72 public void testParenStringLexer1() { 73 String rawText = "(FLAGS (\\Answered \\Seen) " + 74 "ENVELOPE (\"Mon, 12 Mar 2007 19:38:31 -0700\" \"Re: Calm down! :-)\" " + 75 "((\"jim smith\" NIL \"jsmith\" \"scratch.test\")) " + 76 "((\"jim smith\" NIL \"jsmith\" \"scratch.test\")) " + 77 "((\"jim smith\" NIL \"jsmith\" \"scratch.test\")) " + 78 "((\"John Doe\" NIL \"jdoe\" \"generic.test\")) " + "NIL NIL " + 79 "\"<200703121933.25327.jdoe@generic.test>\" " + 80 "\"<7b02460f0703121938sff23a05xd3c2a37dc6b9eb7d@mail.scratch.test>\"))"; 81 82 byte[] data = rawText.getBytes(); 83 Vector result = ImapParser.parenListLexer(data, 0, data.length); 84 assertNotNull(result); 85 86 Character LPAREN = new Character('('); 87 Character RPAREN = new Character(')'); 88 89 Object[] expected = new Object[] { 90 LPAREN, "FLAGS", LPAREN, "\\Answered", "\\Seen", RPAREN, 91 "ENVELOPE", LPAREN, "Mon, 12 Mar 2007 19:38:31 -0700".getBytes(), 92 "Re: Calm down! :-)".getBytes(), LPAREN, LPAREN, "jim smith".getBytes(), "NIL", 93 "jsmith".getBytes(), "scratch.test".getBytes(), RPAREN, RPAREN, LPAREN, LPAREN, 94 "jim smith".getBytes(), "NIL", "jsmith".getBytes(), "scratch.test".getBytes(), RPAREN, RPAREN, 95 LPAREN, LPAREN, "jim smith".getBytes(), "NIL", "jsmith".getBytes(), "scratch.test".getBytes(), 96 RPAREN, RPAREN, LPAREN, LPAREN, "John Doe".getBytes(), "NIL", "jdoe".getBytes(), 97 "generic.test".getBytes(), RPAREN, RPAREN, "NIL", "NIL", 98 "<200703121933.25327.jdoe@generic.test>".getBytes(), 99 "<7b02460f0703121938sff23a05xd3c2a37dc6b9eb7d@mail.scratch.test>".getBytes(), 100 RPAREN, RPAREN 101 }; 102 103 assertEquals(expected.length, result.size()); 104 105 for (int i = 0; i < expected.length; i++) { 106 if(expected[i] instanceof byte[] && result.elementAt(i) instanceof byte[]) { 107 assertEquals(new String((byte[])expected[i]), new String((byte[])result.elementAt(i))); 108 } 109 else { 110 assertEquals(expected[i], result.elementAt(i)); 111 } 112 } 113 } 114 115 public void testParenStringLexer2() { 116 String rawText = "(FLAGS () ENVELOPE (\"Sun, 18 Mar 2007 09:04:29 -0700\" {23}\r\n" + 117 "[list] \"this is a test\" " + 118 "((\"Jim Smith\" NIL \"jsmith\" \"XXXX\")) " + 119 "((\"Jim Smith\" NIL \"jsmith\" \"XXXX\")) " + 120 "((\"Jim Smith\" NIL \"jsmith\" \"XXXX\")) " + 121 "((NIL NIL \"jsmith\" \"XXXXXXXX\")) " + 122 "NIL NIL NIL \"<45FD630D.1040808@XXXXX>\"))"; 123 124 byte[] data = rawText.getBytes(); 125 Vector result = ImapParser.parenListLexer(data, 0, data.length); 126 assertNotNull(result); 127 128 Character LPAREN = new Character('('); 129 Character RPAREN = new Character(')'); 130 131 Object[] expected = new Object[] { 132 LPAREN, "FLAGS", LPAREN, RPAREN, "ENVELOPE", LPAREN, 133 "Sun, 18 Mar 2007 09:04:29 -0700".getBytes(), "[list] \"this is a test\"".getBytes(), 134 LPAREN, LPAREN, "Jim Smith".getBytes(), "NIL", "jsmith".getBytes(), "XXXX".getBytes(), RPAREN, 135 RPAREN, LPAREN, LPAREN, "Jim Smith".getBytes(), "NIL", "jsmith".getBytes(), "XXXX".getBytes(), 136 RPAREN, RPAREN, LPAREN, LPAREN, "Jim Smith".getBytes(), "NIL", "jsmith".getBytes(), 137 "XXXX".getBytes(), RPAREN, RPAREN, LPAREN, LPAREN, "NIL", "NIL", "jsmith".getBytes(), 138 "XXXXXXXX".getBytes(), RPAREN, RPAREN, "NIL", "NIL", "NIL", 139 "<45FD630D.1040808@XXXXX>".getBytes(), RPAREN, RPAREN 140 }; 141 142 assertEquals(expected.length, result.size()); 143 144 for (int i = 0; i < expected.length; i++) { 145 if(expected[i] instanceof byte[] && result.elementAt(i) instanceof byte[]) { 146 assertEquals(new String((byte[])expected[i]), new String((byte[])result.elementAt(i))); 147 } 148 else { 149 assertEquals(expected[i], result.elementAt(i)); 150 } 151 } 152 } 153 154 // /** 155 // * Prints the token list for debugging purposes 156 // * 157 // * @param tokenList the token list 158 // */ 159 // private void printTokenList(Vector tokenList) { 160 // int size = tokenList.size(); 161 // System.err.println("-->"); 162 // for(int i=0; i<size; i++) { 163 // Object element = tokenList.elementAt(i); 164 // if(element instanceof Character) { 165 // System.err.print("'" + element + "' "); 166 // } 167 // else if(element instanceof String) { 168 // System.err.print("[" + element + "] "); 169 // } 170 // else if(element == null) { 171 // System.err.print("<NIL> "); 172 // } 173 // else { 174 // System.err.println("ERROR!!!!"); 175 // } 176 // } 177 // System.err.println(); 178 // } 179 public void testParenStringParserEnvelope1() { 180 String rawText = "(FLAGS (\\Answered \\Seen) " + 181 "ENVELOPE (\"Mon, 12 Mar 2007 19:38:31 -0700\" \"Re: Calm down! :-)\" " + 182 "((\"jim smith\" NIL \"jsmith\" \"scratch.test\")) " + 183 "((\"jim smith\" NIL \"jsmith\" \"scratch.test\")) " + 184 "((\"jim smith\" NIL \"jsmith\" \"scratch.test\")) " + 185 "((\"John Doe\" NIL \"jdoe\" \"generic.test\")) " + "NIL NIL " + 186 "\"<200703121933.25327.jdoe@generic.test>\" " + 187 "\"<7b02460f0703121938sff23a05xd3c2a37dc6b9eb7d@mail.scratch.test>\"))"; 188 189 Vector result = ImapParser.parenListParser(rawText.getBytes()); 190 Vector temp; 191 192 //printTree(result, 0); 193 assertEquals("FLAGS", (String) result.elementAt(0)); 194 195 Vector flags = (Vector) result.elementAt(1); 196 assertEquals("\\Answered", (String) flags.elementAt(0)); 197 assertEquals("\\Seen", (String) flags.elementAt(1)); 198 199 assertEquals("ENVELOPE", (String) result.elementAt(2)); 200 201 Vector envelope = (Vector) result.elementAt(3); 202 assertNotNull(envelope); 203 assertEquals("Mon, 12 Mar 2007 19:38:31 -0700", 204 (byte[]) envelope.elementAt(0)); 205 assertEquals("Re: Calm down! :-)", (byte[]) envelope.elementAt(1)); 206 207 temp = (Vector) envelope.elementAt(2); 208 temp = (Vector) temp.elementAt(0); 209 assertEquals("jim smith", (byte[]) temp.elementAt(0)); 210 assertEquals("NIL", (String) temp.elementAt(1)); 211 assertEquals("jsmith", (byte[]) temp.elementAt(2)); 212 assertEquals("scratch.test", (byte[]) temp.elementAt(3)); 213 214 temp = (Vector) envelope.elementAt(3); 215 temp = (Vector) temp.elementAt(0); 216 assertEquals("jim smith", (byte[]) temp.elementAt(0)); 217 assertEquals("NIL", (String) temp.elementAt(1)); 218 assertEquals("jsmith", (byte[]) temp.elementAt(2)); 219 assertEquals("scratch.test", (byte[]) temp.elementAt(3)); 220 221 temp = (Vector) envelope.elementAt(4); 222 temp = (Vector) temp.elementAt(0); 223 assertEquals("jim smith", (byte[]) temp.elementAt(0)); 224 assertEquals("NIL", (String) temp.elementAt(1)); 225 assertEquals("jsmith", (byte[]) temp.elementAt(2)); 226 assertEquals("scratch.test", (byte[]) temp.elementAt(3)); 227 228 temp = (Vector) envelope.elementAt(5); 229 temp = (Vector) temp.elementAt(0); 230 assertEquals("John Doe", (byte[]) temp.elementAt(0)); 231 assertEquals("NIL", (String) temp.elementAt(1)); 232 assertEquals("jdoe", (byte[]) temp.elementAt(2)); 233 assertEquals("generic.test", (byte[]) temp.elementAt(3)); 234 235 assertEquals("NIL", (String) envelope.elementAt(6)); 236 assertEquals("NIL", (String) envelope.elementAt(7)); 237 assertEquals("<200703121933.25327.jdoe@generic.test>", 238 (byte[]) envelope.elementAt(8)); 239 assertEquals("<7b02460f0703121938sff23a05xd3c2a37dc6b9eb7d@mail.scratch.test>", 240 (byte[]) envelope.elementAt(9)); 241 } 242 243 public void testParenStringParserEnvelope2() { 244 String rawText = "(FLAGS () ENVELOPE (\"Sun, 18 Mar 2007 09:04:29 -0700\" {23}\r\n" + 245 "[list] \"this is a test\" " + 246 "((\"Jim Smith\" NIL \"jsmith\" \"XXXX\")) " + 247 "((\"Jim Smith\" NIL \"jsmith\" \"XXXX\")) " + 248 "((\"Jim Smith\" NIL \"jsmith\" \"XXXX\")) " + 249 "((NIL NIL \"jsmith\" \"XXXXXXXX\")) " + 250 "NIL NIL NIL \"<45FD630D.1040808@XXXXX>\"))"; 251 252 Vector result = ImapParser.parenListParser(rawText.getBytes()); 253 Vector temp; 254 255 //printTree(result, 0); 256 assertEquals("FLAGS", (String) result.elementAt(0)); 257 258 Vector flags = (Vector) result.elementAt(1); 259 assertEquals(0, flags.size()); 260 261 assertEquals("ENVELOPE", (String) result.elementAt(2)); 262 263 Vector envelope = (Vector) result.elementAt(3); 264 assertNotNull(envelope); 265 assertEquals("Sun, 18 Mar 2007 09:04:29 -0700", 266 (byte[]) envelope.elementAt(0)); 267 assertEquals("[list] \"this is a test\"", (byte[]) envelope.elementAt(1)); 268 269 temp = (Vector) envelope.elementAt(2); 270 temp = (Vector) temp.elementAt(0); 271 assertEquals("Jim Smith", (byte[]) temp.elementAt(0)); 272 assertEquals("NIL", (String) temp.elementAt(1)); 273 assertEquals("jsmith", (byte[]) temp.elementAt(2)); 274 assertEquals("XXXX", (byte[]) temp.elementAt(3)); 275 276 temp = (Vector) envelope.elementAt(3); 277 temp = (Vector) temp.elementAt(0); 278 assertEquals("Jim Smith", (byte[]) temp.elementAt(0)); 279 assertEquals("NIL", (String) temp.elementAt(1)); 280 assertEquals("jsmith", (byte[]) temp.elementAt(2)); 281 assertEquals("XXXX", (byte[]) temp.elementAt(3)); 282 283 temp = (Vector) envelope.elementAt(4); 284 temp = (Vector) temp.elementAt(0); 285 assertEquals("Jim Smith", (byte[]) temp.elementAt(0)); 286 assertEquals("NIL", (String) temp.elementAt(1)); 287 assertEquals("jsmith", (byte[]) temp.elementAt(2)); 288 assertEquals("XXXX", (byte[]) temp.elementAt(3)); 289 290 temp = (Vector) envelope.elementAt(5); 291 temp = (Vector) temp.elementAt(0); 292 assertEquals("NIL", (String) temp.elementAt(0)); 293 assertEquals("NIL", (String) temp.elementAt(1)); 294 assertEquals("jsmith", (byte[]) temp.elementAt(2)); 295 assertEquals("XXXXXXXX", (byte[]) temp.elementAt(3)); 296 297 assertEquals("NIL", (String) envelope.elementAt(6)); 298 assertEquals("NIL", (String) envelope.elementAt(7)); 299 assertEquals("NIL", (String) envelope.elementAt(8)); 300 assertEquals("<45FD630D.1040808@XXXXX>", (byte[]) envelope.elementAt(9)); 301 } 302 303 public void testParenStringParserEnvelope3() { 304 String rawText = "(FLAGS (\\Seen) " + 305 "ENVELOPE (\"Fri, 15 Jun 2007 12:37:27 -0400\" {42}\r\n" + 306 "[Theelist] 19\" monitor free to a good home " + 307 "((\"Jim Smith\" NIL \"jsmith\" \"smith.test\")) " + 308 "((NIL NIL \"thelist-bounces\" \"thelist.test\")) " + 309 "((\"This is the list\" NIL \"thelist\" \"thelist.test\")) " + 310 "((\"This is the list\" NIL \"thelist\" \"thelist.test\")) " + 311 "NIL NIL NIL " + 312 "\"<1ECCDABD-5242-4180-9584-E5873C3FEA17@smith.test>\"))"; 313 314 Vector result = ImapParser.parenListParser(rawText.getBytes()); 315 Vector temp; 316 317 //printTree(result, 0); 318 assertEquals("FLAGS", (String) result.elementAt(0)); 319 320 Vector flags = (Vector) result.elementAt(1); 321 assertEquals("\\Seen", (String) flags.elementAt(0)); 322 323 assertEquals("ENVELOPE", (String) result.elementAt(2)); 324 325 Vector envelope = (Vector) result.elementAt(3); 326 assertNotNull(envelope); 327 assertEquals("Fri, 15 Jun 2007 12:37:27 -0400", 328 (byte[]) envelope.elementAt(0)); 329 assertEquals("[Theelist] 19\" monitor free to a good home", 330 (byte[]) envelope.elementAt(1)); 331 332 temp = (Vector) envelope.elementAt(2); 333 temp = (Vector) temp.elementAt(0); 334 assertEquals("Jim Smith", (byte[]) temp.elementAt(0)); 335 assertEquals("NIL", (String) temp.elementAt(1)); 336 assertEquals("jsmith", (byte[]) temp.elementAt(2)); 337 assertEquals("smith.test", (byte[]) temp.elementAt(3)); 338 339 temp = (Vector) envelope.elementAt(3); 340 temp = (Vector) temp.elementAt(0); 341 assertEquals("NIL", (String) temp.elementAt(0)); 342 assertEquals("NIL", (String) temp.elementAt(1)); 343 assertEquals("thelist-bounces", (byte[]) temp.elementAt(2)); 344 assertEquals("thelist.test", (byte[]) temp.elementAt(3)); 345 346 temp = (Vector) envelope.elementAt(4); 347 temp = (Vector) temp.elementAt(0); 348 assertEquals("This is the list", (byte[]) temp.elementAt(0)); 349 assertEquals("NIL", (String) temp.elementAt(1)); 350 assertEquals("thelist", (byte[]) temp.elementAt(2)); 351 assertEquals("thelist.test", (byte[]) temp.elementAt(3)); 352 353 temp = (Vector) envelope.elementAt(5); 354 temp = (Vector) temp.elementAt(0); 355 assertEquals("This is the list", (byte[]) temp.elementAt(0)); 356 assertEquals("NIL", (String) temp.elementAt(1)); 357 assertEquals("thelist", (byte[]) temp.elementAt(2)); 358 assertEquals("thelist.test", (byte[]) temp.elementAt(3)); 359 360 assertEquals("NIL", (String) envelope.elementAt(6)); 361 assertEquals("NIL", (String) envelope.elementAt(7)); 362 assertEquals("NIL", (String) envelope.elementAt(8)); 363 assertEquals("<1ECCDABD-5242-4180-9584-E5873C3FEA17@smith.test>", 364 (byte[]) envelope.elementAt(9)); 365 } 366 367 public void testParenStringParserBodyStructure() { 368 String rawText = "(BODYSTRUCTURE " + 369 "((\"TEXT\" \"PLAIN\" (\"CHARSET\" \"us-ascii\") NIL NIL \"7BIT\" 165 8 NIL NIL NIL) " + 370 "(\"TEXT\" \"HTML\" (\"CHARSET\" \"us-ascii\") NIL NIL \"7BIT\" 627 10 NIL NIL NIL) " + 371 "\"ALTERNATIVE\" (\"BOUNDARY\" \"Boundary-00=_y9RuEFduwo6YU42\") (\"INLINE\" NIL) NIL))"; 372 373 Vector result = ImapParser.parenListParser(rawText.getBytes()); 374 Vector temp1; 375 Vector temp2; 376 Vector temp3; 377 378 //printTree(result, 0); 379 assertEquals("BODYSTRUCTURE", (String) result.elementAt(0)); 380 temp1 = (Vector) result.elementAt(1); 381 382 temp2 = (Vector) temp1.elementAt(0); 383 assertEquals("TEXT", (byte[]) temp2.elementAt(0)); 384 assertEquals("PLAIN", (byte[]) temp2.elementAt(1)); 385 temp3 = (Vector) temp2.elementAt(2); 386 assertEquals("CHARSET", (byte[]) temp3.elementAt(0)); 387 assertEquals("us-ascii", (byte[]) temp3.elementAt(1)); 388 assertEquals("NIL", (String) temp2.elementAt(3)); 389 assertEquals("NIL", (String) temp2.elementAt(4)); 390 assertEquals("7BIT", (byte[]) temp2.elementAt(5)); 391 assertEquals("165", (String) temp2.elementAt(6)); 392 assertEquals("8", (String) temp2.elementAt(7)); 393 assertEquals("NIL", (String) temp2.elementAt(8)); 394 assertEquals("NIL", (String) temp2.elementAt(9)); 395 assertEquals("NIL", (String) temp2.elementAt(10)); 396 397 temp2 = (Vector) temp1.elementAt(1); 398 assertEquals("TEXT", (byte[]) temp2.elementAt(0)); 399 assertEquals("HTML", (byte[]) temp2.elementAt(1)); 400 temp3 = (Vector) temp2.elementAt(2); 401 assertEquals("CHARSET", (byte[]) temp3.elementAt(0)); 402 assertEquals("us-ascii", (byte[]) temp3.elementAt(1)); 403 assertEquals("NIL", (String) temp2.elementAt(3)); 404 assertEquals("NIL", (String) temp2.elementAt(4)); 405 assertEquals("7BIT", (byte[]) temp2.elementAt(5)); 406 assertEquals("627", (String) temp2.elementAt(6)); 407 assertEquals("10", (String) temp2.elementAt(7)); 408 assertEquals("NIL", (String) temp2.elementAt(8)); 409 assertEquals("NIL", (String) temp2.elementAt(9)); 410 assertEquals("NIL", (String) temp2.elementAt(10)); 411 412 assertEquals("ALTERNATIVE", (byte[]) temp1.elementAt(2)); 413 414 temp2 = (Vector) temp1.elementAt(3); 415 assertEquals("BOUNDARY", (byte[]) temp2.elementAt(0)); 416 assertEquals("Boundary-00=_y9RuEFduwo6YU42", (byte[]) temp2.elementAt(1)); 417 418 temp2 = (Vector) temp1.elementAt(4); 419 assertEquals("INLINE", (byte[]) temp2.elementAt(0)); 420 assertEquals("NIL", (String) temp2.elementAt(1)); 421 422 assertEquals("NIL", (String) temp1.elementAt(5)); 423 } 424 425 // /** 426 // * This method prints the parse tree for debugging purposes. 427 // * @param node Node to start at. 428 // * @param level Level to print from. 429 // */ 430 // private void printTree(Object node, int level) { 431 // if(node instanceof Vector) { 432 // Vector vec = (Vector)node; 433 // int size = vec.size(); 434 // for(int i=0; i<size; i++) 435 // printTree(vec.elementAt(i), level + 1); 436 // } 437 // else { 438 // StringBuffer buf = new StringBuffer(); 439 // buf.append(level+">"); 440 // for(int i=0; i<level; i++) 441 // buf.append(" "); 442 // if(node != null) { 443 // buf.append(node.toString()); 444 // } 445 // else { 446 // buf.append("null"); 447 // } 448 // System.err.println(buf.toString()); 449 // } 450 // } 451 452 protected void assertEquals(String expected, byte[] actual) { 453 assertEquals(expected, new String(actual)); 454 } 70 455 71 456 public Test suite() { … … 73 458 74 459 suite.addTest(new ImapParserTest("parseFolderName", new TestMethod() 75 { public void run(TestCase tc) {((ImapParserTest)tc).testParseFolderName(); } })); 460 { public void run(TestCase tc) { ((ImapParserTest) tc).testParseFolderName(); }})); 461 462 suite.addTest(new ImapParserTest("parenStringLexer1", new TestMethod() 463 { public void run(TestCase tc) { ((ImapParserTest) tc).testParenStringLexer1(); }})); 464 465 suite.addTest(new ImapParserTest("parenStringLexer2", new TestMethod() 466 { public void run(TestCase tc) { ((ImapParserTest) tc).testParenStringLexer2(); }})); 467 468 suite.addTest(new ImapParserTest("parenStringParserEnvelope1", new TestMethod() 469 { public void run(TestCase tc) { ((ImapParserTest) tc).testParenStringParserEnvelope1(); }})); 470 471 suite.addTest(new ImapParserTest("parenStringParserEnvelope2", new TestMethod() 472 { public void run(TestCase tc) { ((ImapParserTest) tc).testParenStringParserEnvelope2(); }})); 473 474 suite.addTest(new ImapParserTest("parenStringParserEnvelope3", new TestMethod() 475 { public void run(TestCase tc) { ((ImapParserTest) tc).testParenStringParserEnvelope3(); }})); 476 477 suite.addTest(new ImapParserTest("parenStringParserBodyStructure", new TestMethod() 478 { public void run(TestCase tc) { ((ImapParserTest) tc).testParenStringParserBodyStructure(); }})); 76 479 77 480 return suite; 78 } 481 } 79 482 } -
trunk/LogicMailTests/src/org/logicprobe/LogicMail/mail/imap/ImapProtocolTest.java
r676 r689 37 37 import j2meunit.framework.TestSuite; 38 38 39 import org.logicprobe.LogicMail.mail.MailException; 39 40 import org.logicprobe.LogicMail.mail.MailProgressHandler; 40 41 import org.logicprobe.LogicMail.message.MessageEnvelope; 41 42 import org.logicprobe.LogicMail.util.StringParser; 42 43 44 import java.io.IOException; 43 45 import java.util.Calendar; 44 46 import java.util.Hashtable; 45 47 import java.util.TimeZone; 46 48 import java.util.Vector; 49 47 50 48 51 /** … … 348 351 } 349 352 } 350 353 351 354 public void testExecuteList7() { 352 355 try { 353 356 // Test specified-length encoding for path name, with spaces 354 357 instance.addExecuteExpectation("LIST", "\"\" \"%\"", 355 new String[] {358 new String[] { 356 359 "* LIST (\\Noselect) \":\" {5}", "Marya", 357 360 "* LIST (\\Noselect) \":\" {11}", "Old Inboxes", 358 "* LIST (\\Noinferiors) \":\" {17}", "Pre-filtered Junk" }); 359 361 "* LIST (\\Noinferiors) \":\" {17}", "Pre-filtered Junk" 362 }); 363 360 364 Vector result = instance.executeList("", "%", null); 361 365 assertNotNull(result); … … 364 368 assertTrue(result.elementAt(1) instanceof ImapProtocol.ListResponse); 365 369 assertTrue(result.elementAt(2) instanceof ImapProtocol.ListResponse); 366 370 367 371 ImapProtocol.ListResponse result1 = (ImapProtocol.ListResponse) result.elementAt(0); 368 372 ImapProtocol.ListResponse result2 = (ImapProtocol.ListResponse) result.elementAt(1); 369 373 ImapProtocol.ListResponse result3 = (ImapProtocol.ListResponse) result.elementAt(2); 370 374 371 375 assertTrue(!result1.canSelect); 372 376 assertTrue(!result1.noInferiors); 373 377 assertEquals(":", result1.delim); 374 378 assertEquals("Marya", result1.name); 375 379 376 380 assertTrue(!result2.canSelect); 377 381 assertTrue(!result2.noInferiors); 378 382 assertEquals(":", result2.delim); 379 383 assertEquals("Old Inboxes", result2.name); 380 384 381 385 assertTrue(result3.canSelect); 382 386 assertTrue(result3.noInferiors); 383 387 assertEquals(":", result3.delim); 384 388 assertEquals("Pre-filtered Junk", result3.name); 385 386 389 } catch (AssertionFailedError e) { 387 390 throw e; … … 391 394 } 392 395 } 393 394 private static class ShimCallback implements ImapProtocol.FetchEnvelopeCallback {395 private Vector responses = new Vector();396 397 public void responseAvailable(ImapProtocol.FetchEnvelopeResponse response) {398 if(response != null) {399 responses.addElement(response);400 }401 }402 403 public ImapProtocol.FetchEnvelopeResponse[] getResponses() {404 ImapProtocol.FetchEnvelopeResponse[] result = new ImapProtocol.FetchEnvelopeResponse[responses.size()];405 responses.copyInto(result);406 return result;407 }408 }409 396 410 397 public void testExecuteFetchEnvelope1() { 411 398 try { 412 instance.addExecuteExpectation("FETCH", "1:1 (FLAGS UID ENVELOPE BODYSTRUCTURE)", 399 instance.addExecuteExpectation("FETCH", 400 "1:1 (FLAGS UID ENVELOPE BODYSTRUCTURE)", 413 401 new String[] { 414 402 "* 1 FETCH (FLAGS (\\Answered \\Seen) UID 10 " + … … 425 413 ShimCallback shim = new ShimCallback(); 426 414 instance.executeFetchEnvelope(1, 1, shim, null); 415 427 416 ImapProtocol.FetchEnvelopeResponse[] result = shim.getResponses(); 428 417 429 418 assertNotNull(result); 430 419 assertEquals(1, result.length); … … 482 471 assertEquals("<7b02460f0703121938sff23a05xd3c2a37dc6b9eb7d@mail.scratch.test>", 483 472 env.messageId); 484 473 485 474 ImapParser.MessageSection structure = result[0].structure; 486 475 assertNotNull(structure); … … 497 486 public void testExecuteFetchEnvelope2() { 498 487 try { 499 instance.addExecuteExpectation("FETCH", "1:1 (FLAGS UID ENVELOPE BODYSTRUCTURE)", 488 instance.addExecuteExpectation("FETCH", 489 "1:1 (FLAGS UID ENVELOPE BODYSTRUCTURE)", 500 490 new String[] { 501 491 "* 1 FETCH (" + … … 512 502 ShimCallback shim = new ShimCallback(); 513 503 instance.executeFetchEnvelope(1, 1, shim, null); 504 514 505 ImapProtocol.FetchEnvelopeResponse[] result = shim.getResponses(); 515 506 516 507 assertNotNull(result); 517 508 assertEquals(1, result.length); … … 583 574 public void testExecuteFetchEnvelope3() { 584 575 try { 585 instance.addExecuteExpectation("FETCH", "1:1 (FLAGS UID ENVELOPE BODYSTRUCTURE)", 576 instance.addExecuteExpectation("FETCH", 577 "1:1 (FLAGS UID ENVELOPE BODYSTRUCTURE)", 586 578 new String[] { 587 579 "* 1 FETCH (" + "FLAGS (\\Seen) UID 10 " + … … 599 591 ShimCallback shim = new ShimCallback(); 600 592 instance.executeFetchEnvelope(1, 1, shim, null); 593 601 594 ImapProtocol.FetchEnvelopeResponse[] result = shim.getResponses(); 602 595 … … 627 620 StringParser.createDateString(env.date)); 628 621 629 assertEquals("[LogicMail for BlackBerry] #93: Endless \ \\"refresh folders\\\" loop when using qmail server",622 assertEquals("[LogicMail for BlackBerry] #93: Endless \"refresh folders\" loop when using qmail server", 630 623 env.subject); 631 624 … … 673 666 public void testExecuteFetchEnvelope4() { 674 667 try { 675 instance.addExecuteExpectation("FETCH", "1:1 (FLAGS UID ENVELOPE BODYSTRUCTURE)", 668 instance.addExecuteExpectation("FETCH", 669 "1:1 (FLAGS UID ENVELOPE BODYSTRUCTURE)", 676 670 new String[] { 677 671 "* 1 FETCH (FLAGS (\\Seen) UID 10 " + … … 689 683 ShimCallback shim = new ShimCallback(); 690 684 instance.executeFetchEnvelope(1, 1, shim, null); 685 691 686 ImapProtocol.FetchEnvelopeResponse[] result = shim.getResponses(); 692 687 … … 716 711 StringParser.createDateString(env.date)); 717 712 718 assertEquals("Re: [LogicMail for BlackBerry] #94: Message \ \\"\\\"This message does not contain any sections that could be displayed\\\"",713 assertEquals("Re: [LogicMail for BlackBerry] #94: Message \"\"This message does not contain any sections that could be displayed\"", 719 714 env.subject); 720 715 … … 760 755 } 761 756 } 762 757 763 758 public void testExecuteFetchFlags1() { 764 759 try { 765 760 instance.addExecuteExpectation("FETCH", "1:1 (FLAGS UID)", 766 new String[] { 767 "* 1 FETCH (FLAGS () UID 42)" 768 }); 769 770 ImapProtocol.FetchFlagsResponse[] result = instance.executeFetchFlags(1, 1, null); 771 772 assertNotNull(result); 773 assertEquals(1, result.length); 774 assertEquals(1, result[0].index); 775 assertEquals(42, result[0].uid); 776 777 ImapProtocol.MessageFlags flags = result[0].flags; 778 assertNotNull(flags); 779 assertTrue("answered", !flags.answered); 780 assertTrue("deleted", !flags.deleted); 781 assertTrue("draft", !flags.draft); 782 assertTrue("flagged", !flags.flagged); 783 assertTrue("junk", !flags.junk); 784 assertTrue("recent", !flags.recent); 785 assertTrue("seen", !flags.seen); 786 787 } catch (Throwable t) { 788 fail("Exception thrown during test: " + t.toString()); 789 t.printStackTrace(); 790 } 791 } 792 761 new String[] { "* 1 FETCH (FLAGS () UID 42)" }); 762 763 ImapProtocol.FetchFlagsResponse[] result = instance.executeFetchFlags(1, 764 1, null); 765 766 assertNotNull(result); 767 assertEquals(1, result.length); 768 assertEquals(1, result[0].index); 769 assertEquals(42, result[0].uid); 770 771 ImapProtocol.MessageFlags flags = result[0].flags; 772 assertNotNull(flags); 773 assertTrue("answered", !flags.answered); 774 assertTrue("deleted", !flags.deleted); 775 assertTrue("draft", !flags.draft); 776 assertTrue("flagged", !flags.flagged); 777 assertTrue("junk", !flags.junk); 778 assertTrue("recent", !flags.recent); 779 assertTrue("seen", !flags.seen); 780 } catch (Throwable t) { 781 fail("Exception thrown during test: " + t.toString()); 782 t.printStackTrace(); 783 } 784 } 785 793 786 public void testExecuteFetchFlags2() { 794 787 try { 795 788 instance.addExecuteExpectation("FETCH", "1:1 (FLAGS UID)", 796 new String[] { 797 "* 1 FETCH (FLAGS (\\Seen) UID 42)" 798 }); 799 800 ImapProtocol.FetchFlagsResponse[] result = instance.executeFetchFlags(1, 1, null); 801 802 assertNotNull(result); 803 assertEquals(1, result.length); 804 assertEquals(1, result[0].index); 805 assertEquals(42, result[0].uid); 806 807 ImapProtocol.MessageFlags flags = result[0].flags; 808 assertNotNull(flags); 809 assertTrue("answered", !flags.answered); 810 assertTrue("deleted", !flags.deleted); 811 assertTrue("draft", !flags.draft); 812 assertTrue("flagged", !flags.flagged); 813 assertTrue("junk", !flags.junk); 814 assertTrue("recent", !flags.recent); 815 assertTrue("seen", flags.seen); 816 817 } catch (Throwable t) { 818 fail("Exception thrown during test: " + t.toString()); 819 t.printStackTrace(); 820 } 821 } 822 789 new String[] { "* 1 FETCH (FLAGS (\\Seen) UID 42)" }); 790 791 ImapProtocol.FetchFlagsResponse[] result = instance.executeFetchFlags(1, 792 1, null); 793 794 assertNotNull(result); 795 assertEquals(1, result.length); 796 assertEquals(1, result[0].index); 797 assertEquals(42, result[0].uid); 798 799 ImapProtocol.MessageFlags flags = result[0].flags; 800 assertNotNull(flags); 801 assertTrue("answered", !flags.answered); 802 assertTrue("deleted", !flags.deleted); 803 assertTrue("draft", !flags.draft); 804 assertTrue("flagged", !flags.flagged); 805 assertTrue("junk", !flags.junk); 806 assertTrue("recent", !flags.recent); 807 assertTrue("seen", flags.seen); 808 } catch (Throwable t) { 809 fail("Exception thrown during test: " + t.toString()); 810 t.printStackTrace(); 811 } 812 } 813 823 814 public void testExecuteStore1() { 824 815 try { … … 864 855 } 865 856 } 866 857 867 858 public void testExecuteStore3() { 868 859 try { 869 860 instance.addExecuteExpectation("UID STORE", 870 861 "36410 +FLAGS (\\Deleted)", 871 new String[] { "* 5 FETCH (UID 36410 FLAGS (\\Deleted \\Seen $NotJunk NotJunk))" }); 872 873 ImapProtocol.MessageFlags result = instance.executeStore(36410, true, 874 new String[] { "\\Deleted" }); 862 new String[] { 863 "* 5 FETCH (UID 36410 FLAGS (\\Deleted \\Seen $NotJunk NotJunk))" 864 }); 865 866 ImapProtocol.MessageFlags result = instance.executeStore(36410, 867 true, new String[] { "\\Deleted" }); 875 868 assertNotNull(result); 876 869 … … 890 883 TestSuite suite = new TestSuite("ImapProtocol"); 891 884 892 suite.addTest(new ImapProtocolTest("executeCapability", new TestMethod() 893 { public void run(TestCase tc) { ((ImapProtocolTest) tc).testExecuteCapability(); }})); 894 895 suite.addTest(new ImapProtocolTest("executeNamespace1", new TestMethod() 896 { public void run(TestCase tc) { ((ImapProtocolTest) tc).testExecuteNamespace1(); }})); 897 898 suite.addTest(new ImapProtocolTest("executeNamespace2", new TestMethod() 899 { public void run(TestCase tc) { ((ImapProtocolTest) tc).testExecuteNamespace2(); }})); 900 901 suite.addTest(new ImapProtocolTest("executeList1", new TestMethod() 902 { public void run(TestCase tc) { ((ImapProtocolTest) tc).testExecuteList1(); }})); 903 904 suite.addTest(new ImapProtocolTest("executeList2", new TestMethod() 905 { public void run(TestCase tc) { ((ImapProtocolTest) tc).testExecuteList2(); }})); 906 907 suite.addTest(new ImapProtocolTest("executeList3", new TestMethod() 908 { public void run(TestCase tc) { ((ImapProtocolTest) tc).testExecuteList3(); }})); 909 910 suite.addTest(new ImapProtocolTest("executeList4", new TestMethod() 911 { public void run(TestCase tc) { ((ImapProtocolTest) tc).testExecuteList4(); }})); 912 913 suite.addTest(new ImapProtocolTest("executeList5", new TestMethod() 914 { public void run(TestCase tc) { ((ImapProtocolTest) tc).testExecuteList5(); }})); 915 916 suite.addTest(new ImapProtocolTest("executeList6", new TestMethod() 917 { public void run(TestCase tc) { ((ImapProtocolTest) tc).testExecuteList6(); }})); 918 919 suite.addTest(new ImapProtocolTest("executeList7", new TestMethod() 920 { public void run(TestCase tc) { ((ImapProtocolTest) tc).testExecuteList7(); }})); 921 922 suite.addTest(new ImapProtocolTest("executeFetchEnvelope1", new TestMethod() 923 { public void run(TestCase tc) { ((ImapProtocolTest) tc).testExecuteFetchEnvelope1(); }})); 924 925 suite.addTest(new ImapProtocolTest("executeFetchEnvelope2", new TestMethod() 926 { public void run(TestCase tc) { ((ImapProtocolTest) tc).testExecuteFetchEnvelope2(); }})); 927 928 suite.addTest(new ImapProtocolTest("executeFetchEnvelope3", new TestMethod() 929 { public void run(TestCase tc) { ((ImapProtocolTest) tc).testExecuteFetchEnvelope3(); }})); 930 931 suite.addTest(new ImapProtocolTest("executeFetchEnvelope4", new TestMethod() 932 { public void run(TestCase tc) { ((ImapProtocolTest) tc).testExecuteFetchEnvelope4(); }})); 933 934 suite.addTest(new ImapProtocolTest("executeFetchFlags1", new TestMethod() 935 { public void run(TestCase tc) { ((ImapProtocolTest) tc).testExecuteFetchFlags1(); }})); 936 937 suite.addTest(new ImapProtocolTest("executeFetchFlags2", new TestMethod() 938 { public void run(TestCase tc) { ((ImapProtocolTest) tc).testExecuteFetchFlags2(); }})); 939 940 suite.addTest(new ImapProtocolTest("executeStore1", new TestMethod() 941 { public void run(TestCase tc) { ((ImapProtocolTest) tc).testExecuteStore1(); }})); 942 943 suite.addTest(new ImapProtocolTest("executeStore2", new TestMethod() 944 { public void run(TestCase tc) { ((ImapProtocolTest) tc).testExecuteStore2(); }})); 945 946 suite.addTest(new ImapProtocolTest("executeStore3", new TestMethod() 947 { public void run(TestCase tc) { ((ImapProtocolTest) tc).testExecuteStore3(); }})); 948 885 suite.addTest(new ImapProtocolTest("executeCapability", 886 new TestMethod() { 887 public void run(TestCase tc) { 888 ((ImapProtocolTest) tc).testExecuteCapability(); 889 } 890 })); 891 892 suite.addTest(new ImapProtocolTest("executeNamespace1", 893 new TestMethod() { 894 public void run(TestCase tc) { 895 ((ImapProtocolTest) tc).testExecuteNamespace1(); 896 } 897 })); 898 899 suite.addTest(new ImapProtocolTest("executeNamespace2", 900 new TestMethod() { 901 public void run(TestCase tc) { 902 ((ImapProtocolTest) tc).testExecuteNamespace2(); 903 } 904 })); 905 906 suite.addTest(new ImapProtocolTest("executeList1", 907 new TestMethod() { 908 public void run(TestCase tc) { 909 ((ImapProtocolTest) tc).testExecuteList1(); 910 } 911 })); 912 913 suite.addTest(new ImapProtocolTest("executeList2", 914 new TestMethod() { 915 public void run(TestCase tc) { 916 ((ImapProtocolTest) tc).testExecuteList2(); 917 } 918 })); 919 920 suite.addTest(new ImapProtocolTest("executeList3", 921 new TestMethod() { 922 public void run(TestCase tc) { 923 ((ImapProtocolTest) tc).testExecuteList3(); 924 } 925 })); 926 927 suite.addTest(new ImapProtocolTest("executeList4", 928 new TestMethod() { 929 public void run(TestCase tc) { 930 ((ImapProtocolTest) tc).testExecuteList4(); 931 } 932 })); 933 934 suite.addTest(new ImapProtocolTest("executeList5", 935 new TestMethod() { 936 public void run(TestCase tc) { 937 ((ImapProtocolTest) tc).testExecuteList5(); 938 } 939 })); 940 941 suite.addTest(new ImapProtocolTest("executeList6", 942 new TestMethod() { 943 public void run(TestCase tc) { 944 ((ImapProtocolTest) tc).testExecuteList6(); 945 } 946 })); 947 948 suite.addTest(new ImapProtocolTest("executeList7", 949 new TestMethod() { 950 public void run(TestCase tc) { 951 ((ImapProtocolTest) tc).testExecuteList7(); 952 } 953 })); 954 955 suite.addTest(new ImapProtocolTest("executeFetchEnvelope1", 956 new TestMethod() { 957 public void run(TestCase tc) { 958 ((ImapProtocolTest) tc).testExecuteFetchEnvelope1(); 959 } 960 })); 961 962 suite.addTest(new ImapProtocolTest("executeFetchEnvelope2", 963 new TestMethod() { 964 public void run(TestCase tc) { 965 ((ImapProtocolTest) tc).testExecuteFetchEnvelope2(); 966 } 967 })); 968 969 suite.addTest(new ImapProtocolTest("executeFetchEnvelope3", 970 new TestMethod() { 971 public void run(TestCase tc) { 972 ((ImapProtocolTest) tc).testExecuteFetchEnvelope3(); 973 } 974 })); 975 976 suite.addTest(new ImapProtocolTest("executeFetchEnvelope4", 977 new TestMethod() { 978 public void run(TestCase tc) { 979 ((ImapProtocolTest) tc).testExecuteFetchEnvelope4(); 980 } 981 })); 982 983 suite.addTest(new ImapProtocolTest("executeFetchFlags1", 984 new TestMethod() { 985 public void run(TestCase tc) { 986 ((ImapProtocolTest) tc).testExecuteFetchFlags1(); 987 } 988 })); 989 990 suite.addTest(new ImapProtocolTest("executeFetchFlags2", 991 new TestMethod() { 992 public void run(TestCase tc) { 993 ((ImapProtocolTest) tc).testExecuteFetchFlags2(); 994 } 995 })); 996 997 suite.addTest(new ImapProtocolTest("executeStore1", 998 new TestMethod() { 999 public void run(TestCase tc) { 1000 ((ImapProtocolTest) tc).testExecuteStore1(); 1001 } 1002 })); 1003 1004 suite.addTest(new ImapProtocolTest("executeStore2", 1005 new TestMethod() { 1006 public void run(TestCase tc) { 1007 ((ImapProtocolTest) tc).testExecuteStore2(); 1008 } 1009 })); 1010 1011 suite.addTest(new ImapProtocolTest("executeStore3", 1012 new TestMethod() { 1013 public void run(TestCase tc) { 1014 ((ImapProtocolTest) tc).testExecuteStore3(); 1015 } 1016 })); 1017 949 1018 return suite; 1019 } 1020 1021 private static class ShimCallback implements ImapProtocol.FetchEnvelopeCallback { 1022 private Vector responses = new Vector(); 1023 1024 public void responseAvailable( 1025 ImapProtocol.FetchEnvelopeResponse response) { 1026 if (response != null) { 1027 responses.addElement(response); 1028 } 1029 } 1030 1031 public ImapProtocol.FetchEnvelopeResponse[] getResponses() { 1032 ImapProtocol.FetchEnvelopeResponse[] result = new ImapProtocol.FetchEnvelopeResponse[responses.size()]; 1033 responses.copyInto(result); 1034 1035 return result; 1036 } 950 1037 } 951 1038 … … 979 1066 } 980 1067 981 protected String[] execute(String command, String arguments, MailProgressHandler progressHandler) { 1068 protected String[] execute(String command, String arguments, 1069 MailProgressHandler progressHandler) { 982 1070 assertTrue("No expectations", !executeExpectations.isEmpty()); 983 1071 … … 990 1078 } 991 1079 1080 protected byte[][] executeResponse(String command, String arguments, 1081 MailProgressHandler progressHandler) throws IOException, MailException { 1082 assertTrue("No expectations", !executeExpectations.isEmpty()); 1083 1084 ExecuteExpectation expect = (ExecuteExpectation) executeExpectations.lastElement(); 1085 assertEquals("Bad command", expect.command, command); 1086 assertEquals("Bad arguments", expect.arguments, arguments); 1087 executeExpectations.removeElement(expect); 1088 1089 byte[][] result = new byte[expect.result.length][]; 1090 for(int i=0; i<expect.result.length; i++) { 1091 result[i] = expect.result[i].getBytes(); 1092 } 1093 return result; 1094 } 1095 992 1096 private class ExecuteExpectation { 993 1097 public String command; -
trunk/LogicMailTests/src/org/logicprobe/LogicMail/util/StringParserTest.java
r643 r689 40 40 import java.util.Hashtable; 41 41 import java.util.TimeZone; 42 import java.util.Vector;43 42 44 43 /** … … 190 189 assertEquals("GMT", expected, actual); 191 190 } 192 193 /**194 * Test of nestedParenStringLexer method, of class org.logicprobe.LogicMail.util.StringParser.195 */196 public void testNestedParenStringLexerEnvelope1() {197 System.out.println("nestedParenStringLexer (Envelope1)");198 199 String rawText = "(FLAGS (\\Answered \\Seen) " +200 "ENVELOPE (\"Mon, 12 Mar 2007 19:38:31 -0700\" \"Re: Calm down! :-)\" " +201 "((\"jim smith\" NIL \"jsmith\" \"scratch.test\")) " +202 "((\"jim smith\" NIL \"jsmith\" \"scratch.test\")) " +203 "((\"jim smith\" NIL \"jsmith\" \"scratch.test\")) " +204 "((\"John Doe\" NIL \"jdoe\" \"generic.test\")) " + "NIL NIL " +205 "\"<200703121933.25327.jdoe@generic.test>\" " +206 "\"<7b02460f0703121938sff23a05xd3c2a37dc6b9eb7d@mail.scratch.test>\"))";207 208 Vector result = StringParser.nestedParenStringLexer(rawText);209 Vector temp;210 211 //printTree(result, 0);212 assertEquals("FLAGS", (String) result.elementAt(0));213 214 Vector flags = (Vector) result.elementAt(1);215 assertEquals("\\Answered", (String) flags.elementAt(0));216 assertEquals("\\Seen", (String) flags.elementAt(1));217 218 assertEquals("ENVELOPE", (String) result.elementAt(2));219 220 Vector envelope = (Vector) result.elementAt(3);221 assertNotNull(envelope);222 assertEquals("Mon, 12 Mar 2007 19:38:31 -0700",223 (String) envelope.elementAt(0));224 assertEquals("Re: Calm down! :-)", (String) envelope.elementAt(1));225 226 temp = (Vector) envelope.elementAt(2);227 temp = (Vector) temp.elementAt(0);228 assertEquals("jim smith", (String) temp.elementAt(0));229 assertEquals("NIL", (String) temp.elementAt(1));230 assertEquals("jsmith", (String) temp.elementAt(2));231 assertEquals("scratch.test", (String) temp.elementAt(3));232 233 temp = (Vector) envelope.elementAt(3);234 temp = (Vector) temp.elementAt(0);235 assertEquals("jim smith", (String) temp.elementAt(0));236 assertEquals("NIL", (String) temp.elementAt(1));237 assertEquals("jsmith", (String) temp.elementAt(2));238 assertEquals("scratch.test", (String) temp.elementAt(3));239 240 temp = (Vector) envelope.elementAt(4);241 temp = (Vector) temp.elementAt(0);242 assertEquals("jim smith", (String) temp.elementAt(0));243 assertEquals("NIL", (String) temp.elementAt(1));244 assertEquals("jsmith", (String) temp.elementAt(2));245 assertEquals("scratch.test", (String) temp.elementAt(3));246 247 temp = (Vector) envelope.elementAt(5);248 temp = (Vector) temp.elementAt(0);249 assertEquals("John Doe", (String) temp.elementAt(0));250 assertEquals("NIL", (String) temp.elementAt(1));251 assertEquals("jdoe", (String) temp.elementAt(2));252 assertEquals("generic.test", (String) temp.elementAt(3));253 254 assertEquals("NIL", (String) envelope.elementAt(6));255 assertEquals("NIL", (String) envelope.elementAt(7));256 assertEquals("<200703121933.25327.jdoe@generic.test>",257 (String) envelope.elementAt(8));258 assertEquals("<7b02460f0703121938sff23a05xd3c2a37dc6b9eb7d@mail.scratch.test>",259 (String) envelope.elementAt(9));260 }261 262 /**263 * Test of nestedParenStringLexer method, of class org.logicprobe.LogicMail.util.StringParser.264 */265 public void testNestedParenStringLexerEnvelope2() {266 System.out.println("nestedParenStringLexer (Envelope2)");267 268 String rawText = "(FLAGS () ENVELOPE (\"Sun, 18 Mar 2007 09:04:29 -0700\" {23}\r\n" +269 "[list] \"this is a test\" " +270 "((\"Jim Smith\" NIL \"jsmith\" \"XXXX\")) " +271 "((\"Jim Smith\" NIL \"jsmith\" \"XXXX\")) " +272 "((\"Jim Smith\" NIL \"jsmith\" \"XXXX\")) " +273 "((NIL NIL \"jsmith\" \"XXXXXXXX\")) " +274 "NIL NIL NIL \"<45FD630D.1040808@XXXXX>\"))";275 276 Vector result = StringParser.nestedParenStringLexer(rawText);277 Vector temp;278 279 //printTree(result, 0);280 assertEquals("FLAGS", (String) result.elementAt(0));281 282 Vector flags = (Vector) result.elementAt(1);283 assertEquals(0, flags.size());284 285 assertEquals("ENVELOPE", (String) result.elementAt(2));286 287 Vector envelope = (Vector) result.elementAt(3);288 assertNotNull(envelope);289 assertEquals("Sun, 18 Mar 2007 09:04:29 -0700",290 (String) envelope.elementAt(0));291 assertEquals("[list] \"this is a test\"", (String) envelope.elementAt(1));292 293 temp = (Vector) envelope.elementAt(2);294 temp = (Vector) temp.elementAt(0);295 assertEquals("Jim Smith", (String) temp.elementAt(0));296 assertEquals("NIL", (String) temp.elementAt(1));297 assertEquals("jsmith", (String) temp.elementAt(2));298 assertEquals("XXXX", (String) temp.elementAt(3));299 300 temp = (Vector) envelope.elementAt(3);301 temp = (Vector) temp.elementAt(0);302 assertEquals("Jim Smith", (String) temp.elementAt(0));303 assertEquals("NIL", (String) temp.elementAt(1));304 assertEquals("jsmith", (String) temp.elementAt(2));305 assertEquals("XXXX", (String) temp.elementAt(3));306 307 temp = (Vector) envelope.elementAt(4);308 temp = (Vector) temp.elementAt(0);309 assertEquals("Jim Smith", (String) temp.elementAt(0));310 assertEquals("NIL", (String) temp.elementAt(1));311 assertEquals("jsmith", (String) temp.elementAt(2));312 assertEquals("XXXX", (String) temp.elementAt(3));313 314 temp = (Vector) envelope.elementAt(5);315 temp = (Vector) temp.elementAt(0);316 assertEquals("NIL", (String) temp.elementAt(0));317 assertEquals("NIL", (String) temp.elementAt(1));318 assertEquals("jsmith", (String) temp.elementAt(2));319 assertEquals("XXXXXXXX", (String) temp.elementAt(3));320 321 assertEquals("NIL", (String) envelope.elementAt(6));322 assertEquals("NIL", (String) envelope.elementAt(7));323 assertEquals("NIL", (String) envelope.elementAt(8));324 assertEquals("<45FD630D.1040808@XXXXX>", (String) envelope.elementAt(9));325 }326 327 /**328 * Test of nestedParenStringLexer method, of class org.logicprobe.LogicMail.util.StringParser.329 */330 public void testNestedParenStringLexerEnvelope3() {331 System.out.println("nestedParenStringLexer (Envelope3)");332 333 String rawText = "(FLAGS (\\Seen) " +334 "ENVELOPE (\"Fri, 15 Jun 2007 12:37:27 -0400\" {42}\r\n" +335 "[Theelist] 19\" monitor free to a good home " +336 "((\"Jim Smith\" NIL \"jsmith\" \"smith.test\")) " +337 "((NIL NIL \"thelist-bounces\" \"thelist.test\")) " +338 "((\"This is the list\" NIL \"thelist\" \"thelist.test\")) " +339 "((\"This is the list\" NIL \"thelist\" \"thelist.test\")) " +340 "NIL NIL NIL " +341 "\"<1ECCDABD-5242-4180-9584-E5873C3FEA17@smith.test>\"))";342 343 Vector result = StringParser.nestedParenStringLexer(rawText);344 Vector temp;345 346 //printTree(result, 0);347 assertEquals("FLAGS", (String) result.elementAt(0));348 349 Vector flags = (Vector) result.elementAt(1);350 assertEquals("\\Seen", (String) flags.elementAt(0));351 352 assertEquals("ENVELOPE", (String) result.elementAt(2));353 354 Vector envelope = (Vector) result.elementAt(3);355 assertNotNull(envelope);356 assertEquals("Fri, 15 Jun 2007 12:37:27 -0400",357 (String) envelope.elementAt(0));358 assertEquals("[Theelist] 19\" monitor free to a good home",359 (String) envelope.elementAt(1));360 361 temp = (Vector) envelope.elementAt(2);362 temp = (Vector) temp.elementAt(0);363 assertEquals("Jim Smith", (String) temp.elementAt(0));364 assertEquals("NIL", (String) temp.elementAt(1));365 assertEquals("jsmith", (String) temp.elementAt(2));366 assertEquals("smith.test", (String) temp.elementAt(3));367 368 temp = (Vector) envelope.elementAt(3);369 temp = (Vector) temp.elementAt(0);370 assertEquals("NIL", (String) temp.elementAt(0));371 assertEquals("NIL", (String) temp.elementAt(1));372 assertEquals("thelist-bounces", (String) temp.elementAt(2));373 assertEquals("thelist.test", (String) temp.elementAt(3));374 375 temp = (Vector) envelope.elementAt(4);376 temp = (Vector) temp.elementAt(0);377 assertEquals("This is the list", (String) temp.elementAt(0));378 assertEquals("NIL", (String) temp.elementAt(1));379 assertEquals("thelist", (String) temp.elementAt(2));380 assertEquals("thelist.test", (String) temp.elementAt(3));381 382 temp = (Vector) envelope.elementAt(5);383 temp = (Vector) temp.elementAt(0);384 assertEquals("This is the list", (String) temp.elementAt(0));385 assertEquals("NIL", (String) temp.elementAt(1));386 assertEquals("thelist", (String) temp.elementAt(2));387 assertEquals("thelist.test", (String) temp.elementAt(3));388 389 assertEquals("NIL", (String) envelope.elementAt(6));390 assertEquals("NIL", (String) envelope.elementAt(7));391 assertEquals("NIL", (String) envelope.elementAt(8));392 assertEquals("<1ECCDABD-5242-4180-9584-E5873C3FEA17@smith.test>",393 (String) envelope.elementAt(9));394 }395 396 /**397 * Test of nestedParenStringLexer method, of class org.logicprobe.LogicMail.util.StringParser.398 */399 public void testNestedParenStringLexerBodyStructure() {400 System.out.println("nestedParenStringLexer (BodyStructure)");401 402 String rawText = "(BODYSTRUCTURE " +403 "((\"TEXT\" \"PLAIN\" (\"CHARSET\" \"us-ascii\") NIL NIL \"7BIT\" 165 8 NIL NIL NIL) " +404 "(\"TEXT\" \"HTML\" (\"CHARSET\" \"us-ascii\") NIL NIL \"7BIT\" 627 10 NIL NIL NIL) " +405 "\"ALTERNATIVE\" (\"BOUNDARY\" \"Boundary-00=_y9RuEFduwo6YU42\") (\"INLINE\" NIL) NIL))";406 407 Vector result = StringParser.nestedParenStringLexer(rawText);408 Vector temp1;409 Vector temp2;410 Vector temp3;411 412 //printTree(result, 0);413 assertEquals("BODYSTRUCTURE", (String) result.elementAt(0));414 temp1 = (Vector) result.elementAt(1);415 416 temp2 = (Vector) temp1.elementAt(0);417 assertEquals("TEXT", (String) temp2.elementAt(0));418 assertEquals("PLAIN", (String) temp2.elementAt(1));419 temp3 = (Vector) temp2.elementAt(2);420 assertEquals("CHARSET", (String) temp3.elementAt(0));421 assertEquals("us-ascii", (String) temp3.elementAt(1));422 assertEquals("NIL", (String) temp2.elementAt(3));423 assertEquals("NIL", (String) temp2.elementAt(4));424 assertEquals("7BIT", (String) temp2.elementAt(5));425 assertEquals("165", (String) temp2.elementAt(6));426 assertEquals("8", (String) temp2.elementAt(7));427 assertEquals("NIL", (String) temp2.elementAt(8));428 assertEquals("NIL", (String) temp2.elementAt(9));429 assertEquals("NIL", (String) temp2.elementAt(10));430 431 temp2 = (Vector) temp1.elementAt(1);432 assertEquals("TEXT", (String) temp2.elementAt(0));433 assertEquals("HTML", (String) temp2.elementAt(1));434 temp3 = (Vector) temp2.elementAt(2);435 assertEquals("CHARSET", (String) temp3.elementAt(0));436 assertEquals("us-ascii", (String) temp3.elementAt(1));437 assertEquals("NIL", (String) temp2.elementAt(3));438 assertEquals("NIL", (String) temp2.elementAt(4));439 assertEquals("7BIT", (String) temp2.elementAt(5));440 assertEquals("627", (String) temp2.elementAt(6));441 assertEquals("10", (String) temp2.elementAt(7));442 assertEquals("NIL", (String) temp2.elementAt(8));443 assertEquals("NIL", (String) temp2.elementAt(9));444 assertEquals("NIL", (String) temp2.elementAt(10));445 446 assertEquals("ALTERNATIVE", (String) temp1.elementAt(2));447 448 temp2 = (Vector) temp1.elementAt(3);449 assertEquals("BOUNDARY", (String) temp2.elementAt(0));450 assertEquals("Boundary-00=_y9RuEFduwo6YU42", (String) temp2.elementAt(1));451 452 temp2 = (Vector) temp1.elementAt(4);453 assertEquals("INLINE", (String) temp2.elementAt(0));454 assertEquals("NIL", (String) temp2.elementAt(1));455 456 assertEquals("NIL", (String) temp1.elementAt(5));457 }458 459 // /**460 // * This method prints the parse tree for debugging purposes.461 // * @param node Node to start at.462 // * @param level Level to print from.463 // */464 // private void printTree(Object node, int level) {465 // if(node instanceof Vector) {466 // Vector vec = (Vector)node;467 // int size = vec.size();468 // for(int i=0; i<size; i++)469 // printTree(vec.elementAt(i), level + 1);470 // }471 // else {472 // StringBuffer buf = new StringBuffer();473 // buf.append(level+">");474 // for(int i=0; i<level; i++)475 // buf.append(" ");476 // if(node != null) {477 // buf.append(node.toString());478 // }479 // else {480 // buf.append("null");481 // }482 // System.err.println(buf.toString());483 // }484 // }485 191 486 192 /** … … 839 545 String text = "=A1Hol=E1 Se=F1or!"; 840 546 String expectedResult = "¡Holá Señor!"; 841 String result = StringParser.decodeQuotedPrintable(text );547 String result = StringParser.decodeQuotedPrintable(text.getBytes()); 842 548 assertEquals(expectedResult, result); 843 549 } … … 853 559 "ow=20are=20you=20today?"; 854 560 String expectedResult = "¡Holá Señor! How are you today?"; 855 String result = StringParser.decodeQuotedPrintable(text );561 String result = StringParser.decodeQuotedPrintable(text.getBytes()); 856 562 assertEquals(expectedResult, result); 857 563 } … … 969 675 { public void run(TestCase tc) { ((StringParserTest) tc).testCreateDateString(); }})); 970 676 971 testSuite.addTest(new StringParserTest("nestedParenStringLexerEnvelope1", new TestMethod()972 { public void run(TestCase tc) { ((StringParserTest) tc).testNestedParenStringLexerEnvelope1(); }}));973 974 testSuite.addTest(new StringParserTest("nestedParenStringLexerEnvelope2", new TestMethod()975 { public void run(TestCase tc) { ((StringParserTest) tc).testNestedParenStringLexerEnvelope2(); }}));976 977 testSuite.addTest(new StringParserTest("nestedParenStringLexerEnvelope3", new TestMethod()978 { public void run(TestCase tc) { ((StringParserTest) tc).testNestedParenStringLexerEnvelope3(); }}));979 980 testSuite.addTest(new StringParserTest("nestedParenStringLexerBodyStructure", new TestMethod()981 { public void run(TestCase tc) { ((StringParserTest) tc).testNestedParenStringLexerBodyStructure(); }}));982 983 677 testSuite.addTest(new StringParserTest("parseMailHeaders", new TestMethod() 984 678 { public void run(TestCase tc) { ((StringParserTest) tc).testParseMailHeaders(); }})); -
trunk/LogicMailTests/src/org/logicprobe/LogicMail/util/UtilTests.java
r670 r689 48 48 TestSuite testSuite = new TestSuite("LogicMail.util"); 49 49 testSuite.addTest(new StringParserTest().suite()); 50 testSuite.addTest(new StringArraysTest().suite()); 50 51 testSuite.addTest(new SerializableHashtableTest().suite()); 51 52 testSuite.addTest(new EventListenerListTest().suite());
Note: See TracChangeset
for help on using the changeset viewer.
