Instruction:
作为 Java 安全专家，检测此代码中的安全漏洞：
## 内容1
### 文件路径：
client/src/com/aerospike/client/Value.java
### 代码内容：
package com.aerospike.client;

import java.io.ByteArrayOutputStream;
import java.io.ObjectOutputStream;
import java.nio.ByteBuffer;
import java.util.Arrays;
import java.util.List;
import java.util.Map;
import java.util.Map.Entry;
import java.util.SortedMap;
import java.util.UUID;

import org.luaj.vm2.LuaBoolean;
import org.luaj.vm2.LuaDouble;
import org.luaj.vm2.LuaInteger;
import org.luaj.vm2.LuaNil;
import org.luaj.vm2.LuaString;
import org.luaj.vm2.LuaValue;

import com.aerospike.client.cdt.MapOrder;
import com.aerospike.client.command.Buffer;
import com.aerospike.client.command.ParticleType;
import com.aerospike.client.lua.LuaBytes;
import com.aerospike.client.lua.LuaInstance;
import com.aerospike.client.util.Packer;

/**
 * Polymorphic value classes used to efficiently serialize objects into the wire protocol.
 */
public abstract class Value {
	/**
	 * Should client send boolean particle type for a boolean bin.  If false,
	 * an integer particle type (1 or 0) is sent instead. Must be false for server
	 * versions less than 5.6 which do not support boolean bins. Can set to true for
	 * server 5.6+.
	 */
	public static boolean UseBoolBin = false;

	/**
	 * Null value.
	 */
	public static final Value NULL = NullValue.INSTANCE;

	/**
	 * Infinity value to be used in CDT range comparisons only.
	 */
	public static final Value INFINITY = new InfinityValue();

	/**
	 * Wildcard value to be used in CDT range comparisons only.
	 */
	public static final Value WILDCARD = new WildcardValue();

	/**
	 * Get string or null value instance.
	 */
	public static Value get(String value) {
		return (value == null)? NullValue.INSTANCE : new StringValue(value);
	}

	/**
	 * Get byte array or null value instance.
	 */
	public static Value get(byte[] value) {
		return (value == null)? NullValue.INSTANCE : new BytesValue(value);
	}

	/**
	 * Get byte array with type or null value instance.
	 */
	public static Value get(byte[] value, int type) {
		return (value == null)? NullValue.INSTANCE : new BytesValue(value, type);
	}

	/**
	 * Get byte segment or null value instance.
	 */
	public static Value get(byte[] value, int offset, int length) {
		return (value == null)? NullValue.INSTANCE : new ByteSegmentValue(value, offset, length);
	}

	/**
	 * Get byte segment or null value instance.
	 */
	public static Value get(ByteBuffer bb) {
		return (bb == null)? NullValue.INSTANCE : new BytesValue(bb.array());
	}

	/**
	 * Get byte value instance.
	 */
	public static Value get(byte value) {
		return new ByteValue(value);
	}

	/**
	 * Get integer value instance.
	 */
	public static Value get(int value) {
		return new IntegerValue(value);
	}

	/**
	 * Get long value instance.
	 */
	public static Value get(long value) {
		return new LongValue(value);
	}

	/**
	 * Get double value instance.
	 */
	public static Value get(double value) {
		return new DoubleValue(value);
	}

	/**
	 * Get float value instance.
	 */
	public static Value get(float value) {
		return new FloatValue(value);
	}

	/**
	 * Get boolean value instance.
	 */
	public static Value get(boolean value) {
		if (UseBoolBin) {
			return new BooleanValue(value);
		}
		else {
			return new BoolIntValue(value);
		}
	}

	/**
	 * Get enum value string instance.
	 */
	public static Value get(Enum<?> value) {
		return (value == null)? NullValue.INSTANCE : new StringValue(value.toString());
	}

	/**
	 * Get UUID value string instance.
	 */
	public static Value get(UUID value) {
		return (value == null)? NullValue.INSTANCE : new StringValue(value.toString());
	}

	/**
	 * Get list or null value instance.
	 */
	public static Value get(List<?> value) {
		return (value == null)? NullValue.INSTANCE : new ListValue(value);
	}

	/**
	 * Get map or null value instance.
	 */
	public static Value get(Map<?,?> value) {
		return (value == null)? NullValue.INSTANCE : new MapValue(value);
	}

	/**
	 * Get map or null value instance.
	 */
	public static Value get(Map<?,?> value, MapOrder order) {
		return (value == null)? NullValue.INSTANCE : new MapValue(value, order);
	}

	/**
	 * Get sorted map or null value instance.
	 */
	public static Value get(List<? extends Entry<?,?>> value, MapOrder mapOrder) {
		return (value == null)? NullValue.INSTANCE : new SortedMapValue(value, mapOrder);
	}

	/**
	 * Get value array instance.
	 */
	public static Value get(Value[] value) {
		return (value == null)? NullValue.INSTANCE : new ValueArray(value);
	}

	/**
	 * Get blob or null value instance.
	 */
	public static Value getAsBlob(Object value) {
		return (value == null)? NullValue.INSTANCE : new BlobValue(value);
	}

	/**
	 * Get GeoJSON or null value instance.
	 */
	public static Value getAsGeoJSON(String value) {
		return (value == null)? NullValue.INSTANCE : new GeoJSONValue(value);
	}

	/**
	 * Get HyperLogLog or null value instance.
	 */
	public static Value getAsHLL(byte[] value) {
		return (value == null)? NullValue.INSTANCE : new HLLValue(value);
	}

	/**
	 * Get null value instance.
	 */
	public static Value getAsNull() {
		return NullValue.INSTANCE;
	}

	/**
	 * Determine value given generic object.
	 * This is the slowest of the Value get() methods.
	 * Useful when copying records from one cluster to another.
	 */
	public static Value get(Object value) {
		if (value == null) {
			return NullValue.INSTANCE;
		}

		if (value instanceof Value) {
			return (Value)value;
		}

		if (value instanceof byte[]) {
			return new BytesValue((byte[])value);
		}

		if (value instanceof String) {
			return new StringValue((String)value);
		}

		if (value instanceof Integer) {
			return new IntegerValue((Integer)value);
		}

		if (value instanceof Long) {
			return new LongValue((Long)value);
		}

		if (value instanceof Double) {
			return new DoubleValue((Double)value);
		}

		if (value instanceof Float) {
			return new FloatValue((Float)value);
		}

		if (value instanceof Boolean) {
			if (UseBoolBin) {
				return new BooleanValue((Boolean)value);
			}
			else {
				return new BoolIntValue((Boolean)value);
			}
		}

		if (value instanceof Byte) {
			return new ByteValue((byte)value);
		}

		if (value instanceof Enum) {
        	return new StringValue(value.toString());
		}

		if (value instanceof UUID) {
			return new StringValue(value.toString());
		}

		if (value instanceof List<?>) {
			return new ListValue((List<?>)value);
		}

		if (value instanceof Map<?,?>) {
			return new MapValue((Map<?,?>)value);
		}

		if (value instanceof ByteBuffer) {
			ByteBuffer bb = (ByteBuffer)value;
			return new BytesValue(bb.array());
		}

		return new BlobValue(value);
	}

	/**
	 * Get value from Record object. Useful when copying records from one cluster to another.
	 * @deprecated
	 * <p> Use {@link Value#get(Object)} instead.
	 */
	@Deprecated
	public static Value getFromRecordObject(Object value) {
		return Value.get(value);
	}

	/**
	 * Calculate number of bytes necessary to serialize the value in the wire protocol.
	 */
	public abstract int estimateSize() throws AerospikeException;

	/**
	 * Serialize the value in the wire protocol.
	 */
	public abstract int write(byte[] buffer, int offset) throws AerospikeException;

	/**
	 * Serialize the value using MessagePack.
	 */
	public abstract void pack(Packer packer);

	/**
	 * Validate if value type can be used as a key.
	 * @throws AerospikeException	if type can't be used as a key.
	 */
	public void validateKeyType() throws AerospikeException {
	}

	/**
	 * Get wire protocol value type.
	 */
	public abstract int getType();

	/**
	 * Return original value as an Object.
	 */
	public abstract Object getObject();

	/**
	 * Return value as an Object.
	 */
	public abstract LuaValue getLuaValue(LuaInstance instance);

	/**
	 * Return value as an integer.
	 */
	public int toInteger() {
		return 0;
	}

	/**
	 * Return value as a long.
	 */
	public long toLong() {
		return 0;
	}

	/**
	 * Empty value.
	 */
	public static final class NullValue extends Value {
		public static final NullValue INSTANCE = new NullValue();

		@Override
		public int estimateSize() {
			return 0;
		}

		@Override
		public int write(byte[] buffer, int offset) {
			return 0;
		}

		@Override
		public void pack(Packer packer) {
			packer.packNil();
		}

		@Override
		public void validateKeyType() {
			throw new AerospikeException(ResultCode.PARAMETER_ERROR, "Invalid key type: null");
		}

		@Override
		public int getType() {
			return ParticleType.NULL;
		}

		@Override
		public Object getObject() {
			return null;
		}

		@Override
		public LuaValue getLuaValue(LuaInstance instance) {
			return LuaNil.NIL;
		}

		@Override
		public String toString() {
			return null;
		}

		@Override
		public boolean equals(Object other) {
			if (other == null) {
				return true;
			}
			return this.getClass().equals(other.getClass());
		}

		@Override
		public final int hashCode() {
			return 0;
		}
	}

	/**
	 * Byte array value.
	 */
	public static final class BytesValue extends Value {
		private final byte[] bytes;
		private final int type;

		public BytesValue(byte[] bytes) {
			this.bytes = bytes;
			this.type = ParticleType.BLOB;
		}

		public BytesValue(byte[] bytes, int type) {
			this.bytes = bytes;
			this.type = type;
		}

		@Override
		public int estimateSize() {
			return bytes.length;
		}

		@Override
		public int write(byte[] buffer, int offset) {
			System.arraycopy(bytes, 0, buffer, offset, bytes.length);
			return bytes.length;
		}

		@Override
		public void pack(Packer packer) {
			packer.packParticleBytes(bytes, type);
		}

		@Override
		public int getType() {
			return type;
		}

		@Override
		public Object getObject() {
			return bytes;
		}

