diff options
Diffstat (limited to 'src/Java/gtPlusPlus/api/objects')
14 files changed, 891 insertions, 41 deletions
diff --git a/src/Java/gtPlusPlus/api/objects/Logger.java b/src/Java/gtPlusPlus/api/objects/Logger.java index 1ecdaa9e86..2c50f0c15e 100644 --- a/src/Java/gtPlusPlus/api/objects/Logger.java +++ b/src/Java/gtPlusPlus/api/objects/Logger.java @@ -4,6 +4,7 @@ import org.apache.logging.log4j.LogManager; import cpw.mods.fml.common.FMLLog; import cpw.mods.fml.relauncher.FMLRelaunchLog; + import gtPlusPlus.core.lib.CORE; import gtPlusPlus.core.proxy.ClientProxy; diff --git a/src/Java/gtPlusPlus/api/objects/MaterialHelper.java b/src/Java/gtPlusPlus/api/objects/MaterialHelper.java deleted file mode 100644 index d63ab7a15a..0000000000 --- a/src/Java/gtPlusPlus/api/objects/MaterialHelper.java +++ /dev/null @@ -1,18 +0,0 @@ -package gtPlusPlus.api.objects; - -import gregtech.api.enums.Materials; -import gregtech.api.enums.OrePrefixes; -import gtPlusPlus.core.material.Material; -import gtPlusPlus.core.util.item.ItemUtils; -import net.minecraft.item.ItemStack; - -public class MaterialHelper { - - public static ItemStack getComponentFromMaterial(OrePrefixes oreprefix, Material material, int amount){ - return ItemUtils.getOrePrefixStack(oreprefix, material, amount); - } - public static ItemStack getComponentFromGtMaterial(OrePrefixes oreprefix, Materials material, int amount){ - return ItemUtils.getGregtechOreStack(oreprefix, material, amount); - } - -} diff --git a/src/Java/gtPlusPlus/api/objects/data/AutoMap.java b/src/Java/gtPlusPlus/api/objects/data/AutoMap.java new file mode 100644 index 0000000000..e5b5ded0ad --- /dev/null +++ b/src/Java/gtPlusPlus/api/objects/data/AutoMap.java @@ -0,0 +1,84 @@ +package gtPlusPlus.api.objects.data; + +import java.io.Serializable; +import java.util.*; + +public class AutoMap<V> implements Iterable<V>, Cloneable, Serializable { + + /** + * The Internal Map + */ + private Map<Integer, V> mInternalMap = new HashMap<Integer, V>(); + + /** + * The Internal ID + */ + private int mInternalID = 0; + private static final long serialVersionUID = 3771412318075131790L; + + @Override + public Iterator<V> iterator() { + return values().iterator(); + } + + public synchronized boolean setValue(V object){ + int mOriginalID = this.mInternalID; + put(object); + if (this.mInternalMap.get(mOriginalID).equals(object) || mOriginalID > this.mInternalID){ + return true; + } + else { + return false; + } + } + + public synchronized V put(V object){ + return set(object); + } + + public synchronized V set(V object){ + return mInternalMap.put(mInternalID++, object); + } + + public synchronized V get(int id){ + return mInternalMap.get(id); + } + + public synchronized Collection<V> values(){ + return mInternalMap.values(); + } + + public synchronized int size(){ + return mInternalMap.size(); + } + + public synchronized int hashCode(){ + return mInternalMap.hashCode(); + } + + public synchronized boolean containsKey(int key){ + return mInternalMap.containsKey(key); + } + + public synchronized boolean containsValue(V value){ + return mInternalMap.containsValue(value); + } + + public synchronized boolean isEmpty(){ + return mInternalMap.isEmpty(); + } + + public synchronized boolean clear(){ + this.mInternalID = 0; + this.mInternalMap.clear(); + return true; + } + + public synchronized V[] toArray() { + Collection<V> col = this.mInternalMap.values(); + @SuppressWarnings("unchecked") + V[] val = (V[]) col.toArray(); + return val; + } + +} diff --git a/src/Java/gtPlusPlus/api/objects/data/Pair.java b/src/Java/gtPlusPlus/api/objects/data/Pair.java new file mode 100644 index 0000000000..6ab781cf1e --- /dev/null +++ b/src/Java/gtPlusPlus/api/objects/data/Pair.java @@ -0,0 +1,27 @@ +package gtPlusPlus.api.objects.data; + +import java.io.Serializable; + +public class Pair<K,V> implements Serializable { + + /** + * SVUID + */ + private static final long serialVersionUID = 1250550491092812443L; + private final K key; + private final V value; + + public Pair(final K key, final V value){ + this.key = key; + this.value = value; + } + + final public K getKey(){ + return this.key; + } + + final public V getValue(){ + return this.value; + } + +}
\ No newline at end of file diff --git a/src/Java/gtPlusPlus/api/objects/data/Quad.java b/src/Java/gtPlusPlus/api/objects/data/Quad.java new file mode 100644 index 0000000000..01c62e95e6 --- /dev/null +++ b/src/Java/gtPlusPlus/api/objects/data/Quad.java @@ -0,0 +1,33 @@ +package gtPlusPlus.api.objects.data; + +public class Quad<K,V,C,R> { + + private final K key; + private final V value; + private final C value2; + private final R value3; + + public Quad(final K key, final V value, final C value2, final R value3){ + this.key = key; + this.value = value; + this.value2 = value2; + this.value3 = value3; + } + + final public K getKey(){ + return this.key; + } + + final public V getValue_1(){ + return this.value; + } + + final public C getValue_2(){ + return this.value2; + } + + final public R getValue_3(){ + return this.value3; + } + +}
\ No newline at end of file diff --git a/src/Java/gtPlusPlus/api/objects/data/Triplet.java b/src/Java/gtPlusPlus/api/objects/data/Triplet.java new file mode 100644 index 0000000000..affb03d868 --- /dev/null +++ b/src/Java/gtPlusPlus/api/objects/data/Triplet.java @@ -0,0 +1,27 @@ +package gtPlusPlus.api.objects.data; + +public class Triplet<K,V,C> { + + private final K key; + private final V value; + private final C count; + + public Triplet(final K key, final V value, final C value2){ + this.key = key; + this.value = value; + this.count = value2; + } + + final public K getValue_1(){ + return this.key; + } + + final public V getValue_2(){ + return this.value; + } + + final public C getValue_3(){ + return this.count; + } + +}
\ No newline at end of file diff --git a/src/Java/gtPlusPlus/api/objects/minecraft/BlockPos.java b/src/Java/gtPlusPlus/api/objects/minecraft/BlockPos.java new file mode 100644 index 0000000000..5f0d3a2117 --- /dev/null +++ b/src/Java/gtPlusPlus/api/objects/minecraft/BlockPos.java @@ -0,0 +1,222 @@ +package gtPlusPlus.api.objects.minecraft; + +import java.io.Serializable; +import java.util.HashSet; +import java.util.Set; + +import net.minecraft.block.Block; +import net.minecraft.world.World; + +import gtPlusPlus.api.objects.data.AutoMap; +import net.minecraftforge.common.DimensionManager; + +public class BlockPos implements Serializable{ + + private static final long serialVersionUID = -7271947491316682006L; + public final int xPos; + public final int yPos; + public final int zPos; + public final int dim; + public final World world; + + public BlockPos(int x, int y, int z){ + this(x, y, z, 0); + } + + public BlockPos(int x, int y, int z, int dim){ + this.xPos = x; + this.yPos = y; + this.zPos = z; + this.dim = dim; + this.world = DimensionManager.getWorld(dim); + } + + public BlockPos(int x, int y, int z, World dim){ + this.xPos = x; + this.yPos = y; + this.zPos = z; + this.dim = dim.provider.dimensionId; + this.world = dim; + } + + public String getLocationString() { + return "[X: "+this.xPos+"][Y: "+this.yPos+"][Z: "+this.zPos+"][Dim: "+this.dim+"]"; + } + + @Override + public int hashCode() { + int hash = 5; + hash += (13 * this.xPos); + hash += (19 * this.yPos); + hash += (31 * this.zPos); + hash += (17 * this.dim); + return hash; + } + + @Override + public boolean equals(Object other) { + if (other == null) { + return false; + } + if (other == this) { + return true; + } + if(!(other instanceof BlockPos)) { + return false; + } + BlockPos otherPoint = (BlockPos)other; + return this.xPos == otherPoint.xPos && this.yPos == otherPoint.yPos && this.zPos == otherPoint.zPos && this.dim == otherPoint.dim; + } + + public int distanceFrom(BlockPos target) { + if (target.dim != this.dim) { + return Short.MIN_VALUE; + } + return distanceFrom(target.xPos, target.yPos, target.zPos); + } + + /** + * + * @param x X coordinate of target. + * @param y Y coordinate of target. + * @param z Z coordinate of target. + * @return square of distance + */ + public int distanceFrom(int x, int y, int z) { + int distanceX = this.xPos - x; + int distanceY = this.yPos - y; + int distanceZ = this.zPos - z; + return distanceX * distanceX + distanceY * distanceY + distanceZ * distanceZ; + } + + public boolean isWithinRange(BlockPos target, int range) { + if (target.dim != this.dim) { + return false; + } + return isWithinRange(target.xPos, target.yPos, target.zPos, range); + } + + public boolean isWithinRange(int x, int y, int z, int range) { + return distanceFrom(x, y, z) <= (range * range); + } + + + public BlockPos getUp() { + return new BlockPos(this.xPos, this.yPos+1, this.zPos, this.dim); + } + + public BlockPos getDown() { + return new BlockPos(this.xPos, this.yPos-1, this.zPos, this.dim); + } + + public BlockPos getXPos() { + return new BlockPos(this.xPos+1, this.yPos, this.zPos, this.dim); + } + + public BlockPos getXNeg() { + return new BlockPos(this.xPos-1, this.yPos, this.zPos, this.dim); + } + + public BlockPos getZPos() { + return new BlockPos(this.xPos, this.yPos, this.zPos+1, this.dim); + } + + public BlockPos getZNeg() { + return new BlockPos(this.xPos, this.yPos, this.zPos-1, this.dim); + } + + public AutoMap<BlockPos> getSurroundingBlocks(){ + AutoMap<BlockPos> sides = new AutoMap<BlockPos>(); + sides.put(getUp()); + sides.put(getDown()); + sides.put(getXPos()); + sides.put(getXNeg()); + sides.put(getZPos()); + sides.put(getZNeg()); + return sides; + } + + public Block getBlockAtPos() { + return getBlockAtPos(this); + } + + public Block getBlockAtPos(BlockPos pos) { + return getBlockAtPos(world, pos); + } + + public Block getBlockAtPos(World world, BlockPos pos) { + return world.getBlock(pos.xPos, pos.yPos, pos.zPos); + } + + public int getMetaAtPos() { + return getMetaAtPos(this); + } + + public int getMetaAtPos(BlockPos pos) { + return getMetaAtPos(world, pos); + } + + public int getMetaAtPos(World world, BlockPos pos) { + return world.getBlockMetadata(pos.xPos, pos.yPos, pos.zPos); + } + + public boolean hasSimilarNeighbour() { + return hasSimilarNeighbour(false); + } + + /** + * @param strict - Does this check Meta Data? + * @return - Does this block have a neighbour that is the same? + */ + public boolean hasSimilarNeighbour(boolean strict) { + for (BlockPos g : getSurroundingBlocks().values()) { + if (getBlockAtPos(g) == getBlockAtPos()) { + if (!strict) { + return true; + } + else { + if (getMetaAtPos() == getMetaAtPos(g)) { + return true; + } + } + } + } + return false; + } + + public AutoMap<BlockPos> getSimilarNeighbour() { + return getSimilarNeighbour(false); + } + + /** + * @param strict - Does this check Meta Data? + * @return - Does this block have a neighbour that is the same? + */ + public AutoMap<BlockPos> getSimilarNeighbour(boolean strict) { + AutoMap<BlockPos> sides = new AutoMap<BlockPos>(); + for (BlockPos g : getSurroundingBlocks().values()) { + if (getBlockAtPos(g) == getBlockAtPos()) { + if (!strict) { + sides.put(g); + } + else { + if (getMetaAtPos() == getMetaAtPos(g)) { + sides.put(g); + } + } + } + } + return sides; + } + + public Set<BlockPos> getValidNeighboursAndSelf(){ + AutoMap<BlockPos> h = getSimilarNeighbour(true); + h.put(this); + Set<BlockPos> result = new HashSet<BlockPos>(); + for (BlockPos f : h.values()) { + result.add(f); + } + return result; + } + +} diff --git a/src/Java/gtPlusPlus/api/objects/ChunkManager.java b/src/Java/gtPlusPlus/api/objects/minecraft/ChunkManager.java index 0bace04bf8..82f3adfc9e 100644 --- a/src/Java/gtPlusPlus/api/objects/ChunkManager.java +++ b/src/Java/gtPlusPlus/api/objects/minecraft/ChunkManager.java @@ -6,33 +6,27 @@ * permission unless otherwise specified on the * license page at http://railcraft.info/wiki/info:license. */ -package gtPlusPlus.api.objects; +package gtPlusPlus.api.objects.minecraft; + +import java.util.*; +import java.util.concurrent.ConcurrentHashMap; import com.google.common.collect.LinkedListMultimap; import com.google.common.collect.ListMultimap; -import cpw.mods.fml.common.eventhandler.SubscribeEvent; -import gtPlusPlus.GTplusplus; -import gtPlusPlus.core.util.array.BlockPos; -import gtPlusPlus.core.util.array.Triplet; -import gtPlusPlus.xmod.gregtech.common.tileentities.machines.basic.GregtechMetaTileEntityChunkLoader; -import java.util.HashSet; -import java.util.LinkedList; -import java.util.List; -import java.util.Set; -import java.util.Timer; -import java.util.TimerTask; -import java.util.concurrent.ConcurrentHashMap; +import cpw.mods.fml.common.eventhandler.SubscribeEvent; -import net.minecraft.world.ChunkCoordIntPair; import net.minecraft.entity.Entity; +import net.minecraft.world.ChunkCoordIntPair; import net.minecraft.world.World; import net.minecraft.world.chunk.Chunk; + +import gtPlusPlus.GTplusplus; +import gtPlusPlus.api.objects.Logger; +import gtPlusPlus.api.objects.data.Triplet; +import gtPlusPlus.xmod.gregtech.common.tileentities.machines.basic.GregtechMetaTileEntityChunkLoader; import net.minecraftforge.common.ForgeChunkManager; -import net.minecraftforge.common.ForgeChunkManager.LoadingCallback; -import net.minecraftforge.common.ForgeChunkManager.OrderedLoadingCallback; -import net.minecraftforge.common.ForgeChunkManager.Ticket; -import net.minecraftforge.common.ForgeChunkManager.Type; +import net.minecraftforge.common.ForgeChunkManager.*; import net.minecraftforge.event.entity.EntityEvent; /** diff --git a/src/Java/gtPlusPlus/api/objects/DimChunkPos.java b/src/Java/gtPlusPlus/api/objects/minecraft/DimChunkPos.java index bea0a4ec3b..010e522a14 100644 --- a/src/Java/gtPlusPlus/api/objects/DimChunkPos.java +++ b/src/Java/gtPlusPlus/api/objects/minecraft/DimChunkPos.java @@ -1,6 +1,5 @@ -package gtPlusPlus.api.objects; +package gtPlusPlus.api.objects.minecraft; -import gtPlusPlus.core.util.array.BlockPos; import net.minecraft.client.Minecraft; import net.minecraft.tileentity.TileEntity; import net.minecraft.world.World; diff --git a/src/Java/gtPlusPlus/api/objects/minecraft/FluidGT6.java b/src/Java/gtPlusPlus/api/objects/minecraft/FluidGT6.java new file mode 100644 index 0000000000..2535046792 --- /dev/null +++ b/src/Java/gtPlusPlus/api/objects/minecraft/FluidGT6.java @@ -0,0 +1,31 @@ +package gtPlusPlus.api.objects.minecraft; + +import gregtech.api.GregTech_API; + +import gtPlusPlus.core.lib.CORE; +import net.minecraftforge.fluids.Fluid; + +public class FluidGT6 extends Fluid implements Runnable +{ + private final short[] mRGBa; + public final String mTextureName; + + public FluidGT6(final String aName, final String aTextureName, final short[] aRGBa) { + super(aName); + this.mRGBa = aRGBa; + this.mTextureName = aTextureName; + if (GregTech_API.sGTBlockIconload != null) { + GregTech_API.sGTBlockIconload.add(this); + } + } + + @Override + public int getColor() { + return (Math.max(0, Math.min(255, this.mRGBa[0])) << 16) | (Math.max(0, Math.min(255, this.mRGBa[1])) << 8) | Math.max(0, Math.min(255, this.mRGBa[2])); + } + + @Override + public void run() { + this.setIcons(GregTech_API.sBlockIcons.registerIcon(CORE.MODID+ ":" + "fluids/fluid." + this.mTextureName)); + } +} diff --git a/src/Java/gtPlusPlus/api/objects/GenericStack.java b/src/Java/gtPlusPlus/api/objects/minecraft/GenericStack.java index b3bc94364f..9c1b231961 100644 --- a/src/Java/gtPlusPlus/api/objects/GenericStack.java +++ b/src/Java/gtPlusPlus/api/objects/minecraft/GenericStack.java @@ -1,6 +1,7 @@ -package gtPlusPlus.api.objects; +package gtPlusPlus.api.objects.minecraft; import net.minecraft.item.ItemStack; + import net.minecraftforge.fluids.FluidStack; public class GenericStack { diff --git a/src/Java/gtPlusPlus/api/objects/CSPRNG_DO_NOT_USE.java b/src/Java/gtPlusPlus/api/objects/random/CSPRNG_DO_NOT_USE.java index 19200846ca..b2dc984456 100644 --- a/src/Java/gtPlusPlus/api/objects/CSPRNG_DO_NOT_USE.java +++ b/src/Java/gtPlusPlus/api/objects/random/CSPRNG_DO_NOT_USE.java @@ -33,7 +33,7 @@ * http://www.opensource.org/licenses/bsd-license.php */ -package gtPlusPlus.api.objects; +package gtPlusPlus.api.objects.random; import java.math.BigInteger; import java.security.SecureRandom; import java.util.Random; diff --git a/src/Java/gtPlusPlus/api/objects/random/UUIDGenerator.java b/src/Java/gtPlusPlus/api/objects/random/UUIDGenerator.java new file mode 100644 index 0000000000..fec92368f8 --- /dev/null +++ b/src/Java/gtPlusPlus/api/objects/random/UUIDGenerator.java @@ -0,0 +1,449 @@ +package gtPlusPlus.api.objects.random; + +import java.io.IOException; +import java.net.InetAddress; +import java.util.Random; +import java.util.UUID; + +/** + * + * Implement modified version of Apache's OpenJPA UUID generator. + * This UUID generator is paired with a Blum-Blum-Shub random number generator + * which in itself is seeded by custom SecureRandom. + * + * The UUID generator class has been converted from a static factory to an instanced factory. + * + */ + +//========================================= APACHE BLOCK ========================================= + +/* + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.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.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ + +/** + * UUID value generator. Type 1 generator is based on the time-based generator + * in the Apache Commons Id project: http://jakarta.apache.org/commons/sandbox + * /id/uuid.html The type 4 generator uses the standard Java UUID generator. + * + * The type 1 code has been vastly simplified and modified to replace the + * ethernet address of the host machine with the IP, since we do not want to + * require native libs and Java cannot access the MAC address directly. + * + * In spirit, implements the IETF UUID draft specification, found here:<br /> + * http://www1.ics.uci.edu/~ejw/authoring/uuid-guid/draft-leach-uuids-guids-01 + * .txt + * + * @author Abe White, Kevin Sutter + * @since 0.3.3 + */ +public class UUIDGenerator { + + // supported UUID types + public static final int TYPE1 = 1; + public static final int TYPE4 = 4; + // indexes within the uuid array for certain boundaries + private static final byte IDX_TIME_HI = 6; + private static final byte IDX_TYPE = 6; // multiplexed + private static final byte IDX_TIME_MID = 4; + private static final byte IDX_TIME_LO = 0; + private static final byte IDX_TIME_SEQ = 8; + private static final byte IDX_VARIATION = 8; // multiplexed + // indexes and lengths within the timestamp for certain boundaries + private static final byte TS_TIME_LO_IDX = 4; + private static final byte TS_TIME_LO_LEN = 4; + private static final byte TS_TIME_MID_IDX = 2; + private static final byte TS_TIME_MID_LEN = 2; + private static final byte TS_TIME_HI_IDX = 0; + private static final byte TS_TIME_HI_LEN = 2; + // offset to move from 1/1/1970, which is 0-time for Java, to gregorian + // 0-time 10/15/1582, and multiplier to go from 100nsec to msec units + private static final long GREG_OFFSET = 0xB1D069B5400L; + private static final long MILLI_MULT = 10000L; + // type of UUID -- time based + private final static byte TYPE_TIME_BASED = 0x10; + // random number generator used to reduce conflicts with other JVMs, and + // hasher for strings. + private Random RANDOM; + // 4-byte IP address + 2 random bytes to compensate for the fact that + // the MAC address is usually 6 bytes + private byte[] IP; + // counter is initialized to 0 and is incremented for each uuid request + // within the same timestamp window. + private int _counter; + // current timestamp (used to detect multiple uuid requests within same + // timestamp) + private long _currentMillis; + // last used millis time, and a semi-random sequence that gets reset + // when it overflows + private long _lastMillis = 0L; + private static final int MAX_14BIT = 0x3FFF; + private short _seq = 0; + private boolean type1Initialized = false; /* + * Initializer for type 1 UUIDs. Creates random generator and genenerates + * the node portion of the UUID using the IP address. + */ + private synchronized void initializeForType1() { + if (type1Initialized == true) { + return; + } + // note that secure random is very slow the first time + // it is used; consider switching to a standard random + RANDOM = CSPRNG_DO_NOT_USE.generate(); + _seq = (short) RANDOM.nextInt(MAX_14BIT); + + byte[] ip = null; + try { + ip = InetAddress.getLocalHost().getAddress(); + } catch (IOException ioe) { + throw new RuntimeException(ioe); + } + IP = new byte[6]; + RANDOM.nextBytes(IP); + //OPENJPA-2055: account for the fact that 'getAddress' + //may return an IPv6 address which is 16 bytes wide. + for( int i = 0 ; i < ip.length; ++i ) { + IP[2+(i%4)] ^= ip[i]; + } + type1Initialized = true; + } + /** + * Return a unique UUID value. + */ + public byte[] next(int type) { + if (type == TYPE4) { + return createType4(); + } + return createType1(); + } + /* + * Creates a type 1 UUID + */ + public byte[] createType1() { + if (type1Initialized == false) { + initializeForType1(); + } + // set ip addr + byte[] uuid = new byte[16]; + System.arraycopy(IP, 0, uuid, 10, IP.length); + // Set time info. Have to do this processing within a synchronized + // block because of the statics... + long now = 0; + synchronized (UUIDGenerator.class) { + // Get the time to use for this uuid. This method has the side + // effect of modifying the clock sequence, as well. + now = getTime(); + // Insert the resulting clock sequence into the uuid + uuid[IDX_TIME_SEQ] = (byte) ((_seq & 0x3F00) >>> 8); + uuid[IDX_VARIATION] |= 0x80; + uuid[IDX_TIME_SEQ+1] = (byte) (_seq & 0xFF); + } + // have to break up time because bytes are spread through uuid + byte[] timeBytes = Bytes.toBytes(now); + // Copy time low + System.arraycopy(timeBytes, TS_TIME_LO_IDX, uuid, IDX_TIME_LO, + TS_TIME_LO_LEN); + // Copy time mid + System.arraycopy(timeBytes, TS_TIME_MID_IDX, uuid, IDX_TIME_MID, + TS_TIME_MID_LEN); + // Copy time hi + System.arraycopy(timeBytes, TS_TIME_HI_IDX, uuid, IDX_TIME_HI, + TS_TIME_HI_LEN); + //Set version (time-based) + uuid[IDX_TYPE] |= TYPE_TIME_BASED; // 0001 0000 + return uuid; + } + /* + * Creates a type 4 UUID + */ + private byte[] createType4() { + UUID type4 = UUID.randomUUID(); + byte[] uuid = new byte[16]; + longToBytes(type4.getMostSignificantBits(), uuid, 0); + longToBytes(type4.getLeastSignificantBits(), uuid, 8); + return uuid; + } + /* + * Converts a long to byte values, setting them in a byte array + * at a given starting position. + */ + private void longToBytes(long longVal, byte[] buf, int sPos) { + sPos += 7; + for(int i = 0; i < 8; i++) + buf[sPos-i] = (byte)(longVal >>> (i * 8)); + } + + /** + * Return the next unique uuid value as a 16-character string. + */ + public String nextString(int type) { + byte[] bytes = next(type); + try { + return new String(bytes, "ISO-8859-1"); + } catch (Exception e) { + return new String(bytes); + } + } + /** + * Return the next unique uuid value as a 32-character hex string. + */ + public String nextHex(int type) { + return Base16Encoder.encode(next(type)); + } + /** + * Get the timestamp to be used for this uuid. Must be called from + * a synchronized block. + * + * @return long timestamp + */ + // package-visibility for testing + private long getTime() { + if (RANDOM == null) + initializeForType1(); + long newTime = getUUIDTime(); + if (newTime <= _lastMillis) { + incrementSequence(); + newTime = getUUIDTime(); + } + _lastMillis = newTime; + return newTime; + } + /** + * Gets the appropriately modified timestamep for the UUID. Must be called + * from a synchronized block. + * + * @return long timestamp in 100ns intervals since the Gregorian change + * offset + */ + private long getUUIDTime() { + if (_currentMillis != System.currentTimeMillis()) { + _currentMillis = System.currentTimeMillis(); + _counter = 0; // reset counter + } + // check to see if we have created too many uuid's for this timestamp + if (_counter + 1 >= MILLI_MULT) { + // Original algorithm threw exception. Seemed like overkill. + // Let's just increment the timestamp instead and start over... + _currentMillis++; + _counter = 0; + } + // calculate time as current millis plus offset times 100 ns ticks + long currentTime = (_currentMillis + GREG_OFFSET) * MILLI_MULT; + // return the uuid time plus the artificial tick counter incremented + return currentTime + _counter++; + } + /** + * Increments the clock sequence for this uuid. Must be called from a + * synchronized block. + */ + private void incrementSequence() { + // increment, but if it's greater than its 14-bits, reset it + if (++_seq > MAX_14BIT) { + _seq = (short) RANDOM.nextInt(MAX_14BIT); // semi-random + } + } + + //Add Dependant classes internally + + /** + * This class came from the Apache Commons Id sandbox project in support + * of the UUIDGenerator implementation. + * + * <p>Static methods for managing byte arrays (all methods follow Big + * Endian order where most significant bits are in front).</p> + */ + public static final class Bytes { + /** + * <p>Hide constructor in utility class.</p> + */ + private Bytes() { + } + /** + * Appends two bytes array into one. + * + * @param a A byte[]. + * @param b A byte[]. + * @return A byte[]. + */ + public static byte[] append(byte[] a, byte[] b) { + byte[] z = new byte[a.length + b.length]; + System.arraycopy(a, 0, z, 0, a.length); + System.arraycopy(b, 0, z, a.length, b.length); + return z; + } + /** + * Returns a 8-byte array built from a long. + * + * @param n The number to convert. + * @return A byte[]. + */ + public static byte[] toBytes(long n) { + return toBytes(n, new byte[8]); + } + /** + * Build a 8-byte array from a long. No check is performed on the + * array length. + * + * @param n The number to convert. + * @param b The array to fill. + * @return A byte[]. + */ + public static byte[] toBytes(long n, byte[] b) { + b[7] = (byte) (n); + n >>>= 8; + b[6] = (byte) (n); + n >>>= 8; + b[5] = (byte) (n); + n >>>= 8; + b[4] = (byte) (n); + n >>>= 8; + b[3] = (byte) (n); + n >>>= 8; + b[2] = (byte) (n); + n >>>= 8; + b[1] = (byte) (n); + n >>>= 8; + b[0] = (byte) (n); + + return b; + } + /** + * Build a long from first 8 bytes of the array. + * + * @param b The byte[] to convert. + * @return A long. + */ + public static long toLong(byte[] b) { + return ((((long) b[7]) & 0xFF) + + ((((long) b[6]) & 0xFF) << 8) + + ((((long) b[5]) & 0xFF) << 16) + + ((((long) b[4]) & 0xFF) << 24) + + ((((long) b[3]) & 0xFF) << 32) + + ((((long) b[2]) & 0xFF) << 40) + + ((((long) b[1]) & 0xFF) << 48) + + ((((long) b[0]) & 0xFF) << 56)); + } + /** + * Compares two byte arrays for equality. + * + * @param a A byte[]. + * @param b A byte[]. + * @return True if the arrays have identical contents. + */ + public static boolean areEqual(byte[] a, byte[] b) { + int aLength = a.length; + if (aLength != b.length) { + return false; + } + for (int i = 0; i < aLength; i++) { + if (a[i] != b[i]) { + return false; + } + } + return true; + } + /** + * <p>Compares two byte arrays as specified by <code>Comparable</code>. + * + * @param lhs - left hand value in the comparison operation. + * @param rhs - right hand value in the comparison operation. + * @return a negative integer, zero, or a positive integer as + * <code>lhs</code> is less than, equal to, or greater than + * <code>rhs</code>. + */ + public static int compareTo(byte[] lhs, byte[] rhs) { + if (l |
