001 package com.thaiopensource.datatype.xsd;
002
003 import org.relaxng.datatype.ValidationContext;
004
005 class HexBinaryDatatype extends BinaryDatatype {
006 static private final int INVALID = -1;
007 static private final int WHITESPACE = -2;
008
009 boolean lexicallyAllows(String str) {
010 int len = str.length();
011 int i = 0;
012 while (i < len && weight(str.charAt(i)) == WHITESPACE)
013 i++;
014 while (i + 1 < len && weight(str.charAt(i)) >= 0 && weight(str.charAt(i + 1)) >= 0)
015 i += 2;
016 while (i < len && weight(str.charAt(i)) == WHITESPACE)
017 i++;
018 return i == len;
019 }
020
021 Object getValue(String str, ValidationContext vc) {
022 int len = str.length();
023 int start = 0;
024 while (start < len && weight(str.charAt(start)) == WHITESPACE)
025 start++;
026 int end = len;
027 while (end > start && weight(str.charAt(end - 1)) == WHITESPACE)
028 end--;
029 byte[] value = new byte[(end - start) >> 1];
030 int j = 0;
031 for (int i = start; i < end; i += 2, j++)
032 value[j] = (byte)((weight(str.charAt(i)) << 4) | weight(str.charAt(i + 1)));
033 return value;
034 }
035
036 static private int weight(char c) {
037 switch (c) {
038 case '0': case '1': case '2': case '3': case '4':
039 case '5': case '6': case '7': case '8': case '9':
040 return c - '0';
041 case 'A': case 'B': case 'C':
042 case 'D': case 'E': case 'F':
043 return c + (10 - 'A');
044 case 'a': case 'b': case 'c':
045 case 'd': case 'e': case 'f':
046 return c + (10 - 'a');
047 case ' ': case '\n': case '\r': case '\t':
048 return WHITESPACE;
049 }
050 return INVALID;
051 }
052
053 }