		@Override
		public LuaValue getLuaValue(LuaInstance instance) {
			return new LuaBytes(instance, bytes, type);
		}

		@Override
		public String toString() {
			return Buffer.bytesToHexString(bytes);
		}

		@Override
		public boolean equals(Object other) {
			return (other != null &&
				this.getClass().equals(other.getClass()) &&
				Arrays.equals(this.bytes, ((BytesValue)other).bytes));
		}

		@Override
		public int hashCode() {
			return Arrays.hashCode(bytes);
		}
	}

	/**
	 * Byte segment value.
	 */
	public static final class ByteSegmentValue extends Value {
		private final byte[] bytes;
		private final int offset;
		private final int length;

		public ByteSegmentValue(byte[] bytes, int offset, int length) {
			this.bytes = bytes;
			this.offset = offset;
			this.length = length;
		}

		@Override
		public int estimateSize() {
			return length;

		}

		@Override
		public int write(byte[] buffer, int targetOffset) {
			System.arraycopy(bytes, offset, buffer, targetOffset, length);
			return length;
		}

		@Override
		public void pack(Packer packer) {
			packer.packParticleBytes(bytes, offset, length);
		}

		@Override
		public int getType() {
			return ParticleType.BLOB;
		}

		@Override
		public Object getObject() {
			return this;
		}

		@Override
		public LuaValue getLuaValue(LuaInstance instance) {
			return LuaString.valueOf(bytes, offset, length);
		}

		@Override
		public String toString() {
			return Buffer.bytesToHexString(bytes, offset, length);
		}

		@Override
		public boolean equals(Object obj) {
			if (obj == null) {
				return false;
			}

			if (! this.getClass().equals(obj.getClass())) {
				return false;
			}
			ByteSegmentValue other = (ByteSegmentValue)obj;

			if (this.length != other.length) {
				return false;
			}

			for (int i = 0; i < length; i++) {
				if (this.bytes[this.offset + i] != other.bytes[other.offset + i]) {
					return false;
				}
			}
			return true;
		}

		@Override
		public int hashCode() {
			int result = 1;
			for (int i = 0; i < length; i++) {
				result = 31 * result + bytes[offset+i];
			}
			return result;
		}

		public byte[] getBytes() {
			return bytes;
		}

		public int getOffset() {
			return offset;
		}

		public int getLength() {
			return length;
		}
	}

	/**
	 * Byte value.
	 */
	public static final class ByteValue extends Value {
		private final byte value;

		public ByteValue(byte value) {
			this.value = value;
		}

		@Override
		public int estimateSize() {
			return 8;
		}

		@Override
		public int write(byte[] buffer, int offset) {
			Buffer.longToBytes(value, buffer, offset);
			return 8;
		}

		@Override
		public void pack(Packer packer) {
			packer.packByte(value);
		}

		@Override
		public int getType() {
			// The server does not natively handle one byte, so store as long (8 byte integer).
			return ParticleType.INTEGER;
		}

		@Override
		public Object getObject() {
			return value;
		}

		@Override
		public LuaValue getLuaValue(LuaInstance instance) {
			return LuaInteger.valueOf(value);
		}

		@Override
		public String toString() {
			return Byte.toString(value);
		}

		@Override
		public boolean equals(Object other) {
			return (other != null &&
				this.getClass().equals(other.getClass()) &&
				this.value == ((ByteValue)other).value);
		}

		@Override
		public int hashCode() {
			return value;
		}

		@Override
		public int toInteger() {
			return value;
		}

		@Override
		public long toLong() {
			return value;
		}
	}

	/**
	 * String value.
	 */
	public static final class StringValue extends Value {
		private final String value;

		public StringValue(String value) {
			this.value = value;
		}

		@Override
		public int estimateSize() {
			return Buffer.estimateSizeUtf8(value);
		}

		@Override
		public int write(byte[] buffer, int offset) {
			return Buffer.stringToUtf8(value, buffer, offset);
		}

		@Override
		public void pack(Packer packer) {
			packer.packParticleString(value);
		}

		@Override
		public int getType() {
			return ParticleType.STRING;
		}

		@Override
		public Object getObject() {
			return value;
		}

		@Override
		public LuaValue getLuaValue(LuaInstance instance) {
			return LuaString.valueOf(value);
		}

		@Override
		public String toString() {
			return value;
		}

		@Override
		public boolean equals(Object other) {
			return (other != null &&
				this.getClass().equals(other.getClass()) &&
				this.value.equals(((StringValue)other).value));
		}

		@Override
		public int hashCode() {
			return value.hashCode();
		}
	}

	/**
	 * Integer value.
	 */
	public static final class IntegerValue extends Value {
		private final int value;

		public IntegerValue(int value) {
			this.value = value;
		}

		@Override
		public int estimateSize() {
			return 8;
		}

		@Override
		public int write(byte[] buffer, int offset) {
			Buffer.longToBytes(value, buffer, offset);
			return 8;
		}

		@Override
		public void pack(Packer packer) {
			packer.packInt(value);
		}

		@Override
		public int getType() {
			return ParticleType.INTEGER;
		}

		@Override
		public Object getObject() {
			return value;
		}

		@Override
		public LuaValue getLuaValue(LuaInstance instance) {
			return LuaInteger.valueOf(value);
		}

		@Override
		public String toString() {
			return Integer.toString(value);
		}

		@Override
		public boolean equals(Object other) {
			return (other != null &&
				this.getClass().equals(other.getClass()) &&
				this.value == ((IntegerValue)other).value);
		}

		@Override
		public int hashCode() {
			return value;
		}

		@Override
		public int toInteger() {
			return value;
		}

		@Override
		public long toLong() {
			return value;
		}
	}

	/**
	 * Long value.
	 */
	public static final class LongValue extends Value {
		private final long value;

		public LongValue(long value) {
			this.value = value;
		}

		@Override
		public int estimateSize() {
			return 8;
		}

		@Override
		public int write(byte[] buffer, int offset) {
			Buffer.longToBytes(value, buffer, offset);
			return 8;
		}

		@Override
		public void pack(Packer packer) {
			packer.packLong(value);
		}

		@Override
		public int getType() {
			return ParticleType.INTEGER;
		}

		@Override
		public Object getObject() {
			return value;
		}

		@Override
		public LuaValue getLuaValue(LuaInstance instance) {
			return LuaInteger.valueOf(value);
		}

		@Override
		public String toString() {
			return Long.toString(value);
		}

		@Override
		public boolean equals(Object other) {
			return (other != null &&
				this.getClass().equals(other.getClass()) &&
				this.value == ((LongValue)other).value);
		}

		@Override
		public int hashCode() {
			return (int)(value ^ (value >>> 32));
		}

		@Override
		public int toInteger() {
			return (int)value;
		}

		@Override
		public long toLong() {
			return value;
		}
	}

	/**
	 * Double value.
	 */
	public static final class DoubleValue extends Value {
		private final double value;

		public DoubleValue(double value) {
			this.value = value;
		}

		@Override
		public int estimateSize() {
			return 8;
		}

		@Override
		public int write(byte[] buffer, int offset) {
			Buffer.doubleToBytes(value, buffer, offset);
			return 8;
		}

		@Override
		public void pack(Packer packer) {
			packer.packDouble(value);
		}

		@Override
		public int getType() {
			return ParticleType.DOUBLE;
		}

		@Override
		public Object getObject() {
			return value;
		}

		@Override
		public LuaValue getLuaValue(LuaInstance instance) {
			return LuaDouble.valueOf(value);
		}

		@Override
		public String toString() {
			return Double.toString(value);
		}

		@Override
		public boolean equals(Object other) {
			return (other != null &&
				this.getClass().equals(other.getClass()) &&
				this.value == ((DoubleValue)other).value);
		}

		@Override
		public int hashCode() {
			long bits = Double.doubleToLongBits(value);
			return (int)(bits ^ (bits >>> 32));
		}

		@Override
		public int toInteger() {
			return (int)value;
		}

		@Override
		public long toLong() {
			return (long)value;
		}
	}

	/**
	 * Float value.
	 */
	public static final class FloatValue extends Value {
		private final float value;

		public FloatValue(float value) {
			this.value = value;
		}

		@Override
		public int estimateSize() {
			return 8;
		}

		@Override
		public int write(byte[] buffer, int offset) {
			Buffer.doubleToBytes(value, buffer, offset);
			return 8;
		}

		@Override
		public void pack(Packer packer) {
			packer.packFloat(value);
		}

		@Override
		public int getType() {
			return ParticleType.DOUBLE;
		}

		@Override
		public Object getObject() {
			return value;
		}

		@Override
		public LuaValue getLuaValue(LuaInstance instance) {
			return LuaDouble.valueOf(value);
		}

		@Override
		public String toString() {
			return Float.toString(value);
		}

		@Override
		public boolean equals(Object other) {
			return (other != null &&
				this.getClass().equals(other.getClass()) &&
				this.value == ((FloatValue)other).value);
		}

		@Override
		public int hashCode() {
			return Float.floatToIntBits(value);
		}

		@Override
		public int toInteger() {
			return (int)value;
		}

		@Override
		public long toLong() {
			return (long)value;
		}
	}

	/**
	 * Boolean value.
	 */
	public static final class BooleanValue extends Value {
		private final boolean value;

		public BooleanValue(boolean value) {
			this.value = value;
		}

		@Override
		public int estimateSize() {
			return 1;
		}

		@Override
		public int write(byte[] buffer, int offset) {
			buffer[offset] = value? (byte)1 : (byte)0;
			return 1;
		}

		@Override
		public void pack(Packer packer) {
			packer.packBoolean(value);
		}

		@Override
		public void validateKeyType() {
			throw new AerospikeException(ResultCode.PARAMETER_ERROR, "Invalid key type: boolean");
		}

		@Override
		public int getType() {
			return ParticleType.BOOL;
		}

		@Override
		public Object getObject() {
			return value;
		}

		@Override
		public LuaValue getLuaValue(LuaInstance instance) {
			return LuaBoolean.valueOf(value);
		}

		@Override
		public String toString() {
			return Boolean.toString(value);
		}

		@Override
		public boolean equals(Object other) {
			return (other != null &&
				this.getClass().equals(other.getClass()) &&
				this.value == ((BooleanValue)other).value);
		}

