1 /* 2 * Copyright (C) 2011 The Android Open Source Project 3 * 4 * Licensed under the Apache License, Version 2.0 (the "License"); 5 * you may not use this file except in compliance with the License. 6 * You may obtain a copy of the License at 7 * 8 * http://www.apache.org/licenses/LICENSE-2.0 9 * 10 * Unless required by applicable law or agreed to in writing, software 11 * distributed under the License is distributed on an "AS IS" BASIS, 12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 * See the License for the specific language governing permissions and 14 * limitations under the License. 15 */ 16 17 package com.android.email.mail.store.imap; 18 19 import com.android.emailcommon.Logging; 20 21 import android.util.Log; 22 23 import java.util.ArrayList; 24 25 /** 26 * Utility methods for use with IMAP. 27 */ 28 public class ImapUtility { 29 /** 30 * Apply quoting rules per IMAP RFC, 31 * quoted = DQUOTE *QUOTED-CHAR DQUOTE 32 * QUOTED-CHAR = <any TEXT-CHAR except quoted-specials> / "\" quoted-specials 33 * quoted-specials = DQUOTE / "\" 34 * 35 * This is used primarily for IMAP login, but might be useful elsewhere. 36 * 37 * NOTE: Not very efficient - you may wish to preflight this, or perhaps it should check 38 * for trouble chars before calling the replace functions. 39 * 40 * @param s The string to be quoted. 41 * @return A copy of the string, having undergone quoting as described above 42 */ imapQuoted(String s)43 public static String imapQuoted(String s) { 44 45 // First, quote any backslashes by replacing \ with \\ 46 // regex Pattern: \\ (Java string const = \\\\) 47 // Substitute: \\\\ (Java string const = \\\\\\\\) 48 String result = s.replaceAll("\\\\", "\\\\\\\\"); 49 50 // Then, quote any double-quotes by replacing " with \" 51 // regex Pattern: " (Java string const = \") 52 // Substitute: \\" (Java string const = \\\\\") 53 result = result.replaceAll("\"", "\\\\\""); 54 55 // return string with quotes around it 56 return "\"" + result + "\""; 57 } 58 59 /** 60 * Gets all of the values in a sequence set per RFC 3501. Any ranges are expanded into a 61 * list of individual numbers. If the set is invalid, an empty array is returned. 62 * <pre> 63 * sequence-number = nz-number / "*" 64 * sequence-range = sequence-number ":" sequence-number 65 * sequence-set = (sequence-number / sequence-range) *("," sequence-set) 66 * </pre> 67 */ getImapSequenceValues(String set)68 public static String[] getImapSequenceValues(String set) { 69 ArrayList<String> list = new ArrayList<String>(); 70 if (set != null) { 71 String[] setItems = set.split(","); 72 for (String item : setItems) { 73 if (item.indexOf(':') == -1) { 74 // simple item 75 try { 76 Integer.parseInt(item); // Don't need the value; just ensure it's valid 77 list.add(item); 78 } catch (NumberFormatException e) { 79 Log.d(Logging.LOG_TAG, "Invalid UID value", e); 80 } 81 } else { 82 // range 83 for (String rangeItem : getImapRangeValues(item)) { 84 list.add(rangeItem); 85 } 86 } 87 } 88 } 89 String[] stringList = new String[list.size()]; 90 return list.toArray(stringList); 91 } 92 93 /** 94 * Expand the given number range into a list of individual numbers. If the range is not valid, 95 * an empty array is returned. 96 * <pre> 97 * sequence-number = nz-number / "*" 98 * sequence-range = sequence-number ":" sequence-number 99 * sequence-set = (sequence-number / sequence-range) *("," sequence-set) 100 * </pre> 101 */ getImapRangeValues(String range)102 public static String[] getImapRangeValues(String range) { 103 ArrayList<String> list = new ArrayList<String>(); 104 try { 105 if (range != null) { 106 int colonPos = range.indexOf(':'); 107 if (colonPos > 0) { 108 int first = Integer.parseInt(range.substring(0, colonPos)); 109 int second = Integer.parseInt(range.substring(colonPos + 1)); 110 if (first < second) { 111 for (int i = first; i <= second; i++) { 112 list.add(Integer.toString(i)); 113 } 114 } else { 115 for (int i = first; i >= second; i--) { 116 list.add(Integer.toString(i)); 117 } 118 } 119 } 120 } 121 } catch (NumberFormatException e) { 122 Log.d(Logging.LOG_TAG, "Invalid range value", e); 123 } 124 String[] stringList = new String[list.size()]; 125 return list.toArray(stringList); 126 } 127 } 128