summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--.gitignore8
-rw-r--r--lib/erl/Makefile.am7
-rw-r--r--lib/erl/include/thrift_protocol.hrl12
-rw-r--r--lib/erl/src/thrift_protocol.erl15
-rw-r--r--lib/erl/test/Thrift_omit_with.thrift22
-rw-r--r--lib/erl/test/test_omit.erl79
6 files changed, 126 insertions, 17 deletions
diff --git a/.gitignore b/.gitignore
index 00cf8bb33..bdb84ea59 100644
--- a/.gitignore
+++ b/.gitignore
@@ -207,13 +207,15 @@ project.lock.json
/lib/delphi/test/typeregistry/*.identcache
/lib/delphi/test/typeregistry/*.local
/lib/delphi/test/typeregistry/*.dcu
-/lib/erl/.generated
/lib/erl/.eunit
-/lib/erl/ebin
+/lib/erl/.generated
+/lib/erl/.rebar/
/lib/erl/deps/
+/lib/erl/ebin
/lib/erl/src/thrift.app.src
-/lib/erl/test/*.hrl
/lib/erl/test/*.beam
+/lib/erl/test/*.hrl
+/lib/erl/test/Thrift_omit_without.thrift
/lib/haxe/test/bin
/lib/hs/dist
/lib/java/build
diff --git a/lib/erl/Makefile.am b/lib/erl/Makefile.am
index 92e2204f6..20aadebb3 100644
--- a/lib/erl/Makefile.am
+++ b/lib/erl/Makefile.am
@@ -18,7 +18,9 @@
#
THRIFT = ../../compiler/cpp/thrift
+THRIFT_OMIT_FILE = test/Thrift_omit_without.thrift
THRIFT_FILES = $(wildcard test/*.thrift) \
+ $(THRIFT_OMIT_FILE) \
../../test/ConstantsDemo.thrift \
../../test/NameConflictTest.thrift \
../../test/ThriftTest.thrift
@@ -33,6 +35,10 @@ ERL_FLAG = erl
ERL_FLAG_LEGACY = erl:legacynames
ERL_FLAG_MAPS = erl:maps
endif
+
+$(THRIFT_OMIT_FILE): test/Thrift_omit_with.thrift
+ grep -v omit $< >$@
+
.generated: $(THRIFT) $(THRIFT_FILES)
for f in $(THRIFT_FILES) ; do \
$(THRIFT) --gen $(ERL_FLAG) -o test $$f ; \
@@ -65,6 +71,7 @@ uninstall:
clean:
rm -f .generated
rm -rf test/gen-erl/
+ rm -f $(THRIFT_OMIT_FILE)
$(REBAR) clean
maintainer-clean-local:
diff --git a/lib/erl/include/thrift_protocol.hrl b/lib/erl/include/thrift_protocol.hrl
index f85f4552a..bc0acc883 100644
--- a/lib/erl/include/thrift_protocol.hrl
+++ b/lib/erl/include/thrift_protocol.hrl
@@ -20,12 +20,12 @@
-ifndef(THRIFT_PROTOCOL_INCLUDED).
-define(THRIFT_PROTOCOL_INCLUDED, true).
--record(protocol_message_begin, {name, type, seqid}).
--record(protocol_struct_begin, {name}).
--record(protocol_field_begin, {name, type, id}).
--record(protocol_map_begin, {ktype, vtype, size}).
--record(protocol_list_begin, {etype, size}).
--record(protocol_set_begin, {etype, size}).
+-record(protocol_message_begin, {name :: string(), type :: integer(), seqid :: integer()}).
+-record(protocol_struct_begin, {name :: string()}).
+-record(protocol_field_begin, {name :: string(), type :: integer(), id :: integer()}).
+-record(protocol_map_begin, {ktype :: integer(), vtype :: integer(), size :: integer()}).
+-record(protocol_list_begin, {etype :: integer(), size :: integer()}).
+-record(protocol_set_begin, {etype :: integer(), size :: integer()}).
-type tprot_header_val() :: #protocol_message_begin{}
| #protocol_struct_begin{}
diff --git a/lib/erl/src/thrift_protocol.erl b/lib/erl/src/thrift_protocol.erl
index dc3bfef2e..2fe10d6a2 100644
--- a/lib/erl/src/thrift_protocol.erl
+++ b/lib/erl/src/thrift_protocol.erl
@@ -219,12 +219,11 @@ read_struct_loop(IProto0, SDict, RTuple) ->
end.
skip_field(FType, IProto0, SDict, RTuple) ->
- FTypeAtom = thrift_protocol:typeid_to_atom(FType),
- {IProto1, ok} = thrift_protocol:skip(IProto0, FTypeAtom),
+ {IProto1, ok} = skip(IProto0, typeid_to_atom(FType)),
{IProto2, ok} = read(IProto1, field_end),
read_struct_loop(IProto2, SDict, RTuple).
--spec skip(#protocol{}, any()) -> {#protocol{}, ok}.
+-spec skip(#protocol{}, atom()) -> {#protocol{}, ok}.
skip(Proto0, struct) ->
{Proto1, ok} = read(Proto0, struct_begin),
@@ -261,7 +260,7 @@ skip_struct_loop(Proto0) ->
?tType_STOP ->
{Proto1, ok};
_Else ->
- {Proto2, ok} = skip(Proto1, Type),
+ {Proto2, ok} = skip(Proto1, typeid_to_atom(Type)),
{Proto3, ok} = read(Proto2, field_end),
skip_struct_loop(Proto3)
end.
@@ -271,8 +270,8 @@ skip_map_loop(Proto0, Map = #protocol_map_begin{ktype = Ktype,
size = Size}) ->
case Size of
N when N > 0 ->
- {Proto1, ok} = skip(Proto0, Ktype),
- {Proto2, ok} = skip(Proto1, Vtype),
+ {Proto1, ok} = skip(Proto0, typeid_to_atom(Ktype)),
+ {Proto2, ok} = skip(Proto1, typeid_to_atom(Vtype)),
skip_map_loop(Proto2,
Map#protocol_map_begin{size = Size - 1});
0 -> {Proto0, ok}
@@ -282,7 +281,7 @@ skip_set_loop(Proto0, Map = #protocol_set_begin{etype = Etype,
size = Size}) ->
case Size of
N when N > 0 ->
- {Proto1, ok} = skip(Proto0, Etype),
+ {Proto1, ok} = skip(Proto0, typeid_to_atom(Etype)),
skip_set_loop(Proto1,
Map#protocol_set_begin{size = Size - 1});
0 -> {Proto0, ok}
@@ -292,7 +291,7 @@ skip_list_loop(Proto0, Map = #protocol_list_begin{etype = Etype,
size = Size}) ->
case Size of
N when N > 0 ->
- {Proto1, ok} = skip(Proto0, Etype),
+ {Proto1, ok} = skip(Proto0, typeid_to_atom(Etype)),
skip_list_loop(Proto1,
Map#protocol_list_begin{size = Size - 1});
0 -> {Proto0, ok}
diff --git a/lib/erl/test/Thrift_omit_with.thrift b/lib/erl/test/Thrift_omit_with.thrift
new file mode 100644
index 000000000..8bffc7c73
--- /dev/null
+++ b/lib/erl/test/Thrift_omit_with.thrift
@@ -0,0 +1,22 @@
+struct test1 {
+ 1: i32 one
+ 2: i32 two // omit
+ 3: i32 three
+}
+
+struct test2 {
+ 1: i32 one
+ 2: test2 two // omit
+ 3: i32 three
+}
+
+struct test3 {
+ 1: i32 one
+ 2: list<test1> two // omit
+}
+
+struct test4 {
+ 1: i32 one
+ 2: map<i32,test1> two // omit
+}
+
diff --git a/lib/erl/test/test_omit.erl b/lib/erl/test/test_omit.erl
new file mode 100644
index 000000000..80841e291
--- /dev/null
+++ b/lib/erl/test/test_omit.erl
@@ -0,0 +1,79 @@
+-module(test_omit).
+
+-include("gen-erl/thrift_omit_with_types.hrl").
+
+-ifdef(TEST).
+-include_lib("eunit/include/eunit.hrl").
+
+omit_struct1_test() ->
+ %% In this test, the field that is deleted is a basic type (an i32).
+ A = #test1{one = 1, three = 3},
+ B = #test1{one = 1, two = 2, three = 3},
+ {ok, Transport} = thrift_membuffer_transport:new(),
+ {ok, P0} = thrift_binary_protocol:new(Transport),
+
+ {P1, ok} = thrift_protocol:write(P0, {{struct, {thrift_omit_with_types, element(1, A)}}, A}),
+ {P2, {ok, O0}} = thrift_protocol:read(P1, {struct, {thrift_omit_without_types, element(1, A)}}),
+ ?assertEqual(element(1, A), element(1, O0)),
+ ?assertEqual(element(2, A), element(2, O0)),
+ ?assertEqual(element(4, A), element(3, O0)),
+
+ {P3, ok} = thrift_protocol:write(P2, {{struct, {thrift_omit_with_types, element(1, B)}}, B}),
+ {_P4, {ok, O1}} = thrift_protocol:read(P3, {struct, {thrift_omit_without_types, element(1, A)}}),
+ ?assertEqual(element(1, A), element(1, O1)),
+ ?assertEqual(element(2, A), element(2, O1)),
+ ?assertEqual(element(4, A), element(3, O1)),
+
+ ok.
+
+omit_struct2_test() ->
+ %% In this test, the field that is deleted is a struct.
+ A = #test2{one = 1, two = #test2{one = 10, three = 30}, three = 3},
+ B = #test2{one = 1, two = #test2{one = 10, two = #test2{one = 100}, three = 30}, three = 3},
+
+ {ok, Transport} = thrift_membuffer_transport:new(),
+ {ok, P0} = thrift_binary_protocol:new(Transport),
+
+ {P1, ok} = thrift_protocol:write(P0, {{struct, {thrift_omit_with_types, element(1, A)}}, A}),
+ {P2, {ok, O0}} = thrift_protocol:read(P1, {struct, {thrift_omit_without_types, element(1, A)}}),
+ ?assertEqual(element(1, A), element(1, O0)),
+ ?assertEqual(element(2, A), element(2, O0)),
+ ?assertEqual(element(4, A), element(3, O0)),
+
+ {P3, ok} = thrift_protocol:write(P2, {{struct, {thrift_omit_with_types, element(1, B)}}, B}),
+ {_P4, {ok, O1}} = thrift_protocol:read(P3, {struct, {thrift_omit_without_types, element(1, A)}}),
+ ?assertEqual(element(1, A), element(1, O1)),
+ ?assertEqual(element(2, A), element(2, O1)),
+ ?assertEqual(element(4, A), element(3, O1)),
+
+ ok.
+
+omit_list_test() ->
+ %% In this test, the field that is deleted is a list.
+ A = #test1{one = 1, two = 2, three = 3},
+ B = #test3{one = 1, two = [ A ]},
+
+ {ok, Transport} = thrift_membuffer_transport:new(),
+ {ok, P0} = thrift_binary_protocol:new(Transport),
+
+ {P1, ok} = thrift_protocol:write(P0, {{struct, {thrift_omit_with_types, element(1, B)}}, B}),
+ {_P2, {ok, O0}} = thrift_protocol:read(P1, {struct, {thrift_omit_without_types, element(1, B)}}),
+ ?assertEqual(element(2, B), element(2, O0)),
+
+ ok.
+
+omit_map_test() ->
+ %% In this test, the field that is deleted is a map.
+ A = #test1{one = 1, two = 2, three = 3},
+ B = #test4{one = 1, two = dict:from_list([ {2, A} ])},
+
+ {ok, Transport} = thrift_membuffer_transport:new(),
+ {ok, P0} = thrift_binary_protocol:new(Transport),
+
+ {P1, ok} = thrift_protocol:write(P0, {{struct, {thrift_omit_with_types, element(1, B)}}, B}),
+ {_P2, {ok, O0}} = thrift_protocol:read(P1, {struct, {thrift_omit_without_types, element(1, B)}}),
+ ?assertEqual(element(2, B), element(2, O0)),
+
+ ok.
+
+-endif. %% TEST