--- /dev/null
+/*\r
+\r
+ Derby - Class org.apache.derby.impl.services.uuid.BasicUUID\r
+\r
+ Licensed to the Apache Software Foundation (ASF) under one or more\r
+ contributor license agreements. See the NOTICE file distributed with\r
+ this work for additional information regarding copyright ownership.\r
+ The ASF licenses this file to you under the Apache License, Version 2.0\r
+ (the "License"); you may not use this file except in compliance with\r
+ the License. You may obtain a copy of the License at\r
+\r
+ http://www.apache.org/licenses/LICENSE-2.0\r
+\r
+ Unless required by applicable law or agreed to in writing, software\r
+ distributed under the License is distributed on an "AS IS" BASIS,\r
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\r
+ See the License for the specific language governing permissions and\r
+ limitations under the License.\r
+\r
+ */\r
+\r
+package org.apache.derby.impl.services.uuid;\r
+\r
+import org.apache.derby.iapi.services.io.FormatIdUtil;\r
+import org.apache.derby.iapi.services.io.StoredFormatIds;\r
+import org.apache.derby.iapi.services.io.Formatable;\r
+\r
+import org.apache.derby.catalog.UUID;\r
+\r
+import java.io.ObjectOutput;\r
+import java.io.ObjectInput;\r
+import java.io.IOException;\r
+\r
+import java.io.StringReader;\r
+\r
+\r
+public class BasicUUID implements UUID, Formatable\r
+{\r
+ /*\r
+ ** Fields of BasicUUID\r
+ */\r
+ \r
+ private long majorId; // only using 48 bits\r
+ private long timemillis;\r
+ private int sequence;\r
+\r
+ /*\r
+ ** Methods of BasicUUID\r
+ */\r
+\r
+ /**\r
+ Constructor only called by BasicUUIDFactory.\r
+ **/\r
+ public BasicUUID(long majorId, long timemillis, int sequence)\r
+ {\r
+ this.majorId = majorId;\r
+ this.timemillis = timemillis;\r
+ this.sequence = sequence;\r
+ }\r
+\r
+ /**\r
+ Constructor only called by BasicUUIDFactory.\r
+ Constructs a UUID from the string representation\r
+ produced by toString.\r
+ @see BasicUUID#toString\r
+ **/\r
+ public BasicUUID(String uuidstring)\r
+ {\r
+ StringReader sr = new StringReader(uuidstring);\r
+ sequence = (int) readMSB(sr);\r
+\r
+ long ltimemillis = readMSB(sr) << 32;\r
+ ltimemillis += readMSB(sr) << 16;\r
+ ltimemillis += readMSB(sr);\r
+ timemillis = ltimemillis;\r
+ majorId = readMSB(sr);\r
+ }\r
+\r
+ /**\r
+ Constructor only called by BasicUUIDFactory.\r
+ Constructs a UUID from the byte array representation\r
+ produced by toByteArrayio.\r
+ @see BasicUUID#toByteArray\r
+ **/\r
+ public BasicUUID(byte[] b)\r
+ {\r
+ int lsequence = 0;\r
+ for (int ix = 0; ix < 4; ix++)\r
+ {\r
+ lsequence = lsequence << 8;\r
+ lsequence = lsequence | (0xff & b[ix]);\r
+ }\r
+\r
+ long ltimemillis = 0;\r
+ for (int ix = 4; ix < 10; ix++)\r
+ {\r
+ ltimemillis = ltimemillis << 8;\r
+ ltimemillis = ltimemillis | (0xff & b[ix]);\r
+ }\r
+\r
+ long linetaddr = 0;\r
+ for (int ix = 10; ix < 16; ix++)\r
+ {\r
+ linetaddr = linetaddr << 8;\r
+ linetaddr = linetaddr | (0xff & b[ix]);\r
+ }\r
+\r
+ sequence = lsequence;\r
+ timemillis = ltimemillis;\r
+ majorId = linetaddr;\r
+ }\r
+\r
+ /*\r
+ * Formatable methods\r
+ */\r
+\r
+ // no-arg constructor, required by Formatable \r
+ public BasicUUID() { super(); }\r
+\r
+ /**\r
+ Write this out.\r
+ @exception IOException error writing to log stream\r
+ */\r
+ public void writeExternal(ObjectOutput out) throws IOException \r
+ {\r
+ // RESOLVE: write out the byte array instead?\r
+ out.writeLong(majorId);\r
+ out.writeLong(timemillis);\r
+ out.writeInt(sequence);\r
+ }\r
+\r
+ /**\r
+ Read this in\r
+ @exception IOException error reading from log stream\r
+ */\r
+ public void readExternal(ObjectInput in) throws IOException\r
+ {\r
+ majorId = in.readLong();\r
+ timemillis = in.readLong();\r
+ sequence = in.readInt();\r
+ }\r
+\r
+ /**\r
+ Return my format identifier.\r
+ */\r
+ public int getTypeFormatId() {\r
+ return StoredFormatIds.BASIC_UUID;\r
+ }\r
+\r
+ private static void writeMSB(char[] data, int offset, long value, int nbytes)\r
+ {\r
+ for (int i = nbytes - 1; i >= 0; i--)\r
+ {\r
+ long b = (value & (255L << (8 * i))) >>> (8 * i);\r
+\r
+ int c = (int) ((b & 0xf0) >> 4);\r
+ data[offset++] = (char) (c < 10 ? c + '0' : (c - 10) + 'a');\r
+ c = (int) (b & 0x0f);\r
+ data[offset++] = (char) (c < 10 ? c + '0' : (c - 10) + 'a');\r
+ } \r
+ }\r
+\r
+ /**\r
+ Read a long value, msb first, from its character \r
+ representation in the string reader, using '-' or\r
+ end of string to delimit.\r
+ **/\r
+ private static long readMSB(StringReader sr)\r
+ {\r
+ long value = 0;\r
+\r
+ try\r
+ {\r
+ int c;\r
+ while ((c = sr.read()) != -1)\r
+ {\r
+ if (c == '-')\r
+ break;\r
+ value <<= 4;\r
+\r
+ int nibble;\r
+ if (c <= '9')\r
+ nibble = c - '0';\r
+ else if (c <= 'F')\r
+ nibble = c - 'A' + 10;\r
+ else\r
+ nibble = c - 'a' + 10;\r
+ value += nibble;\r
+ }\r
+ }\r
+ catch (Exception e)\r
+ {\r
+ }\r
+\r
+ return value;\r
+ }\r
+\r
+ /*\r
+ ** Methods of UUID\r
+ */\r
+\r
+ /**\r
+ Implement value equality.\r
+\r
+ **/\r
+ public boolean equals(Object otherObject)\r
+ {\r
+ if (!(otherObject instanceof BasicUUID))\r
+ return false;\r
+\r
+ BasicUUID other = (BasicUUID) otherObject;\r
+\r
+ return (this.sequence == other.sequence)\r
+ && (this.timemillis == other.timemillis)\r
+ && (this.majorId == other.majorId);\r
+ }\r
+\r
+ /**\r
+ Provide a hashCode which is compatible with\r
+ the equals() method.\r
+ **/\r
+ public int hashCode()\r
+ {\r
+ long hc = majorId ^ timemillis;\r
+\r
+ return sequence ^ ((int) (hc >> 4));\r
+ }\r
+\r
+ /**\r
+ Produce a string representation of this UUID which\r
+ can be passed to UUIDFactory.recreateUUID later on\r
+ to reconstruct it. The funny representation is \r
+ designed to (sort of) match the format of Microsoft's\r
+ UUIDGEN utility.\r
+ */\r
+ public String toString() {return stringWorkhorse( '-' );}\r
+\r
+ /**\r
+ Produce a string representation of this UUID which\r
+ is suitable for use as a unique ANSI identifier.\r
+ */\r
+ public String toANSIidentifier() {return "U" + stringWorkhorse( 'X' );}\r
+\r
+ /**\r
+ * Private workhorse of the string making routines.\r
+ *\r
+ * @param separator Character to separate number blocks.\r
+ * Null means do not include a separator.\r
+ *\r
+ * @return string representation of UUID.\r
+ */\r
+ public String stringWorkhorse( char separator )\r
+ {\r
+ char[] data = new char[36];\r
+\r
+ writeMSB(data, 0, (long) sequence, 4);\r
+\r
+ int offset = 8;\r
+ if (separator != 0) data[offset++] = separator;\r
+\r
+ long ltimemillis = timemillis;\r
+ writeMSB(data, offset, (ltimemillis & 0x0000ffff00000000L) >>> 32, 2);\r
+ offset += 4;\r
+ if (separator != 0) data[offset++] = separator;\r
+ writeMSB(data, offset, (ltimemillis & 0x00000000ffff0000L) >>> 16, 2);\r
+ offset += 4;\r
+ if (separator != 0) data[offset++] = separator;\r
+ writeMSB(data, offset, (ltimemillis & 0x000000000000ffffL), 2);\r
+ offset += 4;\r
+ if (separator != 0) data[offset++] = separator;\r
+ writeMSB(data, offset, majorId, 6);\r
+ offset += 12;\r
+\r
+ return new String(data, 0, offset);\r
+ }\r
+\r
+ /**\r
+ Store this UUID in a byte array. Arrange the bytes in the UUID\r
+ in the same order the code which stores a UUID in a string\r
+ does.\r
+ \r
+ @see org.apache.derby.catalog.UUID#toByteArray\r
+ */\r
+ public byte[] toByteArray()\r
+ {\r
+ byte[] result = new byte[16];\r
+\r
+ int lsequence = sequence; \r
+ result[0] = (byte)(lsequence >>> 24);\r
+ result[1] = (byte)(lsequence >>> 16);\r
+ result[2] = (byte)(lsequence >>> 8);\r
+ result[3] = (byte)lsequence;\r
+\r
+ long ltimemillis = timemillis;\r
+ result[4] = (byte)(ltimemillis >>> 40);\r
+ result[5] = (byte)(ltimemillis >>> 32);\r
+ result[6] = (byte)(ltimemillis >>> 24);\r
+ result[7] = (byte)(ltimemillis >>> 16);\r
+ result[8] = (byte)(ltimemillis >>> 8);\r
+ result[9] = (byte)ltimemillis;\r
+\r
+ long linetaddr = majorId;\r
+ result[10] = (byte)(linetaddr >>> 40);\r
+ result[11] = (byte)(linetaddr >>> 32);\r
+ result[12] = (byte)(linetaddr >>> 24);\r
+ result[13] = (byte)(linetaddr >>> 16);\r
+ result[14] = (byte)(linetaddr >>> 8);\r
+ result[15] = (byte)linetaddr;\r
+\r
+ return result;\r
+ }\r
+\r
+ /**\r
+ Clone this UUID.\r
+\r
+ @return a copy of this UUID\r
+ */\r
+ public UUID cloneMe()\r
+ {\r
+ return new BasicUUID(majorId, timemillis, sequence);\r
+ }\r
+\r
+ public String toHexString() {return stringWorkhorse( (char) 0 );}\r
+}\r
+\r