java flash tcp字节流通信(一)-java 协议(5)

来源:互联网 发布:mac imovie使用教程 编辑:程序博客网 时间:2024/06/05 09:17

封装完整的数据包

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);
 }
}

 

原创粉丝点击