/* * @(#)$Id: HexBinaryType.java,v 1.17 2002/03/09 15:27:06 kk122374 Exp $ * * Copyright 2001 Sun Microsystems, Inc. All Rights Reserved. * * This software is the proprietary information of Sun Microsystems, Inc. * Use is subject to license terms. * */ package com.sun.msv.datatype.xsd; import com.sun.msv.datatype.SerializationContext; import org.relaxng.datatype.ValidationContext; /** * "hexBinary" type. * * type of the value object is {@link BinaryValueType}. * See http://www.w3.org/TR/xmlschema-2/#hexBinary for the spec * * @author <a href="mailto:kohsuke.kawaguchi@eng.sun.com">Kohsuke KAWAGUCHI</a> */ public class HexBinaryType extends BinaryBaseType { public static final HexBinaryType theInstance = new HexBinaryType(); private HexBinaryType() { super("hexBinary"); } // hex decoder //==================================== private static int hexToBin( char ch ) { if( '0'<=ch && ch<='9' ) return ch-'0'; if( 'A'<=ch && ch<='F' ) return ch-'A'+10; if( 'a'<=ch && ch<='f' ) return ch-'a'+10; return -1; } public Object _createValue( String lexicalValue, ValidationContext context ) { byte[] buf = load(lexicalValue); if(buf==null) return null; else return new BinaryValueType(buf); } public static byte[] load( String s ) { final int len = s.length(); // "111" is not a valid hex encoding. if( len%2 != 0 ) return null; byte[] out = new byte[len/2]; for( int i=0; i<len; i+=2 ) { int h = hexToBin(s.charAt(i )); int l = hexToBin(s.charAt(i+1)); if( h==-1 || l==-1 ) return null; // illegal character out[i/2] = (byte)(h*16+l); } return out; } protected boolean checkFormat( String lexicalValue, ValidationContext context ) { final int len = lexicalValue.length(); // "111" is not a valid hex encoding. if( len%2 != 0 ) return false; for( int i=0; i<len; i++ ) if( hexToBin(lexicalValue.charAt(i))==-1 ) return false; return true; } public String serializeJavaObject( Object value, SerializationContext context ) { if(!(value instanceof byte[])) throw new IllegalArgumentException(); return save( (byte[])value ); } public static String save( byte[] data ) { StringBuffer r = new StringBuffer(data.length*2); for( int i=0; i<data.length; i++ ) { r.append( encode(data[i]>>4) ); r.append( encode(data[i]&0xF) ); } return r.toString(); } public String convertToLexicalValue( Object value, SerializationContext context ) { if(!(value instanceof BinaryValueType)) throw new IllegalArgumentException(); return serializeJavaObject( ((BinaryValueType)value).rawData, context ); } public static char encode( int ch ) { ch &= 0xF; if( ch<10 ) return (char)('0'+ch); else return (char)('A'+(ch-10)); } }