KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > org > xquark > schema > datatypes > HexBinaryType


1 /*
2  * This file belongs to the XQuark distribution.
3  * Copyright (C) 2003 Universite de Versailles Saint-Quentin.
4  *
5  * This program is free software; you can redistribute it and/or
6  * modify it under the terms of the GNU Lesser General Public
7  * License as published by the Free Software Foundation; either
8  * version 2.1 of the License, or (at your option) any later version.
9  *
10  * This program is distributed in the hope that it will be useful,
11  * but WITHOUT ANY WARRANTY; without even the implied warranty of
12  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
13  * Lesser General Public License for more details.
14  *
15  * You should have received a copy of the GNU Lesser General Public
16  * License along with this program; if not, write to the Free Software
17  * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307.
18  * You can also get it at http://www.gnu.org/licenses/lgpl.html
19  *
20  * For more information on this software, see http://www.xquark.org.
21  */

22
23 package org.xquark.schema.datatypes;
24
25 import java.text.ParseException JavaDoc;
26
27 import org.xquark.schema.SchemaException;
28 import org.xquark.schema.validation.ValidationContextProvider;
29
30
31 class HexBinaryType extends MesureableType {
32     private static final String JavaDoc RCSRevision = "$Revision: 1.5 $";
33     private static final String JavaDoc RCSName = "$Name: $";
34     private static byte[] decodeMap = new byte[256];
35     private static byte[] encodeMap = new byte[16];
36
37     static {
38       for (int i = 0; i < 256; i++) {
39         decodeMap[i] = -1;
40       }
41
42       for (int i = '0'; i <= '9'; i++)
43         decodeMap[i] = (byte)(i-'0');
44       for (int i = 'A'; i <= 'F'; i++)
45         decodeMap[i] = (byte)(i-'A'+10);
46       for (int i = 'a'; i <= 'f'; i++)
47         decodeMap[i] = (byte)(i-'a'+10);
48     
49       for (int i = 0; i < 10; i++)
50         encodeMap[i] = (byte)('0'+i);
51       for (int i = 10; i < 16; i++)
52         encodeMap[i] = (byte)('A'+i-10);
53     }
54
55     HexBinaryType() {
56         super("hexBinary", PrimitiveType.HEX_BINARY);
57     }
58
59     protected Object JavaDoc toValidType(Object JavaDoc data) {
60         if (data instanceof byte[]) {
61             return new Value((byte[])data);
62         } else {
63             return (ByteArray) data;
64         }
65     }
66
67     public void checkFacets(Object JavaDoc valueSpace) throws SchemaException {
68         super.checkFacets(valueSpace);
69         super.checkLength(((ByteArray) valueSpace).getLength(), valueSpace);
70     }
71
72     protected Object JavaDoc toValueSpace(String JavaDoc value, ValidationContextProvider context) throws SchemaException {
73         try {
74             return new Value(decode(value));
75         } catch (ParseException JavaDoc ee) {
76             super.invalidValue(value.toString());
77             return null;
78         }
79     }
80
81     private boolean isHexChar(char c) {
82       return (decodeMap[c] != -1);
83     }
84
85     private int computeSize(String JavaDoc value) throws ParseException JavaDoc {
86         int count = 0;
87         int charLen = value.length();
88         for (int i = 0; i < charLen; i++) {
89             char c = value.charAt(i);
90             if (!Character.isWhitespace(c)) {
91                 if (!isHexChar(c)) {
92                     throw new ParseException JavaDoc("Invalid characted in hexadeciaml encoded string", i);
93                 }
94                 count++;
95             }
96         }
97         if (count % 2 > 0)
98             throw new ParseException JavaDoc("Hexadecimal encoded string has invalid length", charLen);
99         return count/2;
100     }
101
102     public byte[] decode(String JavaDoc value) throws ParseException JavaDoc {
103         int decLen = computeSize(value);
104         byte[] decodedData = new byte[decLen];
105         int charIndex = 0;
106         for (int i = 0; i < decLen; i++) {
107             int tmp = 0;
108             for (int j = 0; j < 2; j++) {
109                 char c = value.charAt(charIndex++);
110                 while (Character.isWhitespace(c))
111                     c = value.charAt(charIndex++);
112                 tmp |= (decodeMap[c] << (4*(1-j)));
113             }
114             decodedData[i] = (byte)(tmp & 0xFF);
115         }
116         return decodedData;
117     }
118
119     public String JavaDoc encode(byte[] data) {
120         int decLen = data.length;
121         int encLen = 2*decLen;
122         // The encoded string is split into lines of 76 characters
123
encLen += (encLen-1)/76;
124         byte[] encodedData = new byte[encLen];
125         int nLines = 0;
126         for (int i = 0; i < decLen; i++) {
127             int encIndex = 2*i+nLines;
128             encodedData[encIndex] = encodeMap[(byte)((data[i] >> 4) & 0xF)];
129             encodedData[encIndex+1] = encodeMap[(byte)(data[i] & 0xF)];
130             if ((i+1) % 38 == 0 && encIndex + 2 < encLen) {
131                 encodedData[encIndex+2] = (byte)0xA;
132                 nLines++;
133             }
134         }
135         return new String JavaDoc(encodedData);
136     }
137
138     public String JavaDoc toXMLString(Object JavaDoc data, ValidationContextProvider context) {
139         if (data instanceof ByteArray) {
140             return encode(((ByteArray)data).getData());
141         } else if (data instanceof byte[]) {
142             return encode((byte[])data);
143         } else {
144             throw new IllegalArgumentException JavaDoc("Not a byte array");
145         }
146     }
147
148     class Value extends ByteArray {
149
150         Value(byte[] value) {
151             super(value);
152         }
153
154         protected boolean checkClass(Object JavaDoc obj) {
155             return obj instanceof Value;
156         }
157
158         public String JavaDoc toString() {
159             return encode(getData());
160         }
161
162     }
163 }
164
Popular Tags