		@Override
		public int hashCode() {
			return value ? 1231 : 1237;
		}

		@Override
		public int toInteger() {
			return value? 1 : 0;
		}

		@Override
		public long toLong() {
			return value? 1L : 0L;
		}
	}

	/**
	 * Boolean value that converts to integer when sending a bin to the server.
	 * This class will be deleted once full conversion to boolean particle type
	 * is complete.
	 */
	public static final class BoolIntValue extends Value {
		private final boolean value;

		public BoolIntValue(boolean value) {
			this.value = value;
		}

		@Override
		public int estimateSize() {
			return 8;
		}

		@Override
		public int write(byte[] buffer, int offset) {
			Buffer.longToBytes(value? 1L : 0L, buffer, offset);
			return 8;
		}

		@Override
		public void pack(Packer packer) {
			packer.packBoolean(value);
		}

		@Override
		public void validateKeyType() {
			throw new AerospikeException(ResultCode.PARAMETER_ERROR, "Invalid key type: BoolIntValue");
		}

		@Override
		public int getType() {
			// The server does not natively handle boolean, so store as long (8 byte integer).
			return ParticleType.INTEGER;
		}

		@Override
		public Object getObject() {
			return value;
		}

		@Override
		public LuaValue getLuaValue(LuaInstance instance) {
			return LuaBoolean.valueOf(value);
		}

		@Override
		public String toString() {
			return Boolean.toString(value);
		}

		@Override
		public boolean equals(Object other) {
			return (other != null &&
				this.getClass().equals(other.getClass()) &&
				this.value == ((BoolIntValue)other).value);
		}

		@Override
		public int hashCode() {
			return value ? 1231 : 1237;
		}

		@Override
		public int toInteger() {
			return value? 1 : 0;
		}

		@Override
		public long toLong() {
			return value? 1L : 0L;
		}
	}

	/**
	 * Blob value.
	 */
	public static final class BlobValue extends Value {
		private final Object object;
		private byte[] bytes;

		public BlobValue(Object object) {
			this.object = object;
		}

		@Override
		public int estimateSize() throws AerospikeException.Serialize {
			try {
				ByteArrayOutputStream bstream = new ByteArrayOutputStream();
				ObjectOutputStream ostream = new ObjectOutputStream(bstream);
				ostream.writeObject(object);
				ostream.close();
				bytes = bstream.toByteArray();
				return bytes.length;
			}
			catch (Exception e) {
				throw new AerospikeException.Serialize(e);
			}
		}

		@Override
		public int write(byte[] buffer, int offset) {
			System.arraycopy(bytes, 0, buffer, offset, bytes.length);
			return bytes.length;
		}

		@Override
		public void pack(Packer packer) {
			packer.packBlob(object);
		}

		@Override
		public void validateKeyType() {
			throw new AerospikeException(ResultCode.PARAMETER_ERROR, "Invalid key type: jblob");
		}

		@Override
		public int getType() {
			return ParticleType.JBLOB;
		}

		@Override
		public Object getObject() {
			return object;
		}

		@Override
		public LuaValue getLuaValue(LuaInstance instance) {
			return LuaString.valueOf(bytes);
		}

		@Override
		public String toString() {
			return Buffer.bytesToHexString(bytes);
		}

		@Override
		public boolean equals(Object other) {
			return (other != null &&
				this.getClass().equals(other.getClass()) &&
				this.object.equals(((BlobValue)other).object));
		}

		@Override
		public int hashCode() {
			return object.hashCode();
		}
	}

	/**
	 * GeoJSON value.
	 */
	public static final class GeoJSONValue extends Value {
		private final String value;

		public GeoJSONValue(String value) {
			this.value = value;
		}

		@Override
		public int estimateSize() {
			// flags + ncells + jsonstr
			return 1 + 2 + Buffer.estimateSizeUtf8(value);
		}

		@Override
		public int write(byte[] buffer, int offset) {
			buffer[offset] = 0; // flags
			Buffer.shortToBytes(0, buffer, offset + 1); // ncells
			return 1 + 2 + Buffer.stringToUtf8(value, buffer, offset + 3); // jsonstr
		}

		@Override
		public void pack(Packer packer) {
			packer.packGeoJSON(value);
		}

		@Override
		public void validateKeyType() {
			throw new AerospikeException(ResultCode.PARAMETER_ERROR, "Invalid key type: GeoJson");
		}

		@Override
		public int getType() {
			return ParticleType.GEOJSON;
		}

		@Override
		public Object getObject() {
			return value;
		}

		@Override
		public LuaValue getLuaValue(LuaInstance instance) {
			return LuaString.valueOf(value);
		}

		@Override
		public String toString() {
			return value;
		}

		@Override
		public boolean equals(Object other) {
			return (other != null &&
				this.getClass().equals(other.getClass()) &&
				this.value.equals(((GeoJSONValue)other).value));
		}

		@Override
		public int hashCode() {
			return value.hashCode();
		}
	}

	/**
	 * HyperLogLog value.
	 */
	public static final class HLLValue extends Value {
		private final byte[] bytes;

		public HLLValue(byte[] bytes) {
			this.bytes = bytes;
		}

		@Override
		public int estimateSize() {
			return bytes.length;
		}

		@Override
		public int write(byte[] buffer, int offset) {
			System.arraycopy(bytes, 0, buffer, offset, bytes.length);
			return bytes.length;
		}

		@Override
		public void pack(Packer packer) {
			packer.packParticleBytes(bytes);
		}

		@Override
		public void validateKeyType() {
			throw new AerospikeException(ResultCode.PARAMETER_ERROR, "Invalid key type: HLL");
		}

		@Override
		public int getType() {
			return ParticleType.HLL;
		}

		@Override
		public Object getObject() {
			return bytes;
		}

		public byte[] getBytes() {
			return bytes;
		}

		@Override
		public LuaValue getLuaValue(LuaInstance instance) {
			return new LuaBytes(instance, bytes);
		}

		@Override
		public String toString() {
			return Buffer.bytesToHexString(bytes);
		}

		@Override
		public boolean equals(Object other) {
			return (other != null &&
				this.getClass().equals(other.getClass()) &&
				Arrays.equals(this.bytes, ((HLLValue)other).bytes));
		}

		@Override
		public int hashCode() {
			return Arrays.hashCode(bytes);
		}
	}

	/**
	 * Value array.
	 */
	public static final class ValueArray extends Value {
		private final Value[] array;
		private byte[] bytes;

		public ValueArray(Value[] array) {
			this.array = array;
		}

		@Override
		public int estimateSize() throws AerospikeException {
			bytes = Packer.pack(array);
			return bytes.length;
		}

		@Override
		public int write(byte[] buffer, int offset) {
			System.arraycopy(bytes, 0, buffer, offset, bytes.length);
			return bytes.length;
		}

		@Override
		public void pack(Packer packer) {
			packer.packValueArray(array);
		}

		@Override
		public void validateKeyType() {
			throw new AerospikeException(ResultCode.PARAMETER_ERROR, "Invalid key type: value[]");
		}

		@Override
		public int getType() {
			return ParticleType.LIST;
		}

		@Override
		public Object getObject() {
			return array;
		}

		@Override
		public LuaValue getLuaValue(LuaInstance instance) {
			return instance.getLuaList(array);
		}

		@Override
		public String toString() {
			return Arrays.toString(array);
		}

		@Override
		public boolean equals(Object other) {
			return (other != null &&
				this.getClass().equals(other.getClass()) &&
				Arrays.equals(this.array, ((ValueArray)other).array));
		}

		@Override
		public int hashCode() {
			return Arrays.hashCode(array);
		}
	}

	/**
	 * List value.
	 */
	public static final class ListValue extends Value {
		private final List<?> list;
		private byte[] bytes;

		public ListValue(List<?> list) {
			this.list = list;
		}

		@Override
		public int estimateSize() throws AerospikeException {
			bytes = Packer.pack(list);
			return bytes.length;
		}

		@Override
		public int write(byte[] buffer, int offset) {
			System.arraycopy(bytes, 0, buffer, offset, bytes.length);
			return bytes.length;
		}

		@Override
		public void pack(Packer packer) {
			packer.packList(list);
		}

		@Override
		public void validateKeyType() {
			throw new AerospikeException(ResultCode.PARAMETER_ERROR, "Invalid key type: list");
		}

		@Override
		public int getType() {
			return ParticleType.LIST;
		}

		@Override
		public Object getObject() {
			return list;
		}

		@Override
		public LuaValue getLuaValue(LuaInstance instance) {
			return instance.getLuaList(list);
		}

		@Override
		public String toString() {
			return list.toString();
		}

		@Override
		public boolean equals(Object other) {
			return (other != null &&
				this.getClass().equals(other.getClass()) &&
				this.list.equals(((ListValue)other).list));
		}

		@Override
		public int hashCode() {
			return list.hashCode();
		}
	}

	/**
	 * Map value.
	 */
	public static final class MapValue extends Value {
		private final Map<?,?> map;
		private final MapOrder order;
		private byte[] bytes;

		public MapValue(Map<?,?> map)  {
			this.map = map;
			this.order = getMapOrder(map);
		}

		public MapValue(Map<?,?> map, MapOrder order)  {
			this.map = map;
			this.order = order;
		}

		public MapOrder getOrder() {
			return order;
		}

		@Override
		public int estimateSize() throws AerospikeException {
			bytes = Packer.pack(map, order);
			return bytes.length;
		}

		@Override
		public int write(byte[] buffer, int offset) {
			System.arraycopy(bytes, 0, buffer, offset, bytes.length);
			return bytes.length;
		}

		@Override
		public void pack(Packer packer) {
			packer.packMap(map, order);
		}

		@Override
		public void validateKeyType() {
			throw new AerospikeException(ResultCode.PARAMETER_ERROR, "Invalid key type: map");
		}

		@Override
		public int getType() {
			return ParticleType.MAP;
		}

		@Override
		public Object getObject() {
			return map;
		}

		@Override
		public LuaValue getLuaValue(LuaInstance instance) {
			return instance.getLuaMap(map);
		}

		@Override
		public String toString() {
			return map.toString();
		}

		@Override
		public boolean equals(Object other) {
			return (other != null &&
				this.getClass().equals(other.getClass()) &&
				this.map.equals(((MapValue)other).map));
		}

