View Javadoc

1   /**
2    *
3    * Copyright 2003-2006 The Apache Software Foundation
4    *
5    *  Licensed under the Apache License, Version 2.0 (the "License");
6    *  you may not use this file except in compliance with the License.
7    *  You may obtain a copy of the License at
8    *
9    *     http://www.apache.org/licenses/LICENSE-2.0
10   *
11   *  Unless required by applicable law or agreed to in writing, software
12   *  distributed under the License is distributed on an "AS IS" BASIS,
13   *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14   *  See the License for the specific language governing permissions and
15   *  limitations under the License.
16   */
17  
18  package org.apache.geronimo.mail.util;
19  
20  import java.io.IOException;
21  import java.io.OutputStream;
22  
23  public class HexEncoder
24      implements Encoder
25  {
26      protected final byte[] encodingTable =
27          {
28              (byte)'0', (byte)'1', (byte)'2', (byte)'3', (byte)'4', (byte)'5', (byte)'6', (byte)'7',
29              (byte)'8', (byte)'9', (byte)'a', (byte)'b', (byte)'c', (byte)'d', (byte)'e', (byte)'f'
30          };
31  
32      /*
33       * set up the decoding table.
34       */
35      protected final byte[] decodingTable = new byte[128];
36  
37      protected void initialiseDecodingTable()
38      {
39          for (int i = 0; i < encodingTable.length; i++)
40          {
41              decodingTable[encodingTable[i]] = (byte)i;
42          }
43  
44          decodingTable['A'] = decodingTable['a'];
45          decodingTable['B'] = decodingTable['b'];
46          decodingTable['C'] = decodingTable['c'];
47          decodingTable['D'] = decodingTable['d'];
48          decodingTable['E'] = decodingTable['e'];
49          decodingTable['F'] = decodingTable['f'];
50      }
51  
52      public HexEncoder()
53      {
54          initialiseDecodingTable();
55      }
56  
57      /**
58       * encode the input data producing a Hex output stream.
59       *
60       * @return the number of bytes produced.
61       */
62      public int encode(
63          byte[]                data,
64          int                    off,
65          int                    length,
66          OutputStream    out)
67          throws IOException
68      {
69          for (int i = off; i < (off + length); i++)
70          {
71              int    v = data[i] & 0xff;
72  
73              out.write(encodingTable[(v >>> 4)]);
74              out.write(encodingTable[v & 0xf]);
75          }
76  
77          return length * 2;
78      }
79  
80      private boolean ignore(
81          char    c)
82      {
83          return (c == '\n' || c =='\r' || c == '\t' || c == ' ');
84      }
85  
86      /**
87       * decode the Hex encoded byte data writing it to the given output stream,
88       * whitespace characters will be ignored.
89       *
90       * @return the number of bytes produced.
91       */
92      public int decode(
93          byte[]                data,
94          int                    off,
95          int                    length,
96          OutputStream    out)
97          throws IOException
98      {
99          byte[]    bytes;
100         byte    b1, b2;
101         int        outLen = 0;
102 
103         int        end = off + length;
104 
105         while (end > 0)
106         {
107             if (!ignore((char)data[end - 1]))
108             {
109                 break;
110             }
111 
112             end--;
113         }
114 
115         int i = off;
116         while (i < end)
117         {
118             while (i < end && ignore((char)data[i]))
119             {
120                 i++;
121             }
122 
123             b1 = decodingTable[data[i++]];
124 
125             while (i < end && ignore((char)data[i]))
126             {
127                 i++;
128             }
129 
130             b2 = decodingTable[data[i++]];
131 
132             out.write((b1 << 4) | b2);
133 
134             outLen++;
135         }
136 
137         return outLen;
138     }
139 
140     /**
141      * decode the Hex encoded String data writing it to the given output stream,
142      * whitespace characters will be ignored.
143      *
144      * @return the number of bytes produced.
145      */
146     public int decode(
147         String                data,
148         OutputStream    out)
149         throws IOException
150     {
151         byte[]    bytes;
152         byte    b1, b2, b3, b4;
153         int        length = 0;
154 
155         int        end = data.length();
156 
157         while (end > 0)
158         {
159             if (!ignore(data.charAt(end - 1)))
160             {
161                 break;
162             }
163 
164             end--;
165         }
166 
167         int i = 0;
168         while (i < end)
169         {
170             while (i < end && ignore(data.charAt(i)))
171             {
172                 i++;
173             }
174 
175             b1 = decodingTable[data.charAt(i++)];
176 
177             while (i < end && ignore(data.charAt(i)))
178             {
179                 i++;
180             }
181 
182             b2 = decodingTable[data.charAt(i++)];
183 
184             out.write((b1 << 4) | b2);
185 
186             length++;
187         }
188 
189         return length;
190     }
191 }