View Javadoc

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