/* Copyright 2008, 2009, 2010 by the Oxford University Computing Laboratory This file is part of HermiT. HermiT is free software: you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License as published by the Free Software Foundation, either version 3 of the License, or (at your option) any later version. HermiT is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more details. You should have received a copy of the GNU Lesser General Public License along with HermiT. If not, see <http://www.gnu.org/licenses/>. */ package org.semanticweb.HermiT.datatypes.binarydata; import java.io.ByteArrayOutputStream; /** * Represents a binary data value. */ public class BinaryData { protected static final char[] INT_TO_HEX=new char[] { '0','1','2','3','4','5','6','7','8','9','A','B','C','D','E','F' }; protected static final int[] HEX_TO_INT=new int[127]; static { for (int i=0;i<HEX_TO_INT.length;i++) HEX_TO_INT[i]=-1; for (int i='0';i<='9';i++) HEX_TO_INT[i]=i-'0'; for (int i='A';i<='F';i++) HEX_TO_INT[i]=i-'A'+10; for (int i='a';i<='f';i++) HEX_TO_INT[i]=i-'a'+10; } protected final BinaryDataType m_binaryDataType; protected final byte[] m_data; protected final int m_hashCode; public BinaryData(BinaryDataType binaryDataType,byte[] data) { m_binaryDataType=binaryDataType; m_data=data; int hashCode=binaryDataType.hashCode(); for (int index=0;index<m_data.length;index++) hashCode=hashCode*3+m_data[index]; m_hashCode=hashCode; } public BinaryDataType getBinaryDataType() { return m_binaryDataType; } public int getNumberOfBytes() { return m_data.length; } public byte getByte(int index) { return m_data[index]; } public boolean equals(Object that) { if (this==that) return true; if (!(that instanceof BinaryData)) return false; BinaryData thatData=(BinaryData)that; if (m_hashCode!=thatData.m_hashCode || m_data.length!=thatData.m_data.length || m_binaryDataType!=thatData.m_binaryDataType) return false; for (int index=m_data.length-1;index>=0;--index) if (m_data[index]!=thatData.m_data[index]) return false; return true; } public int hashCode() { return m_hashCode; } public String toString() { switch (m_binaryDataType) { case HEX_BINARY: return toHexBinary(); case BASE_64_BINARY: return Base64.base64Encode(m_data); default: throw new IllegalStateException("Internal error: invalid binary data type."); } } protected String toHexBinary() { StringBuffer buffer=new StringBuffer(); for (int index=0;index<m_data.length;index++) { int octet=(m_data[index] & 0xFF); int high=octet/16; int low=octet % 16; buffer.append(INT_TO_HEX[high]); buffer.append(INT_TO_HEX[low]); } return buffer.toString(); } public static BinaryData parseHexBinary(String lexicalForm) { try { if ((lexicalForm.length() % 2)!=0) return null; ByteArrayOutputStream result=new ByteArrayOutputStream(); for (int index=0;index<lexicalForm.length();) { char digit1=lexicalForm.charAt(index++); int high=HEX_TO_INT[digit1]; if (high<0) return null; char digit2=lexicalForm.charAt(index++); int low=HEX_TO_INT[digit2]; if (low<0) return null; int octet=(high*16+low); result.write(octet); } return new BinaryData(BinaryDataType.HEX_BINARY,result.toByteArray()); } catch (IndexOutOfBoundsException e) { return null; } } public static BinaryData parseBase64Binary(String lexicalForm) { lexicalForm=removeWhitespace(lexicalForm); try { byte[] data=Base64.decodeBase64(lexicalForm); return new BinaryData(BinaryDataType.HEX_BINARY,data); } catch (IllegalArgumentException error) { return null; } catch (IndexOutOfBoundsException error) { return null; } } protected static String removeWhitespace(String lexicalForm) { lexicalForm=lexicalForm.trim(); for (int index=lexicalForm.length()-1;index>=0;index--) { if (Character.isWhitespace(lexicalForm.charAt(index))) { int upperSpaceIndex=index; while (Character.isWhitespace(lexicalForm.charAt(index))) index--; lexicalForm=lexicalForm.substring(0,index+1)+lexicalForm.substring(upperSpaceIndex+1); } } return lexicalForm; } }