001: /*
002: * Licensed to the Apache Software Foundation (ASF) under one
003: * or more contributor license agreements. See the NOTICE file
004: * distributed with this work for additional information
005: * regarding copyright ownership. The ASF licenses this file
006: * to you under the Apache License, Version 2.0 (the
007: * "License"); you may not use this file except in compliance
008: * with 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,
013: * software distributed under the License is distributed on an
014: * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
015: * KIND, either express or implied. See the License for the
016: * specific language governing permissions and limitations
017: * under the License.
018: */
019: package org.apache.axis2.databinding.types;
020:
021: import java.io.ByteArrayOutputStream;
022: import java.io.Serializable;
023:
024: /** Custom class for supporting primitive XSD data type hexBinary. */
025: public class HexBinary implements Serializable {
026:
027: private static final long serialVersionUID = -5082403899986720767L;
028:
029: byte[] m_value;
030:
031: public HexBinary() {
032: }
033:
034: public HexBinary(String string) {
035: m_value = decode(string);
036: }
037:
038: public HexBinary(byte[] bytes) {
039: m_value = bytes;
040: }
041:
042: public byte[] getBytes() {
043: return m_value;
044: }
045:
046: public String toString() {
047: return encode(m_value);
048: }
049:
050: public int hashCode() {
051: //TODO: How do we hash this?
052: return super .hashCode();
053: }
054:
055: public boolean equals(Object object) {
056: //TODO: Is this good enough?
057: String s1 = object.toString();
058: String s2 = this .toString();
059: return s1.equals(s2);
060: }
061:
062: // public static final String ERROR_ODD_NUMBER_OF_DIGITS =
063: //Messages.getMessage("oddDigits00");
064: //public static final String ERROR_BAD_CHARACTER_IN_HEX_STRING =
065: // Messages.getMessage("badChars01");
066:
067: // Code from Ajp11, from Apache's JServ
068:
069: // Table for HEX to DEC byte translation
070: public static final int[] DEC = { -1, -1, -1, -1, -1, -1, -1, -1,
071: -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
072: -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
073: -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, 00, 01, 02, 03, 04,
074: 05, 06, 07, 8, 9, -1, -1, -1, -1, -1, -1, -1, 10, 11, 12,
075: 13, 14, 15, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
076: -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, 10,
077: 11, 12, 13, 14, 15, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
078: -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
079: -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
080: -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
081: -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
082: -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
083: -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
084: -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
085: -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
086: -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
087: -1, -1, -1, -1, -1, -1, -1, -1, };
088:
089: /**
090: * Convert a String of hexadecimal digits into the corresponding byte array by encoding each two
091: * hexadecimal digits as a byte.
092: *
093: * @param digits Hexadecimal digits representation
094: * @throws IllegalArgumentException if an invalid hexadecimal digit is found, or the input
095: * string contains an odd number of hexadecimal digits
096: */
097: public static byte[] decode(String digits) {
098:
099: ByteArrayOutputStream baos = new ByteArrayOutputStream();
100: for (int i = 0; i < digits.length(); i += 2) {
101: char c1 = digits.charAt(i);
102: if ((i + 1) >= digits.length())
103: throw new IllegalArgumentException();//ERROR_ODD_NUMBER_OF_DIGITS);
104: char c2 = digits.charAt(i + 1);
105: byte b = 0;
106: if ((c1 >= '0') && (c1 <= '9'))
107: b += ((c1 - '0') * 16);
108: else if ((c1 >= 'a') && (c1 <= 'f'))
109: b += ((c1 - 'a' + 10) * 16);
110: else if ((c1 >= 'A') && (c1 <= 'F'))
111: b += ((c1 - 'A' + 10) * 16);
112: else
113: throw new IllegalArgumentException();//ERROR_BAD_CHARACTER_IN_HEX_STRING);
114: if ((c2 >= '0') && (c2 <= '9'))
115: b += (c2 - '0');
116: else if ((c2 >= 'a') && (c2 <= 'f'))
117: b += (c2 - 'a' + 10);
118: else if ((c2 >= 'A') && (c2 <= 'F'))
119: b += (c2 - 'A' + 10);
120: else
121: throw new IllegalArgumentException();//ERROR_BAD_CHARACTER_IN_HEX_STRING);
122: baos.write(b);
123: }
124: return (baos.toByteArray());
125:
126: }
127:
128: /**
129: * Convert a byte array into a printable format containing a String of hexadecimal digit
130: * characters (two per byte).
131: *
132: * @param bytes Byte array representation
133: */
134: public static String encode(byte bytes[]) {
135:
136: StringBuffer sb = new StringBuffer(bytes.length * 2);
137: for (int i = 0; i < bytes.length; i++) {
138: sb.append(convertDigit(bytes[i] >> 4));
139: sb.append(convertDigit(bytes[i] & 0x0f));
140: }
141: return (sb.toString());
142:
143: }
144:
145: /**
146: * Convert 4 hex digits to an int, and return the number of converted bytes.
147: *
148: * @param hex Byte array containing exactly four hexadecimal digits
149: * @throws IllegalArgumentException if an invalid hexadecimal digit is included
150: */
151: public static int convert2Int(byte[] hex) {
152: // Code from Ajp11, from Apache's JServ
153:
154: // assert b.length==4
155: // assert valid data
156: int len;
157: if (hex.length < 4)
158: return 0;
159: if (DEC[hex[0]] < 0)
160: throw new IllegalArgumentException();//ERROR_BAD_CHARACTER_IN_HEX_STRING);
161: len = DEC[hex[0]];
162: len = len << 4;
163: if (DEC[hex[1]] < 0)
164: throw new IllegalArgumentException();//ERROR_BAD_CHARACTER_IN_HEX_STRING);
165: len += DEC[hex[1]];
166: len = len << 4;
167: if (DEC[hex[2]] < 0)
168: throw new IllegalArgumentException();//ERROR_BAD_CHARACTER_IN_HEX_STRING);
169: len += DEC[hex[2]];
170: len = len << 4;
171: if (DEC[hex[3]] < 0)
172: throw new IllegalArgumentException();//ERROR_BAD_CHARACTER_IN_HEX_STRING);
173: len += DEC[hex[3]];
174: return len;
175: }
176:
177: /**
178: * [Private] Convert the specified value (0 .. 15) to the corresponding hexadecimal digit.
179: *
180: * @param value Value to be converted
181: */
182: private static char convertDigit(int value) {
183:
184: value &= 0x0f;
185: if (value >= 10)
186: return ((char) (value - 10 + 'a'));
187: else
188: return ((char) (value + '0'));
189:
190: }
191: }
|