Skip to content

Commit 8a1f228

Browse files
Expose peek_value_size only for tsting
1 parent 78f9d7e commit 8a1f228

2 files changed

Lines changed: 77 additions & 48 deletions

File tree

deps/amqp10_common/src/amqp10_binary_parser.erl

Lines changed: 47 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -17,8 +17,12 @@
1717

1818
-export([parse/1,
1919
parse_many/2,
20-
peek/1,
21-
peek_value_size/1]).
20+
peek/1]).
21+
22+
-ifdef(TEST).
23+
-export([peek_value_size_fixed_test/0,
24+
peek_value_size_variable_test/0]).
25+
-endif.
2226

2327
%% §1.6
2428
-define(CODE_ULONG, 16#80).
@@ -341,18 +345,20 @@ pm_compound(UnitSize, Bin, O, B) ->
341345
reached_body(Position, DescriptorCode) ->
342346
[{{pos, Position}, {body, DescriptorCode}}].
343347

344-
%% Returns the descriptor of the described type at the start of the binary,
345-
%% without parsing the value.
346-
-spec peek(binary()) -> {ulong, non_neg_integer()} | {symbol, binary()}.
348+
%% Returns the descriptor and total byte size (1 + B1 + B2) of the described type
349+
%% at the start of the binary, without parsing the value.
350+
-spec peek(binary()) ->
351+
{({ulong, non_neg_integer()} | {symbol, binary()}), TotalSize :: non_neg_integer()}.
347352
peek(<<?DESCRIBED, Rest/binary>>) ->
348-
{Descriptor, _B1} = parse(Rest),
349-
Descriptor;
353+
{Descriptor, B1} = parse(Rest),
354+
<<_:B1/binary, Rest1/binary>> = Rest,
355+
B2 = peek_value_size(Rest1),
356+
{Descriptor, 1 + B1 + B2};
350357
peek(<<Type, _/binary>>) ->
351358
throw({not_described_type, Type}).
352359

353360
%% Returns the byte size of the AMQP value at the start of the binary
354-
%% without parsing it (no term construction).
355-
-spec peek_value_size(binary()) -> non_neg_integer().
361+
%% without parsing it (no term construction). Used by peek/1.
356362
peek_value_size(<<16#40, _/binary>>) -> 1;
357363
peek_value_size(<<16#41, _/binary>>) -> 1;
358364
peek_value_size(<<16#42, _/binary>>) -> 1;
@@ -394,3 +400,35 @@ peek_value_size(<<16#e0, S:8, _/binary>>) -> 2 + S;
394400
peek_value_size(<<16#f0, S:32, _/binary>>) -> 5 + S;
395401
peek_value_size(<<Type, _/binary>>) ->
396402
throw({primitive_type_unsupported, Type, peek_value_size}).
403+
404+
-ifdef(TEST).
405+
-include_lib("eunit/include/eunit.hrl").
406+
407+
peek_value_size_fixed_test() ->
408+
%% 1-byte primitives (type code only)
409+
?assertEqual(1, peek_value_size(<<16#40, 0>>)),
410+
?assertEqual(1, peek_value_size(<<16#41, 0>>)),
411+
?assertEqual(1, peek_value_size(<<16#45, 0>>)),
412+
%% 2-byte (type + 1 byte)
413+
?assertEqual(2, peek_value_size(<<16#50, 42>>)),
414+
?assertEqual(2, peek_value_size(<<16#53, 16#75>>)),
415+
%% 3-byte (type + 2 bytes)
416+
?assertEqual(3, peek_value_size(<<16#60, 0, 1>>)),
417+
%% 5-byte (type + 4 bytes)
418+
?assertEqual(5, peek_value_size(<<16#70, 0, 0, 0, 0>>)),
419+
%% 9-byte (type + 8 bytes)
420+
?assertEqual(9, peek_value_size(<<16#80, 0:64>>)),
421+
%% 17-byte (uuid)
422+
?assertEqual(17, peek_value_size(<<16#98, 0:128>>)).
423+
424+
peek_value_size_variable_test() ->
425+
%% Binary: 0xa0 + size (1 byte) + payload -> 2 + S
426+
?assertEqual(5, peek_value_size(<<16#a0, 3, "foo">>)),
427+
%% UTF8: 0xa1 + size + payload
428+
?assertEqual(6, peek_value_size(<<16#a1, 4, "test">>)),
429+
%% Symbol (CODE_SYM_8 = 0xa3)
430+
?assertEqual(7, peek_value_size(<<16#a3, 5, "hello">>)),
431+
%% List: 0xc0 + size byte -> 2 + Size
432+
?assertEqual(4, peek_value_size(<<16#c0, 2, 0, 16#40>>)).
433+
434+
-endif.

deps/amqp10_common/test/binary_parser_SUITE.erl

Lines changed: 30 additions & 39 deletions
Original file line numberDiff line numberDiff line change
@@ -22,8 +22,7 @@ all_tests() ->
2222
roundtrip,
2323
array_with_extra_input,
2424
unsupported_type,
25-
peek_value_size_fixed,
26-
peek_value_size_variable,
25+
peek_described_section_total_sizes,
2726
peek_described_section,
2827
peek_non_described_throws,
2928
peek_total_size_matches_parse
@@ -92,55 +91,51 @@ unsupported_type(_Config) ->
9291
?assertThrow(Expected, amqp10_binary_parser:parse_many(Bin, [])).
9392

9493
%%%===================================================================
95-
%%% peek_value_size/1 and peek/1
94+
%%% peek/1 (exercises peek_value_size internally via described types)
9695
%%%===================================================================
9796

98-
peek_value_size_fixed(_Config) ->
99-
%% 1-byte primitives (type code only)
100-
?assertEqual(1, amqp10_binary_parser:peek_value_size(<<16#40, 0>>)),
101-
?assertEqual(1, amqp10_binary_parser:peek_value_size(<<16#41, 0>>)),
102-
?assertEqual(1, amqp10_binary_parser:peek_value_size(<<16#45, 0>>)),
103-
%% 2-byte (type + 1 byte)
104-
?assertEqual(2, amqp10_binary_parser:peek_value_size(<<16#50, 42>>)),
105-
?assertEqual(2, amqp10_binary_parser:peek_value_size(<<16#53, 16#75>>)),
106-
%% 3-byte (type + 2 bytes)
107-
?assertEqual(3, amqp10_binary_parser:peek_value_size(<<16#60, 0, 1>>)),
108-
%% 5-byte (type + 4 bytes)
109-
?assertEqual(5, amqp10_binary_parser:peek_value_size(<<16#70, 0, 0, 0, 0>>)),
110-
%% 9-byte (type + 8 bytes)
111-
?assertEqual(9, amqp10_binary_parser:peek_value_size(<<16#80, 0:64>>)),
112-
%% 17-byte (uuid)
113-
?assertEqual(17, amqp10_binary_parser:peek_value_size(<<16#98, 0:128>>)).
114-
115-
peek_value_size_variable(_Config) ->
116-
%% Binary: 0xa0 + size (1 byte) + payload -> 2 + S
117-
?assertEqual(5, amqp10_binary_parser:peek_value_size(<<16#a0, 3, "foo">>)),
118-
%% UTF8: 0xa1 + size + payload
119-
?assertEqual(6, amqp10_binary_parser:peek_value_size(<<16#a1, 4, "test">>)),
120-
%% Symbol (CODE_SYM_8 = 0xa3)
121-
?assertEqual(7, amqp10_binary_parser:peek_value_size(<<16#a3, 5, "hello">>)),
122-
%% List: 0xc0 + size byte -> 2 + Size
123-
?assertEqual(4, amqp10_binary_parser:peek_value_size(<<16#c0, 2, 0, 16#40>>)).
97+
%% Asserts peek returns total size equal to byte_size for described sections.
98+
%% Covers the same value-size logic as peek_value_size without calling it,
99+
%% so the suite works when the dep is built without exporting peek_value_size (e.g. CI).
100+
peek_described_section_total_sizes(_Config) ->
101+
Sections = [
102+
{described, {ulong, 16#75}, {binary, <<>>}},
103+
{described, {ulong, 16#75}, {binary, <<"x">>}},
104+
{described, {ulong, 16#75}, {binary, <<"payload">>}},
105+
{described, {symbol, <<"amqp:data:binary">>}, {binary, <<"x">>}},
106+
{described, {symbol, <<"amqp:properties:list">>}, {list, []}},
107+
{described, {symbol, <<"URL">>}, {utf8, <<"http://example.org">>}}
108+
],
109+
lists:foreach(
110+
fun(Term) ->
111+
Bin = iolist_to_binary(amqp10_binary_generator:generate(Term)),
112+
{_Descriptor, TotalSize} = amqp10_binary_parser:peek(Bin),
113+
?assertEqual(byte_size(Bin), TotalSize,
114+
"peek total size must equal section byte size")
115+
end,
116+
Sections).
124117

125118
peek_described_section(_Config) ->
126119
%% v1_0.data: described {ulong, 0x75}, value {binary, <<"x">>}
127120
DataSection = {described, {ulong, 16#75}, {binary, <<"x">>}},
128121
Bin = iolist_to_binary(amqp10_binary_generator:generate(DataSection)),
129-
Descriptor = amqp10_binary_parser:peek(Bin),
122+
{Descriptor, TotalSize} = amqp10_binary_parser:peek(Bin),
130123
?assertEqual('v1_0.data', element(1, amqp10_framing0:record_for(Descriptor))),
124+
?assertEqual(6, TotalSize),
131125
%% v1_0.properties (symbol descriptor) with empty list value
132126
PropsSection = {described, {symbol, <<"amqp:properties:list">>}, {list, []}},
133127
BinProps = iolist_to_binary(amqp10_binary_generator:generate(PropsSection)),
134-
DescriptorProps = amqp10_binary_parser:peek(BinProps),
135-
?assertEqual('v1_0.properties', element(1, amqp10_framing0:record_for(DescriptorProps))).
128+
{DescriptorProps, TotalSizeProps} = amqp10_binary_parser:peek(BinProps),
129+
?assertEqual('v1_0.properties', element(1, amqp10_framing0:record_for(DescriptorProps))),
130+
?assertEqual(byte_size(BinProps), TotalSizeProps).
136131

137132
peek_non_described_throws(_Config) ->
138133
%% First byte must be ?DESCRIBED (0); any other type throws
139134
?assertThrow({not_described_type, 16#40}, amqp10_binary_parser:peek(<<16#40>>)),
140135
?assertThrow({not_described_type, 16#41}, amqp10_binary_parser:peek(<<16#41, 0>>)).
141136

142137
peek_total_size_matches_parse(_Config) ->
143-
%% For any described type, total size (1 + descriptor size + value size) must equal bytes consumed by parse
138+
%% For any described type, peek total size must equal bytes consumed by parse
144139
Sections = [
145140
{described, {ulong, 16#75}, {binary, <<>>}},
146141
{described, {ulong, 16#75}, {binary, <<"payload">>}},
@@ -150,13 +145,9 @@ peek_total_size_matches_parse(_Config) ->
150145
lists:foreach(
151146
fun(Term) ->
152147
Bin = iolist_to_binary(amqp10_binary_generator:generate(Term)),
153-
<<0, Rest/binary>> = Bin,
154-
{_Descriptor, B1} = amqp10_binary_parser:parse(Rest),
155-
<<_:B1/binary, Rest1/binary>> = Rest,
156-
B2 = amqp10_binary_parser:peek_value_size(Rest1),
157-
TotalSize = 1 + B1 + B2,
148+
{_Descriptor, TotalSize} = amqp10_binary_parser:peek(Bin),
158149
{_Parsed, BytesParsed} = amqp10_binary_parser:parse(Bin),
159150
?assertEqual(BytesParsed, TotalSize,
160-
"total size must match parse bytes consumed")
151+
"peek total size must match parse bytes consumed")
161152
end,
162153
Sections).

0 commit comments

Comments
 (0)