erlang与as3 socket 解析

这个解析类是我现在项目中用到的一个as3与erlang sokcet通信的一个类

解析出来的数据是数组

本想做成object的 不过这得服务器那边配合 服务器这边的工作量就会加大了 因为每一个值都要加一个元素符 这样才能构成object基本的组成元素

我们的做法是 服务端那边 返回的数据 在协作平台上把数据元素 列出来 前端做开发 就参考这个数据列表来做开发

BertClass.as文件定义一些字头类型

package app.model.comsocket.comParse {
/**
* 字节头类型
* @author zl-主程
*/
public class BertClass{
   public static const BERT_START:String = String.fromCharCode(131);
   public static const SMALL_ATOM:String = String.fromCharCode(115);
   public static const ATOM:String = String.fromCharCode(100);
   public static const BINARY:String = String.fromCharCode(109);
   public static const SMALL_INTEGER:String = String.fromCharCode(97);
   public static const INTEGER:String = String.fromCharCode(98);
   public static const SMALL_BIG:String = String.fromCharCode(110);
   public static const LARGE_BIG:String = String.fromCharCode(111);
   public static const FLOAT:String = String.fromCharCode(99);
   public static const STRING:String = String.fromCharCode(107);
   public static const LIST:String = String.fromCharCode(108);
   public static const SMALL_TUPLE:String = String.fromCharCode(104);
   public static const LARGE_TUPLE:String = String.fromCharCode(105);
   public static const NIL:String = String.fromCharCode(106);
   public static const ZERO:String = String.fromCharCode(0);
}

}

ParseSocketData.as 解析erlang神发送的二进制和发送数据给erlang神

