@Override
public byte[] toBytes() {
ByteBuf byteBuf = Unpooled.buffer();
try {
Class extends BaseBodyCodec> clazz = this.getClass();
Field[] declaredFields = clazz.getDeclaredFields();
Arrays.sort(declaredFields, new Comparator() {
@Override
public int compare(Field o1, Field o2) {
if (!o1.isAnnotationPresent(ProtocolField.class)) {
return -9999;
}
if (!o2.isAnnotationPresent(ProtocolField.class)) {
return 9999;
}
int annotation1 = o1.getAnnotation(ProtocolField.class).sort();
int annotation2 = o2.getAnnotation(ProtocolField.class).sort();
return annotation1 - annotation2;
}
});
for (Field field : declaredFields) {
if (field.isAnnotationPresent(ProtocolField.class)) {
String fieldName = field.getName();
PropertyDescriptor pd = new PropertyDescriptor(fieldName, clazz);
Method readMethod = pd.getReadMethod();
Class> type = field.getType();
if (type == byte.class) {
byte invoke = (byte) readMethod.invoke(this);
byteBuf.writeByte(invoke);
}
if (type == short.class) {
short invoke = (short) readMethod.invoke(this);
byteBuf.writeShort(invoke);
}
if (type == int.class) {
int invoke = (int) readMethod.invoke(this);
byteBuf.writeInt(invoke);
}
if (type == long.class) {
long invoke = (long) readMethod.invoke(this);
byteBuf.writeLong(invoke);
}
if ((type.isArray() && type.getComponentType() == byte.class)) {
byte[] invoke = (byte[]) readMethod.invoke(this);
byteBuf.writeBytes(invoke);
}
if (type.isArray() && type.getComponentType().getSuperclass() == BaseBodyCodec.class) {
BaseBodyCodec[] o = (BaseBodyCodec[]) readMethod.invoke(this);
for (int i = 0; i < o.length; i++) {
byteBuf.retain();
byte[] bytes = o[i].toBytes();
byteBuf.writeBytes(bytes);
}
}
if (type == String.class) {
String invoke = (String) readMethod.invoke(this);
if(invoke!=null){
byteBuf.writeCharSequence(invoke, CharsetUtil.UTF_8);
}
}
if (type.getSuperclass() == BaseBodyCodec.class) {
BaseBodyCodec o = (BaseBodyCodec) readMethod.invoke(this);
byteBuf.retain();
byte[] o_bytes = o.toBytes();
byteBuf.writeBytes(o_bytes);
}
}
}
byte[] bytes = new byte[byteBuf.readableBytes()];
byteBuf.readBytes(bytes);
return bytes;
} catch (Exception e) {
e.printStackTrace();
} finally {
byteBuf.release();
}
return null;
}
@Override
public T fillBodyPojo(ByteBuf byteBuf) {
if (byteBuf != null) {
try {
Class extends BaseBodyCodec> clazz = this.getClass();
Field[] declaredFields = clazz.getDeclaredFields();
Arrays.sort(declaredFields, new Comparator() {
@Override
public int compare(Field o1, Field o2) {
if (!o1.isAnnotationPresent(ProtocolField.class)) {
return -9999;
}
if (!o2.isAnnotationPresent(ProtocolField.class)) {
return 9999;
}
int annotation1 = o1.getAnnotation(ProtocolField.class).sort();
int annotation2 = o2.getAnnotation(ProtocolField.class).sort();
return annotation1 - annotation2;
}
});
for (int i = 0; i < declaredFields.length; i++) {
Field field = declaredFields[i];
if (field.isAnnotationPresent(ProtocolField.class)) {
String fieldName = field.getName();
PropertyDescriptor pd = new PropertyDescriptor(fieldName, clazz);
Method writeMethod = pd.getWriteMethod();
Class> type = field.getType();
if (type == byte.class) {
writeMethod.invoke(this, byteBuf.readByte());
}
if (type == short.class) {
writeMethod.invoke(this, byteBuf.readShort());
}
if (type == int.class) {
writeMethod.invoke(this, byteBuf.readInt());
}
if (type == long.class) {
writeMethod.invoke(this, byteBuf.readLong());
}
if ((type.isArray() && type.getComponentType() == byte.class) || type == String.class) {
if (field.isAnnotationPresent(ProtocolField.class)) {
ProtocolField pf = field.getAnnotation(ProtocolField.class);
int len = pf.len();
String lenField = pf.lenField();
if (len != -1) {
if (type == String.class) {
CharSequence charSequence = byteBuf.readCharSequence(len, CharsetUtil.UTF_8);
writeMethod.invoke(this, charSequence);
} else {
byte[] bytes = new byte[len];
byteBuf.readBytes(bytes);
writeMethod.invoke(this, bytes);
}
} else if (!lenField.equals("")) {
PropertyDescriptor len_field_pd = new PropertyDescriptor(lenField, clazz);
Method readMethod = len_field_pd.getReadMethod();
Integer integer = Integer.valueOf(readMethod.invoke(this).toString());
if (type == String.class) {
CharSequence charSequence = byteBuf.readCharSequence(integer, CharsetUtil.UTF_8);
writeMethod.invoke(this, charSequence);
} else {
byte[] bytes = new byte[integer];
byteBuf.readBytes(bytes);
writeMethod.invoke(this, bytes);
}
}
} else {
throw new RuntimeException(fieldName + " 没有@ProtocolField注解!!");
}
}
//对于BaseBodyCodec[]类型的 如果没有指定名长度则 一定是要放在最后 因为后面只能根据判断后面是否还存在可读字节
//来处理是否继续读取 一直循环下去
if (type.isArray() && type.getComponentType().getSuperclass() == BaseBodyCodec.class) {
Class componentType = type.getComponentType();
if (field.isAnnotationPresent(ProtocolField.class)) {
int itemLen = 0;
ProtocolField pf = field.getAnnotation(ProtocolField.class);
int len = pf.len();
String lenField = pf.lenField();
if (len != -1) {
itemLen = len;
} else if (!lenField.equals("")) {
PropertyDescriptor len_field_pd = new PropertyDescriptor(lenField, clazz);
Method readMethod = len_field_pd.getReadMethod();
itemLen = Integer.valueOf(readMethod.invoke(this).toString());
}
Object o = Array.newInstance(componentType, itemLen);
for (int j = 0; j < itemLen; j++) {
BaseBodyCodec item_o = (BaseBodyCodec) componentType.newInstance();
byteBuf.retain();
item_o.fillBodyPojo(byteBuf);
Array.set(o, j, item_o);
}
writeMethod.invoke(this, o);
} else {
//判断是不是最后一项
if (i == declaredFields.length - 1) {
ArrayList tmpList = new ArrayList();
while (byteBuf.isReadable()) {
BaseBodyCodec item_o = (BaseBodyCodec) componentType.newInstance();
byteBuf.retain();
item_o.fillBodyPojo(byteBuf);
tmpList.add(item_o);
}
Object[] objects = tmpList.toArray();
Object o = Array.newInstance(componentType, objects.length);
for (int j = 0; j < objects.length; j++) {
Array.set(o, j, objects[j]);
}
writeMethod.invoke(this, o);
} else {
throw new RuntimeException(fieldName + " 没有注解而且不是最后一项无法正常解析!!");
}
}
}
if (type.getSuperclass() == BaseBodyCodec.class) {
BaseBodyCodec o = (BaseBodyCodec) type.newInstance();
writeMethod.invoke(this, o);
byteBuf.retain();
o.fillBodyPojo(byteBuf);
}
}
}
return (T) this;
} catch (Exception e) {
e.printStackTrace();
} finally {
byteBuf.release();
}
}
return null;
}