封装完整的数据包
package com.net.tcp;
import java.lang.reflect.Field;
import java.util.ArrayList;
import java.util.Collection;
import java.util.HashMap;
import java.util.Iterator;
import java.util.List;
import java.util.Map;
/**
*
* 数据包
*
*/
public class DataPack {
/**包头*/
private DataHead head;
/**内容*/
private DataContent content;
public DataPack(){
head = new DataHead();
this.setContent(new DataContent());
}
public DataContent getContent() {
return content;
}
private void setContent(DataContent content) {
this.content = content;
head.setLen(this.content.remaining());
}
public DataHead getHead() {
return head;
}
public boolean isComplete(boolean filp) {
if(head.getLen() > 0){
if(filp){
if(head.getLen() == content.remaining()){
return true;
}
}else{
if(head.getLen() == content.position()){
return true;
}
}
}
return false;
}
public void filp(){
content.flip();
head.setLen(this.content.remaining());
}
public void rewind(){
content.rewind();
}
private short getType(){
return content.getShort();
}
@SuppressWarnings("unchecked")
private Object getObject(short type){
short type1 = type == DataType.TYPE_ALL ? this.getType() : type;
int len = 0;
switch(type1){
case DataType.TYPE_NULL:
return null;
case DataType.TYPE_BYTE:
return content.getByte();
case DataType.TYPE_SHORT:
return content.getShort();
case DataType.TYPE_INT:
return content.getInt();
case DataType.TYPE_DOUBLE:
return content.getDouble();
case DataType.TYPE_BOOL:
return content.getBoolean();
case DataType.TYPE_STRING:
len = content.getInt();
return content.getString(len);
case DataType.TYPE_STREAM_OBJECT:
StreamObject so = null;
try {
so = (StreamObject)StreamObjectManager.getClassByName((String)this.getObject(DataType.TYPE_STRING)).newInstance();
so.decode(this);
} catch (InstantiationException e) {
e.printStackTrace();
} catch (IllegalAccessException e) {
e.printStackTrace();
}
return so;
case DataType.TYPE_ARRAY:
List list = new ArrayList();
len = content.getInt();
if(len > 0){
short type2 = this.getType();
if(type2 == DataType.TYPE_STREAM_OBJECT){
StreamObject item = null;
Class c = StreamObjectManager.getClassByName((String)this.getObject(DataType.TYPE_STRING));
for(int i = 0; i < len; i++){
try {
item = (StreamObject)(c.newInstance());
item.decode(this);
} catch (InstantiationException e) {
e.printStackTrace();
} catch (IllegalAccessException e) {
e.printStackTrace();
}
list.add(item);
}
}else{
for(int i = 0; i < len; i++){
list.add(this.getObject(type2));
}
}
}
return list;
case DataType.TYPE_MAP:
Map map = new HashMap();
len = content.getInt();
if(len > 0){
String key = null;
Object value = null;
for(int i = 0; i < len; i++){
key = (String)this.getObject(DataType.TYPE_STRING);
value = this.getObject();
map.put(key, value);
}
}
return map;
default:
return this.getObject(DataType.TYPE_MAP);
}
}
public Object getObject(){
return this.getObject(DataType.TYPE_ALL);
}
private void putType(short type){
this.putObject(type, false, DataType.TYPE_SHORT);
}
private void putObject(Object value, boolean writeType, short ...types){
if(value == null){
content.putShort(DataType.TYPE_NULL);
}else if(value instanceof Number){
short type = types[0];
if(!DataType.isNumberByType(type)){
type = DataType.getTypeByObject(value);
}
if(writeType){
this.putType(type);
}
switch(type){
case DataType.TYPE_BYTE:
content.putByte((Byte)value);
break;
case DataType.TYPE_SHORT:
content.putShort((Short)value);
break;
case DataType.TYPE_INT:
content.putInt((Integer)value);
break;
default:
content.putDouble(((Number)value).doubleValue());
break;
}
}else if(value instanceof Boolean){
if(writeType){
this.putType(DataType.TYPE_BOOL);
}
content.putBoolean((Boolean)value);
}else if(value instanceof String){
if(writeType){
this.putType(DataType.TYPE_STRING);
}
byte[] bytes = ByteUtils.getBytes(value);
content.putInt(bytes.length);
content.putBytes(bytes);
}else if(value instanceof StreamObject){
if(writeType){
this.putType(DataType.TYPE_STREAM_OBJECT);
this.putObject(value.getClass().getSimpleName(), false, DataType.TYPE_STRING);
}
((StreamObject)value).encode(this);
}else if(value instanceof Collection){
if(writeType){
this.putType(DataType.TYPE_ARRAY);
}
Collection<?> collection = (Collection<?>)value;
int len = collection.size();
this.putObject(len, false, DataType.TYPE_INT);
if(len > 0){
Iterator<?> it = collection.iterator();
Object object = it.next();
if(object instanceof StreamObject){
this.putType(DataType.TYPE_STREAM_OBJECT);
this.putObject(object.getClass().getSimpleName(), false, DataType.TYPE_STRING);
}else if(object instanceof Number){
if(DataType.isNumberByType(types[1])){
this.putType(types[1]);
}else{
this.putType(DataType.getTypeByObject(object));
}
}else{
this.putType(DataType.getTypeByObject(object));
}
it = collection.iterator();
short[] types1 = new short[types.length - 1];
for(int i = 0; i < types1.length; i++){
types1[i] = types[i + 1];
}
while(it.hasNext()){
object = it.next();
this.putObject(object, false, types1);
}
}
}else if(value instanceof Map){
if(writeType){
this.putType(DataType.TYPE_MAP);
}
Map<?, ?> map = ((Map<?, ?>)value);
this.putObject(map.size(), false, DataType.TYPE_INT);
for(Map.Entry<?, ?> entry : map.entrySet()){
this.putObject(entry.getKey().toString(), false, DataType.TYPE_STRING);
this.putObject(entry.getValue(), true, DataType.TYPE_OBJECT);
}
}else{
if(writeType){
this.putType(DataType.TYPE_OBJECT);
}
Field[] fields = value.getClass().getDeclaredFields();
Field field = null;
this.putObject(fields.length, false, DataType.TYPE_INT);
for(int i = 0; i < fields.length; i++){
field = fields[i];
field.setAccessible(true);
this.putObject(field.getName(), false, DataType.TYPE_STRING);
try {
this.putObject(field.get(value), true, DataType.TYPE_OBJECT);
} catch (IllegalArgumentException e) {
e.printStackTrace();
} catch (IllegalAccessException e) {
e.printStackTrace();
}
}
}
}
public void putObject(Object value, short ...types){
putObject(value, true, types);
}
}