package app.model.comsocket.comParse {
import app.utility.debug.Debug;
import flash.display.Sprite;
import flash.utils.ByteArray;
/**
* @author silva-主程
*/
public class ParseSocketData extends Sprite {
   public static function bytes_to_string(arr:ByteArray):String {
     var str:String = "";
     var len:int = arr.length;
    //Debug.log("len:" + arr.length);
    for (var i:int = 0; i < len; i++) {
     //Debug.log(arr[i])
      str += String.fromCharCode(arr[i]);
     }
    return str;
    }
   /**
    *
    * @param str Unicode 字符代码
    * @return
    */
   public static function decode(str:String):Array {
    if (String.fromCharCode(str.charCodeAt(0)) != BertClass.BERT_START) {
      Debug.error("不是有效的二进制");
     return [];
     }
     var Obj:Object = decode_inner(str.substring(1));
    try {
     if (Obj.rest !== "") {
       Debug.error("空");
      }
     }catch (e:Error) {
      Debug.error("解析出错!!" + e.toString());
     }
  
    return Obj.value;
    };
   /**
    * 从不同类型中拿数据
    * @param str
    */
   private static function decode_inner(str:String):Object {
     var Type:String = String.fromCharCode(str.charCodeAt(0));
    //Debug.log("Type:"+str.charCodeAt(0));
    //跳过头
     var str:String = str.substring(1);
    switch (Type) {
     case BertClass.SMALL_INTEGER:
      //97
      return decode_integer(str, 1);
     break;
     case BertClass.INTEGER:
      //98
      return decode_integer(str, 4);
     break;
     case BertClass.SMALL_ATOM:
      //115
      return decode_atom(str, 1);
     break;
     case BertClass.FLOAT:
      //99
      return decode_float(str);
     break;
     case BertClass.ATOM:
      //常量 100
      return decode_atom(str, 2);
     break;
     case BertClass.STRING:
      //字符型 107
      return decode_string(str);
     case BertClass.LIST:
      //LIST 108
      return decode_list(str);
     break;
     case BertClass.SMALL_TUPLE:
      //104 {}
      return decode_tuple(str, 1);
     break;
     case BertClass.NIL:
      //
      return decode_nil(str);
     break;
     case BertClass.SMALL_BIG:
      //110
      return decode_big(str, 1);
     break;
     case BertClass.LARGE_BIG:
      //111
      return decode_big(str, 4);
     break;
     default:
       Debug.error("找不到字节头类型" + str.charCodeAt(0));
       Debug.error("找不到字节头类型" + Type==BertClass.SMALL_INTEGER);
       Debug.error("找不到字节头类型" + Type);
       Debug.error("找不到字节头类型" + BertClass.SMALL_INTEGER);
      return {
        value:null
       };
      }
    };
   /**
    * 97 98 获取
    * @param str
    * @param count
    */
   private static function decode_integer(str:String, count:int):Object {
     var Value:int = bytes_to_int(str, count);
     var temStr:String = str.substring(count);
    return {
      value: Value,
      rest: temStr
     };
    };
   /**
    * 99
    * @param str
    * @return
    */
   private static function decode_float(str:String):Object {
     var Size:int = 31;
    return {
      value: parseFloat(str.substring(0, Size)),
      rest: str.substring(Size)
     };
    };
   /**
    * 100 常量字符获取
    * @param str
    * @param count
    * @return
    */
   private static function decode_atom(str:String, count:int):Object {
     var Size:int;
     Size = bytes_to_int(str, count);
     var temStr:String = str.substring(count);
     var value:String;
     var temBy:ByteArray = new ByteArray();
    for (var i:int = 0; i < Size; i++) {
      temBy.writeByte(temStr.charCodeAt(i));
     }
     temBy.position = 0;
     value = temBy.readUTFBytes(Size);
    return {
      value:value,
      rest:temStr.substring(Size)
     }
    };
 
   private static function decode_nil(str:String):Object {
    // nil is an empty list
    return {
      value: [],
      rest: str
     };
    };
   /**
    * 107
    * 获取字符串
    * @param str
    */
   private static function decode_string(str:String):Object {
     var Size:int = bytes_to_int(str, 2);
     var temStr:String = str.substring(2);
     var temBy:ByteArray = new ByteArray();
     var value:String;
    for (var i:int = 0; i < Size; i++) {
      temBy.writeByte(temStr.charCodeAt(i));
     }
     temBy.position = 0;
     value = temBy.readUTFBytes(Size);
    return {
      value: value,
      rest: temStr.substring(Size)
     };
    };
   /**
    * 104
    * @param str
    * @param count
    * @return
    */
   private static function decode_tuple(str:String, count:int):Object {
     var Arr:Array = new Array();
     var El:Object;
     var Size:int = bytes_to_int(str, count);
     var temStr:String = str.substring(count);
    for (var i:int = 0; i < Size; i++) {
      El = decode_inner(temStr);
      Arr.push(El.value);
      temStr = El.rest;
     }
    return {
      value: Arr,
      rest: temStr
     };
    };
   /**
    * 108
    */
   private static function decode_list(str:String):Object {
     var Size:int;
     var El:Object;
     var LastChar:String;
     var Arr:Array = new Array();
     Size = bytes_to_int(str, 4);
     var temStr:String = str.substring(4);
    for (var i:int = 0; i < Size; i++) {
      El = decode_inner(temStr);
      Arr.push(El.value);
      temStr = El.rest;
     }
     LastChar = String.fromCharCode(temStr.charCodeAt(0));
    if (LastChar != BertClass.NIL) {
      Debug.error("数组未结束");
     }
     var temStr2:String = temStr.substring(1);
    return {
      value: Arr,
      rest: temStr2
     };
    };
   /**
    * 110 111
    */
   private static function decode_big(str:String, count:int):Object {
     var Size:int, Value:Number;
     Size = bytes_to_int(str, count);
     var temStr:String = str.substring(count);
     Value = bytes_to_bignum(temStr, Size);
    return {
      value : Value,
      rest: temStr.substring(Size + 1)
     };
    };
   /**
    * 大数字算法
    * @param str
    * @param count
    */
   private static function bytes_to_bignum(str:String, count:int):Number {
     var isNegative:Boolean;
     var n:Number;
     var Num:Number;
     isNegative = (str.charCodeAt(0) === 1);
     str = str.substring(1);
    for (var i:int = count - 1; i >= 0; i--) {
      n = str.charCodeAt(i);
     if (Num === 0) {
       Num = n;
      }
     else {
       Num = Num * 256 + n;
      }
     }
    if (isNegative) {
     return Num * -1;
     }
    return Num;
    };
   /**
    * 返回获取数据的长度
    * @param str
    * @param Length
    * @return
    */
   private static function bytes_to_int(str:String, Length:int):int {
     var isNegative:Boolean;
     var n:Number ;
     var Num:int;
     isNegative = (str.charCodeAt(0) > 128);
    for (var i:int = 0; i < Length; i++) {
      n = str.charCodeAt(i);
     if (isNegative) {
       n = 255 - n;
      }
     if (Num === 0) {
       Num = n;
      }else {
       Num = Num * 256 + n;
      }
     }
    if (isNegative) {
      Num = Num * (0 - 1);
     }
    return Num;
    };
   ///----发送---
   /**
    * 发送数据解析
    * @param _arr:Array 发送数据数组
    * @return 返回ByteArray 对象
    */
   public static function parseSendData(_arr:Array):ByteArray {
     var TemByteArr:ByteArray = new ByteArray();
     var ReturnTemArr:ByteArray = new ByteArray();
     var temBy:Array = new Array();
    //TemByteArr.writeShort(_arr.length);
     TemByteArr.writeByte(131);
     TemByteArr.writeByte(104);
     TemByteArr.writeByte(_arr.length);
     temBy = sendData(_arr);
    for (var i :int = 0; i < temBy.length; i++) {
     //Debug.log(temBy[i])
      TemByteArr.writeByte(temBy[i]);
     }
     ReturnTemArr.writeUnsignedInt(TemByteArr.length);
    //加密发送
     ReturnTemArr.writeBytes(Encrypt.enArc4(TemByteArr));
    return ReturnTemArr as ByteArray;
    }
   /**
    * 声明 暂时没找到AS3区分字符串与常量的办法 故已特殊字符做了一下处理
    * @param _arr:Array 查询数组
    * @return 二进制数组
    */
   private static function sendData(_arr:Array):Array {
     var len:int = _arr.length;
     var SendByteArray:Array = new Array();
    for (var s:int = 0; s < len; s++) {
     if (_arr[s] is String) {
      if (_arr[s].substr(0, 6) == "const@") {
        SendByteArray=SendByteArray.concat(DataUtil.parseCode(_arr[s].split(/@/)[1], "const"));
       }else {
        SendByteArray=SendByteArray.concat(DataUtil.parseCode(_arr[s], "string"));
       }
      }else if (_arr[s] is Number) {
       SendByteArray = SendByteArray.concat(DataUtil.parseCode(_arr[s], "number"));
      }else if (_arr[s] is Array) {
       SendByteArray = SendByteArray.concat([104,_arr[s].length]);
       sendData(_arr[s]);
      continue;
      }
     }
  
    return SendByteArray as Array;
    }
}
}

你可能感兴趣的:(算法,erlang,socket,REST,Flash)