1 36 package org.columba.ristretto.imap; 37 38 import java.io.UnsupportedEncodingException ; 39 import java.nio.ByteBuffer ; 40 41 import org.columba.ristretto.coder.Base64; 42 43 49 public class MailboxNameUTF7Converter { 50 51 private final static int PRINTABLE = 0; 52 private final static int BASE64 = 1; 53 54 60 public static String encode(String mailboxName) { 61 int dataBits = 0; 62 int mode = PRINTABLE; 63 ByteBuffer buffer = ByteBuffer.allocate(mailboxName.length() * 4 + 4); 71 72 73 StringBuffer result = new StringBuffer (); 74 char c; 75 76 for( int i=0; i<mailboxName.length(); i++) { 77 c = mailboxName.charAt(i); 78 79 if( isPrintable(c) ) { 80 if( mode != PRINTABLE && buffer.position()> 0) { 81 if(buffer.position() % 3 != 0 ) { 83 buffer.put(new byte[3 - (buffer.position() % 3)]); 84 } 85 buffer.limit(buffer.position()); 86 87 StringBuffer encoded = Base64.encode(buffer, false); 89 buffer.rewind(); 90 91 String rawEncoded = encoded.toString().replace('/',','); 93 94 97 int encodedBits = rawEncoded.length() * 6; 98 int superfluentChars = (encodedBits - dataBits) / 6; 99 100 if( superfluentChars > 0) { 101 rawEncoded = rawEncoded.substring(0, rawEncoded.length()-superfluentChars); 102 } 103 104 result.append(rawEncoded); 105 106 mode = PRINTABLE; 108 result.append('-'); 109 } 110 111 if( c == '&') { 113 result.append("&-"); 114 } else { 115 result.append(c); 116 } 117 } else { 118 if( mode != BASE64) { 119 result.append('&'); 120 mode = BASE64; 121 } 122 123 try { 124 byte[] utfBytes = mailboxName.substring(i,i+1).getBytes("UTF-16"); 125 if( utfBytes[0] != -2 ) { 126 buffer.put(utfBytes[0]); 127 buffer.put(utfBytes[1]); 128 dataBits += 16; 129 } 130 buffer.put(utfBytes[2]); 131 buffer.put(utfBytes[3]); 132 133 dataBits += 16; 134 } catch (UnsupportedEncodingException e) { 135 } 137 } 138 } 139 140 if( mode != PRINTABLE) { 141 if(buffer.position() % 3 != 0 ) { 143 buffer.put(new byte[3 - (buffer.position() % 3)]); 144 } 145 buffer.limit(buffer.position()); 146 147 StringBuffer encoded = Base64.encode(buffer, false); 149 buffer.rewind(); 150 151 String rawEncoded = encoded.toString().replace('/',','); 153 154 157 int encodedBits = rawEncoded.length() * 6; 158 int superfluentChars = (encodedBits - dataBits) / 6; 159 160 if( superfluentChars > 0) { 161 rawEncoded = rawEncoded.substring(0, rawEncoded.length()-superfluentChars); 162 } 163 164 result.append(rawEncoded); 165 166 mode = PRINTABLE; 168 result.append('-'); 169 } 170 171 return result.toString(); 172 } 173 174 180 public static String decode(String mailboxName) { 181 int lastEnd = 0; 182 int nextAnd = mailboxName.indexOf('&'); 183 184 if( nextAnd == -1 ) return mailboxName; 186 187 StringBuffer result = new StringBuffer (mailboxName.length()); 188 189 while( nextAnd != -1 ) { 190 result.append(mailboxName.substring(lastEnd,nextAnd)); 192 193 if( mailboxName.charAt(nextAnd+1) == '-') { 195 result.append('&'); 196 lastEnd = nextAnd+2; 197 } else { 198 lastEnd = mailboxName.indexOf('-',nextAnd); 200 int expanded = 0; 201 202 StringBuffer rawEncoded = new StringBuffer (mailboxName.substring(nextAnd+1, lastEnd).replace(',','/')); 204 while( rawEncoded.length() % 4 != 0) { 205 rawEncoded.append('A'); 206 expanded++; 207 } 208 209 ByteBuffer decoded = Base64.decode(rawEncoded); 211 decoded.limit( decoded.limit() - expanded ); 212 if( decoded.limit() % 2 != 0) { 213 decoded.limit( decoded.limit() - (decoded.limit() % 2)); 215 } 216 217 result.append(decoded.asCharBuffer()); 218 219 lastEnd++; 220 } 221 222 nextAnd = mailboxName.indexOf('&', lastEnd ); 223 } 224 225 result.append(mailboxName.substring(lastEnd)); 226 227 return result.toString(); 228 } 229 230 private static boolean isPrintable(char c) { 231 return ( c >= 0x020 && c <= 0x7e); 232 } 233 234 } 235 | Popular Tags |