		@Override
		public int hashCode() {
			return map.hashCode();
		}

		public static MapOrder getMapOrder(Map<?,?> map) {
			return (map instanceof SortedMap<?,?>)? MapOrder.KEY_ORDERED : MapOrder.UNORDERED;
		}
	}

	/**
	 * Sorted map value.
	 */
	public static final class SortedMapValue extends Value {
		private final List<? extends Entry<?,?>> list;
		private byte[] bytes;
		private final MapOrder order;

		public SortedMapValue(List<? extends Entry<?,?>> list, MapOrder order)  {
			this.list = list;
			this.order = order;
		}

		@Override
		public int estimateSize() throws AerospikeException {
			bytes = Packer.pack(list, order);
			return bytes.length;
		}

		@Override
		public int write(byte[] buffer, int offset) {
			System.arraycopy(bytes, 0, buffer, offset, bytes.length);
			return bytes.length;
		}

		@Override
		public void pack(Packer packer) {
			packer.packMap(list, order);
		}

		@Override
		public void validateKeyType() {
			throw new AerospikeException(ResultCode.PARAMETER_ERROR, "Invalid key type: map");
		}

		@Override
		public int getType() {
			return ParticleType.MAP;
		}

		@Override
		public Object getObject() {
			return list;
		}

		@Override
		public LuaValue getLuaValue(LuaInstance instance) {
			return instance.getLuaList(list);
		}

		@Override
		public String toString() {
			return list.toString();
		}

		@Override
		public boolean equals(Object other) {
			if (other == null || ! this.getClass().equals(other.getClass())) {
				return false;
			}
			SortedMapValue o = (SortedMapValue)other;
			return this.order == o.order && this.list.equals(o.list);
		}

		@Override
		public int hashCode() {
			return list.hashCode();
		}
	}

	/**
	 * Infinity value.
	 */
	public static final class InfinityValue extends Value {
		@Override
		public int estimateSize() {
			return 0;
		}

		@Override
		public int write(byte[] buffer, int offset) {
			return 0;
		}

		@Override
		public void pack(Packer packer) {
			packer.packInfinity();
		}

		@Override
		public void validateKeyType() {
			throw new AerospikeException(ResultCode.PARAMETER_ERROR, "Invalid key type: INF");
		}

		@Override
		public int getType() {
			throw new AerospikeException(ResultCode.PARAMETER_ERROR, "Invalid particle type: INF");
		}

		@Override
		public Object getObject() {
			return null;
		}

		@Override
		public LuaValue getLuaValue(LuaInstance instance) {
			throw new AerospikeException(ResultCode.PARAMETER_ERROR, "Invalid lua type: INF");
		}

		@Override
		public String toString() {
			return "INF";
		}

		@Override
		public boolean equals(Object other) {
			return (other != null &&
					this.getClass().equals(other.getClass()));
		}

		@Override
		public final int hashCode() {
			return 0;
		}
	}

	/**
	 * Wildcard value.
	 */
	public static final class WildcardValue extends Value {
		@Override
		public int estimateSize() {
			return 0;
		}

		@Override
		public int write(byte[] buffer, int offset) {
			return 0;
		}

		@Override
		public void pack(Packer packer) {
			packer.packWildcard();
		}

		@Override
		public void validateKeyType() {
			throw new AerospikeException(ResultCode.PARAMETER_ERROR, "Invalid key type: wildcard");
		}

		@Override
		public int getType() {
			throw new AerospikeException(ResultCode.PARAMETER_ERROR, "Invalid particle type: wildcard");
		}

		@Override
		public Object getObject() {
			return null;
		}

		@Override
		public LuaValue getLuaValue(LuaInstance instance) {
			throw new AerospikeException(ResultCode.PARAMETER_ERROR, "Invalid lua type: wildcard");
		}

		@Override
		public String toString() {
			return "*";
		}

		@Override
		public boolean equals(Object other) {
			return (other != null &&
					this.getClass().equals(other.getClass()));
		}

		@Override
		public final int hashCode() {
			return 0;
		}
	}
}

## 内容2
### 文件路径：
client/src/com/aerospike/client/command/Buffer.java
### 代码内容：
package com.aerospike.client.command;

import java.io.ByteArrayInputStream;
import java.io.ObjectInputStream;
import java.io.UnsupportedEncodingException;
import java.math.BigInteger;
import java.util.Arrays;

import com.aerospike.client.AerospikeException;
import com.aerospike.client.Value;
import com.aerospike.client.util.Unpacker;

public final class Buffer {

	public static Value bytesToKeyValue(int type, byte[] buf, int offset, int len)
		throws AerospikeException {

		switch (type) {
		case ParticleType.STRING:
			return Value.get(Buffer.utf8ToString(buf, offset, len));

		case ParticleType.INTEGER:
			return bytesToLongValue(buf, offset, len);

		case ParticleType.DOUBLE:
			return new Value.DoubleValue(Buffer.bytesToDouble(buf, offset));

		case ParticleType.BLOB:
			return Value.get(Arrays.copyOfRange(buf, offset, offset+len));

		default:
			return null;
		}
	}

	public static Object bytesToParticle(int type, byte[] buf, int offset, int len)
		throws AerospikeException {

		switch (type) {
		case ParticleType.STRING:
			return Buffer.utf8ToString(buf, offset, len);

		case ParticleType.INTEGER:
			return Buffer.bytesToNumber(buf, offset, len);

		case ParticleType.BOOL:
			return Buffer.bytesToBool(buf, offset, len);

		case ParticleType.DOUBLE:
			return Buffer.bytesToDouble(buf, offset);

		case ParticleType.BLOB:
			return Arrays.copyOfRange(buf, offset, offset+len);

		case ParticleType.JBLOB:
			return Buffer.bytesToObject(buf, offset, len);

		case ParticleType.GEOJSON:
			return Buffer.bytesToGeoJSON(buf, offset, len);

		case ParticleType.HLL:
			return Buffer.bytesToHLL(buf, offset, len);

		case ParticleType.LIST:
			return Unpacker.unpackObjectList(buf, offset, len);

		case ParticleType.MAP:
			return Unpacker.unpackObjectMap(buf, offset, len);

		default:
			return null;
		}
	}

	/*
	private static Object parseList(byte[] buf, int offset, int len) throws AerospikeException {
		int limit = offset + len;
		int itemCount = Buffer.bytesToInt(buf, offset);
		offset += 4;
		ArrayList<Object> list = new ArrayList<Object>(itemCount);

		while (offset < limit) {
			int sz = Buffer.bytesToInt(buf, offset);
			offset += 4;
			int type = buf[offset];
			offset++;
			list.add(bytesToParticle(type, buf, offset, sz));
			offset += sz;
		}
		return list;
	}

	private static Object parseMap(byte[] buf, int offset, int len) throws AerospikeException {
		Object key;
		Object value;

		int limit = offset + len;
		int n_items = Buffer.bytesToInt(buf, offset);
		offset += 4;
		HashMap<Object, Object> map = new HashMap<Object, Object>(n_items);

		while (offset < limit) {
			// read out the key
			int sz = Buffer.bytesToInt(buf, offset);
			offset += 4;
			int type = buf[offset];
			offset++;

			key = bytesToParticle(type, buf, offset, len);
			offset += sz;

			// read out the value
			sz = Buffer.bytesToInt(buf, offset);
			offset += 4;
			type = buf[offset];
			offset++;

			value = bytesToParticle(type, buf, offset, len);
			offset += sz;

			map.put(key, value);
		}
		return map;
	}
	*/

	/**
	 * Estimate size of Utf8 encoded bytes without performing the actual encoding.
	 */
	public static int estimateSizeUtf8(String value) {
		if (value == null) {
			return 0;
		}

		int max = value.length();
		int count = 0;

		for (int i = 0; i < max; i++) {
			char ch = value.charAt(i);

			if (ch < 0x80) {
				count++;
			}
			else if (ch < 0x800) {
				count += 2;
			}
			else if (Character.isHighSurrogate(ch)) {
				count += 4;
				++i;
			} else {
				count += 3;
			}
		}
		return count;
	}

	public static byte[] stringToUtf8(String s) {
		if (s == null || s.length() == 0) {
			return new byte[0];
		}
		int size = estimateSizeUtf8(s);
		byte[] bytes = new byte[size];
		stringToUtf8(s, bytes, 0);
		return bytes;
	}

	/**
	 * Convert input string to UTF-8, copies into buffer (at given offset).
	 * Returns number of bytes in the string.
	 *
	 * Java's internal UTF8 conversion is very, very slow.
	 * This is, rather amazingly, 8x faster than the to-string method.
	 * Returns the number of bytes this translated into.
	 */
	public static int stringToUtf8(String s, byte[] buf, int offset) {
		if (s == null) {
			return 0;
		}
		int length = s.length();
		int startOffset = offset;

		for (int i = 0; i < length; i++) {
			int c = s.charAt(i);
			if (c < 0x80) {
				buf[offset++] = (byte) c;
			}
			else if (c < 0x800) {
				buf[offset++] = (byte)(0xc0 | ((c >> 6)));
				buf[offset++] = (byte)(0x80 | (c & 0x3f));
			}
			else {
				// Encountered a different encoding other than 2-byte UTF8. Let java handle it.
				try {
					byte[] value = s.getBytes("UTF8");
					System.arraycopy(value, 0, buf, startOffset, value.length);
					return value.length;
				}
				catch (UnsupportedEncodingException uee) {
					throw new RuntimeException("UTF8 encoding is not supported.");
				}
			}
		}
		return offset - startOffset;
	}

	public static String utf8ToString(byte[] buf, int offset, int length) {
		// A Thread local implementation does not help here, so
		// allocate character buffer each time.
		if (length == 0) {
			return "";
		}

		char[] charBuffer = new char[length];
		int charCount = 0;
		int limit = offset + length;
		int origoffset = offset;

		while (offset < limit ) {
			int b1 = buf[offset];

			if (b1 >= 0) {
				charBuffer[charCount++] = (char)b1;
				offset++;
			}
			else if ((b1 >> 5) == -2) {
				int b2 = buf[offset + 1];
				charBuffer[charCount++] = (char) (((b1 << 6) ^ b2) ^ 0x0f80);
				offset += 2;
			}
			else {
				// Encountered an UTF encoding which uses more than 2 bytes.
				// Use a native function to do the conversion.
				try {
					return new String(buf, origoffset, length, "UTF8");
				}
				catch (UnsupportedEncodingException uee) {
					throw new RuntimeException("UTF8 decoding is not supported.");
				}
			}
		}
		return new String(charBuffer, 0, charCount);
	}

