HexBinaryValue.java :  » XML » XPath-Saxon » net » sf » saxon » value » Java Open Source

Java Open Source » XML » XPath Saxon 
XPath Saxon » net » sf » saxon » value » HexBinaryValue.java
package net.sf.saxon.value;
import net.sf.saxon.expr.XPathContext;
import net.sf.saxon.om.FastStringBuffer;
import net.sf.saxon.trans.DynamicError;
import net.sf.saxon.trans.XPathException;
import net.sf.saxon.type.*;

/**
* A value of type xs:hexBinary
*/

public class HexBinaryValue extends AtomicValue {

    private byte[] binaryValue;


    /**
    * Constructor: create a hexBinary value from a supplied string, in which
     * each octet is represented by a pair of values from 0-9, a-f, A-F
    */

    public HexBinaryValue(CharSequence s) throws XPathException {
        if ((s.length() & 1) != 0) {
            DynamicError err = new DynamicError(
                    "A hexBinary value must contain an even number of characters");
            err.setErrorCode("FORG0001");
            throw err;
        }
        binaryValue = new byte[s.length() / 2];
        for (int i=0; i<binaryValue.length; i++) {
            binaryValue[i] = (byte)((fromHex(s.charAt(2*i))<<4) +
                    (fromHex(s.charAt(2*i+1))));
        }
    }

    /**
     * Constructor: create a hexBinary value from a given array of bytes
     */

    public HexBinaryValue(byte[] value) {
        this.binaryValue = value;
    }

   /**
     * Get the binary value
     */

    public byte[] getBinaryValue() {
        return binaryValue;
    }

    /**
     * Decode a single hex digit
     * @param c the hex digit
     * @return the numeric value of the hex digit
     * @throws XPathException if it isn't a hex digit
     */

    private int fromHex(char c) throws XPathException {
        int d = "0123456789ABCDEFabcdef".indexOf(c);
        if (d > 15) {
            d = d - 6;
        }
        if (d < 0) {
            DynamicError err = new DynamicError("Invalid hexadecimal digit");
            err.setErrorCode("FORG0001");
            throw err;
        }
        return d;
    }

    /**
    * Convert to target data type
    * @param requiredType an integer identifying the required atomic type
    * @param context
     * @return an AtomicValue, a value of the required type; or an ErrorValue
    */

    public AtomicValue convertPrimitive(BuiltInAtomicType requiredType, boolean validate, XPathContext context) {
        switch(requiredType.getPrimitiveType()) {
        case Type.HEX_BINARY:
        case Type.ANY_ATOMIC:
        case Type.ITEM:
            return this;
        case Type.STRING:
            return new StringValue(getStringValueCS());
        case Type.UNTYPED_ATOMIC:
            return new UntypedAtomicValue(getStringValueCS());
        case Type.BASE64_BINARY:
            return new Base64BinaryValue(binaryValue);

        default:
            ValidationException err = new ValidationException("Cannot convert hexBinarry to " +
                                     requiredType.getDisplayName());
            err.setErrorCode("XPTY0004");
            err.setIsTypeError(true);
            return new ValidationErrorValue(err);
        }
    }

    /**
    * Convert to string
    * @return the canonical representation.
    */

    public String getStringValue() {
        String digits = "0123456789ABCDEF";
        FastStringBuffer sb = new FastStringBuffer(binaryValue.length * 2);
        for (int i=0; i<binaryValue.length; i++) {
            sb.append(digits.charAt((binaryValue[i]>>4)&0xf));
            sb.append(digits.charAt(binaryValue[i]&0xf));
        }
        return sb.toString();
    }


    /**
    * Determine the data type of the exprssion
    * @return Type.HEX_BINARY_TYPE
     * @param th
     */

    public ItemType getItemType(TypeHierarchy th) {
        return Type.HEX_BINARY_TYPE;
    }

    /**
     * Get the number of octets in the value
     */

    public int getLengthInOctets() {
        return binaryValue.length;
    }

    /**
    * Convert to Java object (for passing to external functions)
    */

    public Object convertToJava(Class target, XPathContext context) throws XPathException {

        if (target.isAssignableFrom(HexBinaryValue.class)) {
            return this;
        } else if (target.isAssignableFrom(String.class)) {
            return getStringValue();
        } else {
            Object o = super.convertToJava(target, context);
            if (o == null) {
                throw new DynamicError("Conversion of hexBinary to " + target.getName() +
                        " is not supported");
            }
            return o;
        }
    }


    /**
    * Test if the two hexBinary values are equal.
    */

    public boolean equals(Object other) {
        HexBinaryValue v2;
        if (other instanceof HexBinaryValue) {
            v2 = (HexBinaryValue)other;
        } else if (other instanceof AtomicValue) {
            try {
                v2 = (HexBinaryValue)((AtomicValue)other).convert(Type.HEX_BINARY, null);
            } catch (XPathException err) {
                return false;
            }
        } else {
            return false;
        }
        if (binaryValue.length != v2.binaryValue.length) {
            return false;
        };
        for (int i = 0; i < binaryValue.length; i++) {
            if (binaryValue[i] != v2.binaryValue[i]) {
                return false;
            };
        }
        return true;
    }

     public int hashCode() {
        return Base64BinaryValue.byteArrayHashCode(binaryValue);
    }

}

//
// The contents of this file are subject to the Mozilla Public License Version 1.0 (the "License");
// you may not use this file except in compliance with the License. You may obtain a copy of the
// License at http://www.mozilla.org/MPL/
//
// Software distributed under the License is distributed on an "AS IS" basis,
// WITHOUT WARRANTY OF ANY KIND, either express or implied.
// See the License for the specific language governing rights and limitations under the License.
//
// The Original Code is: all this file.
//
// The Initial Developer of the Original Code is Michael H. Kay, Saxonica.
//
// Portions created by (your name) are Copyright (C) (your legal entity). All Rights Reserved.
//
// Contributor(s): none.
//

java2s.com  | Contact Us | Privacy Policy
Copyright 2009 - 12 Demo Source and Support. All rights reserved.
All other trademarks are property of their respective owners.