/[classpath]/inetlib/source/gnu/inet/imap/UTF7imap.java
ViewVC logotype

Diff of /inetlib/source/gnu/inet/imap/UTF7imap.java

Parent Directory Parent Directory | Revision Log Revision Log | View Patch Patch

revision 1.5 by dog, Thu Oct 21 15:21:55 2004 UTC revision 1.6 by dog, Thu Nov 25 22:15:05 2004 UTC
# Line 1  Line 1 
1  /*  /*
2   * $Id$   * UTF7imap.java
3   * Copyright (C) 2003 The Free Software Foundation   * Copyright (C) 2003 The Free Software Foundation
4   *   *
5   * This file is part of GNU inetlib, a library.   * This file is part of GNU inetlib, a library.
# Line 46  import java.io.IOException; Line 46  import java.io.IOException;
46   * encoding scheme.   * encoding scheme.
47   *   *
48   * @author <a href="mailto:dog@gnu.org">Chris Burdess</a>   * @author <a href="mailto:dog@gnu.org">Chris Burdess</a>
  * @version $Revision$ $Date$  
49   */   */
50  public final class UTF7imap  public final class UTF7imap
51  {  {
# Line 78  public final class UTF7imap Line 77  public final class UTF7imap
77    
78    }    }
79    
80    private UTF7imap ()    private UTF7imap()
81    {    {
82    }    }
83    
# Line 88  public final class UTF7imap Line 87  public final class UTF7imap
87     *     *
88     * @param bs the source byte array     * @param bs the source byte array
89     */     */
90    static byte[] encode (byte[] bs)    static byte[] encode(byte[] bs)
91      {    {
92        int si = 0, ti = 0;         // source/target array indices      int si = 0, ti = 0;         // source/target array indices
93        byte[] bt = new byte[(((bs.length + 2) / 3) * 4) -1];// target byte array      byte[] bt = new byte[(((bs.length + 2) / 3) * 4) -1];// target byte array
94        for (; si < bs.length; si += 3)      for (; si < bs.length; si += 3)
95          {        {
96            int buflen = bs.length - si;          int buflen = bs.length - si;
97            if (buflen == 1)          if (buflen == 1)
98              {            {
99                byte b = bs[si];              byte b = bs[si];
100                int i = 0;              int i = 0;
101                boolean flag = false;              boolean flag = false;
102                bt[ti++] = src[b >>> 2 & 0x3f];              bt[ti++] = src[b >>> 2 & 0x3f];
103                bt[ti++] = src[(b << 4 & 0x30) + (i >>> 4 & 0xf)];              bt[ti++] = src[(b << 4 & 0x30) + (i >>> 4 & 0xf)];
104              }            }
105            else if (buflen == 2)          else if (buflen == 2)
106              {            {
107                byte b1 = bs[si], b2 = bs[si + 1];              byte b1 = bs[si], b2 = bs[si + 1];
108                int i = 0;              int i = 0;
109                bt[ti++] = src[b1 >>> 2 & 0x3f];              bt[ti++] = src[b1 >>> 2 & 0x3f];
110                bt[ti++] = src[(b1 << 4 & 0x30) + (b2 >>> 4 & 0xf)];              bt[ti++] = src[(b1 << 4 & 0x30) + (b2 >>> 4 & 0xf)];
111                bt[ti++] = src[(b2 << 2 & 0x3c) + (i >>> 6 & 0x3)];              bt[ti++] = src[(b2 << 2 & 0x3c) + (i >>> 6 & 0x3)];
112              }            }
113            else if (buflen == 3)          else if (buflen == 3)
114              {            {
115                byte b1 = bs[si], b2 = bs[si + 1], b3 = bs[si + 2];              byte b1 = bs[si], b2 = bs[si + 1], b3 = bs[si + 2];
116                bt[ti++] = src[b1 >>> 2 & 0x3f];              bt[ti++] = src[b1 >>> 2 & 0x3f];
117                bt[ti++] = src[(b1 << 4 & 0x30) + (b2 >>> 4 & 0xf)];              bt[ti++] = src[(b1 << 4 & 0x30) + (b2 >>> 4 & 0xf)];
118                bt[ti++] = src[(b2 << 2 & 0x3c) + (b3 >>> 6 & 0x3)];              bt[ti++] = src[(b2 << 2 & 0x3c) + (b3 >>> 6 & 0x3)];
119                bt[ti++] = src[b3 & 0x3f];              bt[ti++] = src[b3 & 0x3f];
120              }            }
121          }        }
122        return bt;      return bt;
123      }    }
124    
125    /**    /**
126     * Decode the specified byte array using the modified BASE64 algorithm     * Decode the specified byte array using the modified BASE64 algorithm
# Line 129  public final class UTF7imap Line 128  public final class UTF7imap
128     *     *
129     * @param bs the source byte array     * @param bs the source byte array
130     */     */
131    static int[] decode (byte[] bs)    static int[] decode(byte[] bs)
132      {    {
133        int[] buffer = new int[bs.length];      int[] buffer = new int[bs.length];
134        int buflen = 0;      int buflen = 0;
135        int si = 0;      int si = 0;
136        int len = bs.length - si;      int len = bs.length - si;
137        while (len > 0)      while (len > 0)
138          {        {
139            byte b0 = dst[bs[si++] & 0xff];          byte b0 = dst[bs[si++] & 0xff];
140            byte b2 = dst[bs[si++] & 0xff];          byte b2 = dst[bs[si++] & 0xff];
141            buffer[buflen++] = (b0 << 2 & 0xfc | b2 >>> 4 & 0x3);          buffer[buflen++] = (b0 << 2 & 0xfc | b2 >>> 4 & 0x3);
142            if (len > 2)          if (len > 2)
143              {            {
144                b0 = b2;              b0 = b2;
145                b2 = dst[bs[si++] & 0xff];              b2 = dst[bs[si++] & 0xff];
146                buffer[buflen++] = (b0 << 4 & 0xf0 | b2 >>> 2 & 0xf);              buffer[buflen++] = (b0 << 4 & 0xf0 | b2 >>> 2 & 0xf);
147                if (len > 3)              if (len > 3)
148                  {                {
149                    b0 = b2;                  b0 = b2;
150                    b2 = dst[bs[si++] & 0xff];                  b2 = dst[bs[si++] & 0xff];
151                    buffer[buflen++] = (b0 << 6 & 0xc0 | b2 & 0x3f);                  buffer[buflen++] = (b0 << 6 & 0xc0 | b2 & 0x3f);
152                  }                }
153              }            }
154            len = bs.length - si;          len = bs.length - si;
155          }        }
156        int[] bt = new int[buflen];      int[] bt = new int[buflen];
157        System.arraycopy (buffer, 0, bt, 0, buflen);      System.arraycopy(buffer, 0, bt, 0, buflen);
158        return bt;      return bt;
159      }    }
160    
161    /**    /**
162     * Encodes the specified name using the UTF-7.imap encoding.     * Encodes the specified name using the UTF-7.imap encoding.
163     * See IMAP4rev1 spec, section 5.1.3     * See IMAP4rev1 spec, section 5.1.3
164     */     */
165    public static String encode (String name)    public static String encode(String name)
166      {    {
167        try      try
168          {        {
169            StringBuffer buffer = null;          StringBuffer buffer = null;
170            ByteArrayOutputStream encoderSink = null;          ByteArrayOutputStream encoderSink = null;
171            char[] chars = name.toCharArray ();          char[] chars = name.toCharArray();
172            boolean encoding = false;          boolean encoding = false;
173            for (int i = 0; i < chars.length; i++)          for (int i = 0; i < chars.length; i++)
174              {            {
175                char c = chars[i];              char c = chars[i];
176                if (c == '&')              if (c == '&')
177                  {                {
178                    if (buffer == null)                  if (buffer == null)
179                      {                    {
180                        buffer = new StringBuffer ();                      buffer = new StringBuffer();
181                        for (int j = 0; j < i; j++)                      for (int j = 0; j < i; j++)
182                          {                        {
183                            buffer.append (chars[j]);                          buffer.append(chars[j]);
184                          }                        }
185                      }                    }
186                    buffer.append ('&');                  buffer.append('&');
187                    buffer.append ('-');                  buffer.append('-');
188                  }                }
189                if (c < 0x1f || c > 0x7f)              if (c < 0x1f || c > 0x7f)
190                  {                {
191                    // needs encoding                  // needs encoding
192                    if (buffer == null)                  if (buffer == null)
193                      {                    {
194                        buffer = new StringBuffer ();                      buffer = new StringBuffer();
195                        for (int j = 0; j < i; j++)                      for (int j = 0; j < i; j++)
196                          {                        {
197                            buffer.append (chars[j]);                          buffer.append(chars[j]);
198                          }                        }
199                        encoderSink = new ByteArrayOutputStream ();                      encoderSink = new ByteArrayOutputStream();
200                      }                    }
201                    if (!encoding)                  if (!encoding)
202                      {                    {
203                        encoderSink.reset ();                      encoderSink.reset();
204                        buffer.append ('&');                      buffer.append('&');
205                        encoding = true;                      encoding = true;
206                      }                    }
207                    encoderSink.write (((int) c) / 0x100);                  encoderSink.write(((int) c) / 0x100);
208                    encoderSink.write (((int) c) % 0x100);                  encoderSink.write(((int) c) % 0x100);
209                  }                }
210                else if (encoding)              else if (encoding)
211                  {                {
212                    encoderSink.flush ();                  encoderSink.flush();
213                    byte[] encoded = encode (encoderSink.toByteArray ());                  byte[] encoded = encode(encoderSink.toByteArray());
214                    buffer.append (new String (encoded, US_ASCII));                  buffer.append(new String(encoded, US_ASCII));
215                    buffer.append ('-');                  buffer.append('-');
216                    encoding = false;                  encoding = false;
217                    if (c != '-')                  if (c != '-')
218                      {                    {
219                        buffer.append (c);                      buffer.append(c);
220                      }                    }
221                  }                }
222                else if (buffer != null)              else if (buffer != null)
223                  {                {
224                    buffer.append (c);                  buffer.append(c);
225                  }                }
226              }            }
227            if (encoding)          if (encoding)
228              {            {
229                encoderSink.flush ();              encoderSink.flush();
230                byte[] encoded = encode (encoderSink.toByteArray ());              byte[] encoded = encode(encoderSink.toByteArray());
231                buffer.append (new String(encoded, US_ASCII));              buffer.append(new String(encoded, US_ASCII));
232                buffer.append ('-');              buffer.append('-');
233              }            }
234            if (buffer != null)          if (buffer != null)
235              {            {
236                return buffer.toString ();              return buffer.toString();
237              }            }
238          }        }
239        catch (IOException e)      catch (IOException e)
240          {        {
241            // This should never happen          // This should never happen
242            throw new RuntimeException (e.getMessage ());          throw new RuntimeException(e.getMessage());
243          }        }
244        return name;      return name;
245      }    }
246      
247    /**    /**
248     * Decodes the specified name using the UTF-7.imap decoding.     * Decodes the specified name using the UTF-7.imap decoding.
249     * See IMAP4rev1 spec, section 5.1.3     * See IMAP4rev1 spec, section 5.1.3
250     */     */
251    public static String decode (String name)    public static String decode(String name)
252      {    {
253        StringBuffer buffer = null;      StringBuffer buffer = null;
254        ByteArrayOutputStream decoderSink = null;      ByteArrayOutputStream decoderSink = null;
255        char[] chars = name.toCharArray ();      char[] chars = name.toCharArray();
256        boolean encoded = false;      boolean encoded = false;
257        for (int i = 0; i < chars.length; i++)      for (int i = 0; i < chars.length; i++)
258          {        {
259            char c = chars[i];          char c = chars[i];
260            if (c == '&')          if (c == '&')
261              {            {
262                if (buffer == null)              if (buffer == null)
263                  {                {
264                    buffer = new StringBuffer ();                  buffer = new StringBuffer();
265                    decoderSink = new ByteArrayOutputStream ();                  decoderSink = new ByteArrayOutputStream();
266                    for (int j = 0; j < i; j++)                  for (int j = 0; j < i; j++)
267                      {                    {
268                        buffer.append (chars[j]);                      buffer.append(chars[j]);
269                      }                    }
270                  }                }
271                decoderSink.reset ();              decoderSink.reset();
272                encoded = true;              encoded = true;
273              }            }
274            else if (c == '-' && encoded)          else if (c == '-' && encoded)
275              {            {
276                if (decoderSink.size () == 0)              if (decoderSink.size() == 0)
277                  {                {
278                    buffer.append ('&');                  buffer.append('&');
279                  }                }
280                else              else
281                  {                {
282                    int[] decoded = decode (decoderSink.toByteArray ());                  int[] decoded = decode(decoderSink.toByteArray());
283                    for (int j = 0; j < decoded.length - 1; j += 2)                  for (int j = 0; j < decoded.length - 1; j += 2)
284                      {                    {
285                        int hibyte = decoded[j];                      int hibyte = decoded[j];
286                        int lobyte = decoded[j + 1];                      int lobyte = decoded[j + 1];
287                        int d = (hibyte * 0x100) | lobyte;                      int d = (hibyte * 0x100) | lobyte;
288                        buffer.append ((char) d);                      buffer.append((char) d);
289                      }                    }
290                  }                }
291                encoded = false;              encoded = false;
292              }            }
293            else if (encoded)          else if (encoded)
294              {            {
295                decoderSink.write ((byte) c);              decoderSink.write((byte) c);
296              }            }
297            else if (buffer != null)          else if (buffer != null)
298              {            {
299                buffer.append (c);              buffer.append(c);
300              }            }
301          }        }
302        if (buffer != null)      if (buffer != null)
303          {        {
304            return buffer.toString ();          return buffer.toString();
305          }        }
306        return name;      return name;
     }  
   
   public static void main (String[] args)  
     {  
       boolean decode = false;  
       for (int i = 0; i < args.length; i++)  
         {  
           if (args[i].equals ("-d"))  
             {  
               decode = true;  
             }  
           else  
             {  
               String ret = decode ? decode (args[i]) : encode (args[i]);  
               StringBuffer buf = new StringBuffer (args[i]);  
               buf.append (" = \"");  
               buf.append (ret);  
               buf.append ("\" (");  
               for (int j = 0; j < ret.length (); j++)  
                 {  
                   if (j > 0)  
                     {  
                       buf.append (' ');  
                     }  
                   int c = (int) (ret.charAt (j));  
                   buf.append (Integer.toString (c, 16));  
                 }  
               buf.append (")");  
               System.out.println (buf.toString ());  
             }  
         }  
307      }      }
308      
309      public static void main(String[] args)
310      {
311        boolean decode = false;
312        for (int i = 0; i < args.length; i++)
313          {
314            if (args[i].equals("-d"))
315              {
316                decode = true;
317              }
318            else
319              {
320                String ret = decode ? decode(args[i]) : encode(args[i]);
321                StringBuffer buf = new StringBuffer(args[i]);
322                buf.append(" = \"");
323                buf.append(ret);
324                buf.append("\"(");
325                for (int j = 0; j < ret.length(); j++)
326                  {
327                    if (j > 0)
328                      {
329                        buf.append(' ');
330                      }
331                    int c = (int) ret.charAt(j);
332                    buf.append(Integer.toString(c, 16));
333                  }
334                buf.append(")");
335                System.out.println(buf.toString());
336              }
337          }
338      }
339      
340  }  }
341    

Legend:
Removed from v.1.5  
changed lines
  Added in v.1.6

savannah-hackers-public@gnu.org
ViewVC Help
Powered by ViewVC 1.1.26