1717
1818package org .apache .commons .codec .binary ;
1919
20+ import java .io .UnsupportedEncodingException ;
21+
2022import org .apache .commons .codec .BinaryDecoder ;
2123import org .apache .commons .codec .BinaryEncoder ;
24+ import org .apache .commons .codec .CharEncoding ;
2225import org .apache .commons .codec .DecoderException ;
2326import org .apache .commons .codec .EncoderException ;
2427
2528/**
26- * Hex encoder and decoder.
29+ * Hex encoder and decoder. The charset used for certain operation can be set, the default is set in
30+ * {@link #DEFAULT_CHARSET_NAME}
2731 *
2832 * @since 1.1
2933 * @author Apache Software Foundation
3034 * @version $Id$
3135 */
3236public class Hex implements BinaryEncoder , BinaryDecoder {
3337
34- /**
35- * Used to build output as Hex
38+ /**
39+ * Default charset name is {@link CharEncoding#UTF_8}
3640 */
37- private static final char [] DIGITS_LOWER = {
38- '0' , '1' , '2' , '3' , '4' , '5' , '6' , '7' ,
39- '8' , '9' , 'a' , 'b' , 'c' , 'd' , 'e' , 'f'
40- };
41+ public static final String DEFAULT_CHARSET_NAME = CharEncoding .UTF_8 ;
4142
42- /**
43- * Used to build output as Hex
43+ /**
44+ * Used to build output as Hex
4445 */
45- private static final char [] DIGITS_UPPER = {
46- '0' , '1' , '2' , '3' , '4' , '5' , '6' , '7' ,
47- '8' , '9' , 'A' , 'B' , 'C' , 'D' , 'E' , 'F'
48- };
46+ private static final char [] DIGITS_LOWER = {'0' , '1' , '2' , '3' , '4' , '5' , '6' , '7' , '8' , '9' , 'a' , 'b' , 'c' , 'd' , 'e' , 'f' };
4947
5048 /**
51- * Converts an array of characters representing hexadecimal values into an
52- * array of bytes of those same values. The returned array will be half the
53- * length of the passed array, as it takes two characters to represent any
54- * given byte. An exception is thrown if the passed char array has an odd
55- * number of elements.
49+ * Used to build output as Hex
50+ */
51+ private static final char [] DIGITS_UPPER = {'0' , '1' , '2' , '3' , '4' , '5' , '6' , '7' , '8' , '9' , 'A' , 'B' , 'C' , 'D' , 'E' , 'F' };
52+
53+ /**
54+ * Converts an array of characters representing hexadecimal values into an array of bytes of those same values. The
55+ * returned array will be half the length of the passed array, as it takes two characters to represent any given
56+ * byte. An exception is thrown if the passed char array has an odd number of elements.
5657 *
57- * @param data An array of characters containing hexadecimal digits
58- * @return A byte array containing binary data decoded from
59- * the supplied char array.
60- * @throws DecoderException Thrown if an odd number or illegal of characters
61- * is supplied
58+ * @param data
59+ * An array of characters containing hexadecimal digits
60+ * @return A byte array containing binary data decoded from the supplied char array.
61+ * @throws DecoderException
62+ * Thrown if an odd number or illegal of characters is supplied
6263 */
6364 public static byte [] decodeHex (char [] data ) throws DecoderException {
6465
@@ -82,22 +83,6 @@ public static byte[] decodeHex(char[] data) throws DecoderException {
8283 return out ;
8384 }
8485
85- /**
86- * Converts a hexadecimal character to an integer.
87- *
88- * @param ch A character to convert to an integer digit
89- * @param index The index of the character in the source
90- * @return An integer
91- * @throws DecoderException Thrown if ch is an illegal hex character
92- */
93- protected static int toDigit (char ch , int index ) throws DecoderException {
94- int digit = Character .digit (ch , 16 );
95- if (digit == -1 ) {
96- throw new DecoderException ("Illegal hexadecimal charcter " + ch + " at index " + index );
97- }
98- return digit ;
99- }
100-
10186 /**
10287 * Converts an array of bytes into an array of characters representing the hexadecimal values of each byte in order.
10388 * The returned array will be double the length of the passed array, as it takes two characters to represent any
@@ -151,35 +136,87 @@ protected static char[] encodeHex(byte[] data, char[] toDigits) {
151136 }
152137
153138 /**
154- * Converts an array of character bytes representing hexadecimal values into an
155- * array of bytes of those same values. The returned array will be half the
156- * length of the passed array, as it takes two characters to represent any
157- * given byte. An exception is thrown if the passed char array has an odd
158- * number of elements.
139+ * Converts an array of bytes into a String representing the hexadecimal values of each byte in order. The returned
140+ * String will be double the length of the passed array, as it takes two characters to represent any given byte.
141+ *
142+ * @param data
143+ * a byte[] to convert to Hex characters
144+ * @return A String containing hexadecimal characters
145+ * @since 1.4
146+ */
147+ public static String encodeHexString (byte [] data ) {
148+ return new String (encodeHex (data ));
149+ }
150+
151+ /**
152+ * Converts a hexadecimal character to an integer.
159153 *
160- * @param array An array of character bytes containing hexadecimal digits
161- * @return A byte array containing binary data decoded from
162- * the supplied byte array (representing characters).
163- * @throws DecoderException Thrown if an odd number of characters is supplied
164- * to this function
154+ * @param ch
155+ * A character to convert to an integer digit
156+ * @param index
157+ * The index of the character in the source
158+ * @return An integer
159+ * @throws DecoderException
160+ * Thrown if ch is an illegal hex character
161+ */
162+ protected static int toDigit (char ch , int index ) throws DecoderException {
163+ int digit = Character .digit (ch , 16 );
164+ if (digit == -1 ) {
165+ throw new DecoderException ("Illegal hexadecimal charcter " + ch + " at index " + index );
166+ }
167+ return digit ;
168+ }
169+
170+ private String charsetName = DEFAULT_CHARSET_NAME ;
171+
172+ /**
173+ * Creates a new codec with the default charset name {@link #DEFAULT_CHARSET_NAME}
174+ */
175+ public Hex () {
176+ // use default encoding
177+ }
178+
179+ /**
180+ * Creates a new codec with the given charset name.
181+ *
182+ * @param csName
183+ * the charset name.
184+ */
185+ public Hex (String csName ) {
186+ setCharsetName (csName );
187+ }
188+
189+ /**
190+ * Converts an array of character bytes representing hexadecimal values into an array of bytes of those same values.
191+ * The returned array will be half the length of the passed array, as it takes two characters to represent any given
192+ * byte. An exception is thrown if the passed char array has an odd number of elements.
193+ *
194+ * @param array
195+ * An array of character bytes containing hexadecimal digits
196+ * @return A byte array containing binary data decoded from the supplied byte array (representing characters).
197+ * @throws DecoderException
198+ * Thrown if an odd number of characters is supplied to this function
165199 * @see #decodeHex(char[])
166200 */
167201 public byte [] decode (byte [] array ) throws DecoderException {
168- return decodeHex (new String (array ).toCharArray ());
202+ try {
203+ return decodeHex (new String (array , getCharsetName ()).toCharArray ());
204+ } catch (UnsupportedEncodingException e ) {
205+ throw new DecoderException (e .getMessage (), e );
206+ }
169207 }
170-
208+
171209 /**
172- * Converts a String or an array of character bytes representing hexadecimal values into an
173- * array of bytes of those same values. The returned array will be half the
174- * length of the passed String or array, as it takes two characters to represent any
175- * given byte. An exception is thrown if the passed char array has an odd
176- * number of elements.
210+ * Converts a String or an array of character bytes representing hexadecimal values into an array of bytes of those
211+ * same values. The returned array will be half the length of the passed String or array, as it takes two characters
212+ * to represent any given byte. An exception is thrown if the passed char array has an odd number of elements.
177213 *
178- * @param object A String or, an array of character bytes containing hexadecimal digits
179- * @return A byte array containing binary data decoded from
180- * the supplied byte array (representing characters).
181- * @throws DecoderException Thrown if an odd number of characters is supplied
182- * to this function or the object is not a String or char[]
214+ * @param object
215+ * A String or, an array of character bytes containing hexadecimal digits
216+ * @return A byte array containing binary data decoded from the supplied byte array (representing characters).
217+ * @throws DecoderException
218+ * Thrown if an odd number of characters is supplied to this function or the object is not a String or
219+ * char[]
183220 * @see #decodeHex(char[])
184221 */
185222 public Object decode (Object object ) throws DecoderException {
@@ -192,38 +229,73 @@ public Object decode(Object object) throws DecoderException {
192229 }
193230
194231 /**
195- * Converts an array of bytes into an array of bytes for the characters representing the
196- * hexadecimal values of each byte in order. The returned array will be
197- * double the length of the passed array, as it takes two characters to
232+ * Converts an array of bytes into an array of bytes for the characters representing the hexadecimal values of each
233+ * byte in order. The returned array will be double the length of the passed array, as it takes two characters to
198234 * represent any given byte.
199- *
200- * @param array a byte[] to convert to Hex characters
235+ * <p>
236+ * The conversion from hexadecimal characters to the returned bytes is performed with the charset named by
237+ * {@link #getCharsetName()}.
238+ * </p>
239+ *
240+ * @param array
241+ * a byte[] to convert to Hex characters
201242 * @return A byte[] containing the bytes of the hexadecimal characters
243+ * @throws IllegalStateException
244+ * if the charsetName is invalid. This API throws {@link IllegalStateException} instead of
245+ * {@link UnsupportedEncodingException} for backward compatibility.
202246 * @see #encodeHex(byte[])
203247 */
204248 public byte [] encode (byte [] array ) {
205- return new String ( encodeHex (array )). getBytes ( );
249+ return StringUtils . getBytesUnchecked ( encodeHexString (array ), getCharsetName () );
206250 }
207251
208252 /**
209- * Converts a String or an array of bytes into an array of characters representing the
210- * hexadecimal values of each byte in order. The returned array will be
211- * double the length of the passed String or array, as it takes two characters to
212- * represent any given byte.
213- *
214- * @param object a String, or byte[] to convert to Hex characters
253+ * Converts a String or an array of bytes into an array of characters representing the hexadecimal values of each
254+ * byte in order. The returned array will be double the length of the passed String or array, as it takes two
255+ * characters to represent any given byte.
256+ * <p>
257+ * The conversion from hexadecimal characters to bytes to be encoded to performed with the charset named by
258+ * {@link #getCharsetName()}.
259+ * </p>
260+ *
261+ * @param object
262+ * a String, or byte[] to convert to Hex characters
215263 * @return A char[] containing hexadecimal characters
216- * @throws EncoderException Thrown if the given object is not a String or byte[]
264+ * @throws EncoderException
265+ * Thrown if the given object is not a String or byte[]
217266 * @see #encodeHex(byte[])
218267 */
219- public Object encode (Object object ) throws EncoderException {
268+ public Object encode (Object object ) throws EncoderException {
220269 try {
221- byte [] byteArray = object instanceof String ? ((String ) object ).getBytes () : (byte []) object ;
270+ byte [] byteArray = object instanceof String ? ((String ) object ).getBytes (getCharsetName () ) : (byte []) object ;
222271 return encodeHex (byteArray );
223272 } catch (ClassCastException e ) {
224273 throw new EncoderException (e .getMessage (), e );
274+ } catch (UnsupportedEncodingException e ) {
275+ throw new EncoderException (e .getMessage (), e );
225276 }
226277 }
227278
228- }
279+ /**
280+ * Gets the charset name.
281+ *
282+ * @return the charset name.
283+ */
284+ public String getCharsetName () {
285+ return this .charsetName ;
286+ }
287+
288+ /**
289+ * Sets the charset name.
290+ *
291+ * @param charsetName
292+ * the charset name.
293+ */
294+ public void setCharsetName (String charsetName ) {
295+ this .charsetName = charsetName ;
296+ }
229297
298+ public String toString () {
299+ return super .toString () + "[charsetName=" + this .charsetName + "]" ;
300+ }
301+ }
0 commit comments