	public static String utf8ToString(byte[] buf, int offset, int length, StringBuilder sb) {
		if (length == 0) {
			return "";
		}

		// This method is designed to accommodate multiple string conversions on the same
		// thread, but without the ThreadLocal overhead.  The StringBuilder instance is
		// created on the stack and passed in each method invocation.
		sb.setLength(0);
		int limit = offset + length;
		int origoffset = offset;

		while (offset < limit ) {
			if ((buf[offset] & 0x80) == 0) { // 1 byte
				char c = (char) buf[offset];
				sb.append(c);
				offset++;
			}
			else if ((buf[offset] & 0xE0) == 0xC0) { // 2 bytes
				char c =  (char) (((buf[offset] & 0x1f) << 6) | (buf[offset+1] & 0x3f));
				sb.append(c);
				offset += 2;
			}
			else {
				// Encountered an UTF encoding which uses more than 2 bytes.
				// Use a native function to do the conversion.
				try {
					return new String(buf, origoffset, length, "UTF8");
				}
				catch (UnsupportedEncodingException uee) {
					throw new RuntimeException("UTF8 decoding is not supported.");
				}
			}
		}
		return sb.toString();
	}

	/**
	 * Convert UTF8 numeric digits to an integer.  Negative integers are not supported.
	 *
	 * Input format: 1234
	 */
	public static int utf8DigitsToInt(byte[] buf, int begin, int end) {
		int val = 0;
		int mult = 1;

		for (int i = end - 1; i >= begin; i--) {
			val += ((int)buf[i] - 48) * mult;
			mult *= 10;
		}
		return val;
	}

	public static String bytesToHexString(byte[] buf) {
		if (buf == null || buf.length == 0) {
			return "";
		}
		StringBuilder sb = new StringBuilder(buf.length * 2);

		for (int i = 0; i < buf.length; i++) {
			sb.append(String.format("%02x", buf[i]));
		}
		return sb.toString();
	}

	public static String bytesToHexString(byte[] buf, int offset, int length) {
		StringBuilder sb = new StringBuilder(length * 2);

		for (int i = offset; i < length; i++) {
			sb.append(String.format("%02x", buf[i]));
		}
		return sb.toString();
	}

	public static Object bytesToObject(byte[] buf, int offset, int length)
		throws AerospikeException.Serialize {

		if (length <= 0) {
			return null;
		}

		try {
			ByteArrayInputStream bastream = new ByteArrayInputStream(buf, offset, length);
			ObjectInputStream oistream = new ObjectInputStream(bastream);
			return oistream.readObject();
		}
		catch (Exception e) {
			throw new AerospikeException.Serialize(e);
		}
	}

	public static Value bytesToLongValue(byte[] buf, int offset, int len) {
		long val = 0;

		for (int i = 0; i < len; i++) {
			val <<= 8;
			val |= buf[offset+i] & 0xFF;
		}

		return new Value.LongValue(val);
	}

	public static Object bytesToGeoJSON(byte[] buf, int offset, int len) {
		// Ignore the flags for now
		int ncells = bytesToShort(buf, offset + 1);
		int hdrsz = 1 + 2 + (ncells * 8);
		return Value.getAsGeoJSON(Buffer.utf8ToString(buf, offset + hdrsz, len - hdrsz));
	}

	public static Object bytesToHLL(byte[] buf, int offset, int len) {
		byte[] bytes = Arrays.copyOfRange(buf, offset, offset+len);
		return Value.getAsHLL(bytes);
	}

	public static Object bytesToNumber(byte[] buf, int offset, int len) {
		// Server always returns 8 for integer length.
		if (len == 8) {
			return bytesToLong(buf, offset);
		}

		// Handle other lengths just in case server changes.
		if (len == 0) {
			return new Long(0);
		}

		if (len == 4) {
			return new Long(bytesToInt(buf, offset));
		}

		if (len > 8) {
			return bytesToBigInteger(buf, offset, len);
		}

		// Handle variable length integer.
		long val = 0;

		for (int i = 0; i < len; i++) {
			val <<= 8;
			val |= buf[offset+i] & 0xFF;
		}
		return new Long(val);
	}

	public static Object bytesToBigInteger(byte[] buf, int offset, int len) {
		boolean negative = false;

		if ((buf[offset] & 0x80) != 0) {
			negative = true;
			buf[offset] &= 0x7f;
		}
		byte[] bytes = new byte[len];
		System.arraycopy(buf, offset, bytes, 0, len);

		BigInteger big = new BigInteger(bytes);

		if (negative) {
			big = big.negate();
		}
		return big;
	}

	public static boolean bytesToBool(byte[] buf, int offset, int len) {
		if (len <= 0) {
			return false;
		}
		return (buf[offset] == 0)? false : true;
	}

	//-------------------------------------------------------
	// 64 bit double conversions.
	//-------------------------------------------------------

	public static double bytesToDouble(byte[] buf, int offset) {
		return Double.longBitsToDouble(bytesToLong(buf, offset));
	}

	public static void doubleToBytes(double v, byte[] buf, int offset) {
		Buffer.longToBytes(Double.doubleToLongBits(v), buf, offset);
	}

	//-------------------------------------------------------
	// 64 bit number conversions.
	//-------------------------------------------------------

	/**
	 * Convert long to big endian signed or unsigned 64 bits.
	 * The bit pattern will be the same regardless of sign.
	 */
	public static void longToBytes(long v, byte[] buf, int offset) {
		buf[offset++] = (byte)(v >>> 56);
		buf[offset++] = (byte)(v >>> 48);
		buf[offset++] = (byte)(v >>> 40);
		buf[offset++] = (byte)(v >>> 32);
		buf[offset++] = (byte)(v >>> 24);
		buf[offset++] = (byte)(v >>> 16);
		buf[offset++] = (byte)(v >>>  8);
		buf[offset]   = (byte)(v >>>  0);
	}

	/**
	 * Convert long to little endian signed or unsigned 64 bits.
	 * The bit pattern will be the same regardless of sign.
	 */
	public static void longToLittleBytes(long v, byte[] buf, int offset) {
		buf[offset++] = (byte)(v >>> 0);
		buf[offset++] = (byte)(v >>> 8);
		buf[offset++] = (byte)(v >>> 16);
		buf[offset++] = (byte)(v >>> 24);
		buf[offset++] = (byte)(v >>> 32);
		buf[offset++] = (byte)(v >>> 40);
		buf[offset++] = (byte)(v >>> 48);
		buf[offset]   = (byte)(v >>> 56);
	}

	/**
	 * Convert big endian signed 64 bits to long.
	 */
	public static long bytesToLong(byte[] buf, int offset) {
		return (
			((long)(buf[offset]   & 0xFF) << 56) |
			((long)(buf[offset+1] & 0xFF) << 48) |
			((long)(buf[offset+2] & 0xFF) << 40) |
			((long)(buf[offset+3] & 0xFF) << 32) |
			((long)(buf[offset+4] & 0xFF) << 24) |
			((long)(buf[offset+5] & 0xFF) << 16) |
			((long)(buf[offset+6] & 0xFF) << 8) |
			((long)(buf[offset+7] & 0xFF) << 0)
			);
	}

	/**
	 * Convert little endian signed 64 bits to long.
	 */
	public static long littleBytesToLong(byte[] buf, int offset) {
		return (
			((long)(buf[offset]   & 0xFF) << 0) |
			((long)(buf[offset+1] & 0xFF) << 8) |
			((long)(buf[offset+2] & 0xFF) << 16) |
			((long)(buf[offset+3] & 0xFF) << 24) |
			((long)(buf[offset+4] & 0xFF) << 32) |
			((long)(buf[offset+5] & 0xFF) << 40) |
			((long)(buf[offset+6] & 0xFF) << 48) |
			((long)(buf[offset+7] & 0xFF) << 56)
			);
	}

	//-------------------------------------------------------
	// 32 bit number conversions.
	//-------------------------------------------------------

	/**
	 * Convert int to big endian signed or unsigned 32 bits.
	 * The bit pattern will be the same regardless of sign.
	 */
	public static void intToBytes(int v, byte[] buf, int offset) {
		buf[offset++] = (byte)(v >>> 24);
		buf[offset++] = (byte)(v >>> 16);
		buf[offset++] = (byte)(v >>> 8);
		buf[offset]   = (byte)(v >>> 0);
	}

	/**
	 * Convert int to little endian signed or unsigned 32 bits.
	 * The bit pattern will be the same regardless of sign.
	 */
	public static void intToLittleBytes(int v, byte[] buf, int offset) {
		buf[offset++] = (byte)(v >>> 0);
		buf[offset++] = (byte)(v >>> 8);
		buf[offset++] = (byte)(v >>> 16);
		buf[offset]   = (byte)(v >>> 24);
	}

	/**
	 * Convert big endian signed 32 bits to int.
	 */
	public static int bytesToInt(byte[] buf, int offset) {
		return (
			((buf[offset]   & 0xFF) << 24) |
			((buf[offset+1] & 0xFF) << 16) |
			((buf[offset+2] & 0xFF) << 8) |
			((buf[offset+3] & 0xFF) << 0)
			);
	}

	/**
	 * Convert little endian signed 32 bits to int.
	 */
	public static int littleBytesToInt(byte[] buf, int offset) {
		return (
			((buf[offset]   & 0xFF) << 0) |
			((buf[offset+1] & 0xFF) << 8) |
			((buf[offset+2] & 0xFF) << 16) |
			((buf[offset+3] & 0xFF) << 24)
			);
	}

	/**
	 * Convert big endian unsigned 32 bits to long.
	 */
	public static long bigUnsigned32ToLong(byte[] buf, int offset) {
		return (
			((long)(buf[offset]   & 0xFF) << 24) |
			((long)(buf[offset+1] & 0xFF) << 16) |
			((long)(buf[offset+2] & 0xFF) << 8) |
			((long)(buf[offset+3] & 0xFF) << 0)
			);
	}

