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 }