Initial commit of alternative erlang lib


git-svn-id: https://svn.apache.org/repos/asf/incubator/thrift/trunk@666374 13f79535-47bb-0310-9956-ffa450edef68
diff --git a/lib/alterl/src/thrift_protocol.erl b/lib/alterl/src/thrift_protocol.erl
new file mode 100644
index 0000000..66e19b3
--- /dev/null
+++ b/lib/alterl/src/thrift_protocol.erl
@@ -0,0 +1,120 @@
+-module(thrift_protocol).
+
+-export([new/2,
+         write/2,
+         read/2,
+         skip/2,
+
+         typeid_to_atom/1,
+
+         behaviour_info/1]).
+
+-include("thrift_constants.hrl").
+-include("thrift_protocol.hrl").
+
+-record(protocol, {module, data}).
+
+behaviour_info(callbacks) ->
+    [
+     {read, 2},
+     {write, 2}
+    ];
+behaviour_info(_Else) -> undefined.
+
+
+new(Module, Data) when is_atom(Module) ->
+    {ok, #protocol{module = Module,
+                   data = Data}}.
+
+
+write(#protocol{module = Module,
+                data = ModuleData}, Data) ->
+    Module:write(ModuleData, Data).
+
+typeid_to_atom(?tType_STOP) -> field_stop;
+typeid_to_atom(?tType_VOID) -> void;
+typeid_to_atom(?tType_BOOL) -> bool;
+typeid_to_atom(?tType_BYTE) -> byte;
+typeid_to_atom(?tType_DOUBLE) -> double;
+typeid_to_atom(?tType_I16) -> i16;
+typeid_to_atom(?tType_I32) -> i32;
+typeid_to_atom(?tType_I64) -> i64;
+typeid_to_atom(?tType_STRING) -> string;
+typeid_to_atom(?tType_STRUCT) -> struct;
+typeid_to_atom(?tType_MAP) -> map;
+typeid_to_atom(?tType_SET) -> set;
+typeid_to_atom(?tType_LIST) -> list.
+    
+read(#protocol{module = Module,
+               data = ModuleData}, ProtocolType) ->
+    Module:read(ModuleData, ProtocolType).
+
+
+
+skip(Proto, struct) ->
+    ok = read(Proto, struct_begin),
+    ok = skip_struct_loop(Proto),
+    ok = read(Proto, struct_end);
+
+skip(Proto, map) ->
+    Map = read(Proto, map_begin),
+    ok = skip_map_loop(Proto, Map),
+    ok = read(Proto, map_end);
+
+skip(Proto, set) ->
+    Set = read(Proto, set_begin),
+    ok = skip_set_loop(Proto, Set),
+    ok = read(Proto, set_end);
+
+skip(Proto, list) ->
+    List = read(Proto, list_begin),
+    ok = skip_list_loop(Proto, List),
+    ok = read(Proto, list_end);    
+
+skip(Proto, Type) when is_atom(Type) ->
+    _Ignore = read(Proto, Type),
+    ok.
+
+
+skip_struct_loop(Proto) ->
+    #protocol_field_begin{type = Type} = read(Proto, field_begin),
+    case Type of
+        ?tType_STOP ->
+            ok;
+        _Else ->
+            skip(Proto, Type),
+            ok = read(Proto, field_end),
+            skip_struct_loop(Proto)
+    end.
+
+skip_map_loop(Proto, Map = #protocol_map_begin{ktype = Ktype,
+                                               vtype = Vtype,
+                                               size = Size}) ->
+    case Size of
+        N when N > 0 ->
+            skip(Proto, Ktype),
+            skip(Proto, Vtype),
+            skip_map_loop(Proto,
+                          Map#protocol_map_begin{size = Size - 1});
+        0 -> ok
+    end.
+
+skip_set_loop(Proto, Map = #protocol_set_begin{etype = Etype,
+                                               size = Size}) ->
+    case Size of
+        N when N > 0 ->
+            skip(Proto, Etype),
+            skip_set_loop(Proto,
+                          Map#protocol_set_begin{size = Size - 1});
+        0 -> ok
+    end.
+
+skip_list_loop(Proto, Map = #protocol_list_begin{etype = Etype,
+                                                 size = Size}) ->
+    case Size of
+        N when N > 0 ->
+            skip(Proto, Etype),
+            skip_list_loop(Proto,
+                           Map#protocol_list_begin{size = Size - 1});
+        0 -> ok
+    end.