	//-------------------------------------------------------
	// 16 bit number conversions.
	//-------------------------------------------------------

	/**
	 * Convert int to big endian signed or unsigned 16 bits.
	 * The bit pattern will be the same regardless of sign.
	 */
	public static void shortToBytes(int v, byte[] buf, int offset) {
		buf[offset++] = (byte)(v >>> 8);
		buf[offset]   = (byte)(v >>> 0);
	}

	/**
	 * Convert int to little endian signed or unsigned 16 bits.
	 * The bit pattern will be the same regardless of sign.
	 */
	public static void shortToLittleBytes(int v, byte[] buf, int offset) {
		buf[offset++] = (byte)(v >>> 0);
		buf[offset]   = (byte)(v >>> 8);
	}

	/**
	 * Convert big endian unsigned 16 bits to int.
	 */
	public static int bytesToShort(byte[] buf, int offset) {
		return (
			((buf[offset]   & 0xFF) << 8) |
			((buf[offset+1] & 0xFF) << 0)
			);
	}

	/**
	 * Convert little endian unsigned 16 bits to int.
	 */
	public static int littleBytesToShort(byte[] buf, int offset) {
		return (
			((buf[offset]   & 0xFF) << 0) |
			((buf[offset+1] & 0xFF) << 8)
			);
	}

	/**
	 * Convert big endian signed 16 bits to short.
	 */
	public static short bigSigned16ToShort(byte[] buf, int offset) {
		return (short)(
			((buf[offset]   & 0xFF) << 8) |
			((buf[offset+1] & 0xFF) << 0)
			);
	}

	//-------------------------------------------------------
	// Variable byte number conversions.
	//-------------------------------------------------------

	/**
	 *	Encode an integer in variable 7-bit format.
	 *	The high bit indicates if more bytes are used.
	 *  Return byte size of integer.
	 */
	public static int intToVarBytes(int v, byte[] buf, int offset) {
		int i = offset;

		while (i < buf.length && v >= 0x80) {
			buf[i++] = (byte)(v | 0x80);
			v >>>= 7;
		}

		if (i < buf.length) {
			buf[i++] = (byte)v;
			return i - offset;
		}
		return 0;
	}

	/**
	 *	Decode an integer in variable 7-bit format.
	 *	The high bit indicates if more bytes are used.
	 *  Return value and byte size in array.
	 */
	public static int[] varBytesToInt(byte[] buf, int offset) {
		int i = offset;
		int val = 0;
		int shift = 0;
		byte b;

		do {
			b = buf[i++];
			val |= (b & 0x7F) << shift;
			shift += 7;
		} while ((b & 0x80) != 0);

		return new int[] {val, i - offset};
	}
}

## 内容3
### 文件路径：
client/src/com/aerospike/client/util/Packer.java
### 代码内容：
package com.aerospike.client.util;

import java.io.ByteArrayOutputStream;
import java.io.IOException;
import java.io.ObjectOutputStream;
import java.nio.ByteBuffer;
import java.util.ArrayList;
import java.util.List;
import java.util.Map;
import java.util.Map.Entry;

import com.aerospike.client.AerospikeException;
import com.aerospike.client.Value;
import com.aerospike.client.cdt.MapOrder;
import com.aerospike.client.command.Buffer;
import com.aerospike.client.command.ParticleType;

import static com.aerospike.client.Value.MapValue.getMapOrder;

/**
 * Serialize collection objects using MessagePack format specification:
 *
 * https://github.com/msgpack/msgpack/blob/master/spec.md
 */
public final class Packer {

	public static byte[] pack(Value[] val) {
		try {
			Packer packer = new Packer();
			packer.packValueArray(val);
			return packer.toByteArray();
		}
		catch (Exception e) {
			throw new AerospikeException.Serialize(e);
		}
	}

	public static byte[] pack(List<?> val) {
		try {
			Packer packer = new Packer();
			packer.packList(val);
			return packer.toByteArray();
		}
		catch (Exception e) {
			throw new AerospikeException.Serialize(e);
		}
	}

	public static byte[] pack(Map<?,?> val, MapOrder order) {
		try {
			Packer packer = new Packer();
			packer.packMap(val, order);
			return packer.toByteArray();
		}
		catch (Exception e) {
			throw new AerospikeException.Serialize(e);
		}
	}

	public static byte[] pack(List<? extends Entry<?,?>> val, MapOrder order) {
		try {
			Packer packer = new Packer();
			packer.packMap(val, order);
			return packer.toByteArray();
		}
		catch (Exception e) {
			throw new AerospikeException.Serialize(e);
		}
	}

	private byte[] buffer;
	private int offset;
	private ArrayList<BufferItem> bufferList;

	public Packer() {
		this.buffer = ThreadLocalData.getBuffer();
	}

	public void packValueArray(Value[] values) {
		packArrayBegin(values.length);
		for (Value value : values) {
			value.pack(this);
		}
	}

	public void packValueList(List<Value> list) {
		packArrayBegin(list.size());
		for (Value value : list) {
			value.pack(this);
		}
	}

	public void packList(List<?> list) {
		packArrayBegin(list.size());
		for (Object obj : list) {
			packObject(obj);
		}
	}

	public void packArrayBegin(int size) {
		if (size < 16) {
			packByte(0x90 | size);
		}
		else if (size < 65536) {
			packShort(0xdc, size);
		}
		else {
			packInt(0xdd, size);
		}
	}

	public void packValueMap(Map<Value,Value> map) {
		MapOrder order = getMapOrder(map);
		packMapBegin(map.size(), order);

		for (Entry<Value,Value> entry : map.entrySet()) {
			entry.getKey().pack(this);
			entry.getValue().pack(this);
		}
	}

	public void packMap(Map<?,?> map) {
		MapOrder order = getMapOrder(map);
		packMap(map, order);
	}

	public void packMap(Map<?,?> map, MapOrder order) {
		packMapBegin(map.size(), order);

		for (Entry<?,?> entry : map.entrySet()) {
			packObject(entry.getKey());
			packObject(entry.getValue());
		}
	}

	public void packMap(List<? extends Entry<?,?>> list, MapOrder order) {
		packMapBegin(list.size(), order);

		for (Entry<?,?> entry : list) {
			packObject(entry.getKey());
			packObject(entry.getValue());
		}
	}

	public void packMapBegin(int size, MapOrder order) {
		if (order == MapOrder.UNORDERED) {
			packMapBegin(size);
		}
		else {
			// Map is sorted.
			packMapBegin(size + 1);
			packByte(0xc7);
			packByte(0);
			packByte(order.attributes);
			packByte(0xc0);
		}
	}

	public void packMapBegin(int size) {
		if (size < 16) {
			packByte(0x80 | size);
		}
		else if (size < 65536) {
			packShort(0xde, size);
		}
		else {
			packInt(0xdf, size);
		}
	}

	public void packBytes(byte[] b) {
		packByteArrayBegin(b.length);
		packByteArray(b, 0, b.length);
	}

	public void packParticleBytes(byte[] b) {
		packByteArrayBegin(b.length + 1);
		packByte(ParticleType.BLOB);
		packByteArray(b, 0, b.length);
	}

	public void packParticleBytes(byte[] b, int type) {
		packByteArrayBegin(b.length + 1);
		packByte(type);
		packByteArray(b, 0, b.length);
	}

	public void packParticleBytes(byte[] b, int offset, int length) {
		packByteArrayBegin(length + 1);
		packByte(ParticleType.BLOB);
		packByteArray(b, offset, length);
	}

	public void packBlob(Object val) {
		ByteArrayOutputStream bstream = new ByteArrayOutputStream();

		try {
			ObjectOutputStream ostream = new ObjectOutputStream(bstream);
			ostream.writeObject(val);
			ostream.close();
		}
		catch (IOException ioe) {
			throw new AerospikeException.Serialize(ioe);
		}

		byte[] bytes = bstream.toByteArray();
		packByteArrayBegin(bytes.length + 1);
		packByte(ParticleType.JBLOB);
		packByteArray(bytes, 0, bytes.length);
	}

	public void packGeoJSON(String val) {
		byte[] buffer = Buffer.stringToUtf8(val);
		packByteArrayBegin(buffer.length + 1);
		packByte(ParticleType.GEOJSON);
		packByteArray(buffer, 0, buffer.length);
	}

	private void packByteArrayBegin(int size) {
		// Use string header codes for byte arrays.
		packStringBegin(size);
		/*
		if (size < 256) {
			packByte(0xc4, size);
		}
		else if (size < 65536) {
			packShort(0xc5, size);
		}
		else {
			packInt(0xc6, size);
		}
		*/
	}

	public void packObject(Object obj) {
		if (obj == null) {
			packNil();
			return;
		}

		if (obj instanceof Value) {
			Value value = (Value) obj;
			value.pack(this);
			return;
		}

		if (obj instanceof byte[]) {
			packParticleBytes((byte[]) obj);
			return;
		}

		if (obj instanceof String) {
			packParticleString((String) obj);
			return;
		}

		if (obj instanceof Integer) {
			packInt((Integer) obj);
			return;
		}

		if (obj instanceof Long) {
			packLong((Long) obj);
			return;
		}

		if (obj instanceof Double) {
			packDouble((Double) obj);
			return;
		}

		if (obj instanceof Float) {
			packFloat((Float) obj);
			return;
		}

		if (obj instanceof Boolean) {
			packBoolean((Boolean)obj);
			return;
		}

		if (obj instanceof List<?>) {
			packList((List<?>) obj);
			return;
		}

		if (obj instanceof Map<?,?>) {
			packMap((Map<?,?>) obj);
			return;
		}

		if (obj instanceof ByteBuffer) {
			packByteBuffer((ByteBuffer) obj);
			return;
		}

		packBlob(obj);
	}

	public void packByteBuffer(ByteBuffer bb) {
		byte[] b = bb.array();
		packParticleBytes(b);
	}

