Chinaunix首页 | 论坛 | 博客
  • 博客访问: 5119164
  • 博文数量: 921
  • 博客积分: 16037
  • 博客等级: 上将
  • 技术积分: 8469
  • 用 户 组: 普通用户
  • 注册时间: 2006-04-05 02:08
文章分类

全部博文(921)

文章存档

2020年(1)

2019年(3)

2018年(3)

2017年(6)

2016年(47)

2015年(72)

2014年(25)

2013年(72)

2012年(125)

2011年(182)

2010年(42)

2009年(14)

2008年(85)

2007年(89)

2006年(155)

分类: Python/Ruby

2012-12-08 15:36:03

 
include/ems.hrl

 
  1. -define(INTEGER_MAX, 268435455).
  2. -define(INTEGER_MIN, -268435456).
  3. -define(MAX_RESTART, 5).
  4. -define(MAX_TIME, 60).
  5. -define(TIMEOUT, 120000).
  6. -define(HS_HEADER, 3).
  7. -define(HS_BODY_LEN, 1536).
  8. -define(MIN_CLIENT_BUFFER, 100).


  9. %% AMF3 data
  10. -define(AMF3_UNDEFINED, 0).
  11. -define(AMF3_NULL, 1).
  12. -define(AMF3_FALSE, 2).
  13. -define(AMF3_TRUE, 3).
  14. -define(AMF3_INTEGER, 4).
  15. -define(AMF3_NUMBER, 5).
  16. -define(AMF3_STRING, 6).
  17. -define(AMF3_XML, 7).
  18. -define(AMF3_DATE,.
  19. -define(AMF3_ARRAY, 9).
  20. -define(AMF3_OBJECT, 10).
  21. -define(AMF3_XML_STRING, 11).

  22. -define(AMF3_OBJECT_OBJ_INLINE, 1).
  23. -define(AMF3_OBJECT_CLASS_INLINE, 2).
  24. -define(AMF3_OBJECT_PROP_DEF, 4).
  25. -define(AMF3_OBJECT_PROP_SERIAL,.

  26. %% AMF object
  27. -define(AMF3_OBJECT_PROPERTY, 0).
  28. -define(AMF3_OBJECT_EXTERNALIZABLE, 1).
  29. -define(AMF3_OBJECT_VALUE, 2).
  30. -define(AMF3_OBJECT_PROXY, 3).


  31. -record(channel,{
  32. id = undefined,
  33. timestamp = undefined,
  34. length = undefined,
  35. type = undefined,
  36. stream = undefined,
  37. msg = undefined
  38. }).


  39. -record(amf,{
  40. command = [],
  41. id = [],
  42. args = [],
  43. type = invoke %if invoke then id, otherwise notify
  44. }).


  45. -record(amf3, {strings=nil, stringcount=0, objectcount=0,objects=nil}).
  46.     
  47. -record(as_object, {type=nil,keyValue=nil,externalizable=false,dynamic=false}).
 
ems_amf3.erl
 

  1. -module(ems_amf3).
  2. -export([decode/1, decode/3]).
  3. -export([parse_integer/1, parse_string/2,
  4.      parse_array/3, parse_object/3]).
  5. -export([get/2]).

  6. -include("../include/ems.hrl").

  7. decode(Data) ->
  8.     <<Code, Rest/binary>> = iolist_to_binary(Data),
  9.     {Value, Rest_, State} = decode(Code, Rest, #amf3{}),
  10.     {{amf3, Value, State}, Rest_}.

  11. decode(?AMF3_UNDEFINED, Data, S) ->
  12.     {undefined, Data, S};
  13. decode(?AMF3_NULL, Data, S) ->
  14.     {null, Data, S};
  15. decode(?AMF3_FALSE, Data, S) ->
  16.     {false, Data, S};
  17. decode(?AMF3_TRUE, Data, S) ->
  18.     {true, Data, S};
  19. decode(?AMF3_INTEGER, Data, S) ->
  20.     {Num, Rest} = parse_integer(Data),
  21.     {Num, Rest, S};
  22. decode(?AMF3_NUMBER, Data, S) ->
  23.     <<Float:64/float, Rest/binary>> = Data,
  24.     {Float, Rest, S};
  25. decode(?AMF3_STRING, Data, S) ->
  26.     parse_string(Data, S);
  27. decode(?AMF3_XML, Data, S) ->
  28.     {String, Rest, S1} = parse_string(Data, S),
  29.     {{xml, String}, Rest, S1};
  30. decode(?AMF3_DATE, Data, S) ->
  31.     {Type, Rest1} = parse_integer(Data),
  32.     case Type band 1 of
  33.     1 ->
  34.      <<Float:64/float, Rest2/binary>> = Rest1,
  35.      {Ref, S1} = add_object({date, ems_util:float_to_datetime(Float/1000)}, S),
  36.      {Ref, Rest2, S1};
  37.     0 ->
  38.      {{ref, Type bsr 1}, Rest1, S}
  39.     end;
  40. decode(?AMF3_ARRAY, Data, S) ->
  41.     {Type, Rest1} = parse_integer(Data),
  42.     Length = Type bsr 1,
  43.     case Type band 1 of
  44.     1 ->
  45.      parse_array(Length, Rest1, S);
  46.     0 ->
  47.      {{ref, Length}, Rest1, S}
  48.     end;
  49. decode(?AMF3_OBJECT, Data, S) ->
  50.     {Type, Rest1} = parse_integer(Data),
  51.     TypeInfo = Type bsr 1,
  52.     case Type band 1 of
  53.     0 ->
  54.         {{ref, TypeInfo}, Rest1, S}; %% o-ref
  55.     1 ->
  56.      parse_object(Type, Rest1, S)
  57.     end;
  58. decode(?AMF3_XML_STRING, Data, S) ->
  59.     {Type, Rest1} = parse_integer(Data),
  60.     0 = Type band 1,
  61.     Length = Type bsr 1,
  62.     <<String:Length/binary, Rest2/binary>> = Rest1,
  63.     {{xml, String}, Rest2, S}.

  64. parse_integer(Data) ->
  65.     parse_integer(Data, 0, 0).

  66. parse_integer(<<1:1, Num:7, Data/binary>>, Result, N) when N < 3 ->
  67.     parse_integer(Data, (Result bsl 7) bor Num, N + 1);
  68. parse_integer(<<0:1, Num:7, Data/binary>>, Result, N) when N < 3 ->
  69.     {(Result bsl 7) bor Num, Data};
  70. parse_integer(<<Byte, Data/binary>>, Result, _N) ->
  71.     Result1 = (Result bsl 8) bor Byte,
  72.     Result3 = case Result1 band 16#10000000 of
  73.          16#10000000 ->
  74.          Extended = Result1 bor 16#e0000000,
  75.          <<Result2:32/signed>> = <<Extended:32>>,
  76.          Result2;
  77.          0 ->
  78.          Result1
  79.      end,
  80.     {Result3, Data}.

  81. parse_string(Data, S) ->
  82.     {Type, Rest} = parse_integer(Data),
  83.     Length = Type bsr 1,
  84.     case Type band 1 of
  85.     0 ->
  86.      {get_string(Length, S), Rest, S};
  87.     1 ->
  88.         <<StringB:Length/binary, Rest1/binary>> = Rest,
  89.      {String,S1} = add_string(binary_to_list(StringB), S),
  90.      {String, Rest1, S1}
  91.     end.

  92. parse_array(Length, <<1, Data/binary>>, S) ->
  93.     {RefNum, S1} = new_object(S),
  94.     {Array, Rest, S2} = parse_array(Length, Data, S1, [], Length),
  95.     {Ref, S3} = finish_object(RefNum, Array, S2),
  96.     {Ref, Rest, S3}.

  97. parse_array(0, Data, S, Acc, OrigLength) ->
  98.     {{array, OrigLength, lists:reverse(Acc)}, Data, S};
  99. parse_array(Length, Data, S, Acc, OrigLength) ->
  100.     <<Code, Data1/binary>> = Data,
  101.     {Item, Rest, S1} = decode(Code, Data1, S),
  102.     parse_array(Length - 1, Rest, S1, [Item | Acc], OrigLength).

  103. parse_object(Type, Data, S) ->
  104.     {RefNum, S1} = new_object(S),
  105.     {Object, Rest1, S2} = parse_object_info(Type, Data, S1),
  106.     {Ref, S3} = finish_object(RefNum, Object, S2),
  107.     {Ref, Rest1, S3}.

  108. %%traits-ref
  109. parse_object_info(Type, Data, S) when (Type band 3) == 1 ->
  110.     {Type, Data, S};
  111. %%traits-ext
  112. parse_object_info(Type, Data, S) when (Type band 7) == 7 ->
  113.     {Type, Data, S};
  114. parse_object_info(Type, Data, S) ->
  115.     Externalizable = ((Type band 4) == 4),
  116.     Dynamic = ((Type band 8) == 8),
  117.     {ClassName, Rest, S1} = parse_string(Data, S),
  118.     Count = Type bsr 4,
  119.     {Rest1,S2,NameList} = readPropertyName(Count,Rest,S1,Count,[]),
  120.     {Rest2,S3,ValueList} = readPropertyValue(Count,Rest1,S2,Count,[]),
  121.     KeyValues = keyValue(NameList,ValueList,[]),
  122.     {Rest3,S4,KeyValues1} = readDynamicProperty(Dynamic,Rest2,S3,KeyValues,true),
  123.     Object = #as_object{type=ClassName,keyValue=KeyValues1,externalizable=Externalizable,dynamic=Dynamic},
  124.     {Object, Rest3, S4}.



  125. readPropertyName(0,Data,S,Length,List) ->
  126.     {Data,S,lists:reverse(List)};
  127. readPropertyName(Index,Data,S,Length,List) ->
  128.     {String, Rest1, S1} = parse_string(Data,S),
  129.     readPropertyName(Index-1,Rest1,S1,Length,[String|List]).

  130. readPropertyValue(0,Data,S,Length,List) ->
  131.     {Data,S,lists:reverse(List)};
  132. readPropertyValue(Index,Data,S,Length,List) ->
  133.     <<Code, Rest/binary>> = iolist_to_binary(Data),
  134.     {Ref, Rest1, S1} = decode(Code, Rest, S),
  135.     readPropertyValue(Index-1,Rest1,S1,Length,[get(Ref,S1)|List]).

  136. readDynamicProperty(_,Data,S,KeyValues,false) ->
  137.     {<<>>,S,KeyValues};
  138. readDynamicProperty(false,Data,S,KeyValues,_) ->
  139.     {Data,S,KeyValues};
  140. readDynamicProperty(true,Data,S,KeyValues,_) ->
  141.     {String, Rest1, S1} = parse_string(Data,S),
  142.     <<Code, Rest2/binary>> = iolist_to_binary(Rest1),
  143.     {Ref, Rest3, S2} = decode(Code, Rest2, S1),
  144.     {String1, _, _} = parse_string(Rest3,S2),
  145.     Loop = (String1 =/= ""),
  146.     readDynamicProperty(true,Rest3,S2,[{String,get(Ref,S2)}|KeyValues],Loop).


  147. keyValue([],[],KeyValues) ->
  148.     KeyValues;
  149. keyValue([Name|Names],[Value|Values],KeyValues) ->
  150.     keyValue(Names,Values,[{list_to_atom(Name),Value}|KeyValues]).

  151. add_object(Object, S) ->
  152.     OldTree = case S#amf3.objects of
  153.          nil ->
  154.          gb_trees:from_orddict([]);
  155.          _Tree ->
  156.          _Tree
  157.      end,
  158.     RefNum = S#amf3.objectcount,
  159.     Tree = gb_trees:insert(RefNum, Object, OldTree),
  160.     {{ref, RefNum}, S#amf3{objects=Tree, objectcount=1 + RefNum}}.

  161. new_object(S) ->
  162.     RefNum = S#amf3.objectcount,
  163.     {RefNum, S#amf3{objectcount=1 + RefNum}}.

  164. finish_object(RefNum, Object, S) ->
  165.     OldTree = case S#amf3.objects of
  166.          nil ->
  167.          gb_trees:from_orddict([]);
  168.          _Tree ->
  169.          _Tree
  170.      end,
  171.     Tree = gb_trees:insert(RefNum, Object, OldTree),
  172.     {{ref, RefNum}, S#amf3{objects=Tree}}.

  173. add_string("", S) ->
  174.     {"",S};
  175. add_string(String, S) ->
  176.     OldTree = case S#amf3.strings of
  177.          nil ->
  178.          gb_trees:from_orddict([]);
  179.          _Tree ->
  180.          _Tree
  181.      end,
  182.     RefNum = S#amf3.stringcount,
  183.     Tree = gb_trees:insert(RefNum, String, OldTree),
  184.     {String, S#amf3{strings=Tree, stringcount=1 + RefNum}}.

  185. get_object(RefNum, S) ->
  186.     gb_trees:get(RefNum, S#amf3.objects).

  187. get_string(RefNum, S) ->
  188.     gb_trees:get(RefNum, S#amf3.strings).

  189. get({ref, RefNum}, S) ->
  190.     get_object(RefNum, S);
  191. get(Object, _) ->
  192.     Object.

文章来自:http://kebo.iteye.com/blog/415764
阅读(2221) | 评论(0) | 转发(0) |
给主人留下些什么吧!~~