1 /*
2  * Copyright (c) 2004, 2013, Oracle and/or its affiliates. All rights reserved.
3  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
4  *
5  * This code is free software; you can redistribute it and/or modify it
6  * under the terms of the GNU General Public License version 2 only, as
7  * published by the Free Software Foundation.  Oracle designates this
8  * particular file as subject to the "Classpath" exception as provided
9  * by Oracle in the LICENSE file that accompanied this code.
10  *
11  * This code is distributed in the hope that it will be useful, but WITHOUT
12  * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
13  * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
14  * version 2 for more details (a copy is included in the LICENSE file that
15  * accompanied this code).
16  *
17  * You should have received a copy of the GNU General Public License version
18  * 2 along with this work; if not, write to the Free Software Foundation,
19  * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
20  *
21  * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
22  * or visit www.oracle.com if you need additional information or have any
23  * questions.
24  *
25  * THIS FILE WAS MODIFIED BY SUN MICROSYSTEMS, INC.
26  */
27 
28 package com.sun.xml.internal.fastinfoset.algorithm;
29 
30 import java.io.IOException;
31 import java.io.InputStream;
32 import java.io.OutputStream;
33 import com.sun.xml.internal.org.jvnet.fastinfoset.EncodingAlgorithmException;
34 import com.sun.xml.internal.fastinfoset.CommonResourceBundle;
35 
36 public class HexadecimalEncodingAlgorithm extends BuiltInEncodingAlgorithm {
37     private static final char NIBBLE_TO_HEXADECIMAL_TABLE[] =
38         {   '0','1','2','3','4','5','6','7',
39             '8','9','A','B','C','D','E','F' };
40 
41     private static final int HEXADECIMAL_TO_NIBBLE_TABLE[] = {
42         /*'0'*/ 0,
43         /*'1'*/ 1,
44         /*'2'*/ 2,
45         /*'3'*/ 3,
46         /*'4'*/ 4,
47         /*'5'*/ 5,
48         /*'6'*/ 6,
49         /*'7'*/ 7,
50         /*'8'*/ 8,
51         /*'9'*/ 9, -1, -1, -1, -1, -1, -1, -1,
52         /*'A'*/ 10,
53         /*'B'*/ 11,
54         /*'C'*/ 12,
55         /*'D'*/ 13,
56         /*'E'*/ 14,
57         /*'F'*/ 15,
58         /*'G'-'Z'*/-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,
59         /*'[' - '`'*/ -1, -1, -1, -1, -1, -1,
60         /*'a'*/ 10,
61         /*'b'*/ 11,
62         /*'c'*/ 12,
63         /*'d'*/ 13,
64         /*'e'*/ 14,
65         /*'f'*/ 15 };
66 
decodeFromBytes(byte[] b, int start, int length)67     public final Object decodeFromBytes(byte[] b, int start, int length) throws EncodingAlgorithmException {
68         final byte[] data = new byte[length];
69         System.arraycopy(b, start, data, 0, length);
70         return data;
71     }
72 
decodeFromInputStream(InputStream s)73     public final Object decodeFromInputStream(InputStream s) throws IOException {
74         throw new UnsupportedOperationException(CommonResourceBundle.getInstance().getString("message.notImplemented"));
75     }
76 
77 
encodeToOutputStream(Object data, OutputStream s)78     public void encodeToOutputStream(Object data, OutputStream s) throws IOException {
79         if (!(data instanceof byte[])) {
80             throw new IllegalArgumentException(CommonResourceBundle.getInstance().getString("message.dataNotByteArray"));
81         }
82 
83         s.write((byte[])data);
84     }
85 
convertFromCharacters(char[] ch, int start, int length)86     public final Object convertFromCharacters(char[] ch, int start, int length) {
87         if (length == 0) {
88             return new byte[0];
89         }
90 
91         StringBuilder encodedValue = removeWhitespace(ch, start, length);
92         int encodedLength = encodedValue.length();
93         if (encodedLength == 0) {
94             return new byte[0];
95         }
96 
97         int valueLength = encodedValue.length() / 2;
98         byte[] value = new byte[valueLength];
99 
100         int encodedIdx = 0;
101         for (int i = 0; i < valueLength; ++i) {
102             int nibble1 = HEXADECIMAL_TO_NIBBLE_TABLE[encodedValue.charAt(encodedIdx++) - '0'];
103             int nibble2 = HEXADECIMAL_TO_NIBBLE_TABLE[encodedValue.charAt(encodedIdx++) - '0'];
104             value[i] = (byte) ((nibble1 << 4) | nibble2);
105         }
106 
107         return value;
108     }
109 
convertToCharacters(Object data, StringBuffer s)110     public final void convertToCharacters(Object data, StringBuffer s) {
111         if (data == null) {
112             return;
113         }
114         final byte[] value = (byte[]) data;
115         if (value.length == 0) {
116             return;
117         }
118 
119         s.ensureCapacity(value.length * 2);
120         for (int i = 0; i < value.length; ++i) {
121             s.append(NIBBLE_TO_HEXADECIMAL_TABLE[(value[i] >>> 4) & 0xf]);
122             s.append(NIBBLE_TO_HEXADECIMAL_TABLE[value[i] & 0xf]);
123         }
124     }
125 
126 
127 
getPrimtiveLengthFromOctetLength(int octetLength)128     public final int getPrimtiveLengthFromOctetLength(int octetLength) throws EncodingAlgorithmException {
129         return octetLength * 2;
130     }
131 
getOctetLengthFromPrimitiveLength(int primitiveLength)132     public int getOctetLengthFromPrimitiveLength(int primitiveLength) {
133         return primitiveLength / 2;
134     }
135 
encodeToBytes(Object array, int astart, int alength, byte[] b, int start)136     public final void encodeToBytes(Object array, int astart, int alength, byte[] b, int start) {
137         System.arraycopy((byte[])array, astart, b, start, alength);
138     }
139 }
140