	public void packLong(long val) {
		if (val >= 0L) {
			if (val < 128L) {
				packByte((int)val);
				return;
			}

			if (val < 256L) {
				packByte(0xcc, (int)val);
				return;
			}

			if (val < 65536L) {
				packShort(0xcd, (int)val);
				return;
			}

			if (val < 4294967296L) {
				packInt(0xce, (int)val);
				return;
			}
			packLong(0xcf, val);
		}
		else {
			if (val >= -32) {
				packByte(0xe0 | ((int)val + 32));
				return;
			}

			if (val >= Byte.MIN_VALUE) {
				packByte(0xd0, (int)val);
				return;
			}

			if (val >= Short.MIN_VALUE) {
				packShort(0xd1, (int)val);
				return;
			}

			if (val >= Integer.MIN_VALUE) {
				packInt(0xd2, (int)val);
				return;
			}
			packLong(0xd3, val);
		}
	}

	public void packInt(int val) {
		if (val >= 0) {
			if (val < 128) {
				packByte(val);
				return;
			}

			if (val < 256) {
				packByte(0xcc, val);
				return;
			}

			if (val < 65536) {
				packShort(0xcd, val);
				return;
			}
			packInt(0xce, val);
		}
		else {
			if (val >= -32) {
				packByte(0xe0 | (val + 32));
				return;
			}

			if (val >= Byte.MIN_VALUE) {
				packByte(0xd0, val);
				return;
			}

			if (val >= Short.MIN_VALUE) {
				packShort(0xd1, val);
				return;
			}
			packInt(0xd2, val);
		}
	}

	public void packString(String val) {
		int size = Buffer.estimateSizeUtf8(val);
		packStringBegin(size);

		if (offset + size > buffer.length) {
			resize(size);
		}
		offset += Buffer.stringToUtf8(val, buffer, offset);
	}

	public void packParticleString(String val) {
		int size = Buffer.estimateSizeUtf8(val) + 1;
		packStringBegin(size);

		if (offset + size > buffer.length) {
			resize(size);
		}
		buffer[offset++] = (byte)ParticleType.STRING;
		offset += Buffer.stringToUtf8(val, buffer, offset);
	}

	private void packStringBegin(int size) {
		if (size < 32) {
			packByte(0xa0 | size);
		}
		else if (size < 256) {
			packByte(0xd9, size);
		}
		else if (size < 65536) {
			packShort(0xda, size);
		}
		else {
			packInt(0xdb, size);
		}
	}

	public void packByteArray(byte[] src, int srcOffset, int srcLength) {
	   	if (offset + srcLength > buffer.length) {
			resize(srcLength);
		}
 		System.arraycopy(src, srcOffset, buffer, offset, srcLength);
		offset += srcLength;
	}

	public void packDouble(double val) {
		if (offset + 9 > buffer.length) {
			resize(9);
		}
		buffer[offset++] = (byte)0xcb;
		Buffer.longToBytes(Double.doubleToLongBits(val), buffer, offset);
		offset += 8;
	}

	public void packFloat(float val) {
		if (offset + 5 > buffer.length) {
			resize(5);
		}
		buffer[offset++] = (byte)0xca;
		Buffer.intToBytes(Float.floatToIntBits(val), buffer, offset);
		offset += 4;
	}

	private void packLong(int type, long val) {
		if (offset + 9 > buffer.length) {
			resize(9);
		}
		buffer[offset++] = (byte)type;
		Buffer.longToBytes(val, buffer, offset);
		offset += 8;
	}

	private void packInt(int type, int val) {
		if (offset + 5 > buffer.length) {
			resize(5);
		}
		buffer[offset++] = (byte)type;
		Buffer.intToBytes(val, buffer, offset);
		offset += 4;
	}

	private void packShort(int type, int val) {
		if (offset + 3 > buffer.length) {
			resize(3);
		}
		buffer[offset++] = (byte)type;
		Buffer.shortToBytes(val, buffer, offset);
		offset += 2;
	}

	public void packRawShort(int val) {
		// WARNING. This method is not compatible with message pack standard.
		if (offset + 2 > buffer.length) {
			resize(2);
		}
		Buffer.shortToBytes(val, buffer, offset);
		offset += 2;
	}

	private void packByte(int type, int val) {
		if (offset + 2 > buffer.length) {
			resize(2);
		}
		buffer[offset++] = (byte)type;
		buffer[offset++] = (byte)val;
	}

	public void packBoolean(boolean val) {
		if (offset + 1 > buffer.length) {
			resize(1);
		}

		if (val) {
			buffer[offset++] = (byte)0xc3;
		}
		else {
			buffer[offset++] = (byte)0xc2;
		}
	}

	public void packNil() {
		if (offset >= buffer.length) {
			resize(1);
		}
		buffer[offset++] = (byte)0xc0;
	}

	public void packInfinity() {
		if (offset + 3 > buffer.length) {
			resize(3);
		}
		buffer[offset++] = (byte)0xd4;
		buffer[offset++] = (byte)0xff;
		buffer[offset++] = (byte)0x01;
	}

	public void packWildcard() {
		if (offset + 3 > buffer.length) {
			resize(3);
		}
		buffer[offset++] = (byte)0xd4;
		buffer[offset++] = (byte)0xff;
		buffer[offset++] = (byte)0x00;
	}

	public void packByte(int val) {
		if (offset >= buffer.length) {
			resize(1);
		}
		buffer[offset++] = (byte)val;
	}

	private void resize(int size) {
		if (bufferList == null) {
			bufferList = new ArrayList<BufferItem>();
		}
		bufferList.add(new BufferItem(buffer, offset));

		if (size < buffer.length) {
			size = buffer.length;
		}
		buffer = new byte[size];
		offset = 0;
	}

	public byte[] toByteArray() {
		if (bufferList != null) {
			int size = offset;
			for (BufferItem item : bufferList) {
				size += item.length;
			}

			byte[] target = new byte[size];
			size = 0;
			for (BufferItem item : bufferList) {
				System.arraycopy(item.buffer, 0, target, size, item.length);
				size += item.length;
			}

			System.arraycopy(buffer, 0, target, size, offset);
			return target;
		}
		else {
			byte[] target = new byte[offset];
			System.arraycopy(buffer, 0, target, 0, offset);
			return target;
		}
	}

	private static final class BufferItem {
		private final byte[] buffer;
		private final int length;

		private BufferItem(byte[] buffer, int length) {
			this.buffer = buffer;
			this.length = length;
		}
	}
}

## 内容4
### 文件路径：
client/src/com/aerospike/client/util/Unpacker.java
### 代码内容：
package com.aerospike.client.util;

import java.io.ByteArrayInputStream;
import java.io.IOException;
import java.io.ObjectInputStream;
import java.nio.ByteBuffer;
import java.util.AbstractMap;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.Map.Entry;
import java.util.TreeMap;

import com.aerospike.client.AerospikeException;
import com.aerospike.client.Value;
import com.aerospike.client.command.Buffer;
import com.aerospike.client.command.ParticleType;

/**
 * De-serialize collection objects using MessagePack format specification:
 *
 * https://github.com/msgpack/msgpack/blob/master/spec.md
 */
public abstract class Unpacker<T> {

	private final byte[] buffer;
	private int offset;
	private final int length;

	public Unpacker(byte[] buffer, int offset, int length) {
		this.buffer = buffer;
		this.offset = offset;
		this.length = length;
	}

	public final T unpackList() throws AerospikeException {
		if (length <= 0) {
			return getList(new ArrayList<T>(0));
		}

		try {
			int type = buffer[offset++] & 0xff;
			int count;

			if ((type & 0xf0) == 0x90) {
				count = type & 0x0f;
			}
			else if (type == 0xdc) {
				count = Buffer.bytesToShort(buffer, offset);
				offset += 2;
			}
			else if (type == 0xdd) {
				count = Buffer.bytesToInt(buffer, offset);
				offset += 4;
			}
			else {
				return getList(new ArrayList<T>(0));
			}
			return unpackList(count);
		}
		catch (Exception e) {
			throw new AerospikeException.Serialize(e);
		}
	}

	private T unpackList(int count) throws IOException, ClassNotFoundException {
		if (count <= 0) {
			return getList(new ArrayList<T>(0));
		}

		// Extract first object.
		int mark = offset;
		int size = count;
		T val = unpackObject();

		if (val == null) {
			// Determine if null value is because of an extension type.
			int type = buffer[mark] & 0xff;

			if (type != 0xc0) {  // not nil type
				// Ignore extension type.
				size--;
			}
		}

		ArrayList<T> out = new ArrayList<T>(size);

		if (size == count) {
			out.add(val);
		}

		for (int i = 1; i < count; i++) {
			out.add(unpackObject());
		}
		return getList(out);
	}

	public final T unpackMap() throws AerospikeException {
		if (length <= 0) {
			return getMap(new HashMap<T,T>(0));
		}

		try {
			int type = buffer[offset++] & 0xff;
			int count;

			if ((type & 0xf0) == 0x80) {
				count = type & 0x0f;
			}
			else if (type == 0xde) {
				count = Buffer.bytesToShort(buffer, offset);
				offset += 2;
			}
			else if (type == 0xdf) {
				count = Buffer.bytesToInt(buffer, offset);
				offset += 4;
			}
			else {
				return getMap(new HashMap<T,T>(0));
			}
			return unpackMap(count);
		}
		catch (Exception e) {
			throw new AerospikeException.Serialize(e);
		}
	}

	private T unpackMap(int count) throws IOException, ClassNotFoundException {
		if (count <= 0) {
			return getMap(new HashMap<T,T>(0));
		}

		// Peek at buffer to determine map type, but do not advance.
		int type = buffer[offset] & 0xff;

		// Check for extension that the server uses.
		if (type == 0xc7) {
			int extensionType = buffer[offset + 1] & 0xff;

			if (extensionType == 0) {
				int mapBits = buffer[offset + 2] & 0xff;

				// Extension is a map type.  Determine which one.
				if ((mapBits & (0x04 | 0x08)) != 0) {
					// Index/rank range result where order needs to be preserved.
					return unpackMapAsList(count);
				}
				else if ((mapBits & 0x01) != 0) {
					// Sorted map
					return unpackTreeMap(count);
				}
			}
		}
		return unpackHashMap(count);
	}

	private T unpackHashMap(int count) throws IOException, ClassNotFoundException {
		HashMap<T,T> map = new HashMap<T,T>(count);

		for (int i = 0; i < count; i++) {
			T key = unpackObject();
			T val = unpackObject();

			if (key != null) {
				map.put(key, val);
			}
		}
		return getMap(map);
	}

