FileDocCategorySizeDatePackage
UUID.javaAPI DocphoneME MR2 API (J2ME)7627Wed May 02 18:00:30 BST 2007javax.bluetooth

UUID.java

/*
 *
 *
 * Portions Copyright  2000-2007 Sun Microsystems, Inc. All Rights
 * Reserved.  Use is subject to license terms.
 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER
 * 
 * This program is free software; you can redistribute it and/or
 * modify it under the terms of the GNU General Public License version
 * 2 only, as published by the Free Software Foundation.
 * 
 * This program 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
 * General Public License version 2 for more details (a copy is
 * included at /legal/license.txt).
 * 
 * You should have received a copy of the GNU General Public License
 * version 2 along with this work; if not, write to the Free Software
 * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
 * 02110-1301 USA
 * 
 * Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa
 * Clara, CA 95054 or visit www.sun.com if you need additional
 * information or have any questions.
 */

/*
 * (c) Copyright 2001, 2002 Motorola, Inc.  ALL RIGHTS RESERVED.
 */
package javax.bluetooth;

/**
 * This class is defined by the JSR-82 specification
 * <em>Java™ APIs for Bluetooth™ Wireless Technology,
 * Version 1.1.</em>
 */
// JAVADOC COMMENT ELIDED 
public class UUID {

    // JAVADOC COMMENT ELIDED
    private long highBits;

    // JAVADOC COMMENT ELIDED
    private long lowBits;

    // JAVADOC COMMENT ELIDED
    private static final long BASE_UUID_HIGHT = 0x1000L;
    
    // JAVADOC COMMENT ELIDED
    private static final long BASE_UUID_LOW = 0x800000805F9B34FBL;

    // JAVADOC COMMENT ELIDED
    private static final char[] digits = {
        '0', '1', '2', '3', '4', '5',
        '6', '7', '8', '9', 'A', 'B',
        'C', 'D', 'E', 'F'
    };

    // JAVADOC COMMENT ELIDED 
    public UUID(long uuidValue) {

        // check the specified value is out of range
        if (uuidValue < 0 || uuidValue > 0xffffffffL) {
            throw new IllegalArgumentException(
                    "The 'uuidValue' is out of [0, 2^32 - 1] range: "
                    + uuidValue);
        }

        /*
         * Create a UUID from 16/32 bits value.
         *
         * 128_bit_value = 16_bit_value * 2^96 + Bluetooth_Base_UUID
         * 128_bit_value = 32_bit_value * 2^96 + Bluetooth_Base_UUID
         *
         * No need to check the "overflow/negative", because
         * uuidValue is 32 bits & BASE_UUID_HIGHT is 16 bits.
         */
        highBits = (uuidValue << 32) | BASE_UUID_HIGHT;
        lowBits = BASE_UUID_LOW;
    }

    // JAVADOC COMMENT ELIDED 
    public UUID(String uuidValue, boolean shortUUID) {
        if (uuidValue == null) {
            throw new NullPointerException("Specified 'uuidValue' is null");
        }

        /*
         * The zero length is double checked by the parsing operation,
         * but the NumberFormatException is thrown in that case -
         * we need IllegalArgumentException according to spec.
         */
        if (uuidValue.length() == 0 || (shortUUID && uuidValue.length() > 8) ||
                uuidValue.length() > 32) {
            throw new IllegalArgumentException(
                    "Invalid length of specified 'uuidValue': "
                    + uuidValue.length());
        }

        // check if sign character presents
        if (uuidValue.indexOf('-') != -1) {
            throw new NumberFormatException(
                    "The '-' character is not allowed: " + uuidValue);
        }

        /*
         * 16-bit or 32-bit UUID case.
         */
        if (shortUUID) {

            // this checks the format and may throw a NumberFormatException
            long val = Long.parseLong(uuidValue, 16);

            /*
             * create a UUID from 16/32 bits value.
             *
             * No need to check the "overflow/negative", because
             * lVal is 32 bits & BASE_UUID_HIGHT is 16 bits.
             */
            highBits = (val << 32) | BASE_UUID_HIGHT;
            lowBits = BASE_UUID_LOW;
            return;
        }
        
        /*
         * 128-bit UUID case.
         */
        highBits = 0x0L;

        // simple case (optimization)
        if (uuidValue.length() < 16) {
            lowBits = Long.parseLong(uuidValue, 16);
            return;
        }

        /*
         * We have to do a 32 bits parsing, because the
         * Long.parseLong("ffff ffff ffff ffff") does not
         * parse such an unsigned number.
         */
        int l = uuidValue.length();
        lowBits = Long.parseLong(uuidValue.substring(l - 8), 16);
        lowBits |= (Long.parseLong(uuidValue.substring(l - 16, l - 8), 16)
                << 32);

        if (l == 16) {
            return;
        }

        if (l <= 24) {
            highBits = Long.parseLong(uuidValue.substring(0, l - 16), 16);
        } else {
            highBits = Long.parseLong(uuidValue.substring(l - 24, l - 16), 16);
            highBits |= (Long.parseLong(uuidValue.substring(0, l - 24), 16)
                    << 32);
        }
    }

    // JAVADOC COMMENT ELIDED 
    public String toString() {

        /*
         * This implementation is taken from cldc1.1 Integer#toUnsignedString
         * one. The implementation which uses Integer#toHexString() is
         * 2-3 times slower, so such a code duplication is required here.
         */
        int[] ints = new int[] {
            (int) (lowBits & 0xffffffffL),
            (int) (lowBits >>> 32 & 0xffffffffL),
            (int) (highBits & 0xffffffffL),
            (int) (highBits >>> 32 & 0xffffffffL)
        };
        int charPos = 32;
        char[] buf = new char[charPos];
        int shift = 4;
        int mask = 0xf;
        int needZerosIndex = -1;

        /*
         * check with part of value requires the zero characters.
         *
         * I.e. the original algorithm gives as an 1 character
         * for the value '1', but we may want 00000001.
         */
        for (int i = 3; i >= 0; i--) {
            if (ints[i] != 0) {
                needZerosIndex = i - 1;
                break;
            }
        }

        /*
         * Process parts of UUID from low parts to high ones.
         */
        for (int i = 0; i < ints.length; i++) {

            /*
             * The 16 bits are zero & no need to fill with 0,
             * and it's not a UUID with value '0' (i != 0).
             */
            if (ints[i] == 0 && needZerosIndex < i && i != 0) {
                continue;
            }

            if (needZerosIndex >= i) {

                // fill all 8 characters (even if allof them are '0')
                for (int j = 0; j < 8; j++) {
                    buf[--charPos] = digits[ints[i] & mask];
                    ints[i] >>>= shift;
                }
            } else {

                // fill until the highest valuable character
                do {
                    buf[--charPos] = digits[ints[i] & mask];
                    ints[i] >>>= shift;
                } while (ints[i] != 0);
            }
        }
        return new String(buf, charPos, (32 - charPos));
    }

    // JAVADOC COMMENT ELIDED 
    public boolean equals(Object value) {
        return value instanceof UUID &&
                lowBits == ((UUID) value).lowBits &&
                highBits == ((UUID) value).highBits;
    }

    // JAVADOC COMMENT ELIDED 
    public int hashCode() {
        return (int) (highBits ^ highBits >> 32 ^ lowBits ^ lowBits >> 32);
    }
} // end of class 'UUID' definition