/*
* The MIT License
*
* Copyright (c) 2011 Dominic Williams, Daniel Washusen and contributors.
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal
* in the Software without restriction, including without limitation the rights
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
* copies of the Software, and to permit persons to whom the Software is
* furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in
* all copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
* THE SOFTWARE.
*/
package org.scale7.cassandra.pelops;
import java.nio.BufferUnderflowException;
import java.nio.ByteBuffer;
import java.nio.charset.Charset;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collection;
import java.util.HashSet;
import java.util.List;
import java.util.Set;
import java.util.UUID;
/**
* Wraps a {@link java.nio.ByteBuffer} and provides useful methods to operate on it.
* Also provides numerous factory methods to create instances based on various data types.
* <p/>
* <p>In an effort to provide a very stable and well tested marshalling strategy
* this class uses the various methods available on {@link java.nio.ByteBuffer} to perform serialization. The exceptions
* to this are the UUID and String methods (see their javadoc comments for details).</p>
* <p/>
* <b>Note</b>: Instances of this class should *not* be considered thread safe.
*/
public class Bytes {
public static final Bytes EMPTY = fromByteArray(new byte[0]);
public static final Bytes NULL = fromByteBuffer(null);
private final ByteBuffer bytes;
private int hashCode = -1;
/**
* Constructs a new instance based on the provided byte array.
*
* @param bytes the bytes
* @deprecated use {@link #fromByteArray(byte[])} instead
*/
@Deprecated
public Bytes(byte[] bytes) {
this(ByteBuffer.wrap(bytes), false);
}
/**
* Constructs a new instance based on the provided byte buffer. The {@link java.nio.ByteBuffer#position()} must be
* in the correct position to read the appropriate value from it.
*
* @param bytes the bytes
* @deprecated use {@link #fromByteBuffer(java.nio.ByteBuffer)} instead
*/
@Deprecated
public Bytes(ByteBuffer bytes) {
this(bytes, true);
}
/**
* Constructs a new instance based on the provided byte buffer. The {@link java.nio.ByteBuffer#position()} must be
* in the correct position to read the appropriate value from it. The given bytes are either used directly,
* or duplicated.
*
* @param bytes the bytes
* @param duplicate if true, duplicates the given bytes; otherwise, it is rewound and used it as-is
*/
private Bytes(ByteBuffer bytes, boolean duplicate) {
if (bytes != null) {
this.bytes = duplicate ? bytes.duplicate() : (ByteBuffer)bytes.rewind();
this.bytes.mark();
} else
this.bytes = null;
}
/**
* Returns an (expensive) string representation of the bytes as defined by the {@link java.util.Arrays#toString(byte[])} method.
* <p><b>NOTE</b>: The {@link #toUTF8()} method provides the reverse value of the {@link #fromUTF8(String)} method.
*
* @return the string representation
*/
@Override
public String toString() {
if (isNull()) return null;
bytes.reset();
return Arrays.toString(Arrays.copyOfRange(bytes.array(), bytes.position(), bytes.limit()));
}
/**
* Returns the underlying {@link ByteBuffer}.
*
* @return the raw byte array
*/
public ByteBuffer getBytes() {
return bytes;
}
/**
* Returns a duplicate of the bytes instance. The underlying {@link java.nio.ByteBuffer} is duplicated using the
* {@link java.nio.ByteBuffer#duplicate()} method.
*
* @return the raw byte array
* @see java.nio.ByteBuffer#duplicate()
*/
public Bytes duplicate() {
return isNull() ? Bytes.NULL : new Bytes(bytes, true);
}
/**
* Determines if two instances of this class are equals using the {@link Arrays#equals(byte[], byte[])} method.
*
* @param o the other instance
* @return true if they are equal, otherwise false
*/
@Override
public boolean equals(Object o) {
if (this == o) return true;
if (!(o instanceof Bytes)) return false;
Bytes bytes = (Bytes) o;
return this.bytes.equals(bytes.bytes);
}
/**
* Calculates the hash code using {@link java.util.Arrays#hashCode(byte[])}.
* <p>Note that the instances hashCode is calculated the first time this method is called and then cached.</p>
*
* @return the hash code
*/
@Override
public int hashCode() {
if (hashCode == -1) // only calculate the hash code once
hashCode = this.bytes.hashCode();
return hashCode;
}
/**
* Returns the length of the value within the underlying byte buffer.
*
* @return the length
*/
public int length() {
return this.bytes.remaining();
}
/**
* Creates an instance based on the provided byte array.
*
* @param value the value
* @return the Bytes instance
* @deprecated use {@link #fromByteArray(byte[])} instead
*/
@Deprecated
public static Bytes fromBytes(byte[] value) {
return fromByteArray(value);
}
/**
* Creates an instance based on the provided byte array.
*
* @param value the value
* @return the Bytes instance
*/
public static Bytes fromByteArray(byte[] value) {
return new Bytes(BufferHelper.fromByteArray(value), false);
}
/**
* Creates an instance based on the provided byte buffer.
*
* @param value the value
* @return the Bytes instance
*/
public static Bytes fromByteBuffer(ByteBuffer value) {
return new Bytes(value, true);
}
/**
* Creates an instance based on the provided value.
*
* @param value the value
* @return the instance
* @see java.nio.ByteBuffer for details on serializaion format
*/
public static Bytes fromChar(char value) {
return new Bytes(BufferHelper.fromChar(value), false);
}
/**
* Creates an instance based on the provided value handling nulls.
*
* @param value the value
* @return the instance or null if the value provided was null
* @see java.nio.ByteBuffer for details on serializaion format
*/
public static Bytes fromChar(Character value) {
return value == null ? NULL : fromChar(value.charValue());
}
/**
* Creates an instance based on the provided value.
*
* @param value the value
* @return the instance
* @see java.nio.ByteBuffer for details on serializaion format
*/
public static Bytes fromByte(byte value) {
return new Bytes(BufferHelper.fromByte(value), false);
}
/**
* Creates an instance based on the provided value handling nulls.
*
* @param value the value
* @return the instance or null if the value provided was null
* @see java.nio.ByteBuffer for details on serializaion format
*/
public static Bytes fromByte(Byte value) {
return value == null ? NULL : fromByte(value.byteValue());
}
/**
* Creates an instance based on the provided value.
*
* @param value the value
* @return the instance
* @see java.nio.ByteBuffer for details on serializaion format
*/
public static Bytes fromLong(long value) {
return new Bytes(BufferHelper.fromLong(value), false);
}
/**
* Creates an instance based on the provided value handling nulls.
*
* @param value the value
* @return the instance or null if the value provided was null
* @see java.nio.ByteBuffer for details on serializaion format
*/
public static Bytes fromLong(Long value) {
return value == null ? NULL : fromLong(value.longValue());
}
/**
* Creates an instance based on the provided value.
*
* @param value the value
* @return the instance
* @see java.nio.ByteBuffer for details on serializaion format
*/
public static Bytes fromInt(int value) {
return new Bytes(BufferHelper.fromInt(value), false);
}
/**
* Creates an instance based on the provided value handling nulls.
*
* @param value the value
* @return the instance or null if the value provided was null
* @see java.nio.ByteBuffer for details on serializaion format
*/
public static Bytes fromInt(Integer value) {
return value == null ? NULL : fromInt(value.intValue());
}
/**
* Creates an instance based on the provided value.
*
* @param value the value
* @return the instance
* @see java.nio.ByteBuffer for details on serializaion format
*/
public static Bytes fromShort(short value) {
return new Bytes(BufferHelper.fromShort(value), false);
}
/**
* Creates an instance based on the provided value handling nulls.
*
* @param value the value
* @return the instance or null if the value provided was null
* @see java.nio.ByteBuffer for details on serializaion format
*/
public static Bytes fromShort(Short value) {
return value == null ? NULL : fromShort(value.shortValue());
}
/**
* Creates an instance based on the provided value.
*
* @param value the value
* @return the instance
* @see java.nio.ByteBuffer for details on serializaion format
*/
public static Bytes fromDouble(double value) {
return new Bytes(BufferHelper.fromDouble(value), false);
}
/**
* Creates an instance based on the provided value handling nulls.
*
* @param value the value
* @return the instance or null if the value provided was null
* @see java.nio.ByteBuffer for details on serializaion format
*/
public static Bytes fromDouble(Double value) {
return value == null ? NULL : fromDouble(value.doubleValue());
}
/**
* Creates an instance based on the provided value.
*
* @param value the value
* @return the instance
* @see java.nio.ByteBuffer for details on serializaion format
*/
public static Bytes fromFloat(float value) {
return new Bytes(BufferHelper.fromFloat(value), false);
}
/**
* Creates an instance based on the provided value handling nulls.
*
* @param value the value
* @return the instance or null if the value provided was null
* @see java.nio.ByteBuffer for details on serializaion format
*/
public static Bytes fromFloat(Float value) {
return value == null ? NULL : fromFloat(value.floatValue());
}
/**
* Creates an instance based on the provided value.
*
* @param value the value
* @return the instance
* @see java.nio.ByteBuffer for details on serializaion format
*/
public static Bytes fromBoolean(boolean value) {
return new Bytes(BufferHelper.fromBoolean(value), false);
}
/**
* Creates an instance based on the provided value handling nulls.
*
* @param value the value
* @return the instance or null if the value provided was null
* @see java.nio.ByteBuffer for details on serializaion format
*/
public static Bytes fromBoolean(Boolean value) {
return value == null ? NULL : fromBoolean(value.booleanValue());
}
/**
* Creates an instance based on the provided value handling nulls. If the provided value is not null then this method
* delegates to {@link #fromUuid(long, long)} to perform the deserialization.
*
* @param value the value
* @return the instance or null if the value provided was null
* @see java.nio.ByteBuffer for details on long serializaion format
*/
public static Bytes fromUuid(UUID value) {
return value == null ? NULL : new Bytes(BufferHelper.fromUuid(value), false);
}
/**
* Creates an instance based on the provided value handling nulls. If the provided value is not null then a new
* instance of {@link UUID} is created using {@link java.util.UUID#fromString(String)} and then
* {@link #fromUuid(long, long)} is called to perform the deserialization.
*
* @param value the value
* @return the instance or null if the value provided was null
* @see java.nio.ByteBuffer for details on long serializaion format
*/
public static Bytes fromUuid(String value) {
return value == null ? NULL : new Bytes(BufferHelper.fromUuid(value), false);
}
/**
* Creates an instance based on the provided values. The {@link java.nio.ByteBuffer#putLong(long)} is called twice,
* the first call for the msb value and second for the lsb value.
*
* @param msb the msb value
* @param lsb the lsb value
* @return the instance or null if the value provided was null
* @see java.nio.ByteBuffer for details on long serializaion format
*/
public static Bytes fromUuid(long msb, long lsb) {
return new Bytes(BufferHelper.fromUuid(msb, lsb), false);
}
/**
* Creates an instance based on the provided value handling nulls. If the provided value is not null then this method
* delegates to {@link #fromUuid(long, long)} to perform the deserialization.
*
* @param value the value
* @return the instance or null if the value provided was null
* @see java.nio.ByteBuffer for details on long serializaion format
*/
public static Bytes fromTimeUuid(com.eaio.uuid.UUID value) {
return value == null ? NULL : fromUuid(value.getTime(), value.getClockSeqAndNode());
}
/**
* Creates an instance based on the provided value handling nulls.
*
* @param value the value
* @return the instance or null if the value provided was null
* @see java.nio.ByteBuffer for details on long serializaion format
* @deprecated use {@link #fromUuid(UUID)} instead
*/
@Deprecated
public static Bytes fromTimeUuid(UUID value) {
return fromUuid(value);
}
/**
* Creates an instance based on the provided value handling nulls.
*
* @param value the value
* @return the instance or null if the value provided was null
* @see java.nio.ByteBuffer for details on long serializaion format
* @deprecated use {@link #fromUuid(String)} instead
*/
@Deprecated
public static Bytes fromTimeUuid(String value) {
return fromUuid(value);
}
/**
* Creates an instance based on the provided values.
*
* @param time the time value
* @param clockSeqAndNode the clockSeqAndNode value
* @return the instance or null if the value provided was null
* @see java.nio.ByteBuffer for details on long serializaion format
* @deprecated use {@link #fromUuid(long, long)} instead
*/
@Deprecated
public static Bytes fromTimeUuid(long time, long clockSeqAndNode) {
return fromUuid(time, clockSeqAndNode);
}
/**
* Creates an instance based on the provided value in UTF-8 format handling nulls.
*
* @param value the value
* @return the instance or null if the value provided was null
* @see String#getBytes(java.nio.charset.Charset) for details on the format
*/
public static Bytes fromUTF8(String value) {
return value == null ? NULL : new Bytes(BufferHelper.fromUTF8(value), false);
}
/**
* Converts the backing array to the appropriate object instance handling nulls.
*
* @param defaultIfNull the value to return is the backing array is null
* @return the deserialized instance
*/
public Character toChar(Character defaultIfNull) {
if (isNull())
return defaultIfNull;
else
return toChar();
}
/**
* Converts the backing array to the appropriate primitive.
*
* @return the deserialized primitive
* @throws IllegalStateException if the underlying array does not contain the appropriate data
*/
public char toChar() throws IllegalStateException {
try {
bytes.reset();
return this.bytes.getChar();
} catch (BufferUnderflowException e) {
throw new IllegalStateException("Failed to read value due to invalid format. See cause for details...", e);
} finally {
this.bytes.reset();
}
}
/**
* Converts the backing array to the appropriate object instance handling nulls.
*
* @param defaultIfNull the value to return is the backing array is null
* @return the deserialized instance
*/
public byte[] toByteArray(byte[] defaultIfNull) {
if (isNull())
return defaultIfNull;
else
return toByteArray();
}
/**
* Converts the backing array to the appropriate primitive.
*
* @return the deserialized primitive
* @throws IllegalStateException if the underlying array does not contain the appropriate data
*/
public byte[] toByteArray() throws IllegalStateException {
try {
bytes.reset();
return Arrays.copyOfRange(this.bytes.array(), this.bytes.position(), this.bytes.limit());
} catch (BufferUnderflowException e) {
throw new IllegalStateException("Failed to read value due to invalid format. See cause for details...", e);
} finally {
this.bytes.reset();
}
}
/**
* Converts the backing array to the appropriate object instance handling nulls.
*
* @param defaultIfNull the value to return is the backing array is null
* @return the deserialized instance
*/
public Byte toByte(Byte defaultIfNull) {
if (isNull())
return defaultIfNull;
else
return toByte();
}
/**
* Converts the backing array to the appropriate primitive.
*
* @return the deserialized primitive
* @throws IllegalStateException if the underlying array does not contain the appropriate data
*/
public byte toByte() throws IllegalStateException {
try {
bytes.reset();
return this.bytes.get();
} catch (BufferUnderflowException e) {
throw new IllegalStateException("Failed to read value due to invalid format. See cause for details...", e);
} finally {
this.bytes.reset();
}
}
/**
* Pads a byte buffer to match a specified length.
*
* @param totalLength the length to pad the buffer
* @param originalByteBuffer the buffer with data to pad
* @return the padded buffer; this may be the original buffer or a new buffer
*/
private static ByteBuffer padValue(int totalLength, ByteBuffer originalByteBuffer) {
if (originalByteBuffer.capacity() >= totalLength)
return originalByteBuffer;
byte[] originalByteArray = originalByteBuffer.array();
byte[] newByteArray = new byte[totalLength];
for (int i = originalByteArray.length - 1; i >= 0; i--)
newByteArray[(totalLength - 1) - i] = originalByteArray[i];
return ByteBuffer.wrap(newByteArray);
}
/**
* Converts the backing array to the appropriate object instance handling nulls.
*
* @param defaultIfNull the value to return is the backing array is null
* @return the deserialized instance
*/
public Long toLong(Long defaultIfNull) {
if (isNull())
return defaultIfNull;
else
return toLong();
}
/**
* Converts the backing array to the appropriate primitive.
*
* @return the deserialized primitive
* @throws IllegalStateException if the underlying array does not contain the appropriate data
*/
public long toLong() throws IllegalStateException {
try {
bytes.reset();
return padValue(8, this.bytes).getLong();
} catch (BufferUnderflowException e) {
throw new IllegalStateException("Failed to read value due to invalid format. See cause for details...", e);
} finally {
this.bytes.reset();
}
}
/**
* Converts the backing array to the appropriate object instance handling nulls.
*
* @param defaultIfNull the value to return is the backing array is null
* @return the deserialized instance
*/
public Integer toInt(Integer defaultIfNull) {
if (isNull())
return defaultIfNull;
else
return toInt();
}
/**
* Converts the backing array to the appropriate primitive.
*
* @return the deserialized primitive
* @throws IllegalStateException if the underlying array does not contain the appropriate data
*/
public int toInt() throws IllegalStateException {
try {
bytes.reset();
return padValue(4, this.bytes).getInt();
} catch (BufferUnderflowException e) {
throw new IllegalStateException("Failed to read value due to invalid format. See cause for details...", e);
} finally {
this.bytes.reset();
}
}
/**
* Converts the backing array to the appropriate object instance handling nulls.
*
* @param defaultIfNull the value to return is the backing array is null
* @return the deserialized instance
*/
public Short toShort(Short defaultIfNull) {
if (isNull())
return defaultIfNull;
else
return toShort();
}
/**
* Converts the backing array to the appropriate primitive.
*
* @return the deserialized primitive
* @throws IllegalStateException if the underlying array does not contain the appropriate data
*/
public short toShort() throws IllegalStateException {
try {
bytes.reset();
return padValue(2, this.bytes).getShort();
} catch (BufferUnderflowException e) {
throw new IllegalStateException("Failed to read value due to invalid format. See cause for details...", e);
} finally {
this.bytes.reset();
}
}
/**
* Converts the backing array to the appropriate object instance handling nulls.
*
* @param defaultIfNull the value to return is the backing array is null
* @return the deserialized instance
*/
public Double toDouble(Double defaultIfNull) {
if (isNull())
return defaultIfNull;
else
return toDouble();
}
/**
* Converts the backing array to the appropriate primitive.
*
* @return the deserialized primitive
* @throws IllegalStateException if the underlying array does not contain the appropriate data
*/
public double toDouble() throws IllegalStateException {
try {
bytes.reset();
return this.bytes.getDouble();
} catch (BufferUnderflowException e) {
throw new IllegalStateException("Failed to read value due to invalid format. See cause for details...", e);
} finally {
this.bytes.reset();
}
}
/**
* Converts the backing array to the appropriate object instance handling nulls.
*
* @param defaultIfNull the value to return is the backing array is null
* @return the deserialized instance
*/
public Float toFloat(Float defaultIfNull) {
if (isNull())
return defaultIfNull;
else
return toFloat();
}
/**
* Converts the backing array to the appropriate primitive.
*
* @return the deserialized primitive
* @throws IllegalStateException if the underlying array does not contain the appropriate data
*/
public float toFloat() throws IllegalStateException {
try {
bytes.reset();
return this.bytes.getFloat();
} catch (BufferUnderflowException e) {
throw new IllegalStateException("Failed to read value due to invalid format. See cause for details...", e);
} finally {
this.bytes.reset();
}
}
/**
* Converts the backing array to the appropriate object instance handling nulls.
*
* @param defaultIfNull the value to return is the backing array is null
* @return the deserialized instance
*/
public Boolean toBoolean(Boolean defaultIfNull) {
if (isNull())
return defaultIfNull;
else
return toBoolean();
}
/**
* Converts the backing array to the appropriate primitive.
*
* @return the deserialized primitive
* @throws IllegalStateException if the underlying array does not contain the appropriate data
*/
public boolean toBoolean() throws IllegalStateException {
try {
bytes.reset();
return this.bytes.get() != BufferHelper.BOOLEAN_FALSE;
} catch (BufferUnderflowException e) {
throw new IllegalStateException("Failed to read value due to invalid format. See cause for details...", e);
} finally {
this.bytes.reset();
}
}
/**
* Converts the backing array to the appropriate object instance handling nulls.
*
* @return the deserialized instance or null if the backing array was null
* @throws IllegalStateException if the underlying array does not contain the appropriate data
*/
public UUID toUuid() throws IllegalStateException {
if (isNull()) return null;
try {
bytes.reset();
long msb = this.bytes.getLong();
long lsb = this.bytes.getLong();
return new UUID(msb, lsb);
} catch (BufferUnderflowException e) {
throw new IllegalStateException("Failed to read value due to invalid format. See cause for details...", e);
} finally {
this.bytes.reset();
}
}
/**
* Converts the backing array to the appropriate object instance handling nulls.
*
* @return the deserialized instance or null if the backing array was null
* @throws IllegalStateException if the underlying array does not contain the appropriate data
*/
public com.eaio.uuid.UUID toTimeUuid() throws IllegalStateException {
UUID uuid = toUuid();
if (uuid == null) return null;
return new com.eaio.uuid.UUID(uuid.getMostSignificantBits(), uuid.getLeastSignificantBits());
}
/**
* Efficiently constructs a uuid from a bytes array without creating any intermediate objects
*
* @param uuid The bytes representing the uuid.
* @return A uuid object
*/
public static UUID uuidFromBytes(byte[] uuid) {
long msb = 0;
long lsb = 0;
assert uuid.length == 16;
for (int i = 0; i < 8; i++)
msb = (msb << 8) | (uuid[i] & 0xff);
for (int i = 8; i < 16; i++)
lsb = (lsb << 8) | (uuid[i] & 0xff);
return new UUID(msb, lsb);
}
/**
* Efficiently constructs a uuid from a bytes array without creating any intermediate objects
*
* @param uuid The bytes representing the uuid.
* @return A uuid object
* @deprecated use {@link #uuidFromBytes(byte[])} instead
*/
@Deprecated
public static UUID timeUuidFromBytes(byte[] uuid) {
return uuidFromBytes(uuid);
}
/**
* Createa a UTF-8 representation of a uuid from a bytes array
* @param uuid The bytes representing the uuid.
* @return A string representation of the uuid
*/
public static String utf8UuidFromBytes(byte[] uuid) {
return uuidFromBytes(uuid).toString();
}
/**
* Createa a UTF-8 representation of a uuid from a bytes array
* @param uuid The bytes representing the uuid.
* @return A string representation of the uuid
* @deprecated use {@link #utf8UuidFromBytes(byte[])} instead
*/
@Deprecated
public static String utf8TimeUuidFromBytes(byte[] uuid) {
return utf8UuidFromBytes(uuid);
}
/**
* Converts the backing array to the appropriate object instance handling nulls.
* <p/>
* <p>Note: we could potentially depend on the {@link org.apache.cassandra.utils.ByteBufferUtil#string(java.nio.ByteBuffer, java.nio.charset.Charset)}.
* Is it a public API?
*
* @return the deserialized instance or null if the backing array was null
*/
public String toUTF8() {
if (isNull()) return null;
try {
bytes.reset();
return new String(this.bytes.array(), this.bytes.position(), this.bytes.remaining(), BufferHelper.UTF8);
} finally {
this.bytes.reset();
}
}
/**
* Convert the byte buffer to a UTF-8 string. The byte buffer will maintain it's original
* {@link java.nio.ByteBuffer#position()}.
*
* @param bytes The UTF-8 string, encoded as raw bytes
* @return The UTF-8 string object represented by the byte array
*/
public static String toUTF8(ByteBuffer bytes) {
if (bytes == null)
return null;
int position = bytes.position();
try {
return new String(bytes.array(), position, bytes.remaining(), BufferHelper.UTF8);
} finally {
bytes.position(position);
}
}
/**
* Convert a raw byte array to a UTF-8 string
*
* @param bytes The UTF-8 string, encoded as raw bytes
* @return The UTF-8 string object represented by the byte array
*/
public static String toUTF8(byte[] bytes) {
if (bytes == null)
return null;
return new String(bytes, BufferHelper.UTF8);
}
/**
* Transforms the provided list of {@link Bytes} instances into a list of byte arrays.
*
* @param arrays the list of Bytes instances
* @return the list of byte arrays
*/
public static Set<ByteBuffer> transformBytesToSet(Collection<Bytes> arrays) {
if (arrays == null) return null;
Set<ByteBuffer> transformed = new HashSet<ByteBuffer>(arrays.size());
for (Bytes array : arrays) {
transformed.add(array.getBytes());
}
return transformed;
}
/**
* Transforms the provided list of {@link Bytes} instances into a list of byte arrays.
*
* @param arrays the list of Bytes instances
* @return the list of byte arrays
*/
public static List<ByteBuffer> transformBytesToList(Collection<Bytes> arrays) {
if (arrays == null) return null;
List<ByteBuffer> transformed = new ArrayList<ByteBuffer>(arrays.size());
for (Bytes array : arrays) {
transformed.add(array.getBytes());
}
return transformed;
}
/**
* Transforms the provided list of {@link String} instances into a list of byte arrays.
*
* @param strings the list of String instances
* @return the list of byte arrays
*/
public static Set<ByteBuffer> transformUTF8ToSet(Collection<String> strings) {
if (strings == null) return null;
Set<ByteBuffer> transformed = new HashSet<ByteBuffer>(strings.size());
for (String string : strings) {
transformed.add(Bytes.fromUTF8(string).getBytes());
}
return transformed;
}
/**
* Transforms the provided list of {@link String} instances into a list of byte arrays.
*
* @param strings the list of String instances
* @return the list of byte arrays
*/
public static List<ByteBuffer> transformUTF8ToList(Collection<String> strings) {
if (strings == null) return null;
List<ByteBuffer> transformed = new ArrayList<ByteBuffer>(strings.size());
for (String string : strings) {
transformed.add(Bytes.fromUTF8(string).getBytes());
}
return transformed;
}
/**
* Returns the underlying byte array of the provided bytes instance or null if the provided instance was null.
*
* @param bytes the bytes instance
* @return the underlying byte array of the instance or null
*/
public static ByteBuffer nullSafeGet(Bytes bytes) {
return bytes == null ? null : bytes.getBytes();
}
/**
* Helper used to determine if the underlying {@link ByteBuffer} is null.
*
* @return true if null, otherwise false
*/
public boolean isNull() {
return this.bytes == null;
}
/**
* Creates an instance of {@link CompositeBuilder} and assumes that the composite will be made up of two parts.
* @return the composite composite
* @deprecated Deprecated in {@link org.scale7.cassandra.pelops.types.CompositeType}. NOTE: This method generates composites that are not compatible with the official Cassandra {@link org.scale7.cassandra.pelops.types.CompositeType composite type}.
*/
public static CompositeBuilder composite() {
return new CompositeBuilder(2);
}
/**
* Creates an instance of {@link CompositeBuilder} with a specified number of parts.
* @param parts the number of parts the composite will be created from
* @return the composite
* @deprecated Deprecated in {@link org.scale7.cassandra.pelops.types.CompositeType}. NOTE: This method generates composites that are not compatible with the official Cassandra {@link org.scale7.cassandra.pelops.types.CompositeType composite type}.
* */
public static CompositeBuilder composite(int parts) {
return new CompositeBuilder(parts);
}
/**
* A composite that's used to create instance of composite keys.
* @deprecated Deprecated in {@link org.scale7.cassandra.pelops.types.CompositeType}. NOTE: This class generates composites that are not compatible with the official Cassandra {@link org.scale7.cassandra.pelops.types.CompositeType composite type}.
*/
public static class CompositeBuilder {
private List<ByteBuffer> parts;
private int length;
public CompositeBuilder(int count) {
parts = new ArrayList<ByteBuffer>(count);
}
public CompositeBuilder addByteBuffer(ByteBuffer value) {
parts.add(value);
length += value.rewind().remaining();
return this;
}
public CompositeBuilder addBytes(Bytes value) {
return addByteBuffer(value.getBytes());
}
public CompositeBuilder addBoolean(boolean value) {
return addByteBuffer(BufferHelper.fromBoolean(value));
}
public CompositeBuilder addBoolean(Boolean value) {
return addByteBuffer(BufferHelper.fromBoolean(value));
}
public CompositeBuilder addByte(byte value) {
return addByteBuffer(BufferHelper.fromByte(value));
}
public CompositeBuilder addByte(Byte value) {
return addByteBuffer(BufferHelper.fromByte(value));
}
public CompositeBuilder addByteArray(byte[] value) {
return addByteBuffer(BufferHelper.fromByteArray(value));
}
public CompositeBuilder addChar(char value) {
return addByteBuffer(BufferHelper.fromChar(value));
}
public CompositeBuilder addChar(Character value) {
return addByteBuffer(BufferHelper.fromChar(value));
}
public CompositeBuilder addDouble(double value) {
return addByteBuffer(BufferHelper.fromDouble(value));
}
public CompositeBuilder addDouble(Double value) {
return addByteBuffer(BufferHelper.fromDouble(value));
}
public CompositeBuilder addFloat(float value) {
return addByteBuffer(BufferHelper.fromFloat(value));
}
public CompositeBuilder addFloat(Float value) {
return addByteBuffer(BufferHelper.fromFloat(value));
}
public CompositeBuilder addInt(int value) {
return addByteBuffer(BufferHelper.fromInt(value));
}
public CompositeBuilder addInt(Integer value) {
return addByteBuffer(BufferHelper.fromInt(value));
}
public CompositeBuilder addLong(long value) {
return addByteBuffer(BufferHelper.fromLong(value));
}
public CompositeBuilder addLong(Long value) {
return addByteBuffer(BufferHelper.fromLong(value));
}
public CompositeBuilder addShort(short value) {
return addByteBuffer(BufferHelper.fromShort(value));
}
public CompositeBuilder addShort(Short value) {
return addByteBuffer(BufferHelper.fromShort(value));
}
public CompositeBuilder addUTF8(String str) {
return addByteBuffer(BufferHelper.fromUTF8(str));
}
public CompositeBuilder addUuid(UUID value) {
return addByteBuffer(BufferHelper.fromUuid(value));
}
public CompositeBuilder addUuid(String value) {
return addByteBuffer(BufferHelper.fromUuid(value));
}
public CompositeBuilder addUuid(long msb, long lsb) {
return addByteBuffer(BufferHelper.fromUuid(msb, lsb));
}
public CompositeBuilder addTimeUuid(com.eaio.uuid.UUID value) {
return addByteBuffer(BufferHelper.fromUuid(value.getTime(), value.getClockSeqAndNode()));
}
/** @deprecated use {@link #addUuid(UUID)} instead */
@Deprecated
public CompositeBuilder addTimeUuid(UUID value) {
return addUuid(value);
}
/** @deprecated use {@link #addUuid(String)} instead */
@Deprecated
public CompositeBuilder addTimeUuid(String value) {
return addUuid(value);
}
/** @deprecated use {@link #addUuid(long, long)} instead */
@Deprecated
public CompositeBuilder addTimeUuid(long time, long clockSeqAndNode) {
return addUuid(time, clockSeqAndNode);
}
public Bytes build() {
final ByteBuffer buffer = ByteBuffer.allocate(length);
for (ByteBuffer part : parts) {
buffer.put(part);
}
return new Bytes(buffer, false);
}
}
/**
* Encapsulates ByteBuffer allocation.
*/
public static class BufferHelper {
static final int SIZEOF_BYTE = Byte.SIZE / Byte.SIZE;
static final int SIZEOF_BOOLEAN = SIZEOF_BYTE;
static final byte BOOLEAN_TRUE = (byte)1;
static final byte BOOLEAN_FALSE = (byte)0;
static final int SIZEOF_CHAR = Character.SIZE / Byte.SIZE;
static final int SIZEOF_SHORT = Short.SIZE / Byte.SIZE;
static final int SIZEOF_INT = Integer.SIZE / Byte.SIZE;
static final int SIZEOF_LONG = Long.SIZE / Byte.SIZE;
static final int SIZEOF_FLOAT = Float.SIZE / Byte.SIZE;
static final int SIZEOF_DOUBLE = Double.SIZE / Byte.SIZE;
static final int SIZEOF_UUID = SIZEOF_LONG + SIZEOF_LONG;
public static final Charset UTF8 = Charset.forName("UTF-8");
// Utility class
private BufferHelper(){}
public static ByteBuffer fromByteArray(byte[] value) {
return ByteBuffer.wrap(value);
}
public static ByteBuffer fromChar(char value) {
return ByteBuffer.allocate(SIZEOF_CHAR).putChar(value);
}
public static ByteBuffer fromByte(byte value) {
return ByteBuffer.allocate(SIZEOF_BYTE).put(value);
}
public static ByteBuffer fromLong(long value) {
return ByteBuffer.allocate(SIZEOF_LONG).putLong(value);
}
public static ByteBuffer fromInt(int value) {
return ByteBuffer.allocate(SIZEOF_INT).putInt(value);
}
public static ByteBuffer fromShort(short value) {
return ByteBuffer.allocate(SIZEOF_SHORT).putShort(value);
}
public static ByteBuffer fromDouble(double value) {
return ByteBuffer.allocate(SIZEOF_DOUBLE).putDouble(value);
}
public static ByteBuffer fromFloat(float value) {
return ByteBuffer.allocate(SIZEOF_FLOAT).putFloat(value);
}
public static ByteBuffer fromBoolean(boolean value) {
return ByteBuffer.allocate(SIZEOF_BOOLEAN).put(value ? BOOLEAN_TRUE : BOOLEAN_FALSE);
}
public static ByteBuffer fromUuid(UUID value) {
return fromUuid(value.getMostSignificantBits(), value.getLeastSignificantBits());
}
public static ByteBuffer fromUuid(String value) {
return fromUuid(UUID.fromString(value));
}
public static ByteBuffer fromUuid(long msb, long lsb) {
return ByteBuffer.allocate(SIZEOF_UUID).putLong(msb).putLong(lsb);
}
public static ByteBuffer fromUTF8(String value) {
return fromByteArray(value.getBytes(UTF8));
}
}
}