	@SuppressWarnings("unchecked")
	private T unpackTreeMap(int count) throws IOException, ClassNotFoundException {
		TreeMap<T,T> map = new TreeMap<T,T>();

		for (int i = 0; i < count; i++) {
			T key = unpackObject();
			T val = unpackObject();

			if (key != null) {
				if (key instanceof byte[]) {
					// TreeMap does not support byte[] keys,
					// so wrap byte[] in a ByteBuffer.
					key = (T)ByteBuffer.wrap((byte[])key);
				}
				map.put(key, val);
			}
		}
		return getMap(map);
	}

	@SuppressWarnings("unchecked")
	private T unpackMapAsList(int count) throws IOException, ClassNotFoundException {
		// Index/rank range result where order needs to be preserved.
		// Store in List<Entry<?,?> to preserve order.
		// The first entry is going to be null (ignored), so use "count - 1" size.
		List<Entry<T,T>> list = new ArrayList<Entry<T,T>>(count - 1);

		for (int i = 0; i < count; i++) {
			T key = unpackObject();
			T val = unpackObject();

			if (key != null) {
				list.add(new AbstractMap.SimpleEntry<T,T>(key, val));
			}
		}
		return getList((List<T>)list);
	}

	private T unpackBlob(int count) throws IOException, ClassNotFoundException {
		int type = buffer[offset++] & 0xff;
		count--;
		T val;

		switch (type) {
		case ParticleType.STRING:
			val = getString(Buffer.utf8ToString(buffer, offset, count));
			break;

		case ParticleType.JBLOB:
			ByteArrayInputStream bastream = new ByteArrayInputStream(buffer, offset, count);
			ObjectInputStream oistream = new ObjectInputStream(bastream);
			val = getJavaBlob(oistream.readObject());
			break;

		case ParticleType.GEOJSON:
			val = getGeoJSON(Buffer.utf8ToString(buffer, offset, count));
			break;

		default:
			val = getBlob(Arrays.copyOfRange(buffer, offset, offset + count));
			break;
		}
		offset += count;
		return val;
	}

	public T unpackObject() throws IOException, ClassNotFoundException {
		int type = buffer[offset++] & 0xff;

		switch (type) {
			case 0xc0: { // nil
				return null;
			}

			case 0xc3: { // boolean true
				return getBoolean(true);
			}

			case 0xc2: { // boolean false
				return getBoolean(false);
			}

			case 0xca: { // float
				float val = Float.intBitsToFloat(Buffer.bytesToInt(buffer, offset));
				offset += 4;
				return getDouble(val);
			}

			case 0xcb: { // double
				double val = Double.longBitsToDouble(Buffer.bytesToLong(buffer, offset));
				offset += 8;
				return getDouble(val);
			}

			case 0xd0: { // signed 8 bit integer
				return getLong(buffer[offset++]);
			}

			case 0xcc: { // unsigned 8 bit integer
				return getLong(buffer[offset++] & 0xff);
			}

			case 0xd1: { // signed 16 bit integer
				short val = Buffer.bigSigned16ToShort(buffer, offset);
				offset += 2;
				return getLong(val);
			}

			case 0xcd: { // unsigned 16 bit integer
				int val = Buffer.bytesToShort(buffer, offset);
				offset += 2;
				return getLong(val);
			}

			case 0xd2: { // signed 32 bit integer
				int val = Buffer.bytesToInt(buffer, offset);
				offset += 4;
				return getLong(val);
			}

			case 0xce: { // unsigned 32 bit integer
				long val = Buffer.bigUnsigned32ToLong(buffer, offset);
				offset += 4;
				return getLong(val);
			}

			case 0xd3: { // signed 64 bit integer
				long val = Buffer.bytesToLong(buffer, offset);
				offset += 8;
				return getLong(val);
			}

			case 0xcf: { // unsigned 64 bit integer
				// Java is constrained to signed longs, so that is the best we can do here.
				long val = Buffer.bytesToLong(buffer, offset);
				offset += 8;
				return getLong(val);
			}

			case 0xc4:
			case 0xd9: { // string/raw bytes with 8 bit header
				int count = buffer[offset++] & 0xff;
				return (T)unpackBlob(count);
			}

			case 0xc5:
			case 0xda: { // string/raw bytes with 16 bit header
				int count = Buffer.bytesToShort(buffer, offset);
				offset += 2;
				return (T)unpackBlob(count);
			}

			case 0xc6:
			case 0xdb: { // string/raw bytes with 32 bit header
				// Java array length is restricted to positive int values (0 - Integer.MAX_VALUE).
				int count = Buffer.bytesToInt(buffer, offset);
				offset += 4;
				return (T)unpackBlob(count);
			}

			case 0xdc: { // list with 16 bit header
				int count = Buffer.bytesToShort(buffer, offset);
				offset += 2;
				return unpackList(count);
			}

			case 0xdd: { // list with 32 bit header
				// Java array length is restricted to positive int values (0 - Integer.MAX_VALUE).
				int count = Buffer.bytesToInt(buffer, offset);
				offset += 4;
				return unpackList(count);
			}

			case 0xde: { // map with 16 bit header
				int count = Buffer.bytesToShort(buffer, offset);
				offset += 2;
				return unpackMap(count);
			}

			case 0xdf: { // map with 32 bit header
				// Java array length is restricted to positive int values (0 - Integer.MAX_VALUE).
				int count = Buffer.bytesToInt(buffer, offset);
				offset += 4;
				return unpackMap(count);
			}

			case 0xd4: { // Skip over type extension with 1 byte
				offset += 1 + 1;
				return null;
			}

			case 0xd5: { // Skip over type extension with 2 bytes
				offset += 1 + 2;
				return null;
			}

			case 0xd6: { // Skip over type extension with 4 bytes
				offset += 1 + 4;
				return null;
			}

			case 0xd7: { // Skip over type extension with 8 bytes
				offset += 1 + 8;
				return null;
			}

			case 0xd8: { // Skip over type extension with 16 bytes
				offset += 1 + 16;
				return null;
			}

			case 0xc7: { // Skip over type extension with 8 bit header and bytes
				int count = buffer[offset] & 0xff;
				offset += count + 1 + 1;
				return null;
			}

			case 0xc8: { // Skip over type extension with 16 bit header and bytes
				int count = Buffer.bytesToShort(buffer, offset);
				offset += count + 1 + 2;
				return null;
			}

			case 0xc9: { // Skip over type extension with 32 bit header and bytes
				int count = Buffer.bytesToInt(buffer, offset);
				offset += count + 1 + 4;
				return null;
			}

			default: {
				if ((type & 0xe0) == 0xa0) { // raw bytes with 8 bit combined header
					return unpackBlob(type & 0x1f);
				}

				if ((type & 0xf0) == 0x80) { // map with 8 bit combined header
					return unpackMap(type & 0x0f);
				}

				if ((type & 0xf0) == 0x90) { // list with 8 bit combined header
					return unpackList(type & 0x0f);
				}

				if (type < 0x80) { // 8 bit combined unsigned integer
					return getLong(type);
				}

				if (type >= 0xe0) { // 8 bit combined signed integer
					return getLong(type - 0xe0 - 32);
				}
				throw new IOException("Unknown unpack type: " + type);
			}
		}
	}

	protected abstract T getMap(Map<T,T> value);
	protected abstract T getList(List<T> value);
	protected abstract T getJavaBlob(Object value);
	protected abstract T getBlob(byte[] value);
	protected abstract T getString(String value);
	protected abstract T getLong(long value);
	protected abstract T getDouble(double value);
	protected abstract T getBoolean(boolean value);
	protected abstract T getGeoJSON(String value);

	public static Object unpackObjectList(byte[] buffer, int offset, int length) throws AerospikeException {
		ObjectUnpacker unpacker = new ObjectUnpacker(buffer, offset, length);
		return unpacker.unpackList();
	}

	public static Object unpackObjectMap(byte[] buffer, int offset, int length) throws AerospikeException {
		ObjectUnpacker unpacker = new ObjectUnpacker(buffer, offset, length);
		return unpacker.unpackMap();
	}

	public static Object unpackObject(byte[] buffer, int offset, int length) throws AerospikeException {
		try {
			if (length <= 0) {
				return null;
			}
			ObjectUnpacker unpacker = new ObjectUnpacker(buffer, offset, length);
			return unpacker.unpackObject();
		}
		catch (Exception e) {
			throw new AerospikeException.Serialize(e);
		}
	}

	public static final class ObjectUnpacker extends Unpacker<Object> {

		public ObjectUnpacker(byte[] buffer, int offset, int length) {
			super(buffer, offset, length);
		}

		@Override
		protected Object getMap(Map<Object,Object> value) {
			return value;
		}

		@Override
		protected Object getList(List<Object> value) {
			return value;
		}

		@Override
		protected Object getJavaBlob(Object value) {
			return value;
		}

		@Override
		protected Object getBlob(byte[] value) {
			return value;
		}

		@Override
		protected Object getString(String value) {
			return value;
		}

		@Override
		protected Object getLong(long value) {
			return value;
		}

		@Override
		protected Object getDouble(double value) {
			return value;
		}

		@Override
		protected Object getBoolean(boolean value) {
			return value;
		}

		@Override
		protected Object getGeoJSON(String value) {
			return Value.getAsGeoJSON(value);
		}
	}
}

Output:
【漏洞类型】反序列化漏洞
【严重性】高
【漏洞摘要】反序列化漏洞是指在程序中使用不安全的反序列化方法，如Java的`ObjectInputStream`，这可能导致攻击者通过构造恶意序列化数据来执行任意代码。在提供的代码中，`Value.java`、`Buffer.java`和`Packer.java`文件中的`bytesToObject`和`packBlob`方法分别使用了`ObjectInputStream`进行反序列化和`ObjectOutputStream`进行序列化。这些方法没有对输入数据进行验证和过滤，直接反序列化用户提供的数据，从而存在代码执行的安全风险。
【关键代码模式】`ObjectInputStream`、`ObjectOutputStream`、`bytesToObject`、`packBlob`
【修复方法说明】禁用了Java运行时的序列化和反序列化功能，通过抛出`AerospikeException`异常来防止用户输入的恶意数据被反序列化。