/*
*
*
* Portions Copyright 2000-2009 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;
}
for (int j = 0; j < 8; j++) {
buf[--charPos] = digits[ints[i] & mask];
ints[i] >>>= shift;
}
}
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