Files
pinpoint/src/main/java/com/profiler/common/util/AnnotationTranscoder.java
T

194 lines
5.9 KiB
Java

package com.profiler.common.util;
import java.io.ByteArrayInputStream;
import java.io.ByteArrayOutputStream;
import java.io.IOException;
import java.io.ObjectInputStream;
import java.io.ObjectOutputStream;
import java.io.UnsupportedEncodingException;
import java.util.Date;
public class AnnotationTranscoder {
private static final String DEFAULT_CHARSET = "UTF-8";
static final int SERIALIZED = 1;
// Special flags for specially handled types.
protected static final int SPECIAL_MASK = 0xff00;
static final int SPECIAL_BOOLEAN = (1 << 8);
static final int SPECIAL_INT = (2 << 8);
static final int SPECIAL_LONG = (3 << 8);
static final int SPECIAL_DATE = (4 << 8);
static final int SPECIAL_BYTE = (5 << 8);
static final int SPECIAL_FLOAT = (6 << 8);
static final int SPECIAL_DOUBLE = (7 << 8);
static final int SPECIAL_BYTEARRAY = (8 << 8);
protected final TranscoderUtils tu = new TranscoderUtils(true);
public static final class Encoded {
private final int valueType;
private final byte[] bytes;
public Encoded(int valueType, byte[] bytes) {
this.valueType = valueType;
this.bytes = bytes;
}
public int getValueType() {
return valueType;
}
public byte[] getBytes() {
return bytes;
}
}
public Object decode(int dataType, byte[] data) {
Object rv = null;
int flags = dataType & SPECIAL_MASK;
if ((dataType & SERIALIZED) != 0 && data != null) {
rv = deserialize(data);
} else if (flags != 0 && data != null) {
switch (flags) {
case SPECIAL_BOOLEAN:
rv = Boolean.valueOf(tu.decodeBoolean(data));
break;
case SPECIAL_INT:
rv = new Integer(tu.decodeInt(data));
break;
case SPECIAL_LONG:
rv = new Long(tu.decodeLong(data));
break;
case SPECIAL_DATE:
rv = new Date(tu.decodeLong(data));
break;
case SPECIAL_BYTE:
rv = new Byte(tu.decodeByte(data));
break;
case SPECIAL_FLOAT:
rv = new Float(Float.intBitsToFloat(tu.decodeInt(data)));
break;
case SPECIAL_DOUBLE:
rv = new Double(Double.longBitsToDouble(tu.decodeLong(data)));
break;
case SPECIAL_BYTEARRAY:
rv = data;
break;
default:
// LOG.warn("Undecodeable with flags %x", flags);
}
} else {
rv = decodeString(data);
}
return rv;
}
public Encoded encode(Object o) {
byte[] b = null;
int flags = 0;
if (o instanceof String) {
b = encodeString((String) o);
} else if (o instanceof Long) {
b = tu.encodeLong((Long) o);
flags |= SPECIAL_LONG;
} else if (o instanceof Integer) {
b = tu.encodeInt((Integer) o);
flags |= SPECIAL_INT;
} else if (o instanceof Boolean) {
b = tu.encodeBoolean((Boolean) o);
flags |= SPECIAL_BOOLEAN;
} else if (o instanceof Date) {
b = tu.encodeLong(((Date) o).getTime());
flags |= SPECIAL_DATE;
} else if (o instanceof Byte) {
b = tu.encodeByte((Byte) o);
flags |= SPECIAL_BYTE;
} else if (o instanceof Float) {
b = tu.encodeInt(Float.floatToRawIntBits((Float) o));
flags |= SPECIAL_FLOAT;
} else if (o instanceof Double) {
b = tu.encodeLong(Double.doubleToRawLongBits((Double) o));
flags |= SPECIAL_DOUBLE;
} else if (o instanceof byte[]) {
b = (byte[]) o;
flags |= SPECIAL_BYTEARRAY;
} else {
b = serialize(o);
flags |= SERIALIZED;
}
assert b != null;
return new Encoded(flags, b);
}
protected byte[] serialize(Object o) {
if (o == null) {
throw new NullPointerException("Can't serialize null");
}
byte[] rv = null;
try {
ByteArrayOutputStream bos = new ByteArrayOutputStream();
ObjectOutputStream os = new ObjectOutputStream(bos);
os.writeObject(o);
os.close();
bos.close();
rv = bos.toByteArray();
} catch (IOException e) {
throw new IllegalArgumentException("Non-serializable object, cause=" + e.getMessage(), e);
}
return rv;
}
protected Object deserialize(byte[] in) {
Object rv = null;
try {
if (in != null) {
ByteArrayInputStream bis = new ByteArrayInputStream(in);
ObjectInputStream is = new ObjectInputStream(bis);
rv = is.readObject();
is.close();
bis.close();
}
} catch (IOException e) {
// LOG.error(e.getMessage(), e);
} catch (ClassNotFoundException e) {
// LOG.error(e.getMessage(), e);
}
return rv;
}
/**
* Decode the string with the current character set.
*/
protected String decodeString(byte[] data) {
String rv = null;
try {
if (data != null) {
rv = new String(data, DEFAULT_CHARSET);
}
} catch (UnsupportedEncodingException e) {
throw new RuntimeException(e);
}
return rv;
}
/**
* Encode a string into the current character set.
*/
protected byte[] encodeString(String in) {
byte[] rv = null;
try {
rv = in.getBytes(DEFAULT_CHARSET);
} catch (UnsupportedEncodingException e) {
throw new RuntimeException(e);
}
return rv;
}
}