001    /**
002     *
003     *  Licensed to the Apache Software Foundation (ASF) under one or more
004     *  contributor license agreements.  See the NOTICE file distributed with
005     *  this work for additional information regarding copyright ownership.
006     *  The ASF licenses this file to You under the Apache License, Version 2.0
007     *  (the "License"); you may not use this file except in compliance with
008     *  the License.  You may obtain a copy of the License at
009     *
010     *     http://www.apache.org/licenses/LICENSE-2.0
011     *
012     *  Unless required by applicable law or agreed to in writing, software
013     *  distributed under the License is distributed on an "AS IS" BASIS,
014     *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
015     *  See the License for the specific language governing permissions and
016     *  limitations under the License.
017     */
018    
019    package org.apache.geronimo.util.encoders;
020    
021    /**
022     * Converters for going from hex to binary and back. Note: this class assumes ASCII processing.
023     */
024    public class HexTranslator
025        implements Translator
026    {
027        private static final byte[]   hexTable =
028            {
029                (byte)'0', (byte)'1', (byte)'2', (byte)'3', (byte)'4', (byte)'5', (byte)'6', (byte)'7',
030                (byte)'8', (byte)'9', (byte)'a', (byte)'b', (byte)'c', (byte)'d', (byte)'e', (byte)'f'
031            };
032    
033        /**
034         * size of the output block on encoding produced by getDecodedBlockSize()
035         * bytes.
036         */
037        public int getEncodedBlockSize()
038        {
039            return 2;
040        }
041    
042        public int encode(
043            byte[]  in,
044            int     inOff,
045            int     length,
046            byte[]  out,
047            int     outOff)
048        {
049            for (int i = 0, j = 0; i < length; i++, j += 2)
050            {
051                out[outOff + j] = hexTable[(in[inOff] >> 4) & 0x0f];
052                out[outOff + j + 1] = hexTable[in[inOff] & 0x0f];
053    
054                inOff++;
055            }
056    
057            return length * 2;
058        }
059    
060        /**
061         * size of the output block on decoding produced by getEncodedBlockSize()
062         * bytes.
063         */
064        public int getDecodedBlockSize()
065        {
066            return 1;
067        }
068    
069        public int decode(
070            byte[]  in,
071            int     inOff,
072            int     length,
073            byte[]  out,
074            int     outOff)
075        {
076            int halfLength = length / 2;
077            byte left, right;
078            for (int i = 0; i < halfLength; i++)
079            {
080                left  = in[inOff + i * 2];
081                right = in[inOff + i * 2 + 1];
082    
083                if (left < (byte)'a')
084                {
085                    out[outOff] = (byte)((left - '0') << 4);
086                }
087                else
088                {
089                    out[outOff] = (byte)((left - 'a' + 10) << 4);
090                }
091                if (right < (byte)'a')
092                {
093                    out[outOff] += (byte)(right - '0');
094                }
095                else
096                {
097                    out[outOff] += (byte)(right - 'a' + 10);
098                }
099    
100                outOff++;
101            }
102    
103            return halfLength;
104        }
105    }