4 内存值的转化
本节内存值的转化主要指的是:在实现java版c语言解释器时,将java数据值转化为c语言类型长度的字节数组值;将c语言类型长度的字节数组值转化为java数据值。
4.1 Java->C
public class ConvertJavaData2CBytes {
public static byte[] convertToBytes(short value, int size) {
byte[] result = new byte[size];
for (int i = 0; i < size; i++) {
result[i] = (byte) (value >> (i * 8));
}
return result;
}
public static byte[] convertToBytes(int value, int size) {
byte[] result = new byte[size];
for (int i = 0; i < size; i++) {
result[i] = Integer.valueOf(value >> (i * 8)).byteValue();
}
return result;
}
public static byte[] convertToBytes(long value, int size) {
byte[] result = new byte[size];
for (int i = 0; i < size; i++) {
result[i] = Long.valueOf(value >> (i * 8)).byteValue();
}
return result;
}
public static byte[] convertToBytes(float value, int size) {
return convertToBytes(Float.floatToIntBits(value), size);
}
public static byte[] convertToBytes(double value, int size) {
return convertToBytes(Double.doubleToLongBits(value), size);
}
public static byte[] covertToBytes(Character c) {
byte[] bs = new byte[1];
bs[0] = (byte) (c.charValue() & 0xFF);
return bs;
}
/**
* 将n转化为使用大端(值较大的部分放在字节数组下标较大的位置)表示的字节数组
* @param n
* @return
*/
public static byte[] convertToBytes(Number n) {
byte[] bs = null;
if (n instanceof Short) {
bs = convertToBytes(n.shortValue(), 2);
} else if (n instanceof Integer) {
bs = convertToBytes(n.intValue(), 4);
} else if (n instanceof Long) {
bs = convertToBytes(n.longValue(), 4);
} else if (n instanceof Float) {
bs = convertToBytes(n.floatValue(), 4);
} else if (n instanceof Double) {
bs = convertToBytes(n.doubleValue(), 8);
} else if (n instanceof BigDecimal || n instanceof BigInteger) {
if (n instanceof BigDecimal)
n = ((BigDecimal) n).toBigInteger();
byte[] bb = ((BigInteger) n).toByteArray();
int len = bb.length;
bs = new byte[len];
for (int i = 0; i < len; i++) {
bs[i] = bb[len - i - 1];
}
} else {
throw new UnsupportedOperationException("不支持的符号类型" + n.getClass());
}
return bs;
}
}
4.2 C->Java
public class CovertCBytes2JavaData {
@SuppressWarnings("unchecked")
public static <T extends Object> T convertValue(byte[] bytes, Class<T> clazz) {
T value = null;
if (clazz == Integer.class) {
value = (T) convert2Int(bytes);
} else if (clazz == Short.class) {
value = (T) convert2Short(bytes);
} else if (clazz == Long.class) {
value = (T) convert2Long(bytes);
} else if (clazz == Float.class) {
value = (T) convert2Float(bytes);
} else if (clazz == Double.class) {
value = (T) convert2Double(bytes);
} else if (clazz == BigInteger.class) {
int len = bytes.length;
byte[] bb = new byte[len];
for (int i = 0; i < len; i++) {
bb[i] = bytes[len - i - 1];
}
value = (T) new BigInteger(bb);
} else if (clazz == String.class) {
String str = new String(bytes);
StringBuffer buffer = new StringBuffer();
for (int i = 0, size = str.length(); i < size; i++) {
char c = str.charAt(i);
if (c == '\0') {
break;
}
buffer.append(c);
}
value = (T) buffer.toString();
} else {
throw new UnsupportedOperationException("不支持的转换类型" + clazz);
}
/**暂时未支持BigDecimal**/
return value;
}
private static byte[] convertBytes(byte[] bytes, int size) {
byte[] after = new byte[size / 8];
for (int i = 0, j = 0; i < after.length; i++, j++) {
if (j < bytes.length) {
after[i] = bytes[j];
} else {
after[i] = 0;
}
}
return after;
}
public static Short convert2Short(byte[] bytes) {
byte[] after = convertBytes(bytes, Short.SIZE);
short result = 0;
result |= ((after[0]) & 0xFF);
result |= ((after[1] << 8) & 0xFFFF);
return result;
}
public static Integer convert2Int(byte[] bytes) {
byte[] after = convertBytes(bytes, Integer.SIZE);
int result = 0;
result |= ((after[0]) & 0xFF);
result |= ((after[1] << 8) & 0xFFFF);
result |= ((after[2] << 16) & 0xFFFFFF);
result |= ((after[3] << 24) & 0xFFFFFFFFL);
return result;
}
public static Long convert2Long(byte[] bytes) {
byte[] after = convertBytes(bytes, Integer.SIZE);
long result = 0;
result |= ((after[0]) & 0xFF);
result |= ((after[1] << 8) & 0xFFFF);
result |= ((after[2] << 16) & 0xFFFFFF);
result |= ((after[3] << 24) & 0xFFFFFFFFL);
if (after.length == 8) {
result |= ((after[4] << 32) & 0xFFFFFFFFFFL);
result |= ((after[5] << 40) & 0xFFFFFFFFFFFFL);
result |= ((after[6] << 48) & 0xFFFFFFFFFFFFFFL);
result |= ((after[7] << 56) & 0xFFFFFFFFFFFFFFFFL);
}
return result;
}
public static Float convert2Float(byte[] bytes) {
byte[] after = convertBytes(bytes, Float.SIZE);
return Float.intBitsToFloat(convert2Int(after));
}
public static Double convert2Double(byte[] bytes) {
byte[] after = convertBytes(bytes, Double.SIZE);
return Double.longBitsToDouble(convert2Long(after));
}
}