blob: 66e19b38117045692f446512d77a35c8bd88eb3a [file] [log] [blame]
David Reissac549552008-06-10 22:56:59 +00001-module(thrift_protocol).
2
3-export([new/2,
4 write/2,
5 read/2,
6 skip/2,
7
8 typeid_to_atom/1,
9
10 behaviour_info/1]).
11
12-include("thrift_constants.hrl").
13-include("thrift_protocol.hrl").
14
15-record(protocol, {module, data}).
16
17behaviour_info(callbacks) ->
18 [
19 {read, 2},
20 {write, 2}
21 ];
22behaviour_info(_Else) -> undefined.
23
24
25new(Module, Data) when is_atom(Module) ->
26 {ok, #protocol{module = Module,
27 data = Data}}.
28
29
30write(#protocol{module = Module,
31 data = ModuleData}, Data) ->
32 Module:write(ModuleData, Data).
33
34typeid_to_atom(?tType_STOP) -> field_stop;
35typeid_to_atom(?tType_VOID) -> void;
36typeid_to_atom(?tType_BOOL) -> bool;
37typeid_to_atom(?tType_BYTE) -> byte;
38typeid_to_atom(?tType_DOUBLE) -> double;
39typeid_to_atom(?tType_I16) -> i16;
40typeid_to_atom(?tType_I32) -> i32;
41typeid_to_atom(?tType_I64) -> i64;
42typeid_to_atom(?tType_STRING) -> string;
43typeid_to_atom(?tType_STRUCT) -> struct;
44typeid_to_atom(?tType_MAP) -> map;
45typeid_to_atom(?tType_SET) -> set;
46typeid_to_atom(?tType_LIST) -> list.
47
48read(#protocol{module = Module,
49 data = ModuleData}, ProtocolType) ->
50 Module:read(ModuleData, ProtocolType).
51
52
53
54skip(Proto, struct) ->
55 ok = read(Proto, struct_begin),
56 ok = skip_struct_loop(Proto),
57 ok = read(Proto, struct_end);
58
59skip(Proto, map) ->
60 Map = read(Proto, map_begin),
61 ok = skip_map_loop(Proto, Map),
62 ok = read(Proto, map_end);
63
64skip(Proto, set) ->
65 Set = read(Proto, set_begin),
66 ok = skip_set_loop(Proto, Set),
67 ok = read(Proto, set_end);
68
69skip(Proto, list) ->
70 List = read(Proto, list_begin),
71 ok = skip_list_loop(Proto, List),
72 ok = read(Proto, list_end);
73
74skip(Proto, Type) when is_atom(Type) ->
75 _Ignore = read(Proto, Type),
76 ok.
77
78
79skip_struct_loop(Proto) ->
80 #protocol_field_begin{type = Type} = read(Proto, field_begin),
81 case Type of
82 ?tType_STOP ->
83 ok;
84 _Else ->
85 skip(Proto, Type),
86 ok = read(Proto, field_end),
87 skip_struct_loop(Proto)
88 end.
89
90skip_map_loop(Proto, Map = #protocol_map_begin{ktype = Ktype,
91 vtype = Vtype,
92 size = Size}) ->
93 case Size of
94 N when N > 0 ->
95 skip(Proto, Ktype),
96 skip(Proto, Vtype),
97 skip_map_loop(Proto,
98 Map#protocol_map_begin{size = Size - 1});
99 0 -> ok
100 end.
101
102skip_set_loop(Proto, Map = #protocol_set_begin{etype = Etype,
103 size = Size}) ->
104 case Size of
105 N when N > 0 ->
106 skip(Proto, Etype),
107 skip_set_loop(Proto,
108 Map#protocol_set_begin{size = Size - 1});
109 0 -> ok
110 end.
111
112skip_list_loop(Proto, Map = #protocol_list_begin{etype = Etype,
113 size = Size}) ->
114 case Size of
115 N when N > 0 ->
116 skip(Proto, Etype),
117 skip_list_loop(Proto,
118 Map#protocol_list_begin{size = Size - 1});
119 0 -> ok
120 end.