/**
   * @Title: decode @Description: TODO 解码器
   *
   * @author anlong
   * @throws
   */
  @SuppressWarnings("static-access")
  public void decode(InputStream stream) throws Exception {
    try {
      // 输入IO流
      inputStream = stream;
      if (inputStream == null) {
        IMLog.anlong("IO流中没有数据响应!");
        throw new IOException();
      }

      // 消息体字节大小,不包括表示大小的4个字节
      int limit = 0;

      // 消息字节大小,包括表示大小的4个字节
      int msgSize = 0;

      // 消息字节数组
      byte[] data = null;

      // 保证IO流中可读字节数大于 4个字节
      byte[] dataSize = new byte[HandleStaticValue.PROTOCOL_SIZE];

      if (inputStream.read(dataSize) == HandleStaticValue.PROTOCOL_SIZE) {
        msgSize = ByteAndInt.byteArray2Int(dataSize);
        IMLog.anlong("响应报文字节大小:" + msgSize);

        // 标识从该处读取剩余字节数
        limit = msgSize - HandleStaticValue.PROTOCOL_SIZE;
        IMLog.anlong("响应报文体字节数:" + limit + "=" + Utils.getFileSizeString((long) limit));

        // TODO 大于10M丢弃
        if (limit > 10000000) {
          IMLog.anlong("丢弃一个大小为 " + limit + "的数据包!");

          throw new IOException();
        }

        // 定义消息字节数组大小
        data = new byte[limit];
      }

      // 循环读取消息字节
      int len = 0;
      while (len < limit) {
        len += inputStream.read(data, len, (limit - len));
        IMLog.anlong("读取字节数:" + len);
      }

      if (data == null) throw new IOException();

      IMLog.anlong("读取流完成,byte[]的长度:" + data.length);
      dataInputStream = new DataInputStream(new ByteArrayInputStream(data));

      if (dataInputStream != null) {
        // 业务编码
        short bCode = dataInputStream.readShort();
        // 密钥
        int key = dataInputStream.readInt();
        // 用户ID
        int uid = dataInputStream.readInt();
        // 返回编码
        short rtCode = dataInputStream.readShort();
        // 错误编码
        String rtMsg = dataInputStream.readUTF();
        // 消息流水号
        int msgSerial = dataInputStream.readInt();

        // 消息头打印
        IMLog.anlong(
            "limit size:"
                + limit
                + " bCode:"
                + bCode
                + " key:"
                + key
                + " uid:"
                + uid
                + " rtCode:"
                + rtCode
                + " rtMsg:"
                + rtMsg
                + " msgSerial:"
                + msgSerial);

        if (bCode == 0) {
          IMLog.anlong("业务编码错误!");
          throw new IOException();
        }

        // 获取对象
        String requestPath = HandleStaticValue.RESPONSE_PACKEAGE + ".Response" + bCode;
        Class requestClass = Class.forName(requestPath);

        // 解析消息体
        Object obj = ReadValue(requestClass, dataInputStream);

        // 反射设置消息头
        ReflectionUtil.invokeMethod(
            obj, "init", msgSize, bCode, key, uid, rtCode, rtMsg, msgSerial);

        // 分发事件
        try {
          if (bCode != 0 && obj != null) {
            MessageEvent event = new MessageEvent(bCode, obj);
            new MessageEventSource().getSingleton().notifyMessageEvent(event);
          }
        } catch (Exception e) {
          IMLog.anlong("监听队列没有找到 " + bCode + "!");
          IMLog.anlong("已丢弃一个没有注册监听的数据包:" + bCode + "!");
          throw e;
        }

      } else {
        IMLog.anlong("没有数据响应!");
        throw new Exception();
      }

    } catch (Exception e) {
      throw e;
    }
  }
  /** 利用反射解析IO数据,返回数据对象 */
  @SuppressWarnings("unchecked")
  private Object ReadValue(Class<Object> clz, DataInputStream dataInputStream) {

    // 创建对象实例
    Object obj = null;
    try {
      obj = clz.newInstance();
    } catch (InstantiationException e1) {
      // TODO Auto-generated catch block
      e1.printStackTrace();
    } catch (IllegalAccessException e1) {
      // TODO Auto-generated catch block
      e1.printStackTrace();
    }
    // 反射对象名称List集合
    Field arrField = null;
    try {
      arrField = obj.getClass().getDeclaredField("fieldArr");
    } catch (NoSuchFieldException e1) {
      // TODO Auto-generated catch block
      e1.printStackTrace();
    }
    arrField.setAccessible(true);
    String[] fieldList = null;
    try {
      fieldList = (String[]) arrField.get(obj);
    } catch (IllegalArgumentException e1) {
      // TODO Auto-generated catch block
      e1.printStackTrace();
    } catch (IllegalAccessException e1) {
      // TODO Auto-generated catch block
      e1.printStackTrace();
    }

    // 属性类型
    String fieldType = null;
    // 首字母大写名称
    String fieldNameUpper = null;

    for (String fieldName : fieldList) {
      Field field = null;
      try {
        field = obj.getClass().getDeclaredField(fieldName);
      } catch (NoSuchFieldException e1) {
        Log.e(TAG, "无法找到映射解析类------------->" + fieldName);
        continue;
      }
      fieldType = field.getType().getSimpleName();
      fieldNameUpper = Character.toUpperCase(fieldName.charAt(0)) + fieldName.substring(1);

      if (fieldType.equals("Byte")) {
        /*byte val = dataInputStream.readByte();
        IMLog.anlong(fieldNameUpper + ": " + val);
        ReflectionUtil.invokeMethod(obj, "set"+fieldNameUpper, val);*/

        try {
          ReflectionUtil.invokeMethod(obj, "set" + fieldNameUpper, dataInputStream.readByte());
        } catch (Exception e) {
          Log.e(TAG, "映射解析--Byte--错误->set" + fieldNameUpper);
          continue;
        }
      } else if (fieldType.equals("Short")) {
        //					short val = dataInputStream.readShort();
        //					IMLog.anlong(fieldNameUpper + ": " + val);
        //					ReflectionUtil.invokeMethod(obj, "set"+fieldNameUpper, val);

        try {
          ReflectionUtil.invokeMethod(obj, "set" + fieldNameUpper, dataInputStream.readShort());
        } catch (Exception e) {
          Log.e(TAG, "映射解析--Short--错误->set" + fieldNameUpper);
          continue;
        }
      } else if (fieldType.equals("Integer")) {
        //					int val = dataInputStream.readInt();
        //					IMLog.anlong(fieldNameUpper + ": " + val);
        //					ReflectionUtil.invokeMethod(obj, "set"+fieldNameUpper, val);

        try {
          ReflectionUtil.invokeMethod(obj, "set" + fieldNameUpper, dataInputStream.readInt());
        } catch (Exception e) {
          Log.e(TAG, "映射解析--Integer--错误->set" + fieldNameUpper);
          continue;
        }
      } else if (fieldType.equals("String")) {
        String value = null;
        try {
          value = dataInputStream.readUTF();
        } catch (IOException e1) {
          Log.e(TAG, "映射解析--readUTF--错误->set" + fieldNameUpper);
          continue;
        }
        IMLog.anlong(fieldNameUpper + ": " + value);
        if (value.equals("蔡健")) {
          Log.e("debug", "-------------出现警告解析");
        }
        try {
          ReflectionUtil.invokeMethod(obj, "set" + fieldNameUpper, value);
        } catch (Exception e) {
          Log.e(TAG, "映射解析--String--错误->set" + fieldNameUpper);
          continue;
        }

      } else if (fieldType.equals("List")) { // 集合数据类型
        // 数组长度
        short arrSize = 0;
        try {
          arrSize = dataInputStream.readShort();
        } catch (IOException e) {
          Log.e(TAG, "映射解析集合数据类型--List--错误->");
          continue;
        }
        Type fc = field.getGenericType();
        List<Object> list = new ArrayList<Object>();

        // 这里判断是泛型集合
        if (fc instanceof ParameterizedType) {
          ParameterizedType pt = (ParameterizedType) fc;
          // 得到泛型里的class类型对象。
          Class<Object> genericClazz = (Class<Object>) pt.getActualTypeArguments()[0];

          // 向集合添加数据
          for (int i = 0; i < arrSize; i++) {

            try {
              // 基本数据类型
              if (genericClazz.getSimpleName().equals("Byte")) {
                list.add(dataInputStream.readByte());

              } else if (genericClazz.getSimpleName().equals("Short")) {
                list.add(dataInputStream.readShort());

              } else if (genericClazz.getSimpleName().equals("Integer")) {
                list.add(dataInputStream.readInt());

              } else if (genericClazz.getSimpleName().equals("String")) {
                String str = dataInputStream.readUTF();
                list.add(str);
              } else { // 自定义数据类型
                // 获取对象大小
                int byteCount = dataInputStream.readShort();
                IMLog.anlong("[响应]对象大小:" + byteCount);

                byte[] objdata = new byte[byteCount];
                dataInputStream.readFully(objdata, 0, byteCount);
                DataInputStream dataInputStream1 =
                    new DataInputStream(new ByteArrayInputStream(objdata));

                // 递归获取对象信息
                list.add(ReadValue(genericClazz, dataInputStream1));
              }
            } catch (IOException e) {
              Log.e(TAG, "映射解析集合数据类型--List--错误->");
              continue;
            }
          }

          // 反射设置list集合
          Method method2 = null;
          try {
            method2 = clz.getMethod("set" + fieldNameUpper, List.class);
          } catch (NoSuchMethodException e1) {
            Log.e(TAG, "映射解析反射设置list集合--List--错误->  set" + fieldNameUpper);
            continue;
          }
          try {
            method2.invoke(obj, list);
          } catch (Exception e) {
            e.printStackTrace();
            continue;
          }
        }
      } else { // 自定义数据类型
        String requestPath = HandleStaticValue.RESPONSE_VO + "." + fieldType;
        Class requestClass = null;
        try {
          requestClass = Class.forName(requestPath);
        } catch (ClassNotFoundException e) {
          Log.e(TAG, "映射解析自定义数据类型----错误->" + requestPath);
          e.printStackTrace();
          continue;
        }
        try {
          ReflectionUtil.invokeMethod(
              obj, "set" + fieldNameUpper, ReadValue(requestClass, dataInputStream));
        } catch (Exception e) {
          Log.e(TAG, "映射解析自定义数据类型错误===注意字符类型->" + requestPath);
          e.printStackTrace();
          continue;
        }
      }
    }

    return obj;
  }